## MiniBC区块链V004 - 工作量证明POW #
#### 共识算法
在整个区块链工作过程中,会有很多的机器加入其中,每一台机器成为一个节点,它们互相协作,来共同维护区块链的安全和数据的一致。其中,生成新的区块就是一项很重要的工作。因为新的区块里面包含很多新产生的重要数据,比如交易信息等。为了让这项工作有序和可控,通常会在所有节点上通过竞争选出一个节点,由这个胜出的节点负责打包新产生的数据,并通知和传播给其它节点。
通过竞争选择优胜者的机制称为共识算法,目前主流加密货币引入了很多共识算法,比如pow, pos, dpos, pbft等等。象比特币就是采用了pow算法,也就是工作量证明。
#### 工作量证明
工作量证明 (Proof Of Work,简称POW),就是用来确认你做过一定量的工作的一份证明。通常,监测工作过程是极为低效的,而通过对工作的结果的认证来证明完成了相应的工作量,则是一种非常高效的方式。比如现实生活中的毕业证、驾驶证等,也是通过检验结果的方式(通过相关的考试)所取得的证明。
区块链的工作量证明,就是由系统给出一个难题,让节点们各自通过计算来解决这个难题。凡是声称解决难题的节点,都要把自己的答案交由其它节点进行验证,最终选出优胜者,由它来负责生成新的区块。为什么节点有动力耗费自己的资源去解决难题呢?因为新区块的生成者有一定的奖励,这就是比特币中所说的挖矿。在区块链中,网络的一些参与者(矿工)努力维持网络,向其添加新区块,并获得对其工作的奖励。正是由于他们的工作,区块以安全和及时的方式被整合到区块链中,保持了整个区块链数据库的稳定性和连续性。
另外,工作量证明算法必须满足要求:完成工作很难,但验证证明很容易。证明通常会交给其他人,因此对他们来说,验证它不应该花费太多时间。
我们要实现的工作量证明算法与比特币的算法相同,就是给定一个256位的大数字target(称为难度目标),节点们通过变化新区块Block中成员Nonce的数值,使得Block的hash值小于或者等于难度目标target。
Pow表示一个工作量算法结构:
type Pow struct {
//要进行工作量计算的区块
block *Block
//工作量难度目标
bits int32
}
里面包含一个新创建的区块block和难度目标bits。我们这里做了简化,真正的难度目标应该是256位的大数,我们先用一个32位的整数替代,由bits通过简单的变换生成256位的难度目标,下面有具体的变换算法。
我们通过不断变换nonce值来计算区块的hash,找到符合给定难度目标的nonce值
func (pow *Pow) Run() {
//将0x1左移pow.bits位生成一个256位的大整数target,这是真正的难度目标值
target := big.NewInt(1)
target.Lsh(target, uint(pow.bits))
//通过不断变换nonce值来计算区块的hash,直至找到小于或等于target的nonce值
var hashInt big.Int
for nonce := int32(0); nonce < math.MaxInt32; nonce++ {
hashInt.SetBytes(pow.getHash(pow.bits, nonce))
if hashInt.Cmp(target) <= 0 {
//找到合适的nonce值,将其写入block中
pow.block.Nonce = nonce
pow.block.Bits = pow.bits
break
}
}
}
另外,修改一下BlockBrowser的显示,能够打印出找到随机数nonce:
content = content + "当前区块哈希值:" + BytesToHex(block.GetHash()) + "<br>"
content = content + "当前区块内容为:" + string(block.Data) + "<br>"
content = content + "当前区块Nonce为:" + strconv.Itoa(int(block.Nonce)) + "<br>"
content = content + "前一区块哈希值:" + BytesToHex(block.HashPrevBlock) + "<br>"
content = content + "=============================================" + "<br>"
运行后输出:
当前MiniBC区块链高度:10
当前区块哈希值:6068fa9b758532a182be2552e0e532c99e2c5717f6696558d008eec5f5c7cb87
当前区块内容为:MiniBC Block 9
当前区块Nonce为:7746
前一区块哈希值:97100d2c4efe4f11ac4508d5da17816b738d99795021de5676aebf90868990e0
=============================================
当前区块哈希值:97100d2c4efe4f11ac4508d5da17816b738d99795021de5676aebf90868990e0
当前区块内容为:MiniBC Block 8
当前区块Nonce为:2311874
前一区块哈希值:5bc776166df69054ed1490670ee7ad38cefea49ba3799749a9c47381c6e152ad
=============================================
当前区块哈希值:5bc776166df69054ed1490670ee7ad38cefea49ba3799749a9c47381c6e152ad
当前区块内容为:MiniBC Block 7
当前区块Nonce为:9428
前一区块哈希值:9d2afa19dfbf840387f71bbabebd7dd4358999151bcf5a496a838eeb2afebd79
=============================================
当前区块Nonce显示内容是我们通过计算找到的随机数。
一切正常~~~~~~~
#### 我们实现的和将要实现的
我们已经构建了一个简单的区块链,并且实现了一个KV数据库、区块链浏览器和工作量证明,下一步来实现交易Transaction。
#### 交流和疑问
大家可以从v001开始逐步深入的研究学习,每个源码文件均有完整的说明和注释。如果有疑问、建议和不明白的问题,尽可以与我联系。
MiniBC区块链交流可以加入qq群:<font size=5><b>777804802</b></font>,go开发者乐园
我的微信:<font size=5><b>bkra50 </b></font>
github addr: https://github.com/wangshizebin/minibc
另外,招募一群志同道合者,共同维护项目,共同推进项目,为开源世界贡献力量,欢迎勾搭。
Let's go~~~~~~~~~~~~~~~~~~~~~~~~~~~~
有疑问加站长微信联系(非本文作者))