协议演进 / BIP/比特币改进提案 / BIP-442

BIP-442 OP_PAIRCOMMIT

为 Tapscript 新增 OP_PAIRCOMMIT:用带标签哈希一次性承诺栈顶的两个元素,提供有限的向量承诺能力,支撑 Merkle 化的合约与数据可用性安排。本 BIP 目前处于草案状态。

一、档案卡

档案卡
编号BIP-442
标题OP_PAIRCOMMIT
作者moonsettler <[email protected]>, Brandon Black <[email protected]>
指定日期2024-12-09
层级Consensus (soft fork)(共识(软分叉))
类型Specification(规范类)
状态Draft(草案)
阅读版https://bips.dev/442
官方原文https://github.com/bitcoin/bips/blob/master/bip-0442.md

二、放在哪一族

Tapscript 扩展与契约(covenant)/向量承诺一族。它是一个小而专一的新操作码:只做“把两个栈元素绑成一个哈希承诺”这一件事,复杂结构靠反复使用它搭出来。

相关提案:

BIP-342:Tapscript;本 BIP 在叶子版本 0xc0 的 Taproot 脚本花费中,用 OP_SUCCESS205(0xcd)的位置部署

BIP-340:Schnorr 签名;本 BIP 沿用其带标签哈希(tagged hash)记法与构造

BIP-443:OP_CHECKCONTRACTVERIFY;原文把“向量承诺类操作码”列为与它配合、共同搭出状态机的部件,本 BIP 正提供这类能力的一种实现

BIP-119:OP_CHECKTEMPLATEVERIFY;原文的 Lightning Symmetry 示例中与它及 OP_CHECKSIGFROMSTACK、OP_INTERNALKEY 组合使用

它也常与 LNhance 一组提案放在一起讨论,但档案上它是一份独立编号、独立规范的 BIP。

三、它要解决什么

比特币脚本经常对单个数据项做承诺,例如哈希锁、时间锁、按公钥哈希付款;但缺少原生手段把多个数据项一起承诺。

没有这种手段时,想把一组元素绑成一棵 Merkle 树、只留一个根哈希,合约要么做不了,要么绕远路。原文举了两类受影响的场景:

在 MATT(Merklize All The Things)框架里,这类工作原先靠 OP_CAT 拼接再哈希;原文指出朴素地用 OP_CAT 有字节移位(byte shifting)攻击的风险,拼接结果的边界不唯一。

BIP-442 的主张是:直接给一个专为“成对承诺”设计的操作码,高效、安全,不必先拼接。

四、规则本身

4.1 栈语义

在叶子版本 0xc0 的 Taproot 脚本花费中,OP_PAIRCOMMIT 重新定义 OP_SUCCESS205(0xcd)。执行时:

因为每个元素都带长度前缀,(a, b) 的划分是唯一的,不会出现拼接式的边界歧义。原文还指出,标签可预计算为 SHA256 中间状态,典型情形(两个 32 字节元素)只需很少的哈希轮次。

4.2 两个以上元素:逐层成对

操作码本身只处理一对。要承诺三个元素 a、b、c,就先算 PC(b, c),再算 PC(a, PC(b, c)),得到一个总承诺;验证时把见证中的 a、b、c 依次压栈、两次执行 OP_PAIRCOMMIT,再与脚本里写死的承诺值 OP_EQUALVERIFY 即可。如此逐层成对,即可构成 Merkle 化的向量承诺:一个短哈希绑住整组元素,日后可逐个揭示。

4.3 示例:Lightning Symmetry 中的用法

原文用 Lightning Symmetry(基于 eltoo 思路的通道构造)示范数据可用性问题:争议关闭时需要拿到结算数据。做法是强迫各方把结算交易哈希放进见证:脚本先对状态哈希做模板校验,再用 OP_PAIRCOMMIT 把“状态恢复数据”与“状态哈希”绑成一对哈希,配合 OP_INTERNALKEY 取内部密钥、用 OP_CHECKSIGFROMSTACK 验签——双方必须对同一个成对哈希签名,更新数据与结算数据就被迫同时出现在见证里,后来的更新能据此重建中间状态的脚本,而各方只需保存最新状态。

4.4 被否决的替代方案

原文列出考虑过并放弃的路线,包括:OP_CAT(及其限长版本)、SHA256 流式操作码、专门的 Merkle 操作码、在 OP_CHECKTEMPLATEVERIFY 中承诺 Taproot annex、用 OP_CHECKSIGFROMSTACK 直接签 n 个元素、推广到 n 个元素的 OP_VECTORCOMMIT、ReKey/Laddering、以及 OP_RETURN。结论是 OP_PAIRCOMMIT 能在不引入 OP_CAT 风险的前提下支撑有用的脚本。

五、谁必须动

普通持币人:现在不必做任何事。本 BIP 仍是草案,未激活,部署方式在原文中写为 TBD(待定)。

钱包开发者:现在不必动。它是脚本层操作码,普通收付款钱包不直接构造这类脚本。

脚本与二层协议开发者:这是主要受众。若将来激活,设计 Merkle 化承诺、Lightning Symmetry、MATT 类合约时可直接使用;同时要注意,它依赖 OP_SUCCESS 的软分叉升级位,与 OP_CHECKSIGFROMSTACK、OP_INTERNALKEY 等提案组合时要以各自最终文本为准。

全节点与矿工:若将来激活,需按新语义验证 0xcd 在 Tapscript 中的执行。原文指出:约束 OP_SUCCESS 操作码属于向后兼容的软分叉,但原先依赖 OP_SUCCESS205 “无条件成功”行为的脚本将不再有效。

共识层:只在 Tapscript 内新增一个操作码,不动其他脚本环境。

六、现在算不算数,以及一个常见误读

状态为 Draft(草案),原文的 Deployment 一节写为 TBD。今天的主网 Tapscript 中没有 OP_PAIRCOMMIT:0xcd 仍是 OP_SUCCESS,执行到即成功,而不是算成对哈希。原文给出的成本对比(如 Lightning Symmetry 各种构造的权重比较)是提案层面的论证,不是已上线协议的实测数据。

常见误读:

“OP_PAIRCOMMIT 就是把两个元素拼起来的 OP_CAT。”

不对。OP_CAT 产出的是拼接后的原始字节,边界靠使用方自己守,朴素用法有字节移位攻击;OP_PAIRCOMMIT 不产出拼接结果,而是对“长度前缀 + 数据”做带 PairCommit 标签的哈希,压回一个 32 字节承诺值。它承诺的是这对元素,而不是把这对元素递给你。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。