协议演进 / BIP/比特币改进提案 / BIP-372
BIP-372
为 PSBT 新增一个 pay-to-contract 微调字段,让外部签名者知道某把公钥被加过承诺微调、签名前必须把同一微调值加到私钥上。本 BIP 目前处于草案状态。
一、档案卡
| 编号 | BIP-372 |
|---|---|
| 标题 | Pay-to-contract tweak fields for PSBT |
| 作者 | Maxim Orlovsky <[email protected]> |
| 指定日期 | 2022-01-16 |
| 层级 | Applications(应用) |
| 类型 | Specification(规范类) |
| 状态 | Draft(草案) |
| 依赖 | BIP-174 |
| 阅读版 | https://bips.dev/372 |
| 官方原文 | https://github.com/bitcoin/bips/blob/master/bip-0372.mediawiki |
二、放在哪一族
PSBT 扩展族中很窄的一支:只管“花费带 pay-to-contract(P2C)承诺的旧输出”时,签名信息怎么传递。
P2C 的想法最早由 Ilja Gerhardt 与 Timo Hanke 提出,后来被 Eternity Wall、OpenTimestamps、Elements 侧链以及 LNPBP-1 等协议以不同形式采用;Peter Todd 的 single-use-seals(单次使用封印)与建立在其上的 RGB 等客户端验证协议,也用到这类微调。
BIP-372 本身不定义任何一种 P2C 协议,它抽象掉各协议的细节,只给 PSBT 定一个通用字段。它依赖 BIP-174 的 PSBT 框架,并同时适用于 PSBTv0 与 BIP-370 的 PSBTv2。
三、它要解决什么
密钥微调(key tweaking)是利用椭圆曲线性质对一段链外消息作密码学承诺的手法:把消息的哈希乘以生成点 G,再加到一把公钥上,得到微调后的公钥,其中就藏着对这段消息的承诺。输出所有者知道对应的原始私钥。
花费这种输出时有个麻烦:只有原始私钥还不够。签名者必须知道当初加了多大的微调值,并把同一个值加到私钥上(模群的阶),才能作出有效签名。
链上能检测出这是一个 P2C 输出,却看不出微调值是多少。尤其是外部签名者——比如一台只保管私钥的硬件设备——可能完全不知道这笔承诺的存在与内容。信息缺口不在共识层,而在签名协作环节:PSBT 里没有地方告诉签名者“这把公钥被微调过,微调值是这个”。
BIP-372 要补的就是这一句交代。
四、规则本身
4.1 唯一的新字段
PSBT_IN_P2C_TWEAK(0x19),每输入一个字段类型:
- 键数据
<pubkey>:33 字节压缩公钥序列化,指明微调可能作用于哪把原始公钥——必须是微调之前的公钥。BIP-340 的密钥按在末尾追加0x02字节的方式序列化。 - 值数据
<tweak>:32 字节微调值,必须把它加到私钥上,才能作出正确的 ECDSA 和/或 Schnorr 签名。
签名者在构造出 PSBT_IN_PARTIAL_SIG 后,应当(SHOULD)移除该字段。
4.2 签名者怎么用
被微调的公钥其实已经出现在 PSBT 现有字段里——赎回脚本、见证脚本、Taproot 内部密钥、Taproot 叶子脚本等处。缺的只是“它是从哪把原始公钥变来的”这一层对应关系。
有了新字段,签名者的处理是:认出哪些原始公钥是自己掌握私钥的,把微调值分别试加,检查结果是否出现在上述脚本字段中;确认对应关系后,对相应私钥作同样微调,再签名。
4.3 覆盖范围
原文称该字段足以支持对以下含微调公钥的输出类型作有效签名:裸脚本、P2PK、P2PKH、P2SH、见证 v0 的 P2WPKH 与 P2WSH、嵌套的 P2WPKH-P2SH 与 P2WSH-P2SH。兼容性一节同时提醒:0 版之后的见证版本(含 Taproot 输出与未来见证版本)可能不在覆盖范围内,可能需要另加 PSBT 输入字段。
4.4 范围刻意收窄
本提案只处理“花费已有的 P2C 输出”,不处理“构造新的 P2C 承诺或带 P2C 输出的交易”。原文给出的理由是:新建承诺涉及链外数据的结构,各协议格式不同且不断演变,让硬件设备去理解这些结构可能带来链外价值损失风险,应由其他标准或厂商方案处理;花费旧输出不产生新承诺,没有这类风险。
五、谁必须动
普通持币人:一般无感。只有持有 P2C 微调输出(例如经 RGB 等客户端验证协议形成的资产相关输出)并使用外部签名设备时,才会走到这条流程。
钱包开发者:构造花费 P2C 输出的 PSBT 时,需要为相关输入填入 PSBT_IN_P2C_TWEAK,键放微调前的原始公钥,值放 32 字节微调值。
硬件钱包与外部签名者:需要实现“按字段试加微调、比对脚本中的公钥、私钥加微调后签名”的逻辑,否则面对 P2C 输出只能拒绝或签出无效签名。
全节点与矿工:无需动作。原文明确:本提案与现行共识规则兼容,不要求修改共识。
六、现在算不算数,以及一个常见误读
状态为 Draft(草案)。原文中的参考实现标注为进行中(WIP),测试向量标注为待定(TBD)。因此它目前是一份字段设计草案,不能当作已经落地的通用标准来假设各钱包都支持;实际使用前要逐个确认钱包与签名设备是否实现。
常见误读:“ BIP-372 定义了 pay-to-contract 协议,或要求新建 P2C 承诺也走 PSBT 这套字段。”不对。它既不新造 P2C 协议,也不处理承诺的构造,只解决花费环节的一件事:把微调值通过 PSBT 交到签名者手里。
七、延伸
- 阅读版:https://bips.dev/372
- 官方原文:https://github.com/bitcoin/bips/blob/master/bip-0372.mediawiki
- 相关:BIP-174 PSBTv0、BIP-370 PSBTv2、BIP-371 PSBT 的 Taproot 字段
- 仓库总目录:https://github.com/bitcoin/bips
