← Back to Bitcoin Improvement Proposals
BIP 345specificationClosedopcodescovenantskey-managementscript

OP_VAULT

BIP: 345 Layer: Consensus (soft fork) Title: OP_VAULT

No reviews
James O'Beirne·Updated Mar 29, 2026·0 reviews·0 attestations·View source
Collections:BIPs — Merged

Specification

  BIP: 345
  Layer: Consensus (soft fork)
  Title: OP_VAULT
  Authors: James O'Beirne 
           Greg Sanders 
  Status: Closed
  Type: Specification
  Assigned: 2023-02-03
  License: BSD-3-Clause
  Discussion: 2023-01-09: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-January/021318.html [bitcoin-dev] OP_VAULT announcement
              2023-03-01: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-March/021510.html [bitcoin-dev] BIP for OP_VAULT
  Proposed-Replacement: 443

Introduction

This BIP proposes two new tapscript opcodes that add consensus support for a specialized covenant: OP_VAULT and OP_VAULT_RECOVER. These opcodes, in conjunction with OP_CHECKTEMPLATEVERIFY (BIP-0119), allow users to enforce a delay period before designated coins may be spent to an arbitrary destination, with the exception of a prespecified "recovery" path. At any time prior to final withdrawal, the coins can be spent to the recovery path.

Copyright

This document is licensed under the 3-clause BSD license.

Motivation

The hazard of custodying Bitcoin is well-known. Users of Bitcoin must go to significant effort to secure their private keys, and hope that once provisioned their custody system does not yield to any number of evolving and persistent threats. Users have little means to intervene once a compromise is detected. This proposal introduces a mechanism that significantly mitigates the worst-case outcome of key compromise: coin loss.

Introducing a way to intervene during unexpected spends allows users to incorporate highly secure key storage methods or unusual fallback strategies that are only exercised in the worst case, and which may otherwise be operationally prohibitive. The goal of this proposal is to make this strategy usable for custodians of any size with minimal complication.

Example uses

A common configuration for an individual custodying Bitcoin is "single signature and passphrase" using a hardware wallet. A user with such a configuration might be concerned about the risk associated with relying on a single manufacturer for key management, as well as physical access to the hardware.

This individual can use OP_VAULT to make use of a highly secure key as the unlikely recovery path, while using their existing signing procedure as the withdrawal trigger key with a configured spend delay of e.g. 1 day.

The recovery path key can be of a highly secure nature that might otherwise make it impractical for daily use. For example, the key could be generated in some analog fashion, or on an old computer that is then destroyed, with the private key replicated only in paper form. Or the key could be a 2-of-3 multisig using devices from different manufacturers. Perhaps the key is geographically or socially distributed.

Since it can be any Bitcoin script policy, the recovery key can include a number of spending conditions, e.g. a time-delayed fallback to an "easier" recovery method, in case the highly secure key winds up being too highly secure.

The user can run software on their mobile device that monitors the blockchain for spends of the vault outpoints. If the vaulted coins move in an unexpected way, the user can immediately sweep them to the recovery path, but spending the coins on a daily basis works in the same way it did prior to vaulting (aside from the spend delay).

Institutional custodians of Bitcoin may use vaults in similar fashion.

= Provable timelocks

=

This proposal provides a mitigation to the "$5 wrench attack." By setting the spend delay to, say, a week, and using as the recovery path a script that enforces a longer relative timelock, the owner of the vault can prove that he is unable to access its value immediately. To the author's knowledge, this is the only way to configure this defense without rolling timelocked coins for perpetuity or relying on a trusted third party.

Goals

frame|center

Vaults in Bitcoin have been discussed formally since 2016 (MES16) and informally since 2014. The value of having a configurable delay period with recovery capability in light of an unexpected spend has been widely recognized.

The only way to implement vaults given the existing consensus rules, aside from emulating vaults with large multisig configurations, is to use presigned transactions created with a one-time-use key. This approach was first demonstrated in 2020.

Unfortunately, this approach has a number of practical shortcomings:

  • generating and securely deleting ephemeral keys, which are used to emulate the vault covenant, is required,
  • amounts and withdrawal patterns must be precommitted to,
  • there is a necessity to precommit to an address that the funds must pass through on their way to the final withdrawal target, which is likely only known at unvault time,
  • the particular fee management technique or wallet must be decided upon vault creation,
  • coin loss follows if a vault address is reused,
  • the transaction data that represents the "bearer asset" of the vault must be stored for perpetuity, otherwise value is lost, and
  • the vault creation ceremony must be performed each time a new balance is to be deposited.
The deployment of a "precomputed" covenant mechanism like OP_CHECKTEMPLATEVERIFY or SIGHASH_ANYPREVOUT would both remove the necessity to use an ephemeral key, since the covenant is enforced on-chain, and lessen the burden of sensitive data storage, since the necessary transactions can be generated from a set of compact parameters. This approach was demonstrated in 2022.

However, the limitations of precomputation still apply: amounts, destinations, and fee management are all fixed. Funds must flow through a fixed intermediary to their final destination. Batch operations, which may be vital for successful recovery during fee spikes or short spend delay, are not possible.

frame|center

