python环境挖矿
A. 挖矿难度表示
比特币的挖矿难度可以使用Target Threshold,nBits或Difficulty表示,它们互相等价:
这三个值的转化关系可以采用下面的实例来说明:
首先获取哈希值为 的区块原生十六进制信息如下:
区块中nBits采用小端格式表示,解析区块信息,得到nBits字段值为0x4c86041b。因此转化为大端格式为0x1B04864C,这个值是Target Threshold的压缩格式表示,可以将它转化成256位的Target Threshold值:
开头的一个字节为指数,后面三个字节为系数,则:
计算出Target Threshold值为 。
再计算Difficulty的值,它有两个值,计算公式分别为:
由此可以使用 Python 计算出bdiff的值:
因此,得到在比特币客户端中的difficulty值bdiff为14484.162361225399。
为了检验上述结果,可以在比特币核心客户端中使用 getblock "" 命令得到该区块的json格式信息:
最终,可以发现该区块的bits和difficulty字段信息与上面分析计算的相关结果一致。
nBits的大端格式表示法中,其系数最大为0x7fffff,这是因为Target Threshold数据类型是无符号整型,而它继承自有符号数据类,则在实际中Target Threshold系数的最高位有可能是1,这可能会被解析成一个负数。则在挖矿过程中难度值永远无法小于一个负数。因此,为了解决这个问题,比特币核心在生成nBits值时需要首先检查一下生成的nBits是否会被解析为一个负数。如果是,首先在系数开头补8位0,即除以256,然后指数再加上1。这样由nBits转化为Target Threshold过程中转化公式就与普通值相同了,即指数位都是减去3,转化过程上面已经提到。
举个例子说明:
哈希值为 的区块信息如下:
发现bdiff值为1,则利用bdiff与Target Threshold关系可以计算出:
将Target Threshold值 转化为nBits的过程中可以发现其系数为0xffff00,指数为0x1c,这样:
然而由于系数最高位为1,则如果这样表示的话就可能将Target Threshold解析为负数。因此,我们将系数除以256,指数加上1,得到系数为0x00ffff,指数为0x1d。这样:
最终,nBits值为0x1d00ffff(大端表示),与json格式信息一致。