知识库详情
知识库

以“词条释义”的形式对比特币区块链技术中经常涉及的术语及基本概念进行专业化的阐释和解读。

难度
返回上级
BSV区块链编辑 2022-04-14 17:33 450

什么是难度?

难度是在给定区块难度目标(target)的条件下,对找到有效哈希值的困难程度的一种度量。“难度”回答了以下问题:现在挖掘区块比当年挖掘创世区块难了多少倍?“难度”与“区块难度目标”虽密切相关,但并不是一回事。他们之间呈反向关系,即难度高意味着相应的区块难度目标低。

在比特币网络上,区块难度是统一的。有效区块的哈希值一定低于此区块难度目标的值。矿池通常还会自己设定一个收益(share)难度,为矿工可获得收益的哈希值(向矿池提交的有效工作量)设定一个更低的难度。

 

网络难度多久变化一次?

参考区块难度目标

 

难度公式是什么?

difficulty = difficulty_1_target / current_target

难度 = 难度为1的区块难度目标/当前区块难度目标

区块难度目标值是一个 256 位的数字

难度为1的区块难度目标值是创世区块的区块难度目标值,代表难度为1。

对于衡量难度的不同方法来说,难度为1的区块难度目标值可能会有所不同。一般来说,它表示一个有32位前导0,其余位数为 1(这称为“pool difficulty”或“pdiff”)的哈希值。比特币协议用有限精度的自定义浮点方式来表达区块难度目标值,客户端都使用这种方式估算难度,它被称为“bdiff”。

 

难度如何被存储在区块中?

每个区块的区块头中都存储着一个被压缩为十六进制的、代表区块难度目标值的字段,它被称为Bits。区块难度目标值可以根据Bits字段的值,通过预定义的公式推导出来。例如,如果区块中打包的Bits值为 0x1b0404cb,则区块难度目标值(也用十六进制表示)为:

