难度不是一个比率,是一条线
理解 nBits 的前提是理解难度目标(target):它是一个 256 位的大整数,规则是区块头的哈希值必须数值上小于它才算有效区块。哈希输出可以视为随机均匀分布的数,目标越小,落在其下的概率越低,矿工需要的尝试次数越多。平时说的”难度 90T”只是把目标与创世目标值的比值换算成人类易读的数字,真正写进区块头的原始信息另有其人——一个四字节的字段 nBits。
编码:一个指数加一个尾数
nBits 采用浮点式的紧凑表示。最高一字节是指数,低三字节是有符号尾数,解码公式为:目标值等于尾数乘以 256 的(指数减三)次方。以创世区块为例,其 nBits 为 0x1d00ffff:指数 0x1d 即 29,尾数 0x00ffff,解码得到目标值等于 0xffff 后面跟 26 个字节宽的零,展开成 32 字节就是 00000000ffff0000...0000。这正是著名的”难度 1 目标”。当前主网的目标在这个基础上再小若干个数量级,体现为更多前导零。
这种编码和科学计数法同构:指数决定小数点位置,尾数给出有效数字。十六进制世界里指数每加一相当于左移两个字符,对 32 字节的哈希空间而言,用一字节指数加三字节尾数足以覆盖全部合法区间。
陷阱一:同一个数字有多种写法
浮点式的表示天然不唯一:尾数 0x00ffff 乘 256 的 26 次方,与尾数 0x0fff 乘 256 的 27 次方数值相等。若不加约束,同一个目标就能以多个 nBits 存在,校验逻辑立刻歧义丛生。协议因此要求区块里写的必须是规范化写法:尾数最高字节若为零要并入指数,尾数超过 0x007fffff 也要进位调整,总之保证”每值一码”。节点校验时会把收到的 nBits 解码再重新编码,对不上就按无效区块处理。历史上确有软件因实现差异写出过非规范形式而被拒收的教训,这也说明”数值相等”在共识系统里永远让位于”字节一致”。
陷阱二:尾数带符号
四字节里还藏着符号位。按紧凑格式定义,尾数最高位为 1 会被解读成负目标,而负数不存在合法的哈希小于关系,这类区块直接无效。合法编码里出现负号是必须避开的写法。两个陷阱合起来说明一个原则:nBits 是一个有严格文法的编码,接近浮点数却没有浮点数的一切模糊性。
与难度调整的关系
每 2016 个块,节点根据中位时间统计区间耗时,按比例缩放上一期目标得到新目标,再以 nBits 形式写进下一个区块头。也就是说:矿工的哈希比较对象是解码后的目标,难度软件读的是 nBits,公开仪表盘上的”难度”数字又是从 nBits 换算的衍生指标——三层之间隔着的都是这同一个编解码。审计一个分叉币的难度实现、排查自建测试链同步失败、或者读懂矿池协议里的 nBits 字段,第一步都是手推一遍这四个字节的展开。按公式动手算一次创世值,比读十篇文章都牢靠。
用 nBits 估算要挖多久
拿到目标值,工作量立刻可算:单次哈希尝试命中的概率约等于目标除以二分之一二的二百五十六次方,需要的平均尝试次数是其倒数。以难度一目标为例,平均需要约二分之一二的三十二次方次哈希才能出一个块——这解释了为什么难度一要换算成天文数字倍的哈希率才现实。矿机说明书上的每秒万亿次、矿池仪表盘上的全网算力,都可以通过”目标除以哈希空间再乘以每秒尝试数”与真实出块速率相互对账。这也是审计一个分叉币最快的体检:解码它的 nBits,对照它的出块间隔宣称与算力规模,三者对不上账的链,参数表上一定有故事。手推一次从 0x1d00ffff 到创世目标的展开,再套一次上面的概率公式,比读十篇解释都牢靠。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。