把复杂脚本的哈希藏进一个普通地址、付款时再亮出真脚本——这个今天叫 P2SH 的机制在 2012 年初其实有两条竞争路线:一条是 Gavin Andresen 的 BIP-16,靠给解锁脚本加前缀结构、改标准交易认定来实现;另一条是 Luke Dashjr 的 BIP-17,直接发明一条新指令 OP_CHECKHASHVERIFY(CHV)。BIP-16 最终部署上线,BIP-17 以关闭(Closed)收场,2012 年 1 月 18 日立项、同年消失在采纳竞赛里。被记住的提案讲「发生了什么」,被关掉的提案讲「还有什么可能」,这篇讲后者的图纸。
一条指令怎么装下整套机制
CHV 的设计核心是一行语义:执行时,把「上一个 OP_CODESEPARATOR 之后」到当前指令为止这段先前脚本的内容做哈希,与栈顶元素比对——相等就当无事发生继续往下走,不相等脚本立刻失败;并且为了向后兼容,比对成功后栈顶那个哈希值不弹出。落地的标准交易形态写成两行:锁定脚本是「推 20 字节哈希、OP_CHECKHASHVERIFY、OP_DROP」,解锁脚本则是「若干签名、OP_CODESEPARATOR、真脚本」。哈希边界靠 OP_CODESEPARATOR 划出来,这个本来就存在、平时少有人用的指令第一次承担了结构性职责。
指令编号不是新分配的,而是征用当时闲置的 OP_NOP2。提案明说这么选的原因:这样旧链上已按 BIP-12(另一条用 OP_EVAL 的旧提案)格式花掉的钱还能继续赎回,不必推倒重来。重定义闲置操作码、保留旧数据可赎回性,这套「腾挪存量」的手法在此后十几年的比特币脚本提案里反复出现。

和 BIP-16 的分歧点
两条路线目标一致,差异全在实现形状。BIP-17 把机制做进共识验证规则:验证节点必须真的执行哈希比对,未升级节点不认识新指令、会把这类交易当非标准不中继。BIP-16 则尽量不动指令集,用输出脚本模板加交易标准化的方式圈出新格式。Dashjr 在提案动机段辩护道:把复杂脚本整段交给付款方的方案「有人觉得完全够用了」,但那样商家、钱包、交易所已经建好的「扫一个二维码寄 20 字节地址」的基础设施全得重写,而 CHV 路线让收款端几乎零改动。这段辩护本身就是当年路线之争的直接史料——最终市场选择了改动更小的 BIP-16,但地址格式层又靠 BIP-13 单独定义了哈希地址的版本字节,两条提案的分层思路殊途同归。
投票与激活的早期实验
BIP-17 的激活方案是字符串投票加时间闸门:矿工升级后在自己出的块里把 coinbase 输入写入字符串 p2sh/CHV,2012 年 2 月 8 日检查前 7 天的区块,若至少六成含此字符串,则所有时间戳晚于 2012 年 2 月 23 日 00:00 GMT 的区块强制按新规则验证;没过门槛就推迟,或干脆放弃。同一时期 BIP-16 用的是字符串 /P2SH/、550 块、4 月 1 日时间戳的设计。这两份提案共同构成了比特币「用区块内信号判断矿工支持率」的激活工具箱,后来演进为高度结构化的 BIP9 版本位机制。提案里还专门分析了一类对旧实现的一确认攻击:攻击者自己造一个旧软件认、新软件不认的哈希脚本交易,再花掉它并付给只跑旧节点的受害者,若受害者接受一确认就可能吃到回滚——这种「新旧验证不对称」的攻防模板,此后几乎每份脚本类提案都要抄一遍。
快速问答
问:BIP-17 说被取代了,那 CHV 现在等于废弃操作码吗? 答:它从未在主网激活,OP_NOP2 这个编号后来被时间锁类提案按流程重新征用;BIP-17 自身状态是 Closed,属于关闭未部署,不是部署后废弃。
问:CHV 与今天 Taproot 的脚本承诺有什么关系? 答:只有精神联系,没有代码联系。CHV 验证的是「上一段脚本字节的哈希」,Taproot 验证的是默克尔分支与密钥调整,两者解决的问题不同代。
问:当年 BIP-16 和 BIP-17 能共存吗? 答:机制上可以叠加(提案各自都处理了向后兼容),但社区不愿同时推两条解决同一问题的路线,最终只留一条。
常见误区
一是把「Closed」读成「被技术否决」,更准确的说法是在部署竞赛中输给改动面更小的同题提案;二是以为重定义操作码随手可行,实际 BIP-17 特意挑了闲置编号并写明理由,比特币对「回收哪个字节」历来极其讲究;三是把哈希边界机制与今天的隔离见证混淆,CHV 全程在解锁脚本内操作,与把签名数据挪出交易主体的隔离见证不是一个维度。
风险提示:本文为协议机制与提案历史科普,不构成投资建议;涉及资产的脚本类型请核实其在当前网络中的标准性与钱包支持。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。