多签和离线签名生态里有一个长期被低估的死角:签名设备的知识完全来自你递给它的那份 PSBT。付给合约(Pay-to-Contract,简称 P2C)这类承诺技术偏偏会在链上制造「设备看不懂的输出」——公钥被一个外部承诺的哈希微调过,光有原来的私钥根本花不掉,必须把当初那个 tweak 值也加回私钥上(按曲线阶取模)才能签出有效签名。BIP-372 由 Maxim Orlovsky 在 2022 年 1 月立项,状态仍是草案,做的事情很朴素:给 PSBTv0(BIP-174)和 PSBTv2(BIP-370)各加一批字段,让承诺数据随交易一起旅行。
先看背景。P2C 的做法是把消息哈希乘以曲线生成点 G,再叠加到原公钥上,得到一个「内含承诺」的新公钥:链上只看得到一枚普通公钥,但持有者将来花钱时得同时交代原私钥和那个 tweak。这条路从 Ilja Gerhardt 与 Timo Hanke 的原始论文、Eternity Wall 的实践,一路演化出 OpenTimeStamps、Elements 侧链 tweak、LNPBP-1(用于 RGB 等客户端验证协议里的单次使用封条)等多个变体。问题来了:你把交易交给硬件钱包签名时,设备面对的 tweaked 公钥与你账户里登记的原始公钥对不上,它要么拒签、要么需要你为每笔交易手动导入额外信息,各家格式还互不相同。
BIP-372 的设计抓住一个观察:tweaked 后的公钥其实早就出现在 PSBT 现有字段里——PSBT_IN_REDEEM_SCRIPT、PSBT_IN_WITNESS_SCRIPT、PSBT_IN_TAP_INTERNAL_KEY、PSBT_IN_TAP_LEAF_SCRIPT 都可能装载它。设备缺的不是那串字节,而是「这个公钥是从我的哪一把原始密钥微调来的、tweak 是多少」这层对应关系。于是提案引入新字段 PSBT_IN_P2C_TWEAK,键部分放原始公钥,值部分放对应的 tweak 数据,设备逐字段比对就能判断该用哪把密钥签。字段挂在输入维度上,因为被花的输出才带承诺;对 PSBTv2 则按 BIP-370 的输入结构做相应适配。规范刻意把具体 P2C 协议细节挡在门外——它不规定承诺怎么算、哈希用什么函数,只负责「把 tweak 从协调者搬到签名者手里」这一段传输,所以各类变体可以共用同一批字段。
这套「补字段而不是造新协议」的思路对钱包工程相当友好:协调者软件(桌面钱包、服务端)负责填充 tweak 字段,签名设备只需增加一个字段解析和一条「tweak 加回私钥」的规则,无需理解任何链上承诺语义。反过来说,草案阶段的它尚未被主流签名设备普遍实现,实践中 P2C 输出仍然更多由知道全部上下文的软件钱包直接处理。
把镜头拉远一点,BIP-372 是「PSBT 字段扩展潮」里的一块拼图。静默支付需要随附标签,于是有了专门的输入标签字段提案;MuSig2 聚合签名需要在签名者之间传递公钥与 nonce,于是也有了对应的 PSBT 扩展;P2C 需要 tweak 对应表,于是有了 BIP-372。三者的共同剧本都是:新型输出在链上越来越常见,而离线签名器的世界观越来越不够用,只好在协调者与签名器之间加宽信息通道。这也解释了为什么规范刻意保持协议中立——承诺哈希怎么算、由哪个协议规定,字段一概不管,它只保证「tweak 与原始密钥的配对关系」完整送达。对钱包开发者,判断要不要支持它其实只有一个问题:你的用户会不会花 P2C 输出。答案是不会,这批字段就是纯开销;答案是会,那么没有这批字段,用户的硬件签名器形同虚设。
快速问答
问:P2C 和 Taproot 里的密钥 tweak 是一回事吗? 答:数学工具相同(公钥加一个标量乘 G),用途不同。Taproot 的内部密钥 tweak 由脚本树本身决定,任何参与方都能从交易重构;P2C 的 tweak 承载的是交易之外的信息,签名者无法自行推出来,这才是需要 BIP-372 随附传递的原因。
问:它和 BIP-375(静默支付的 PSBT 字段)冲突吗? 答:不冲突。BIP-375 为静默支付输出传递标签,BIP-372 面向广义的 P2C 承诺输入,两者都在给「设备算不出来的秘密」修传送带。
风险提示:密钥承诺类输出一旦丢失 tweak 记录即无法支出,操作前请确认钱包支持对应的 PSBT 字段并有可验证的备份。

发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。