Having a "general" covenant mechanism that can encode arbitrary transactional state machines would allow us to solve these issues, but at the cost of complex and large scripts that would probably be duplicated many times over in the blockchain. The particular design and deployment timeline of such a general framework is also uncertain. This approach was demonstrated in 2016.

This proposal intends to address the problems outlined above by providing a delay period/recovery path use with minimal transactional and operational overhead using a specialized covenant.

The design goals of the proposal are:

  • efficient reuse of an existing vault configuration. A single vault configuration, whether the same literal scriptPubKey or not, should be able to “receive” multiple deposits.
  • batched operations for recovery and withdrawal to allow managing multiple vault coins efficiently.
  • unbounded partial withdrawals, which allows users to withdraw partial vault balances without having to perform the setup ceremony for a new vault.
  • dynamic unvault targets, which allow the proposed withdrawal target for a vault to be specified at withdrawal time rather than when the vault is first created. This would remove the need for a prespecified, intermediate wallet that only exists to route unvaulted funds to their desired destination.
  • dynamic fee management that, like dynamic targets, defers the specification of fee rates and source to unvault time rather than vault creation time.
These goals are accompanied by basic safety considerations (e.g. not being vulnerable to mempool pinning) and a desire for concision, both in terms of the number of outputs created as well as script sizes.

This proposal is designed to be compatible with any future sighash modes (e.g. SIGHASH_GROUP) or fee management strategies (e.g. transaction sponsors) that may be introduced. Use of these opcodes will benefit from, but do not strictly rely on, v3 transaction relay and ephemeral anchors.

Design

In typical usage, a vault is created by encumbering coins under a taptree (BIP-341) containing at least two leaves: one with an OP_VAULT-containing script that facilitates the expected withdrawal process, and another leaf with OP_VAULT_RECOVER which ensures the coins can be recovered at any time prior to withdrawal finalization.

The rules of OP_VAULT ensure the timelocked, interruptible withdrawal by allowing a spending transaction to replace the OP_VAULT tapleaf with a prespecified script template, allowing for some parameters to be set at spend (trigger) time. All other leaves in the taptree must be unchanged in the destination output, which preserves the recovery path as well as any other spending conditions originally included in the vault. This is similar to the TAPLEAF_UPDATE_VERIFY design that was proposed in 2021.

These tapleaf replacement rules, described more precisely below, ensure a timelocked withdrawal, where the timelock is fixed by the original OP_VAULT parameters, to a fixed set of outputs (via OP_CHECKTEMPLATEVERIFY) which is chosen when the withdrawal process is triggered.

While OP_CHECKTEMPLATEVERIFY is used in this proposal as the preferred method to bind the proposed withdrawal to a particular set of final outputs, OP_VAULT is composable with other (and future) opcodes to facilitate other kinds of withdrawal processes.

frame|center

Transaction types

The vault has a number of stages, some of them optional:

  • vault transaction: encumbers some coins into a Taproot structure that includes at least one OP_VAULT leaf and one OP_VAULT_RECOVER leaf.
  • trigger transaction: spends one or more OP_VAULT-tapleaf inputs into an output which is encumbered by a timelocked withdrawal to a fixed set of outputs, chosen at trigger time. This publicly broadcasts the intent to withdraw to some specific set of outputs.

    The trigger transaction may have an additional output which allocates some of the vault balance into a partial "revault," which simply encumbers the revaulted portion of the value into the same scriptPubKey as the OP_VAULT-containing input(s) being spent.
  • withdrawal transaction: spends the timelocked, destination-locked trigger inputs into a compatible set of final withdrawal outputs (per, e.g., a CHECKTEMPLATEVERIFY hash), after the trigger inputs have matured per the spend delay. Timelocked CTV transactions are the motivating usage of OP_VAULT, but any script template can be specified during the creation of the vault.
  • recovery transaction: spends one or more vault inputs via OP_VAULT_RECOVER tapleaf to the prespecified recovery path, which can be done at any point before the withdrawal transaction confirms. Each input can optionally require a witness satisfying a specified recovery authorization script, an optional script prefixing the OP_VAULT_RECOVER fragment. The use of recovery authorization has certain trade-offs discussed later.

Fee management

A primary consideration of this proposal is how fee management is handled. Providing dynamic fee management is critical to the operation of a vault, since

  • precalculated fees are prone to making transactions unconfirmable in high fee environments, and
  • a fee wallet that is prespecified might be compromised or lost before use.
But dynamic fee management can introduce pinning vectors. Care has been taken to avoid unnecessarily introducing these vectors when using the new destination-based spending policies that this proposal introduces.

Originally, this proposal had a hard dependency on reformed transaction nVersion=3 policies, including ephemeral anchors, but it has since been revised to simply benefit from these changes in policy as well as other potential fee management mechanisms.

Specification

The tapscript opcodes OP_SUCCESS187 (0xbb) and OP_SUCCESS188 (0xbc) are constrained with new rules to implement OP_VAULT and OP_VAULT_RECOVER, respectively.

OP_VAULT evaluation

When evaluating OP_VAULT (OP_SUCCESS187, 0xbb), the expected format of the stack, shown top to bottom, is:



[  leaf-update script data items ... ]



where

[Content truncatedview full spec at source]

Discussion (0 threads)

Loading discussions...