比特币契约第三部分:SIGHASH_ANYPREVOUT(APO)技术解析
SIGHASH_ANYPREVOUT,这个技术术语背后,其实是一个相当大胆的突破:它允许签名不再绑定具体的输入UTXO,而是只对输出结果负责。这为闪电网络的Eltoo改造铺平了道路,也大幅降低了状态存储的需求,从而让通道工厂和轻量级瞭望塔的构建成为可能。

换句话说,APO(即SIGHASH_ANYPREVOUT的简称)让比特币的签名可以授权任何兼容的UTXO,而不是被锁死在固定的输出点上。这意味着Lightning网络、Vault以及各种Layer-2协议,能够在无需额外密钥管理开销的前提下,使用可重新绑定的预签名交易。
这个概念最早可以追溯到Joseph Poon和Thaddeus Dryja在2026年Lightning Network论文中提出的SIGHASH_NOINPUT,随后在同年2月,Joseph Poon在比特币开发邮件列表上正式将其作为提案推出。需要明确的是,它并非一个新的操作码,而是对SIGHASH标志的一个新提议值,计划通过软分叉升级引入比特币网络。SIGHASH标志附加在签名之后,决定了交易哪些部分已被签署,并由CHECKSIG操作码验证。选择哪种标志,完全由签署人决定,而非由scriptPubKey强制执行。受限于软分叉的技术细节,目前SIGHASH_ANYPREVOUT提案仅适用于从Taproot地址发出的支出。
如图1所示,比特币已有的标准SIGHASH模式各有侧重。如果标志设置为SIGHASH_ALL,签名必须覆盖所有输入、所有输出以及具体的输出点,将授权严格绑定到特定的UTXO。输出点(outpoint)由交易ID和输出索引组成,唯一标识被消耗的UTXO。相比之下,SIGHASH_NONE只对输入签名,输出不受约束;SIGHASH_SINGLE则对所有输入签名,但只对与输入索引相同的输出签名。ANYONECANPAY修饰符则允许单个输入独立签名,增加了灵活性。关键在于,这些现有模式都要求签名包含对输出点的承诺,而SIGHASH_ANYPREVOUT正是为了打破这一限制而生。

BIP-118定义了两种ANYPREVOUT变体,它们的主要区别在于摘要中省略了哪些前一输出的信息(图2对此做了清晰总结):
- 输出点被排除在摘要之外,但签名仍会承诺之前输出的金额和scriptPubKey,以及输入的nSequence。
SIGHASH_ANYPREVOUT:
- 金额和scriptPubKey也被排除在外,这意味着签名完全不绑定在已花费输出的锁定脚本上。
SIGHASH_ANYPREVOUTANYSCRIPT:
所有其他承诺都遵循标准的Taproot签名消息结构,并依赖于所选的基础标志(如SIGHASH_ALL或SIGHASH_SINGLE)。

由于摘要中省略了输出点,同一个签名可以授权使用任何满足剩余提交字段的兼容UTXO。举个例子:假设一笔交易被预先签名为ANYPREVOUT | SIGHASH_ALL,当同一地址后续收到另一个0.5 BTC的UTXO时,即使创建原始签名的私钥已经不可用,这个签名依然可以重复使用,产生0.5 BTC的输出。但需要注意的是,如果新UTXO的金额超过0.5 BTC,且原始签名没有包含变更输出,矿工就会损失多余的部分。这种“重新绑定”特性,正是ANYPREVOUT在第二层协议中极具价值的原因——同一预签名交易可以适用于多个可能的链上UTXO,无需为每个协议重新签名。
对于类似契约的应用场景,ANYPREVOUT变体保留了对前一输出scriptPubKey的承诺,确保资金始终绑定在同一锁定脚本下。而ANYPREVOUTANYSCRIPT完全去除了这种绑定,因此不太适合需要严格契约约束的场景。
与OP_CTV类似,SIGHASH_ANYPREVOUT改进了预签名交易的逻辑能力,但它本身并不支持递归契约或交易自省。它的核心价值,在于放松了签名与特定UTXO之间的绑定,允许签名在多个兼容UTXO间重复使用。
一些研究指出,移除输出点承诺可以实现“密钥恢复构造”——即可以从固定的签名和消息对中推导出公钥,使得对应的私钥对任何人都可证明为未知。这样一来,UTXO的密钥路径可被证明不可使用,强制任何花费都必须通过脚本路径。这种机制避免了临时密钥的需求,而临时密钥在依赖脚本路径强制执行的构造中,是使密钥路径不可用的关键。这一观察见于Jacob Swambo等人(2026年)的《比特币契约:三种控制未来的方式》,尽管它目前仍属理论探索,并非BIP-118的设计初衷。
说到风险,SIGHASH_ANYPREVOUT签名的主要隐患在于签名重放。由于签名不承诺特定输出点,只要新UTXO满足剩余提交字段,同一个签名就能被用于花费与原意不同的UTXO。以下场景会加剧重放风险:
- 使用ANYPREVOUT | SIGHASH_SINGLE,且输出钱额可重新排列;
- 存在具有相同scriptPubKey和金额的独立UTXO;
- 同一公钥以兼容文字出现(如ANYPREVOUTANYSCRIPT);
- 矿工可以影响交易排序和包含性,利用上述条件。
不过,这些场景大多属于故意滥用,或是源于用户/开发者在协议设计时,未能充分考虑重放条件。
在下一篇文章中,我们将探讨一些作为辅助工具的操作码。这些工具能扩展比特币脚本或数据处理的表达力,但除非与其他操作码结合,否则并不直接实现契约功能。下一类将重点讨论OP_CHECKSIGFROMSTACK和OP_CAT。