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

BIP-346 OP_TXHASH

提出 OP_TXHASH,让脚本按字段选择器算出花费交易选定部分的 32 字节哈希并压栈,从而在脚本内约束交易本身。本 BIP 目前处于草案状态。

一、档案卡

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

二、放在哪一族

交易自省(transaction introspection)与契约族。比特币脚本今天几乎“看不见”正在花费自己的这笔交易:签名校验能间接约束交易,但脚本不能直接读版本号、输入输出等字段。BIP-346 给 Tapscript 加一个最基础的自省原语:按需算出交易选定字段的哈希。

它与几个邻居的关系很紧:

BIP-119:OP_CHECKTEMPLATEVERIFY。本 BIP 是它的严格推广——字段选择器取空值时的默认模板,语义上等同于 CTV 承诺的那组字段。

BIP-348:OP_CHECKSIGFROMSTACK。TXHASH 算出的哈希交给 CSFS 验签,就得到完全通用的签名哈希构造。

BIP-118:SIGHASH_ANYPREVOUT。其签名模式及 ANYPREVOUTANYSCRIPT 等变体,可以用 1 字节选择器 + CSFS 组合模拟出来,不必再单独改签名算法。

BIP-342:Tapscript 规则与 sigops 预算,本 BIP 的升级路径与资源计费都建在它之上。

原文致谢里也点明了血统:想法源自 Russell O’Connor 把 CTV 推广为 TXHASH 的思路,及 Jeremy Rubin 的 BIP-119 工作。

三、它要解决什么

脚本若想对花费交易施加条件——“这笔钱只能这样花”——现有手段只有两类:一是预签名交易(交互式、要保存数据、金额目标定死),二是签名哈希标志间接捎带的条件,粒度粗且不可组合。

OP_TXHASH 的定位是给一个通用的底层原语:脚本指定“把交易的哪些部分拿出来算哈希”,把哈希压回栈上,脚本随后可以:

原文还指出,TxFieldSelector 这套字段选择编码将来可复用于一个假想的 OP_TX(直接把字段压栈而不哈希),算出的 TransactionHash 也可能被未来的 SegWit 版本用作原生签名哈希。但这些是铺垫,不是本 BIP 的内容。

四、规则本身

4.1 操作码与基本语义

以软分叉方式重定义 Tapscript 的 OP_SUCCESS189(0xbd)为 OP_TXHASH,仅在 Tapscript 语境生效。执行时:

它只负责“算出并压栈”,本身不做任何校验——是否与预期相等、是否拿去验签,都由后续脚本决定。

4.2 TxFieldSelector:选哪些字段进哈希

选择器是一个位图式的编码,能选的字段包括:版本号、锁定时间、当前输入下标、当前输入的控制块与被花脚本、上一个 OP_CODESEPARATOR 位置、当前输入的 Taproot annex、选择器本身(control 位);以及输入侧的前序输出(prevouts)、序列号、scriptSig、前序输出的 scriptPubKey 与金额、各输入的 annex;输出侧的 scriptPubKey 与金额。对输入输出还可指定选择范围:全部、仅当前下标对应的那个、前若干个,或逐个列出最多 32 个下标(绝对下标或相对当前输入的下标)。

三种写法:

原文提醒:同一组被选数据可能有多种选择器写法,因此建议总是把 control 位置上、让哈希同时承诺所用的选择器本身,以免歧义。

4.3 资源计费

每次执行 OP_TXHASH,按 BIP-342 的 sigops 预算扣 25,预算扣成负数脚本立即失败。体积任意大的字段在哈希时都先取其哈希值、且结果可缓存,原文给出了领先模式下的 SHA256 上下文缓存策略,避免反复计算成为拒绝服务入口。

五、谁必须动

普通持币人:无直接变化。草案未激活,你的钱包与地址都不受影响。

钱包与协议开发者:多一个可编程原语。用它做契约或多方协议时,关键是把选择器设计对:选少了约束不住,选多了把不该锁死的字段(如手续费安排的余地)也锁死。原文建议恒承诺选择器本身。

全节点与矿工:若将来部署,这是一次共识软分叉:节点要实现选择器解析与 TxHash 计算、计入 sigops 预算。不升级的旧节点按 OP_SUCCESS 旧语义直接放行含该操作码的脚本,这正是占位操作码升级路径的设计。

共识层:除 Tapscript 语境外不生效;旧脚本语境中的 OP_SUCCESS189 不受影响。

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

状态为 Draft(草案),原文的部署一节只说可用 BIP-9 版本位部署、具体策略与位分配未定。也就是说,它没有激活时间表,主网节点今天不会按新语义验证 OP_TXHASH;仓库里附了 Rust 参考实现与测试向量,Bitcoin Core 与 rust-bitcoin 也有早期实现尝试,但原文注明那些实现基于较早版本的规范、正在更新。

常见误读:

“OP_TXHASH 就是 OP_CHECKTEMPLATEVERIFY 换了个名字。”

不对。CTV 是“算模板哈希并当场比对、不等就失败”的校验型操作码;TXHASH 只把哈希压栈,什么都不校验。取空选择器时它算出的哈希与 CTV 的模板语义相当,但后续既可以做相等比较,也可以交给 OP_CHECKSIGFROMSTACK 验签、或参与别的计算。用原文的话说,它严格推广了 BIP-119,而不是改名。

七、延伸

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