工作量证明 | Proof Of Work
区块链是通过网络上匿名的节点协同维护的,所以比特币需要每个区块证明在创建他们的过程中投入了足够多的工作量,从而确保那些想篡改历史区块信息的不可信懒的节点必须要比只想添加新区块到区块链的诚实节点付出更多的工作量。
将区块链在一起使得只修改一个交易而不修改所有后续交易成为不可能。因此随着新的区块被添加到区块链,修改一个特定区块的成本在不断提升,从而放大了工作量证明的作用。
比特币中的工作量证明利用了密码学哈希的伪随机性。一个好的密码学哈希算法可以将任意数据转换为看似随机的数字。如果原始数据的任何地方被更改了,然后重新做哈希,一个新的看似随机的数字就产生出来了,所以通过更改原始数据预测哈希值是不可能做到的。
为了证明你为创造一个区块做了一些工作,你必须算出一个不超过某个特定值的区块头的哈希值。比如,如果这个哈希值最大为 2256-1,你可以证明你算出一个小于 2255 的哈希值做了至多两次组合。
在上面给出的例子中,你可能在某次尝试中就得到了一个成功的哈希值。你甚至可以估算出算出低于目标阈值的概率。比特币设定了一个线性的概率,目标阈值越小,你需要尝试计算的哈希值次数越多(平均来说)。
当一个新的区块的哈希值至少与一致性协议期望的难度值相当时,它才会被加到区块链中。每产生 2,016 个区块,比特币网络使用存储在区块头中的时间戳来计算这 2,016 个区块的第一个和最后一个区块的时间差值,理想的值为 1,209,600 秒(及两周)。
- 如果生成这 2,016 个区块所用的时间比两周短,那么预期的难度将会相应的增长(大概为 300%),这样在哈希算力保持不变的情况下,之后的 2,016 个区块的生成应该刚好会用两周的时间。
- 如果生成这些区块的时间超过了两周,出于同样的原因,预期的难度也会相应的递减(大概为 75%)。
(注意:在比特币内核实现中存在一个差一错误,导致算力难度的是由 2,016 个区块中的 2,015 个区块的时间戳来更新的,产生了一个微小的偏差。)
因为每一个区块头的哈希值必须是比目标阈值要小的,并且每个区块与先前的一个链接在一起,所以想对一个区块做更改需要(一般来说)付出整个比特币网络从原始区块时间点到当前时间点所消耗的哈希算力。只有当你拥有了整个网络大部分的哈希算力时你才有可能发起一个有效的 51 攻击来篡改交易纪录(当然,需要指出的是,即便你拥有的算力小于 50%,仍然有机会发起这样的攻击。)
区块头提供了一些便于修改的字段,例如 nonce 字段,因此获取新的哈希值时并不需要为新的交易而等待(译者注:我理解这里的意思是通过缓存状态而避免每次计算哈希都需要遍历交易记录。)同时,只有区块头的 80 个字节被用来当作工作量证明做哈希,所以并不会因为区块读取其包含的大量的交易数据所产生的 I/O 延时而延缓哈希运算,并且在添加一个额外的交易数据时只需要重新计算一下 merkle 树的原始节点哈希即可。