跳转到正文
buybitcoinsmart

术语表 /协议与升级

SIGHASH_ANYPREVOUT

又称 APO。

SIGHASH_ANYPREVOUT 是什么?
SIGHASH_ANYPREVOUT 是一种针对 Taproot 脚本提出的签名模式,可让一个签名花费任何锁定在匹配脚本上的币,而不是仅限于它最初对应的那一枚币。

规定于 BIP-118。

BIP-118为 tapscript 定义了一种新的公钥类型,长度为33字节,以0x01 开头,而不是在普通密钥上增加一个标志。该提案于2017年2月分配编号,从未被激活,且仅适用于脚本路径花费,不适用于密钥路径花费。您的钱包中没有任何功能可以用这种方式签名,因此任何声称可在主网上使用 eltoo 通道的产品,描述的都是未来。

运作方式

状态: BIP-118为 Draft(草案),编号分配于2017-02-28,依赖 BIP-340、BIP-341和 BIP-342,其 Deployment 部分的内容为 TODO。没有任何内容被取代,因为没有任何内容上线。

Taproot 签名会承诺被花费那枚币的 outpoint,即在 BIP-118所修改的 ANYONECANPAY 摘要中,由 txid 和索引构成的36字节,使签名永远绑定于一枚币。如果从被签名的消息中去掉 outpoint,签名就不再指明某一枚币,而是指明一种形态,之后任何属于该形态的 UTXO 都可以与它绑定。该 BIP 将此称为 dynamic rebinding(动态重新绑定)。

文中定义了两个变体,二者的区别在于仍然承诺哪些内容。

  • SIGHASH_ANYPREVOUT,位值为0x40,去掉 outpoint,但保留输入的金额(8字节)、其 scriptPubKey(此处始终为35字节)和 tapleaf 哈希。这样,该签名适用于任何在同一脚本下持有相同金额的币。
  • SIGHASH_ANYPREVOUTANYSCRIPT,位值为0xc0,同时去掉金额、scriptPubKey 和 tapleaf 哈希。它适用于任何其脚本能被该密钥满足的币。

选择启用发生在创建地址时,而不是签名时。这类密钥只能通过 tapscript 叶子使用,因此地址的默克尔树中必须包含这样一个叶子,在被花费之前,它与其他任何 Taproot 地址无法区分。有一个常量将两者区分开:BIP-118密钥的 key_version 为0x01,普通 tapscript 密钥为0x00,因此同一个私钥无法生成在两套规则下都有效的签名。六个新的 hash_type 字节变为合法:0x41、0x42、0x43、0xc1、0xc2 和0xc3。

在哪里会遇到它

SIGHASH_ANYPREVOUT 没有出现在任何主网交易中,BIP-118预计,即使它存在,也 "only be rarely used in practice"(实际中仅会很少使用),因为脚本路径花费体积更大,也更容易被识别。

它是为 eltoo 设计的,这是一种链下更新方案。链下协议必须应对对手方发布的任何旧状态,而普通签名会承诺其所响应的那笔确切交易,因此每一个可能出现的状态都需要一个新的签名。eltoo 则利用脚本和 nLockTime 使签名具有不对称性,带有较新签名的交易可以花费带有较旧签名的交易,反之则不行,因此一个更新签名可以应用在对手方发布的任何更早的更新之上。

这个名称记录了一次更正。Joseph Poon 于2016年2月在最初的闪电网络论文提出这一想法之后,将其作为 SIGHASH_NOINPUT 提出,而更名表明输入并非真正被忽略:nSequence 始终被签名,在 SIGHASH_ANYPREVOUT 下,脚本和金额也会被签名。

该 BIP 的安全部分指出了代价:重放。ANYPREVOUT 签名可被重复用于任何具有相同脚本和相同金额的其他 UTXO,ANYPREVOUTANYSCRIPT 签名则可被用于在其任一脚本中重复使用该密钥的任何 UTXO,因此密钥重用从隐私方面的麻烦变成了损失资金的途径。这类交易也可被陌生人篡改:任何能提供匹配输入的人,无需私钥就能改变 txid。

SIGHASH_ANYPREVOUT vs SIGHASH_ANYONECANPAY

SIGHASH_ANYONECANPAY 目前已存在于网络中,它会去掉除被签名输入之外的所有输入;SIGHASH_ANYPREVOUT 则连保留下来的那个输入的一部分也去掉。BIP-118将其摘要描述为去掉 outpoint 的 ANYONECANPAY 摘要,只有一行之差,后果却很大。ANYONECANPAY 签名无法被重放,因为它所指明的 outpoint 只能被花费一次。放弃这一承诺后,重放保护必须来自构建在其上的协议,而不是来自签名本身。

请勿混淆

常见问题

现在可以使用 SIGHASH_ANYPREVOUT 吗?

不可以。BIP-118仍为 Draft,其 Deployment 部分的内容为 TODO,主网上没有任何节点执行这些规则,因此以这种方式签名的内容无法在主网上花费。

SIGHASH_ANYPREVOUT 与 SIGHASH_NOINPUT 是同一回事吗?

是的,它是同一想法经过更名和重新设计的版本。Joseph Poon 于2016年2月提出了 SIGHASH_NOINPUT;ANYPREVOUT 草案仅针对 Taproot 脚本路径花费,仍然承诺 nSequence,并可选择性地承诺脚本和金额,新名称反映的正是这一点。

为什么 BIP-118定义的是一种新的公钥类型,而不仅仅是一个新标志?

因为这一能力必须在创建地址时选择启用。这类签名只能用于 tapscript 叶节点内的 BIP-118公钥,所以没有此类叶节点的地址永远无法以这种方式花费,而且在被花费之前,它与其他任何 Taproot 地址都无法区分。

接着阅读

相关术语

协议与升级中的更多术语

阅读本页英文版