0x0404cb * 2**(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000

请注意,这里的0x0404cb在这个格式下是有符号的(正值),且该字段的最大合法值为 0x7fffff,最小合法值为0x008000。每当要提升难度值时,Bits必须要至少下调一个完整字节。

 

难度是如何计算的? bdiff 和 pdiff 和有什么差别?

我们把最大的区块难度目标值(难度 1)定义为 0x1d00ffff,十六进制表示为:

0x00ffff * 2**(8*(0x1d - 3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000

需要注意的是,矿池挖矿通常使用非截断区块难度目标值, 故“矿池难度1”为:

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

基于这种区别,0x1b0404cb对应的两种难度表达分别是:

0x00000000FFFF0000000000000000000000000000000000000000000000000000 /
0x00000000000404CB000000000000000000000000000000000000000000000000 
= 16307.420938523983 (bdiff)

和:

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /
0x00000000000404CB000000000000000000000000000000000000000000000000 
= 16307.669773817162 (pdiff)

以下是一种快速计算比特币难度的方法。它使用修改后的泰勒级数作为对数(你可以在flipcode和维基百科上看到教程)并依靠对数表来转换难度计算:

<source lang=”cpp”>

  1. include <iostream>
  2. include <cmath>
  int * const exp_ptr = reinterpret_cast (&val);
  int x = *exp_ptr;
  const int log_2 = ((x >> 23) & 255) - 128;
  x &= ~(255 << 23);
  x += 127 << 23;
  *exp_ptr = x;
  val = ((-1.0f/3) * val + 2) * val - 2.0f/3;
  return ((val + log_2) * 0.69314718f);

}

float difficulty(unsigned int bits) {

   static double max_body = fast_log(0x00ffff), scaland = fast_log(256);
   return exp(max_body - fast_log(bits & 0x00ffffff) + scaland * (0x1d - ((bits & 0xff000000) >> 24)));

}

int main() {

   std::cout << difficulty(0x1b0404cb) << std::endl;
   return 0;

} </source>

想要从数学角度查看从普通难度计算(需要比任何普通整数中的空间都大的大整数)到上面的计算过程,下文是该过程的 python 实现:

<source lang=”python”> import decimal, math l = math.log e = math.e

print 0x00ffff * 2**(8*(0x1d – 3)) / float(0x0404cb * 2**(8*(0x1b – 3))) print l(0x00ffff * 2**(8*(0x1d – 3)) / float(0x0404cb * 2**(8*(0x1b – 3)))) print l(0x00ffff * 2**(8*(0x1d – 3))) – l(0x0404cb * 2**(8*(0x1b – 3))) print l(0x00ffff) + l(2**(8*(0x1d – 3))) – l(0x0404cb) – l(2**(8*(0x1b – 3))) print l(0x00ffff) + (8*(0x1d – 3))*l(2) – l(0x0404cb) – (8*(0x1b – 3))*l(2) print l(0x00ffff / float(0x0404cb)) + (8*(0x1d – 3))*l(2) – (8*(0x1b – 3))*l(2) print l(0x00ffff / float(0x0404cb)) + (0x1d – 0x1b)*l(2**8) </source>

 

目前的难度是多少?

查询当前难度

 

最大的难度值是多少?

不存在最小的区块难度目标值。最大难度约为:maximum_target / 1(因为0会导致无穷大),这是一个非常大的数字(接近2^224)。

区块难度目标值为0时的难度是实际可能出现的最大难度,但如果发生这种情况,我们将无法计算难度。(幸运的是,这种情况永远不会出现。)

在BSV网络中,在单次调整中,网络的难度值最多可以上调 100%。

BTC网络仍然在使用最初的协议规则,在单次调整中,难度值的上调幅度最大可以达到 400%。

 

网络难度可以降低吗?

难度可以降低。参见区块难度目标的内容。

在BSV网络上,在单次调整中,网络难度最大可以下调50%。

BTC网络仍然在使用最初的协议规则,在单次调整中,网络难度最大可以下调 75%。

 

最小难度是多少?

最小难度为 1,它对应着区块难度目标值所可以达到的最大值。这个最小难度1正是创世区块的难度。

 

网络上的算力会如何影响难度?

每生成 2016 个区块,网络就会根据生产这 2016 个区块所花费的时间,调整一次难度。我们期望区块以每 10 分钟一个的速率生产出来,理论上2016 个区块将需要整整两周时间才能挖掘出来。如果挖掘之前的 2016 个区块花费了两周以上的时间,那么难度就会降低。如果花费了不到两周的时间,难度就会上升。难度的变化量与多于或少于两周(挖掘2016 个区块需要的时间)的时间量成正比。

要找到一个区块,哈希值必须小于区块难度目标值。哈希值是一个介于 0 和 2**256-1 之间的随机数。难度 1 的区块难度目标值被设定为:

0xffff * 2**208

难度 D的区块难度目标值就是 :

(0xffff * 2**208)/D

想要找到一个难度为 D 的区块,我们要进行的哈希运算次数的期望值为:

D * 2**256 / (0xffff * 2**208)

或简化为

D * 2**48 / 0xffff

难度设置为之前的 2016 块将以每 10 分钟一个的速度被发现,因此我们在 600 秒内计算 (D * 2**48 / 0xffff) 次哈希。这意味着在挖掘之前的 2016 个区块的过程中,网络的哈希率是

D * 2**48 / 0xffff / 600

不失准确性,可以进一步简化为

D * 2**32 / 600

在难度 1 的条件下,大约每秒 7,000,000次哈希运算,可以表示为7MH/s。

假设当前难度为 22012.4941572,这意味着在挖掘此前的 2016 个区块的那段时间里,平均网络哈希率为

22012.4941572 * 2**32 / 600 = around 157 Ghashes per second.

 

相关链接

比特币协议
创世区块
Coinbase
区块
区块哈希算法
工作量证明(PoW)
区块哈希目标值
区块补贴
挖矿
中本聪共识
难度
区块重组
孤块
比特币单位:聪
比特币协议
BSV化名协议(BSVAlias)
SHA-256
RIPEMD-160
签名标识
矿工补贴
区块时间戳
Secp256k1
传统签名算法
版本握手