区块链工作量证明 POW

1. 共识算法

在整个区块链工作过程中,会有很多的机器加入其中,每一台机器成为一个节点,它们互相协作,来共同维护区块链的安全和数据的一致。其中,生成新的区块就是一项很重要的工作。因为新的区块里面包含很多新产生的重要数据,比如交易信息等。为了让这项工作有序和可控,通常会在所有节点上通过竞争选出一个节点,由这个胜出的节点负责打包新产生的数据,并通知和传播给其它节点。

通过竞争选择优胜者的机制称为共识算法,目前主流加密货币引入了很多共识算法,比如 pow, pos, dpos, pbft 等等。象比特币就是采用了 pow 算法,也就是工作量证明。

2. 工作量证明

工作量证明 (Proof Of Work,简称POW),就是用来确认你做过一定量的工作的一份证明。通常,监测工作过程是极为低效的,而通过对工作的结果的认证来证明完成了相应的工作量,则是一种非常高效的方式。比如现实生活中的毕业证、驾驶证等,也是通过检验结果的方式(通过相关的考试)所取得的证明。

区块链的工作量证明,就是由系统给出一个难题,让节点们各自通过计算来解决这个难题。凡是声称解决难题的节点,都要把自己的答案交由其它节点进行验证,最终选出优胜者,由它来负责生成新的区块。为什么节点有动力耗费自己的资源去解决难题呢?因为新区块的生成者有一定的奖励,这就是比特币中所说的挖矿。在区块链中,网络的一些参与者(矿工)努力维持网络,向其添加新区块,并获得对其工作的奖励。正是由于他们的工作,区块以安全和及时的方式被整合到区块链中,保持了整个区块链数据库的稳定性和连续性。

另外,工作量证明算法必须满足要求:完成工作很难,但验证证明很容易。证明通常会交给其他人,因此对他们来说,验证它不应该花费太多时间。

我们要实现的工作量证明算法与比特币的算法相同,就是给定一个256 位的大数字 target(称为难度目标),节点们通过变化新区块 Block 中成员 Nonce 的数值,使得 Block 的 hash 值小于或者等于难度目标 target。

Pow 表示一个工作量算法结构(以下为 golang 代码):

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()) + ""
	content = content + "当前区块内容为:" +  string(block.Data) + ""
	content = content + "当前区块Nonce为:" +  strconv.Itoa(int(block.Nonce)) + ""
	content = content + "前一区块哈希值:" +  BytesToHex(block.HashPrevBlock) + ""
	content = content + "=============================================" + ""

3. 运行区块链

运行后输出:

当前MiniBC区块链高度:10

当前区块哈希值:6068fa9b758532a182be2552e0e532c99e2c5717f6696558d008eec5f5c7cb87
当前区块内容为:MiniBC Block 9
当前区块Nonce为:7746
前一区块哈希值:97100d2c4efe4f11ac4508d5da17816b738d99795021de5676aebf90868990e0
=============================================
当前区块哈希值:97100d2c4efe4f11ac4508d5da17816b738d99795021de5676aebf90868990e0
当前区块内容为:MiniBC Block 8
当前区块Nonce为:2311874
前一区块哈希值:5bc776166df69054ed1490670ee7ad38cefea49ba3799749a9c47381c6e152ad
=============================================
当前区块哈希值:5bc776166df69054ed1490670ee7ad38cefea49ba3799749a9c47381c6e152ad
当前区块内容为:MiniBC Block 7
当前区块Nonce为:9428
前一区块哈希值:9d2afa19dfbf840387f71bbabebd7dd4358999151bcf5a496a838eeb2afebd79
=============================================

当前区块Nonce显示内容是我们通过计算找到的随机数。

4. 我们实现的和将要实现的目标

我们已经构建了一个简单的区块链,并且实现了一个KV数据库、区块链浏览器和工作量证明,下一步来实现交易Transaction。

源码地址:https://github.com/wangshizebin/minibc

下一章:MetaMask 使用教程

MetaMask 是一款在谷歌浏览器 Chrome 上使用的插件型的轻量级以太坊钱包,MetaMask 钱包无需下载,只要在谷歌浏览器添加对应的扩展程序即可,使用起来非常方便。 1、Chrome的安装既 ...