为什么要Mining?
交易(transaction)确认后的资讯以Merkle tree 来做纪录,所以就要有Block 来储存这个Merkle tree。这个时候就需要有新的区块。
在Bitcoin 的生态中,mining(挖矿)的主要目的就是「产生新的区块」,当区块产生时,就会产生另一个「副作用」:新Bitcoin 被产生出来。
简单说,产生新的Bitcoin 并不是挖矿的主要目的,这只是挖矿的副作用。挖矿的主要目的,是生产区块来确认并纪录新的交易资讯。本章的目标,在学习挖矿的基本知识,内容以简单易懂为原则,并不是介绍如何重新实作Bitcoin 的挖矿技术。但教学内容会以Bitcoin 做为实例,辅助说明mining 技术。
Difficulty
众所皆知,Bitcoin 的挖矿难度是非常高的。这个意思是:产生新的Block 是一件非常困难的事情。Bitcoin 将挖矿设计的非常困难,其实是有一个很重要的原因:避免有人任意产生区块。
要产生新的区块,就会有所谓的difficulty(难度),这个difficulty 的作用是什么呢?主要目的是:决定新的hash 值产生条件。
要产生新的区块前,必须先计算出这个区块的Block Hash,区块的hash 值如何决定呢?这点后续再谈。因为,这里有一个更重要的问题:如何决定这个hash 值是否可用?
例如,根据新的交易与其它资讯,运算出一个double SHA-256 的hash 值如下:
18AC3E7343F016890C510E93F935261169D9E3F565436429830FAF0934F4F8E4
新的区块是否就能直接使用这个hash 值呢?如果可以,表示新的hash 值已成功(success)建立,如果不行,表示新的hash 值产生失败。系统必须不断进行运算,「直到成功得到新的hash 值」。
不如用一个简单的方法,来「定义什么是success」:当产生的hash 值前面「有足够的零」时,就是success。例如,「前面至少要有2 个零」,上述的hash 值就是失败的运算。以下的这个hash 值,则是success:
0018AC3E7343F016890C510E93F935261169D9E3F565436429830FAF0934F4F8
这个条件就是difficulty 会储存在最后一个区块上,所以修改22.1 节的范例,加入difficulty 栏位,并且在Genesis Block 里,设定最原始的difficulty 为「前面至少有2 个零」。
function Block(block) { this.hash = block.hash || ''; this.previousHash = block.previousHash || ''; this.timestamp = block.timestamp || new Date(); this.merkleRoot = block.merkleRoot || {}; this.difficulty = block.difficulty || '00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'; }
以JavaScript 来实作时,只要以字串比对方式,就可以知道hash 值是否为success 了。例如:
if ('CD18AC3E7343F016890C510E93F935261169D9E3F565436429830FAF0934F4' <'00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF') { // success } else { // failed }
越来越难
新的区块产生后,会「重新调整」这个difficulty。例如,将difficulty 调整为「前面至少有3 个零」,这时,可以将新区块的difficulty 栏位设定为:
000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Difficulty 的条件设定,由每一个区块链系统的设计者所制定。但是有一个基本原则就是:难度必须越来越高,以上述例子来说,要产生「前面3 个零」的hash 值,其难度大于「前面2 个零」的hash 值。
小结
认识为什么要mining 以及什么是difficulty 后,就可以开始设计mining 的算法了。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。