BIP-143 想解决什么
2017 年 8 月隔离见证随区块 481824 激活(BIP-141 定义交易结构,BIP-143 定义新签名哈希算法)。在此之前,签名算法要追溯到老中本聪时代的设计:签名前把整笔交易复制一份、替换掉被签输入的脚本、再对整个序列化结果做双 SHA-256。这个做法有两个历史包袱:一是每签一个输入都要重造并重哈希接近整笔交易,验证成本随输入数平方增长;二是脚本内容会随见证数据变化,为后来被称为”交易可延展性”的问题埋了根。BIP-143 的目标就是把”到底在签哪些字节的哈希”重写成一份逐项列清单的规范。

清单上有哪些项
按 BIP-143 的规范顺序,签名消息由十段数据序列化后做双 SHA-256:
- 版本号;
- hashPrevouts——所有输入的”交易哈希加输出序号”整体序列化后的双哈希;
- hashSequence——所有输入的 nSequence 序列化后的双哈希;
- outpoint——当前被签输入指向的那一个前作输出;
- scriptCode——当前输入对应的脚本(对 P2WPKH 就是固定的那 25 字节模板);
- value——被花输入的金额,以 8 字节小端整数写入;
- nSequence——当前输入的序列号;
- hashOutputs——所有输出序列化后的双哈希;
- 锁时间;
- sighash 类型。
关键变化藏在第 2、3、8 项的写法里:全交易的输入点、序列、输出列表被”预哈希”成三个 32 字节摘要。同一笔交易里签十个输入时,这三个摘要算一次、复用十次,签名哈希的总工作量从平方级降回线性级。这也是隔离见证顺带修复验证成本问题的机制来源。
为什么要签金额和脚本
老算法不直接包含被花输入的金额。攻击者如果能诱导签名设备在”金额信息不足”的情况下签名字节,就可能在别处把这些字节重新组装。BIP-143 把 value 明确写进签名消息,让签名字节与”这笔签名最多允许花掉多少输入”绑定;scriptCode 入签则把”按哪段脚本执行”钉死。这两项配合 sighash 的选项位,后来也成了硬件钱包和 PSBT 离线签名可以安全工作的地基。
与可延展性的关系
隔离见证时代常被提及的”修复延展性”,机制上应主要记在 BIP-141 名下:签名不再覆盖脚本中的签名字节本身,wtxid 把见证数据计入另一个哈希、txid 则不含见证。BIP-143 的贡献是让签名消息与见证内容脱钩——签名的输入清单里没有”自己”,自然不存在自我包含的哈希循环。两者一套管结构、一套管哈希,常被混为一谈。
各模式与常见误区
BIP-143 沿用 SIGHASH_ALL、NONE、SINGLE 及 ANYONECANPAY 标志位。以 ALL 为例,上面十项完整入签;NONE 会把 hashOutputs 换成 32 字节全零(意味着签名者放弃对输出内容的约束);SINGLE 只把与当前输入同序号的那一个输出写进 hashOutputs;ANYONECANPAY 把 hashPrevouts 换成全零——任何拿到这份签名的人都可以再拼接别的输入,绝大多数钱包场景都不该用它。另外注意 hashSequence 的宽容规则:只要 ANYONECANPAY、SINGLE、NONE 三者有其一,全输入的序列摘要就整体换成全零,当前输入自己的 nSequence 仍作为独立一项入签。一个实现细节:被签交易里某项数据缺失或模式不要求时,规范用 32 字节全零占位而不是干脆不哈希——早期就有钱包因为”省事跳过某项”签出了可以合法重放的消息。这类偏差不会报错,只会安静地扩大一张签名合法的适用范围,正是审查签名实现时最值得盯的地方。
规范文本在解释设计时还提到一点:清单式结构把”与当前输入无关的数据”都收敛成可缓存的摘要,签名一笔交易的某个输入不再需要先重哈希整笔交易的全部历史内容——这也是大型多输入交易的签名成本不再随输入数平方膨胀的另一面。
落地与自查
普通用户不需要手动碰这些字节,但两类人需要:自写钱包或签名工具的开发读者(以 BIP-143 与 BIP-141 规范文本为准逐字节比对测试向量),以及评估”某钱包是否兼容隔离见证”的人——判断标准是钱包生成的签名消息是否遵循清单式结构,而不是宣传页上有没有”SegWit”字样。所有具体地址与样例都不指向任何真实资产,仅示意结构。涉及真实资产的操作建议先小额演练。本文只做机制说明,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。