jamesob/bips 的 bips/bip-0345.mediawiki,位于 e2ff23b3f07215450e75779f7f944d24660a9d47

  • jamesob
  • 发布于 2025-01-28 14:42
  • 阅读 27

该BIP(比特币改进提案)提出了两种新的Tapscript操作码OP_VAULT和OP_VAULT_RECOVER,旨在为比特币添加共识支持,实现一种专门的承诺(covenant)。这些操作码允许用户在指定资金可以花费到任意目的地之前强制执行一段延迟期,但可以通过预先指定的“恢复”路径随时取回资金,从而显著降低密钥泄露导致资金丢失的风险。

BIP: 345 Layer: Consensus (软分叉) Title: OP_VAULT Author: James O'Beirne <vaults@au92.org> Greg Sanders <gsanders87@gmail.com> Anthony Towns <aj@erisian.com.au> Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0345 Status: Draft Type: Standards Track Created: 2023-02-03 License: BSD-3-Clause Post-History: 2023-01-09: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-January/021318.html [bitcoin-dev] OP_VAULT announcment 2023-03-01: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-March/021510.html [bitcoin-dev] BIP for OP_VAULT


|     |
| --- |
| ## 目录&lt;br>[永久链接:目录](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#table-of-contents)&lt;br>- [简介](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Introduction) &lt;br>  - [动机](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Motivation) &lt;br>    - [用例示例](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Example_uses) &lt;br>      - [可证明的**时间锁**](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Provable_timelocks)&lt;br>- [目标](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Goals)&lt;br>- [设计](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Design) &lt;br>  - [交易类型](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Transaction_types)&lt;br>  - [费用管理](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Fee_management)&lt;br>- [规范](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Specification) &lt;br>  - [`OP_VAULT` 计算](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-codeOP_VAULTcode_evaluation)&lt;br>  - [`OP_VAULT_RECOVER` 计算](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-codeOP_VAULT_RECOVERcode_evaluation)&lt;br>  - [延迟检查计算](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Deferred_check_evaluation)&lt;br>- [策略变更](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Policy_changes)&lt;br>- [实现](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Implementation)&lt;br>- [应用](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Applications) &lt;br>  - [创建 vault](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Creating_a_vault)&lt;br>  - [触发提款](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Triggering_a_withdrawal)&lt;br>  - [恢复授权](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Recovery_authorization) &lt;br>    - [未经授权的恢复](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Unauthorized_recovery)&lt;br>    - [授权恢复](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Authorized_recovery)&lt;br>    - [建议:使用简单的离线恢复授权密钥种子](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Recommendation_use_a_simple_offline_recovery_authorization_key_seed)&lt;br>  - [地址重用和恢复](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Address_reuse_and_recovery) &lt;br>    - [建议:为新的 trigger 密钥生成新的恢复地址](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Recommendation_generate_new_recovery_addresses_for_new_trigger_keys)&lt;br>    - [费用管理](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Fee_management-2)&lt;br>  - [批量处理](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Batching) &lt;br>    - [在 trigger 期间](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-During_trigger)&lt;br>    - [在提款期间](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-During_withdrawal)&lt;br>    - [在恢复期间](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-During_recovery)&lt;br>  - [瞭望塔](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Watchtowers)&lt;br>  - [输出描述符](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Output_descriptors)&lt;br>- [部署](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Deployment)&lt;br>- [向后兼容性](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Backwards_compatibility)&lt;br>- [原理](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Rationale)&lt;br>- [参考](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-References)&lt;br>- [致谢](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#user-content-Acknowledgements) |

### 简介

