签名也是一段字节:编码不统一,交易 ID 就不唯一
一笔比特币交易的 ID 是对整笔交易序列化后的哈希,签名是其中的一部分。早期的脚本验证器对“什么算合法签名”比较宽容:同样一个数学上有效的 ECDSA 签名,可以用不同的字节写法序列化,多几个前导零、长度前缀写法不同,都能通过验证。麻烦在于:这些不同写法对应不同的交易哈希。一个人可以不改私钥、不碰资金,只把别人未确认交易里的签名重写成另一种合法写法,交易 ID 就变了——依赖旧 ID 追踪状态的钱包和服务商会被打断,后续拼建的子交易也会失效。这就是交易可延展性问题在编码层的来源。

规则本身:只认一种写法
BIP66 规定所有参与脚本验证的签名必须严格符合 DER 编码:整数必须用最少字节、长度前缀必须与实际内容一致。规范自己的兼容性一节提到,自参考客户端 0.8.0 起这就是默认中继政策,链上违规交易到 2015 年 1 月已经很少,而且任何不合规签名都能被无损失地转换为合规写法。也就是说,这次软分叉只是把“钱包本来就该守的规矩”从网络礼仪升格为链上共识,合法性判断从此与字节的写法唯一绑定。
双门槛部署:750 与 950
BIP66 复用了 BIP34 式的双门槛机制,只是信号位换成区块版本 3:当一个高度之前的一千个块里至少有 750 个是版本 3,新规则对版本 3 的区块生效;当达到 950 个,版本 2 区块本身变为无效,此后全部区块强制新规则。这种“观察期加强制期”的结构给了不升级节点一个退出窗口,是那个年代软分叉部署的通用模板。
一次事后披露:顺手堵住了更深的洞
BIP 文件的披露一节记载:全网采用该 BIP 之后,作者Pieter Wuille 才公开,严格 DER 签名无意中解决了他此前发现的一个共识层面的缺陷——验证器在解析非规范编码时行为不一致,理论上可能被用来构造同一区块两种不同解释的风险。先部署、后说明的次序在当年引发过流程争议,也让这次升级成了密码学工程史上“修复必须与披露分离”的经典案例。
它没有讲完的后半段
堵住了编码层的可延展性,还剩两个口子:ECDSA 签名天生可以把 S 换成“曲线阶减 S”仍然有效;验证失败时压回栈的那个失败签名本身可以是任意字节。这两点后来由 BIP146 的 LOW_S 与 NULLFAIL 规则在隔离见证时代补齐;而真正让第三方改 ID 失效的,是隔离见证把签名挪进独立的见证数据、交易 ID 不再包含见证的结构改革。对今天的用户来说,日常钱包生成的签名早已全部合规,这段历史的意义更多在于理解:为什么比特币对“字节级的确定性”执着到愿意动用软分叉。
本文是历史与机制回顾,不构成投资建议,也不应被解读为对任何升级方式的立场判断。
用今天的视角回看这次升级
从结果倒推,BIP66 是一场教科书级的软分叉:信号窗口清晰、兼容期充分、无分叉事故。它也留下一份方法论遗产,影响了之后所有类似变更的叙事方式。第一,能用中继政策先行的规则,先让网络在“软约束”下运行一段,观察违规样本的真实分布,再用共识收口,风险远低于一步到位。第二,规范里“任何违规签名都能无损转换为合规写法”这句话,等于提前声明了这次规则对合法用户零功能损失——这是软分叉能拿到共识支持的前提。第三,那次事后披露让社区付出了流程信誉的代价,也换来了共识缺陷公开流程的成熟:先修复、再披露、部署与披露解耦,成了后来处理同类问题的默认姿势。对现在的读者而言,链上早已找不到非规范 DER 的样本,但每当讨论交易 ID 稳定性、PSBT 各参与方为何不必担心对方重排签名时,链条的源头都指向 2015 年那次版本 3 的投票。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。