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

BIP-443 OP_CHECKCONTRACTVERIFY

为 Tapscript 新增 OP_CHECKCONTRACTVERIFY:让 UTXO 携带对数据的动态承诺,脚本可内省该数据,并约束花费交易输出的内部公钥、taptree 与金额分配,由此搭出带状态的 UTXO 与状态机。本 BIP 目前处于草案状态。

一、档案卡

档案卡
编号BIP-443
标题OP_CHECKCONTRACTVERIFY
作者Salvatore Ingala <[email protected]>
指定日期2025-05-08
讨论日期2022-11-08
层级Consensus (soft fork)(共识(软分叉))
类型Specification(规范类)
状态Draft(草案)
阅读版https://bips.dev/443
官方原文https://github.com/bitcoin/bips/blob/master/bip-0443.mediawiki

二、放在哪一族

契约(covenant)与“带状态的 UTXO”一族。它不针对某一个应用做专用操作码,而是提供一个原文所称的基础构件(fundamental building block):让一枚 UTXO 带着一份数据承诺往下传,脚本在花费时能验这份数据、并规定下一枚 UTXO 的程序与数据。

它与近亲的区别:

BIP-119:OP_CHECKTEMPLATEVERIFY,把花费交易约束到一个固定输出模板;本 BIP 约束的是输出的程序(内部公钥与 taptree)与所嵌数据,数据还可以动态计算

BIP-345:OP_VAULT,面向两步提款的专用金库构造;原文把它列为“约束币的未来”这一共同诉求下的专门方案之一

BIP-442:OP_PAIRCOMMIT 等向量承诺操作码;原文说,与这类操作码配合,本 BIP 才能把任意状态机组合出来——状态转移是否合法,取决于 taptree 中脚本能表达的条件

BIP-341:Taproot;本 BIP 的数据承诺完全寄生在 Taproot 的密钥 tweak 结构里,不另造输出格式

三、它要解决什么

“约束一枚币的未来能去哪、能变成什么”超出预签名交易能做的范围,是许多改进尝试的共同核心。原文列举:

而 BitVM 等构造绕开“UTXO 不能带状态”这一缺失,用 Lamport 签名与乐观执行硬搭智能合约,代价是复杂度、交互轮次,以及某些执行路径上的区块占用都极高,完全免信任的桥接设计仍未实现。

BIP-443 的主张是:不为某个应用做专用优化,而是补上那个共同缺失的原语——UTXO 携带状态(state-carrying UTXOs),让上述构造有统一的底层构件可用。

四、规则本身

4.1 数据怎么嵌进 UTXO

把一个 P2TR UTXO 的“程序”看作两部分:一个 x-only 公钥(原文称 naked key,裸公钥)与一棵脚本 Merkle 树(taptree)。

由此带来三个性质:被承诺的数据不让 UTXO 变大;知道裸公钥私钥、且知道所嵌数据(或其哈希)的一方,仍可走密钥路径花费;taptree 里只有真正需要访问数据的叶子,才为此付见证字节的成本。

4.2 操作码的栈格式与语义

OP_CHECKCONTRACTVERIFY(简称 OP_CCV)占用 Tapscript 的 OP_SUCCESS187(0xbb)。执行时栈自底向上应为:

<data> <index> <pk> <taptree> <mode>

一句话语义:验证下标为 index 的那个输入或输出,是一个 P2TR UTXO,其 Taproot 输出公钥由 pk 出发——数据非空时先用数据哈希 tweak,再在 taptree 非空时做 taptweak——推导得到。各参数的特殊取值:

其余不合格式的取值使验证立即失败。对输入用它,可内省该输入所嵌的数据与程序;对输出用它,可定义该输出的程序与所嵌数据——这正是“把状态传给下一枚 UTXO”的入口。

4.3 四种模式与金额语义

mode 决定检查对象与金额处理:

其他 mode 值使操作码立即成功——这是为将来软分叉引入新模式预留的口子。防重复计账的规矩:同一输出在同一交易中不能既被默认模式又被扣除模式检查,也不能被扣除模式检查多次;但多个输入可以用默认模式共同汇入同一个输出。

原文特别提醒两点:扣除模式并不校验该输出的确切金额,这类合约的金额还需用签名或其他内省手段另行约束,否则金额可被篡改;又因为金额语义以“全额保留”为基调,手续费须从外部支付——另加一个输入、用 anchor 输出等办法解决,不能指望忽略金额模式(该模式下输出金额无约束,矿工理论上可吞掉该输入的全部价值,该模式只是为未来兼容预留)。

五、谁必须动

普通持币人:现在不必做任何事。本 BIP 仍是草案,未激活;普通 P2TR 收付款完全不涉及它。

钱包开发者:现在不必动。将来若激活,也只有构造这类契约的钱包/应用才需要按 4.1 的方式嵌数据、按 4.3 分配金额,并为手续费另备输入。

脚本与二层协议开发者:这是主要受众。Ark、共享 UTXO、金库、状态机等构造可用它作底层构件;但要清醒:任意状态机还需要向量承诺类操作码配合,且原文的 Applications 一节尚为 TODO,应用清单不是已定稿的承诺。

全节点与矿工:若将来激活,需实现交易级与输入级的金额记账初始化及 0xbb 的新语义。它把原本无条件成功的 OP_SUCCESS187 收紧为带条件的验证,原文定性为软分叉:未升级软件除挖矿与区块验证外仍可正常工作。

共识层:只改 Tapscript 中一个 OP_SUCCESS 操作码的语义,不动其他脚本环境;激活机制与同批部署的其他 BIP,原文写为待定(to be determined)。

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

状态为 Draft(草案)。原文中 sigops 预算、Policy changes、Applications、Acknowledgements 等多节仍标 TODO,说明文本本身尚未定稿;参考实现以 Bitcoin Core 拉取请求的形式给出。今天的主网上没有 OP_CCV:0xbb 仍是 OP_SUCCESS,UTXO 也不能按本 BIP 的方式携带可内省的数据承诺。

常见误读:

“BIP-443 就是 OP_CHECKTEMPLATEVERIFY 或 OP_VAULT 的改名。”

不对。三者同属“约束币的未来”这一族,但机制不同:BIP-119 约束的是整笔交易的固定输出模板,BIP-345 是专为两步提款设计的金库操作码,而 BIP-443 约束的是单个输入/输出的程序与所嵌数据,数据可以动态计算、可被脚本内省,并自带金额分配语义——原文明确说它的目标是通用构件,而不是为某个应用优化的专用构造。

七、延伸

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