[永久链接:简介](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#introduction)

该 BIP 提议了两个新的 **tapscript** 操作码,它们增加了对专门**约定**的共识支持:`OP_VAULT` 和 `OP_VAULT_RECOVER`。这些操作码与
`OP_CHECKTEMPLATEVERIFY`
([BIP-0119](https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki)) 结合使用,
允许用户在指定的币被花费到任意目的地之前强制执行一个延迟期,但预先指定的“恢复”路径除外。
在最终提款之前的任何时间,币都可以花费到恢复路径。

#### 动机

[永久链接:动机](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#motivation)

托管比特币的风险是众所周知的。比特币用户必须付出巨大的努力来保护他们的私钥,并希望一旦配置好,他们的托管系统不会屈服于任何数量的不断演变和持续的威胁。一旦检测到泄露,用户几乎没有办法进行干预。该提案引入了一种机制,可以显著减轻密钥泄露的最坏结果:币损失。

引入一种在意外花费期间进行干预的方法,允许用户采用高度安全的密钥存储方法或不寻常的后备策略,这些方法或策略仅在最坏情况下才会被使用,并且在其他情况下可能在操作上受到禁止。该提案的目标是使这种策略能够被任何规模的托管人使用,并且复杂性最低。

##### 用例示例

[永久链接:用例示例](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#example-uses)

个人托管比特币的常见配置是使用硬件钱包进行“单签名和密码短语”。拥有这种配置的用户可能会担心依赖单一制造商进行密钥管理以及对硬件的物理访问相关的风险。

该个人可以使用 `OP_VAULT` 来利用高度安全的密钥作为不太可能发生的恢复路径,同时使用他们现有的签名程序作为提款 **trigger** 密钥,并配置例如 1 天的花费延迟。

恢复路径密钥可以是高度安全的,否则可能使其不适合日常使用。例如,可以使用某种模拟方式生成密钥,或者在然后销毁的旧计算机上生成密钥,并且私钥仅以纸质形式复制。或者密钥可以是使用来自不同制造商的设备的 2-of-3 多重签名。也许密钥在地理上或社交上是分布式的。

由于它可以是任何比特币脚本策略,因此恢复密钥可以包括许多花费条件,例如,如果高度安全的密钥最终变得**太**高度安全,则可以**时间延迟**回退到“更简单”的恢复方法。

用户可以在他们的移动设备上运行软件,以监视区块链上 vault 输出的输出。如果 vault 中的币以意外的方式移动,用户可以立即将其清理到恢复路径,但是每天花费币的方式与使用 vault 之前的方式相同(除了花费延迟)。

比特币的机构托管人可以使用类似的方式使用 vault。

###### 可证明的**时间锁**

[永久链接:可证明的**时间锁**](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#provable-timelocks)

该提案提供了一种缓解
["$5 扳手攻击"](https://web.archive.org/web/20230210123933/https://xkcd.com/538.) 的方法。通过将花费延迟设置为例如一周,并使用强制执行更长的相对**时间锁**的脚本作为恢复路径,vault 的所有者可以证明他无法立即访问其价值。据作者所知,这是在不永久滚动具有**时间锁**的币或不依赖受信任的第三方的情况下配置此防御的唯一方法。

### 目标

[永久链接:目标](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#goals)

[![](https://img.learnblockchain.cn/2025/07/13/79015420_image.png)](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345/vaults-Basic.png)

自 2016 年以来([MES16](http://fc16.ifca.ai/bitcoin/papers/MES16.pdf))正式讨论了比特币中的 Vault,自 [2014](https://web.archive.org/web/20160220215151/https://bitcointalk.org/index.php?topic=511881.0) 以来非正式讨论了比特币中的 Vault。
在出现意外花费的情况下,具有可配置延迟期和恢复功能的价值已被广泛认可。

除了[使用大型多重签名配置模拟 Vault](https://github.com/revault) 之外,在现有共识规则下实现 Vault 的唯一方法是使用使用一次性密钥创建的预签名交易。
这种方法最早在 [2020](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html) 中得到证明。

不幸的是,这种方法有许多实际缺点:

- 需要生成并安全地删除用于模拟 vault 约定的临时密钥,
- 必须预先确定数量和提款模式,
- 有必要预先确定资金必须通过的地址才能到达最终提款目标,而该目标可能仅在 **unvault** 时才知道,
- 必须在 vault 创建时决定特定的费用管理技术或钱包,
- 如果重复使用 vault 地址,则会发生币损失,
- 必须永久存储表示 vault 的“不记名资产”的交易数据,否则价值会丢失,并且
- 每次要存入新余额时,都必须执行 vault 创建仪式。

类似于 [OP\_CHECKTEMPLATEVERIFY](https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki) 或
[SIGHASH\_ANYPREVOUT](https://github.com/bitcoin/bips/blob/master/bip-0118.mediawiki) 的“预计算”约定机制的部署,
将消除使用临时密钥的必要性,因为约定是在链上强制执行的,并减轻了敏感数据存储的负担,
因为必要的交易可以从一组紧凑的参数生成。这种方法在 [2022](https://github.com/jamesob/simple-ctv-vault) 中得到了证明。

但是,预计算的局限性仍然适用:数量、目的地和费用管理都是固定的。资金必须流经固定的中介才能到达其最终目的地。
在费用激增或花费延迟短的情况下,批量操作可能对于成功恢复至关重要,但这是不可能的。

[![](https://img.learnblockchain.cn/2025/07/13/withdrawal-comparison.drawio.png)](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345/withdrawal-comparison.drawio.png)

拥有可以编码任意交易状态机的“通用”约定机制将使我们能够解决这些问题,但代价是复杂而庞大的脚本,这些脚本可能会在区块链中重复多次。
这种通用框架的特定设计和部署时间表也不确定。这种方法在 [2016](https://blog.blockstream.com/en-covenants-in-elements-alpha/) 中得到了证明。

该提案旨在通过使用专门的约定,通过最小的交易和运营开销,提供延迟期/恢复路径的使用,来解决上述问题。

该提案的设计目标是:

- **高效地重用现有的 vault 配置**。\[ [1](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-1)\] 单个 vault 配置,无论是否是相同的字面 `scriptPubKey`,都应该能够“接收”多个存款。
- 用于恢复和取款的**批量操作**,以有效地管理多个 vault 币。
- **无限的部分取款**,允许用户提取部分 vault 余额,而无需为新的 vault 执行设置仪式。
- **动态 unvault 目标**,它允许在取款时而不是最初创建 vault 时指定提议的 vault 取款目标。这将消除对预先指定的中间钱包的需求,该钱包仅用于将 **unvault** 资金路由到其所需的目的地。
- **动态费用管理**,与动态目标一样,它将费用率和来源的规范推迟到 **unvault** 时间,而不是 vault 创建时间。

这些目标伴随着基本的安全考虑因素(例如,不易受到 **mempool** **pinning** 的影响)以及对简洁性的渴望,无论是在创建的输出数量还是脚本大小方面。

此提案旨在与可能引入的任何未来的 **sighash** 模式(例如 `SIGHASH_GROUP`)或费用管理策略(例如 [交易赞助](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html))兼容。这些操作码的使用将受益于,但不严格依赖于 [v3 交易中继](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-September/020937.html) 和 [临时锚点](https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawiki)。

### 设计

[永久链接:设计](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#design)

在典型的用法中,通过在 **taptree** [(BIP-341)](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) 中保护币来创建 vault,该 **taptree** 包含至少两个叶子:一个带有包含 `OP_VAULT` 的脚本,该脚本有助于预期的取款过程,另一个带有 `OP_VAULT_RECOVER` 的叶子,该叶子确保币可以在取款完成之前的任何时间恢复。

`OP_VAULT` 的规则通过允许支出交易用预先指定的脚本模板替换 `OP_VAULT` **tapleaf**,从而允许在支出(**trigger**)时设置某些参数,来确保具有**时间锁**的可中断取款。
**taptree** 中的所有其他叶子在目标输出中必须保持不变,这保留了恢复路径以及最初包含在 vault 中的任何其他支出条件。
这类似于 [2021](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019419.html) 中提出的 `TAPLEAF_UPDATE_VERIFY` 设计。

下面将更精确地描述这些 **tapleaf** 替换规则,确保具有**时间锁**的取款,其中**时间锁**由原始 `OP_VAULT` 参数固定,到一组固定的输出(通过
`OP_CHECKTEMPLATEVERIFY`\[ [2](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-2)\])在 **trigger** 取款过程时选择。

虽然在此提案中使用 `OP_CHECKTEMPLATEVERIFY` 作为将提议的取款绑定到一组特定最终输出的首选方法,但 `OP_VAULT` 可以与其他(和将来的)操作码组合使用,以促进其他类型的取款过程。

[![](https://img.learnblockchain.cn/2025/07/13/opvault.drawio.png)](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345/opvault.drawio.png)

#### 交易类型

[永久链接:交易类型](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#transaction-types)

vault 有许多阶段,其中一些是可选的:

- **vault 交易**:将一些币保护到一个 **Taproot** 结构中,该结构至少包含一个 `OP_VAULT` 叶子和一个 `OP_VAULT_RECOVER` 叶子。
- **trigger 交易**:将一个或多个 `OP_VAULT`-**tapleaf** 输入支出到一个输出中,该输出受**时间锁**取款的保护,以获得一组固定的输出,这些输出在 **trigger** 时选择。这公开广播了提取到某些特定输出集的意图。

**trigger** 交易可能具有一个额外的输出,该输出将一些 vault 余额分配到部分“**revault**”中,该“**revault**”只是将价值的 **revault** 部分保护到与正在支出的包含 `OP_VAULT` 的输入相同的 `scriptPubKey` 中。
- **取款交易**:在 **trigger** 输入按照花费延迟到期后,将锁定**时间锁**、锁定目标的 **trigger** 输入支出到一组兼容的最终取款输出(例如,每个 `CHECKTEMPLATEVERIFY` 哈希)。具有**时间锁**的 CTV 交易是 OP\_VAULT 的激励性用法,但是可以在创建 vault 期间指定任何脚本模板。
- **恢复交易**:通过 `OP_VAULT_RECOVER` **tapleaf** 将一个或多个 vault 输入支出到预先指定的恢复路径,这可以在取款交易确认之前的任何时间完成。每个输入可以选择性地需要满足指定的**恢复授权**脚本的见证,该脚本是 `OP_VAULT_RECOVER` 片段的可选脚本前缀。稍后将讨论使用恢复授权的某些权衡。

#### 费用管理

[永久链接:费用管理](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#fee-management)

该提案的主要考虑因素是如何处理费用管理。
提供动态费用管理对于 vault 的运行至关重要,因为

- 预先计算的费用容易使交易在高费用环境下无法确认,并且
- 预先指定的费用钱包可能会在使用前被盗用或丢失。

但是动态费用管理会引入
[**pinning** 向量](https://bitcoinops.org/en/topics/transaction-pinning/)。
在使用此提案引入的新的基于目标的支出策略时,已注意避免不必要地引入这些向量。

最初,此提案对改革后的交易 **nVersion**=3 策略(包括临时锚点)具有硬性依赖关系,但此后已对其进行了修改,以简单地从这些策略以及其他潜在的费用管理机制中受益。

### 规范

[永久链接:规范](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#specification)

**tapscript** 操作码 `OP_SUCCESS187` (`0xbb`) 和
`OP_SUCCESS188` (`0xbc`) 受新规则的约束
以分别实现 `OP_VAULT` 和 `OP_VAULT_RECOVER`。

#### `OP_VAULT` 计算

[永久链接:`OP_VAULT` 计算](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#op_vault-evaluation)

在计算 `OP_VAULT`(`OP_SUCCESS187`,
`0xbb`)时,堆栈的预期格式(从上到下显示)为:

<leaf-update-script-body> <n-pushes> [ n leaf-update script data items ... ] <trigger-vout-idx> <revault-vout-idx> <revault-amount>


其中

- `&lt;leaf-update-script-body>` 是序列化脚本的最小编码数据推送。\[ [3](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-3)\]
  - 否则,脚本执行必须失败并立即终止。
- `&lt;n-pushes>` 是一个最大 4 字节的 `CScriptNum` 编码的数字,指示应从堆栈中弹出多少个叶子更新脚本项目。\[ [4](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-4)\]
  - 如果此值未解码为有效的 **CScriptNum**,则在支出此输出时,脚本执行必须失败并立即终止。
  - 如果此值小于 0,则在支出此输出时,脚本执行必须失败并立即终止。
  - 如果堆栈上的项目少于 `&lt;n-pushes> + 2` 个,则在支出此输出时,脚本执行必须失败并立即终止。
- 以下 `&lt;n-pushes>` 堆栈项目从堆栈中弹出,并作为最小编码的推送数据参数作为前缀添加到 `&lt;leaf-update-script-body>`,以构造预期的 **tapleaf** 替换脚本。
  - 如果堆栈上的项目少于 `&lt;n-pushes> + 2` 个,则在支出此输出时,脚本执行必须失败并立即终止。
- `&lt;trigger-vout-idx>` 是一个最大 4 字节的 **CScriptNum** 编码的数字,指示输出的索引,该索引与可选的 **revault** 输出结合使用,可以结转此输入的值,并且除了当前执行的叶子之外,具有相同的 **taptree**。
  - 如果此值未解码为有效的 **CScriptNum**,则在支出此输出时,脚本执行必须失败并立即终止。
  - 如果此值小于 0 或大于或等于输出的数量,则在支出此输出时,脚本执行必须失败并立即终止。
- `&lt;revault-vout-idx>` 是一个最大 4 字节的 **CScriptNum** 编码的数字,可以选择性地指示输出的索引,该索引与 **trigger** 输出结合使用,可以结转此输入的值,并且具有与当前输入相同的 **scriptPubKey**。
  - 如果此值未解码为有效的 **CScriptNum**,则在支出此输出时,脚本执行必须失败并立即终止。
  - 如果此值大于或等于输出的数量,则在支出此输出时,脚本执行必须失败并立即终止。
- `&lt;revault-amount>` 是一个最大 7 字节的 **CScriptNum** 编码的数字,指示要 **revault** 的 **satoshis** 的数量。
  - 如果此值未解码为有效的 **CScriptNum**,则在支出此输出时,脚本执行必须失败并立即终止。
  - 如果此值不大于或等于 0,则在支出此输出时,脚本执行必须失败并立即终止。
  - 如果此值不为零,但 `&lt;revault-vout-idx>` 为负,则在支出此输出时,脚本执行必须失败并立即终止。

解析堆栈后,将执行以下验证检查:
- 将由 `&lt;trigger-vout-idx>` 指定的输出称为 **triggerOut**。
- 如果 **triggerOut** 的 scriptPubKey 不是与当前执行脚本相同版本和相同 tapleaf 版本的见证程序,则脚本执行 **必须** 失败并立即终止。
- 通过获取 `&lt;leaf-update-script-body>` 并在其前面加上 `&lt;n-pushes>` leaf-update 脚本数据项的最小编码数据推送来构建的脚本称为 **leaf-update-script**。
  - 注意:leaf-update 数据项在 **leaf-update-script** 中的顺序与它们在堆栈中出现的顺序相同。
- 如果 **triggerOut** 的 scriptPubKey 与 taptree 的 scriptPubKey 不匹配,而该 taptree 与当前评估的输入的 taptree 相同,只是将 leaf 脚本替换为 **leaf-update-script**,则当花费此输出时,脚本执行 **必须** 失败并立即终止。
  - 注意:允许生成的 taproot 输出的奇偶校验位变化,因此必须检查新输出的两个值。
- 将由 `&lt;revault-vout-idx>` 指定的输出(如果索引值为非负数)称为 **revaultOut**。
- 如果 **revaultOut** 的 scriptPubKey 与正在花费的输入的 scriptPubKey 不相等,则当花费此输出时,脚本执行 **必须** 失败并立即终止。
- 实现建议:如果 **triggerOut** 和 **revaultOut**(如果存在)的金额之和不大于或等于此输入的值,则当花费此输出时,脚本执行 **应该** 失败并立即终止。
  - 金额检查最终通过延迟检查完成,但此检查可以帮助快速排除明显无效的花费。
- 将一个延迟检查\[ [5](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-5)\]排队,以确保此输入的 `nValue` 减去 `&lt;revault-amount>` 的 satoshis 包含在 `&lt;trigger-vout-idx>` 处的输出 `nValue` 中。
- 将一个延迟检查排队,以确保 `&lt;revault-amount>` satoshis(如果非零)包含在 `&lt;revault-vout-idx>` 处的输出 `nValue` 中。
  - 这些延迟检查可以用下面的伪代码(在 **延迟检查** 中)来描述,如下所示:

    `TriggerCheck(input_amount, &lt;revault-amount>, &lt;trigger-vout-idx>, &lt;revault-vout-idx>)`。

如果没有条件失败,则在堆栈上留下一个真值(`0x01`)。

#### `OP_VAULT_RECOVER` 评估

[永久链接:OP_VAULT_RECOVER 评估](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#op_vault_recover-evaluation)

在评估 `OP_VAULT_RECOVER`(`OP_SUCCESS188`,
`0xbb`)时,预期的堆栈格式(从上到下显示)为:

<recovery-sPK-hash> <recovery-vout-idx>


其中

- `&lt;recovery-sPK-hash>` 是一个 32 字节的数据推送。
  - 如果长度不为 32 字节,则当花费此输出时,脚本执行 **必须** 失败并立即终止。
- `&lt;recovery-vout-idx>` 是一个最多 4 字节的 CScriptNum 编码的数字,指示 recovery 输出的索引。
  - 如果此值无法解码为有效的 CScriptNum,则当花费此输出时,脚本执行 **必须** 失败并立即终止。
  - 如果此值小于 0 或大于或等于输出的数量,则当花费此输出时,脚本执行 **必须** 失败并立即终止。

解析堆栈后,将执行以下验证检查:

- 将索引 `&lt;recovery-vout-idx>` 处的输出称为 **recoveryOut**。
- 如果 **recoveryOut** 的 scriptPubKey 没有等于 `&lt;recovery-sPK-hash>` 的 tagged hash(`tagged_hash("VaultRecoverySPK", recoveryOut.scriptPubKey) == recovery-sPK-hash`,其中 `tagged_hash()` 来自 [BIP-0340 reference code](https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py)),则当花费此输出时,脚本执行 **必须** 失败并立即终止。
  - 实现建议:如果 **recoveryOut** 的 `nValue` 不大于或等于此输入的金额,则脚本 **应该** 失败并立即终止。
- 将一个延迟检查排队,以确保 **recoveryOut** 的 `nValue` 包含此输入的整个 `nValue`。\[ [6](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-6)\]
  - 可以用下面的伪代码将此延迟检查描述为 `RecoveryCheck(&lt;recovery-vout-idx>, input_amount)`。

如果没有条件失败,则在堆栈上留下一个真值(`0x01`)。

#### 延迟检查评估

[永久链接:延迟检查评估](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#deferred-check-evaluation)

一旦根据上述规则验证了交易的所有输入,**必须** 评估排队的所有延迟检查。

以下是 Python 伪代码:

class TriggerCheck: """Queued by evaluation of OP_VAULT (withdrawal trigger).""" input_amount: int revault_amount: int trigger_vout_idx: int revault_vout_idx: int

class RecoveryCheck: """Queued by evaluation of OP_VAULT_RECOVER.""" input_amount: int vout_idx: int

def validate_deferred_checks(checks: [DeferredCheck], tx: Transaction) -> bool: """ Ensure that all value from vault inputs being triggered or recovered is preserved in suitable output nValues. """

Map to hold expected output values.

out_map: Dict[int, int] = defaultdict(lambda: 0)

for c in checks:
    if isinstance(c, TriggerCheck):
        out_map[c.trigger_vout_idx] += (c.input_amount - c.revault_amount)

        if c.revault_amount > 0:
            out_map[c.revault_vout_idx] += c.revault_amount

    elif isinstance(c, RecoveryCheck):
        out_map[c.vout_idx] += c.input_amount

for (vout_idx, amount_sats) in out_map.items():
    # Trigger/recovery value can be greater than the constituent vault input
    # amounts.
    if tx.vout[vout_idx].nValue &lt; amount_sats:
        return False

return True

如果上述过程或等效过程返回 false,则脚本执行 **必须** 失败并立即终止。

这确保了所有兼容的 vault 输入可以批量处理到共享的相应触发或 recovery 输出中,同时保留其整个输入值。

### 策略变更

[永久链接:策略变更](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#policy-changes)

为了防止可能的 pinning 攻击,recovery 交易必须是可替换的。

- 当验证正在花费的 `OP_VAULT_RECOVER` 输入时,如果同时满足以下两个条件,则脚本 **必须** 失败(按策略,而不是共识)并立即终止\[ [7](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-7)\]
1. 根据 [BIP-0125](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki),该输入未通过具有小于 `0xffffffff - 1` 的 nSequence 号码标记为选择加入可替换,并且
2. recovery 交易的版本具有除 3 之外的 nVersion。

如果包含 `OP_VAULT_RECOVER` 的脚本小于等于 34 字节\[ [8](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-8)\],则称其为“未经授权”,因为没有脚本保护 recovery 过程。为了防止在未经授权的 recovery 情况下出现 pinning 攻击 - 因为输入的花费(以及交易的结构)未通过签名的签名消息授权 - 未经授权的 recovery 交易的输出结构受到限制。

- 如果 recovery 未经授权,则 recovery 交易 **必须**(按策略)遵守以下约束:
  - 如果花费交易具有两个以上的输出,则脚本 **必须** 失败并立即终止。
  - 如果花费交易具有两个输出,并且不是 **recoveryOut** 的输出不是 [ephemeral anchor](https://github.com/instagibbs/bips/blob/ephemeral_anchor/bip-ephemeralanchors.mediawiki),则脚本 **必须** 失败并立即终止。\[ [9](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_note-9)\]

### 实现

[永久链接:实现](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#implementation)

在 bitcoin-inquisition 上有一个示例实现 [here](https://github.com/jamesob/bitcoin/tree/2023-01-opvault-inq),并附有相关的 [pull request](https://github.com/bitcoin-inquisition/bitcoin/pull/21)。

### 应用

[永久链接:应用](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#applications)

上面的规范可能令人惊讶地没有具体说明如何实现具有固定目标的相对时间锁定的 withdrawal 过程。`OP_VAULT` 中指定的 tapleaf 更新语义以及 `OP_VAULT_RECOVER` 启用的基于输出的授权可用于实现 vault,但如果没有其他两个部分,它们是不完整的:

- 一种强制相对时间锁定的方法,例如 `OP_CHECKSEQUENCEVERIFY`,以及
- 一种强制提议的 withdrawal 最终被花费到一组精确的输出的方法,例如 `OP_CHECKTEMPLATEVERIFY`。

这两个部分与 `OP_VAULT` 的 tapleaf 更新功能相结合,以创建一个 vault,如下所述。

#### 创建一个 vault

[永久链接:创建一个 vault](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#creating-a-vault)

为了 vault Coin,可以将它们花费到一个见证 v1 `scriptPubKey` 中,该 `scriptPubKey` 包含一个 taptree,其形式为

tr(<internal-pubkey>, leaves = { recover: <recovery-sPK-hash> OP_VAULT_RECOVER,

trigger:
  &lt;trigger-auth-pubkey> OP_CHECKSIGVERIFY                     (i)
  &lt;spend-delay> 2 $leaf-update-script-body OP_VAULT,          (ii)

... [ possibly other leaves ]

} )


其中

- `$leaf-update-script-body` 是,例如,`OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY`。
  - 这是触发脚本的一个示例,但可以使用 **任何** 脚本片段,从而可以创建不同类型的 vault。例如,你可以使用 `OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKSIG` 将Coin时间延迟转移到另一个密钥。这也为未来的脚本功能提供了 `OP_VAULT` 的未来保障。
- `(i)` 中的脚本片段称为“触发授权”,因为它控制着触发 withdrawal。这可以通过钱包设计者喜欢的任何方式完成。
- `(ii)` 中的脚本片段是不完整的 `OP_VAULT` 调用 - 一旦触发交易见证提供了其余参数(CTV 目标哈希、触发 vout 索引和 revault vout 索引),它将被完成。

通常,将指定 vault taproot 输出的内部密钥,以便它由与 recovery 路径相同的描述符控制,这有助于将 vault 输出 recovery 到 recovery 路径的另一种(尽管可能未使用)方式。这具有在不泄露它是一个 vault 的情况下 recovery Coin的潜在优势。

否则,可以选择内部密钥为一个不可花费的 NUMS 点,以强制执行 taptree 的内容。

#### 触发 withdrawal

[永久链接:触发 withdrawal](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#triggering-a-withdrawal)

为了利用 vault 并将其花费到某个输出,我们构建了上述 `tr()` 输出的花费,该花费只是将“trigger”leaf 替换为完整的 leaf-update 脚本(在本例中,是一个时间锁定的 CTV 脚本):

见证堆栈:

  • <revault-amount>
  • <revault-vout-idx> (-1 如果没有)
  • <trigger-vout-idx>
  • <target-CTV-hash>
  • <trigger-auth-pubkey-signature>
  • [ "trigger" leaf 脚本内容 ]
  • [ taproot 控制块,提示脚本路径花费到 "trigger" leaf ]

输出脚本:

[\ tr(<internal-pubkey>,\ leaves = {\ recover:\ <recovery-sPK-hash> OP_VAULT_RECOVER, <-- 未更改\ \ trigger:\ <target-CTV-hash> <spend-delay>\ OP_CHECKSEQUENCEVERIFY OP_DROP OP_CHECKTEMPLATEVERIFY <-- 根据 OP_VAULT\ 的 leaf-update\ 规则更改\ ... [ 可能有其他 leaves ]\ }\ ),\ \ [ 可选的 revault 输出,具有与\ 原始 vault 输出相同的 sPK ],\ ]



`OP_VAULT` 允许转换 taptree,以便 trigger leaf 成为时间锁定的 CTV 脚本,这实际上有助于宣布的 withdrawal。withdrawal 可通过 recovery 路径中断,因为“recover”leaf 与原始 taptree 中的 leaf 完全相同。

请注意,CTV 哈希是在花费时使用见证堆栈指定的,并通过 `OP_VAULT` 花费规则“锁定”,该规则断言其存在于输出中。

vault 资金可以在时间锁定的 CTV 脚本花费之前的任何时间通过使用“recover”leaf 的脚本路径花费来 recovery。

#### Recovery 授权

[永久链接:Recovery 授权](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#recovery-authorization)

在配置 vault 时,用户必须决定是否希望 recovery 过程由前缀为“recover”leaf 中的 `OP_VAULT_RECOVER` 指令的脚本片段控制。它的使用需要权衡。

##### 未经授权的 Recovery

[永久链接:未经授权的 Recovery](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#unauthorized-recovery)

未经授权的 recovery 简化了 vault 的使用,因为 recovery 不需要 vault 输出点的位置和 recovery 路径之外的其他信息 - “授权”只是 recovery 路径的显示,即 `&lt;recovery-sPK-hash>` 的原像。

但是,由于此显示是花费 vault Coin进行 recovery 所必需的唯一授权,因此用户必须期望一次性 recovery 所有此类 vault,因为观察者可以重放此 recovery(前提是他们知道输出点)。

此外,无法在同一交易中跨多个不同的 recovery 路径执行未经授权的 recovery,并且费用控制受到更多限制:由于未经授权的 recovery 的输出结构受到限制,因此费用管理依赖于完全用于支付费用的输入或可选的 ephemeral anchor 和包中继的使用。

这些限制是为了避免 pinning 攻击。

##### 授权的 Recovery

[永久链接:授权的 Recovery](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#authorized-recovery)

通过授权的 recovery,用户必须跟踪额外的信息:在需要 recovery 时如何解决 recovery 授权脚本片段。

如果此密钥丢失,用户将无法启动其Coin的 recovery 过程。如果攻击者获得了 recovery 密钥,他们可能会在 recovery 过程中通过构建低费用率的 recovery 交易并广播它来恶意攻击用户(尽管他们将无法因为 recovery 交易的可替换性要求而进行 pinning)。

但是,授权的 recovery 配置具有显着的好处。对于具有其他不兼容的 recovery 参数的 vault,可以进行批量 recovery。费用管理更加灵活,因为授权的 recovery 交易是“自由形式”的,可以添加不相关的输入和输出,可能用于处理费用。

##### 建议:使用简单的离线 Recovery 授权密钥种子

[永久链接:建议:使用简单的离线 Recovery 授权密钥种子](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#recommendation-use-a-simple-offline-recovery-authorization-key-seed)

授权 recovery 提供的批处理和费用管理的好处非常显着。如果 recovery 授权密钥落入攻击者手中,结果不是灾难性的,但如果用户丢失了他们的 recovery 授权密钥以及他们的 trigger 密钥,结果很可能导致Coin丢失。因此,作者的建议是为 recovery 授权密钥使用一个简单的种子,该种子可以离线写下并复制。

请注意,recovery 授权密钥 **不是** recovery 路径密钥,这与如何生成 recovery 路径密钥本身的任何建议 **大不相同**。

#### 地址重用和 Recovery

[永久链接:地址重用和 Recovery](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#address-reuse-and-recovery)

在创建 vault 时,有四个因素会影响生成的 P2TR 地址:

1. 内部公钥(可能属于 recovery 钱包)
2. recovery leaf
3. trigger leaf
4. taptree 中存在的任何其他 leaf

最终用户可以选择沿描述符更改某些内容,以避免重用 vault 地址而不影响密钥管理,例如 trigger 授权公钥。

请注意,当使用未经授权的 recovery 时,显示 recovery scriptPubKey 将允许任何观察者启动任何具有匹配 recovery 参数的 vault 的 recovery 过程,前提是他们能够找到 vault 输出点。因此,建议预期 **所有共享相同未经授权的 `&lt;recovery-sPK-hash>` 的输出都应一起 recovery**。

可以通过沿单个描述符更改每个 vault 的 recovery scriptPubKey 的生成来避免这种情况,但请注意,这将阻止将多个单独的 vault recovery 到单个 recovery 输出中。

更改内部公钥将阻止将多个 vault 输入的触发批量处理到单个触发输出中;因此,建议用户更改 trigger leaf 脚本的某些组件(如果不需要地址重用)。用户可以沿描述符更改 trigger 公钥,保持 recovery 路径和内部公钥相同,这既避免了重用地址,又允许批量触发和 recovery 操作。

##### 建议:为新的 Trigger 密钥生成新的 Recovery 地址

[永久链接:建议:为新的 Trigger 密钥生成新的 Recovery 地址](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#recommendation-generate-new-recovery-addresses-for-new-trigger-keys)

如果使用未经授权的 recovery,建议你不要在单独的 trigger 密钥之间共享 recovery scriptPubKey。如果一个 trigger 密钥受到破坏,那将需要(未经授权)recovery 所有具有该 trigger 密钥的 vault,这将显示 recovery 路径原像。这意味着观察者可能能够启动由未受破坏的 trigger 密钥控制的 vault 的 recovery。

##### 费用管理

[永久链接:费用管理](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#fee-management-1)

可以通过多种方式管理费用,但值得注意的是,trigger 和 recovery 交易都必须保留 vault 输入的总价值,因此无法将 vault 值重新用于支付费用。这不适用于 withdrawal 交易,该交易可以任意分配价值。

在使用 recovery 授权的 vault 的情况下,所有交易都可以通过不相关的输入和输出以“自带费用”的形式出现。一旦部署了相关的中继策略,这些交易也可以自由指定 ephemeral anchor。这意味着使用 recovery 授权的 vault 不依赖于 v3 中继策略的部署。

对于使用未经授权的 recovery 的 vault,recovery 交易依赖于完全花费的费用输入或 ephemeral anchor 输出的使用。这意味着不使用 recovery 授权的 vault 实际上依赖于 v3 交易中继策略的部署。

#### 批处理

[永久链接:批处理](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#batching)

##### 在 Trigger 期间

[永久链接:在 Trigger 期间](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#during-trigger)

具有相同 taptree 的 `OP_VAULT` 输出(除了略有不同的 trigger leaf 外)可以在同一 withdrawal 过程中批量处理在一起。如果两个“trigger”leaf 具有相同的 `OP_VAULT` 参数,则它们是兼容的。

请注意,这允许 trigger 授权(前缀为 `OP_VAULT` 调用的脚本)不同,同时仍然允许批处理。

Trigger 交易可以对多个不兼容的 `OP_VAULT` 输入集执行操作,前提是每个集都具有合适的关联 **triggerOut** 输出。

由于 `SIGHASH_DEFAULT` 可用于签署 trigger 授权,因此可以包含不相关的输入和输出,可能用于促进费用管理或批量 withdrawal 不兼容的 vault。

##### 在 Withdrawal 期间

[永久链接:在 Withdrawal 期间](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#during-withdrawal)

在最终 withdrawal 期间,只要它们共享相同的 `&lt;target-CTV-hash>` 参数,就可以将多个 trigger 输出用于同一 withdrawal 交易。这有助于批量 withdrawals。

##### 在 Recovery 期间

[永久链接:在 Recovery 期间](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#during-recovery)

具有相同 `&lt;recovery-sPK-hash>` 的 `OP_VAULT_RECOVER` 输出可以 recovery 到同一输出中。

具有授权 recovery 的 Recovery 不兼容 vault 可以在同一交易中 recovery,只要每个集(按 `&lt;recovery-sPK-hash>` 分组)具有关联的 **recoveryOut**。这允许不相关的 recoveries 共享常见的费用管理。

#### Watchtower

[永久链接:Watchtower](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#watchtowers)

vault 的价值取决于拥有监控,该监控将在发生意外花费时提醒所有者。这可以通过多种方式完成,对 watchtower 的自动化和信任程度各不相同。

在最大信任的情况下,watchtower 可以完全了解所有 vault Coin,并且如果有花费没有预先报告给 watchtower,则有权启动 recovery 过程。

在最小信任的情况下,用户可以提供他们希望监控的Coin的概率过滤器;然后,如果任何与过滤器匹配的Coin移动,watchtower 会提醒用户,用户将负责忽略误报并处理 recovery 启动。

#### 输出描述符

[永久链接:输出描述符](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#output-descriptors)

与 vault 相关的输出的输出描述符将在后续的 BIP 中介绍。

### 部署

[永久链接:部署](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#deployment)

激活机制待定。

此 BIP 应与 BIP-0119 同时部署,以实现 vault 的充分利用。

### 向后兼容性

[永久链接:向后兼容性](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#backwards-compatibility)

`OP_VAULT` 和 `OP_VAULT_RECOVER` 分别使用更严格的验证语义替换了仅见证 v1 的操作码 OP\_SUCCESS187 和 OP\_SUCCESS188。因此,使用这些操作码的脚本以前有效,但在此更改后将不再有效。

OP\_SUCCESSx 操作码的更严格的验证语义是一个软分叉,因此现有的软件在升级时可以完全正常工作,除了挖掘和区块验证。

向后兼容性考虑因素与 OP\_CHECKSEQUENCEVERIFY 和 OP\_CHECKLOCKTIMEVERIFY 的先前部署非常相似(请参阅 [BIP-0065](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) 和 [BIP-0112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki))。

### 理由

[永久链接:理由](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#rationale)

1. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-1-0)** **为什么这支持地址重用?** 该提案不依赖或鼓励地址重用,但如果无法处理地址重用,某些使用是不安全的 - 例如,如果托管人给其用户一个 vault 地址进行存款,它无法强制这些用户为每个地址进行单笔存款。
2. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-2-0)** **为什么此提案依赖于 `OP_CHECKTEMPLATEVERIFY` (BIP-119)?** 在 withdrawal 过程中,必须提交提议的 withdrawal 价值的最终目的地。`OP_CTV` 是将某些Coin的花费提交到一组特定输出的最简单、最安全的方法。此提案的早期版本试图使用一种更简单但类似的方法,将Coin的花费锁定到一组输出,但是此方法引入了 txid 延展性。

请注意,如果应部署其他将花费锁定到一组特定输出的方法,则可以在 `OP_VAULT` `&lt;leaf-update-script-body>` 中使用该方法,而无需进行任何更改。
3. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-3-0)** 与 leaf-update 数据项结合使用,它指示输出 taptree 中将替换当前执行的 tapleaf 脚本。
4. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-4-0)** **为什么只在前面加上数据推送?** 在 `leaf-update-script-body` 前面加上操作码会打开在前面加上 OP\_SUCCESSX 操作码的大门(仅举一个例子),从而绕过打算由已提交脚本运行的验证。
5. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-5-0)** **什么是延迟检查,为什么此提案需要它们才能正确评估脚本?** 延迟检查是一种验证检查,该检查仅在验证了所有输入脚本后才执行,并且基于在每个输入的 EvalScript 运行期间收集的聚合信息。

目前,每个输入的有效性(通常)在交易中的所有输入中同时检查。由于该提案允许将多个 vault 输入的花费批量处理到单个 recovery 或 withdrawal 输出中,因此我们需要一种机制来确保每个输出的所有预期值都可以求和然后进行检查。这需要引入一组“聚合”检查,这些检查只能在评估每个输入的脚本后执行。请注意,批量输入验证或跨输入签名聚合也需要类似的功能。
6. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-6-0)** **Recovery 交易如何支付费用?** 如果 recovery 未经授权,则费用通过 CPFP 与 ephemeral anchor 或作为仅用于支付费用的输入(即没有更改输出)附加。如果 recovery 经过授权,则可以以任何方式附加费用,例如不相关的输入和输出或通过 anchor 的 CPFP。
7. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-7-0)** **为什么需要将 recovery 交易设为可替换?** 在未经授权的 recoveries 的情况下,攻击者可能会尝试通过广播具有低费用率的“重新捆绑”版本来 pinning recovery 交易。vault 所有者必须能够通过替换来克服这一点。在授权 recovery 的情况下,如果攻击者窃取了 recovery 授权密钥,则攻击者可能会尝试在盗窃期间 pinning recovery 交易。需要可替换性确保所有者始终可以提高 recovery 交易的费用率,即使他们在过程中受到 RBF 规则 #3 的恶意攻击。
8. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-8-0)** 34 字节是仅由 `&lt;recovery-sPK-hash> OP_VAULT_RECOVER` 组成的 recovery 脚本的长度。
9. **[^](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#cite_ref-9-0)** **为什么未经授权的 recoveries 只能处理单个 recovery 路径?** 因为未经授权的 recoveries 不需要签名,所以如果允许额外的输出,观察 mempool 中的 recovery 的人将[永久链接:参考文献](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#references)

- [\[bitcoin-dev\] Bitcoin Vaults (2016)](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-February/012470.html)
- [\[bitcoin-dev\] Simple lock/unlock mechanism (2018)](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-February/015793.html)
- [\[bitcoin-dev\] On-chain vaults prototype (2020)](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-April/017755.html)
- [\[bitcoin-dev\] TAPLEAF\_UPDATE\_VERIFY covenant opcode (2021)](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019419.html)
- [Custody Protocols Using Bitcoin Vaults (2020)](https://arxiv.org/abs/2005.11776)
- [Vaults and Covenants (2023)](https://jameso.be/vaults.pdf)

### 致谢

[永久链接:致谢](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki#acknowledgements)

作者要感谢:

- AJ Towns 和 Greg Sanders 提供的讨论、改进提案的众多建议以及建议。
- Jeremy Rubin 提供的灵感、建议和指导。
- BL 提供的讨论和见解。
- John Moffett 提供的早期反馈和一个演示递归脚本评估攻击的测试用例。
- Johan Halseth 提供的概念性审查和指出的 pinning attack。
- Pieter Wuille 提供的实施建议。

>- 原文链接: [github.com/jamesob/bips/...](https://github.com/jamesob/bips/blob/e2ff23b3f07215450e75779f7f944d24660a9d47/bip-0345.mediawiki)
>- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
jamesob
jamesob
江湖只有他的大名,没有他的介绍。