如果让两家钱包各自实现「同一个三方两签钱包」,它们生成的地址多半对不上:派生路径各写各的,公钥排列顺序各排各的。脚本是逐字节定身份的,一个字节不同就是另一个地址。2015 年 11 月 20 日,Eric Lombrozo 和 William Swanson 提交 BIP-124《层级确定性脚本模板》,提出把脚本写成「带填空的模板」,把填进去的钥匙全部锚定到 BIP-32 派生路径上,让任何钱包只要声明遵守同一模板,产出的脚本就完全一致。这份提案最终状态 Closed,编码一节甚至留着 TODO,但它的问题意识比很多 Final 提案更长久。
模板语法极简。一个密钥写作 A 下标 k,读作「A 的派生路径再走第 k 号」;一组对称的密钥写成键组——n 条派生路径共用同一个自由索引 k。脚本模板就是在一串操作码之间插入方括号占位符,比如两取三多签写成「2 [X] 3 OP_CHECKMULTISIG」,把键组第 k 代的 n 把公钥按字典序填进三个空位。这里藏着模板的第二块基石:排序。脚本语义对多签公钥的排列顺序并不敏感,但脚本字节敏感,所以模板强制字典序这一种规范形态——既保证跨钱包一致,也顺带让脚本形态不带个人信息。
示例最能说明这套记号的表达力。第一例就是上面那个 2-of-3。第二例写成「先 OP_DUP 填 A 再 OP_CHECKSIG,否则进入 OP_NOTIF 分支走 2 [B] 3 OP_CHECKMULTISIGVERIFY」,即「超级用户一个人能花,否则三人群体两个人也能花」的弹性策略,一个模板同时填一把主钥和一个三人键组。第三例是带超时的双花通道:OP_IF 分支里 Alice 拿 Hash160 后的钥匙即时可花,OP_ELSE 分支里 Bob 必须先过 OP_CHECKLOCKTIMEVERIFY 的超时线再签名——这正是闪电网络支付通道的骨架,模板把「谁先走哪条路」写成纸面契约。动机一节明说了这层野心:BIP-65 和 BIP-112 带来时间锁脚本之后,钱包之间必须能协作生成更复杂的脚本;而当时正在成型的闪电网络这类多层协议,需要能快速演进又不失一致性的通用模板。
它没走完的路也写在原文里:排序规范只留了一句 TODO(压缩公钥?编码?),二进制编码整节空缺。更根本的是,这份 2015 年的文本把模板当作「钱包间的口头约定」,没有给出机器可读的模板格式。后来接管这个位置的是输出脚本描述符:同样是「模板加占位符加派生路径」,但描述符有严格语法、可校验和、可导入 Core 钱包,把 BIP-124 停留在论文速记层面的东西做成了能运行的软件。
一个容易被忽略的细节是键组的对称性主张。当脚本对一组密钥的地位完全平等对待——比如多签里谁排第几不改变语义——模板强制把这组密钥按字典序展开,等于宣布「这组钥匙没有座位次序」。这除了统一产物之外还有隐私含义:脚本形态不携带任何「谁先谁后」的组织信息,外人从链上脚本读不出参与方的谈判格局。对称性、规范化、可派生三件事被同一份记号一次性绑定,这是这份短提案在设计品味上最值钱的一笔。
常见误区有三个。其一,把模板当成一种上链的东西:脚本模板永远留在钱包内部,链上只有填完空的成品脚本。其二,以为键组排序随便:语义等价、字节不同,排序不统一则所有钱包的地址互相错开,模板的意义整个塌掉。其三,把这份 Closed 提案读成失败:它回答的问题(跨钱包确定性脚本)后来被描述符正面解决,BIP-124 的问题清单就是它的遗产。
快速问答。问:它和 BIP-32 什么关系?答:完全建立在 BIP-32 之上,路径和索引决定密钥,模板只决定怎么把密钥拼进脚本。问:为什么用字典序而不是坐标序?答:字典序对字节串实现最直接,也不泄露各参与方约定的座位次序。问:今天写复杂策略钱包该看什么?答:先读 BIP-380 一族描述符,再看 Miniscript 的策略语言。
风险提示:本文是脚本机制科普,不构成投资建议;自行拼写脚本策略风险极高,错误模板生成的地址资金可能无法找回,务必先以极小金额验证每条花费路径。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。