挖矿难度

\[H(version,target,nonce,Hash_{pre},MerkleTreeRoot) <= target\]

比特币中使用的Hash算法是SHA-256,产生的Hash值是256位。即整个输出空间是$2^{256}$。比特币的挖矿难度的调整,就是调整目标空间占输出空间的比例,通俗来讲就是Hash值前面要有多少个0。比如对于256位的Hash值,要称为合法的区块,要求算出来的Hash值前面至少有70个0。

挖矿的难度跟目标阈值成反比,即目标阈值越大,挖矿难度越小。

那么为什么要调整挖矿难度呢?如果不调整挖矿难度会有什么问题?

随着系统中的总算力越来越强,如果不调整挖矿难度,那么出块时间会越来越短。假如不到一秒就出一个块,但区块在网络上传播的时间可能就需要几十秒。别的节点在没有收到这个块之前还会继续沿着已有的区块链往下扩展。如果有两个节点同时发布一个区块,这时就会出现分叉。

出块时间越短,分叉越容易出现,不仅会出现二分叉,还会出现更多的分叉。假如同时有10个块被挖出,那么系统可能会出现10分叉。

分叉过多,对于系统达成共识没有任何好处,而且还会威胁到系统的安全性。比特币协议是假设大部分算力是掌握在诚实的矿工手里,这种情况下,系统中总算力越强,系统安全性就越高。因为系统总算力越强,恶意节点想掌握51%算力就越困难。

出块过快,不可避免的会出现分叉。分叉过多会导致算力分散,此时恶意节点发动攻击成功的概率就很大,因为并不需要掌控51%的算力,甚至可能10%的算力就可以发动攻击。

比特币中出块时间大约为10min。那么10min的出块时间是不是最优的?答案是不一定,改成其它值也可以,间隔只是说应该有个常数范围。例如以太坊的出块时间在15s左右。

如何调整挖矿难度

在比特币协议中规定,没2016个区块后就要调整目标阈值,大概是每两星期调整一次,公式如下:

difficulty = difficulty_1_target/target

difficulty_1_target指挖矿难度为1时的目标阈值,此时挖矿难度为1,target是个非常大的数。

\[target = target * (actual \quad time/expected \quad time)\]

actual time指产生2016个区块实际用时,expected time指产生2016个区块应该花费的时间,即 2016 * 10min

从上面的公式可以看出,如果平均出块时间大于10min,则target值会相应增大,挖矿难度则会相应减小。

实际上,上调和下调都有四倍的限制,即实际时间超过8个星期,也只能按4倍算,目标阈值增大最多只能增大4倍。

目标阈值如何同步

计算target的方法是写在比特币系统的源码里面,每生成2016个区块,系统就会自动进行调整。

那如果有恶意节点故意不调呢?

nBits是target编码后的版本,在blocke header里没有直接存储target的域。因为target的域是256位,直接存储的话要32个字节,nBits只有4个字节,所以可以认为nBits是target编码后的。

如果有恶意节点在该调的时候不调,它生成的区块在发布到网络上时,其它节点会先检查该区块的合法性。检查的内容就包括nBits,检查不通过,其它节点就不会接受该区块。


声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin92
Github: mengbin92
cnblogs: 恋水无意