Vaulted Bitcoin Custody

Sam Abbassi
FCAT Blockchain Incubator
14 min readSep 28, 2020

We describe Bitcoin transactions, restricted transactions called Covenants, and our own research into secure Bitcoin custody using a type of Covenant called Vaults.

Introduction

Custody sits core to digital asset infrastructure and is dictated by key management. Keys are what generate signatures that can spend bitcoins, and thus, key management determines how digital assets are held and secured. The problem the FCAT team tried to solve was the access, incentives and corresponding attack surfaces that are presented when keys, or a set of keys, are compromised. In that, attackers can arbitrarily spend bitcoins custodied by those compromised keys at will.

The team presents a Vault custody protocol that uses pre-signed transactions, a relative time-lock, and a key-deletion method to activate Covenants.

What is a Bitcoin Transaction

A Bitcoin transaction is a contract that transfers bitcoins between wallets. The wallets are interfaces for keys, and the corresponding addresses those keys have dominion over.

Each transaction is a made up of a set of inputs and a set of outputs. The inputs are funds that the spender of the transaction has the authority to spend. They have this authority through custody of their keys. The keys generate signatures that are required in order to spend the transaction. The inputs need to be consumed in the transaction to spend them, and as a result, a set of new unspent outputs (called UTXO’s — Unspent Transaction Outputs) are created, each with their own requirements that need to be met to spend. When the authorized party wants to spend these new outputs (they are unspent by definition) they go through the same process and consume those unspent outputs as inputs in their new transaction, and spend them. Once again, a new set of outputs are created.

Rather than understand bitcoins as cash, bitcoins (more specifically, unspent Bitcoin outputs) should rather be understood as check deposits. I cannot simply walk down the street, find some unspent Bitcoin output crumbled on the floor, pick it up and spend it. My key needs to generate the signature required to spend said output. In that sense, the underwriter of your funds is the cryptography that the Bitcoin protocol adheres to. The economy of miners and node-runners that maintain the network also rely on the integrity of the same cryptography.

In the traditional banking system, you write someone a check, it has your signature and the bank knows that you’ve authorized it because it has your signature. The graphology, in the case of Bitcoin, is cryptography. The difference with the traditional banking system is that accounts don’t exist in Bitcoin and fund management happens at the transactional level (or the UTXO-level).

To spend the unspent outputs (UTXO), you gather a bunch of UTXO’s that are in your wallet (the aggregate value of those UTXO’s is your bitcoin balance), and you tell the network that you are spending them by:

1. signing them (flexing your authority to spend), and

2. broadcasting them to the network

Doing only one of these does nothing. Signing without broadcasting means that you’ve signed a check but never gave it to the recipient to cash the check. Broadcasting without signing means that you gave a check to someone without a signature and they weren’t able to cash the check.

The Anatomy of a Bitcoin transaction

A Bitcoin transaction is a reference to unspent outputs that the user has the right to spend and a constructed a set of limitations on where or when the newly created funds can go in the form of UTXO’s.

Figure 1. Diagram depicts a Bitcoin transaction with a set of inputs and a set of outputs (UTXO’s)
Figure 2. Diagram depicts a Bitcoin Transaction 0 (counting starts from 0 in computer science), who’s UTXO 1 (from its set of UTXO’s) is being referenced and consumed as an input (INPUT 3) in the new Bitcoin Transaction 1.

In Figure 2, Bitcoin Transaction 1 consumes (spends) UTXO 1 sitting at index 1 (UTXO 0 is at index 0, and UTXO 1 is at index 1) in Bitcoin Transaction 0 and creates two new UTXO’s with their own spending conditions (UTXO 2 and UTXO 3). This is the very process of what a movement of coins looks like in Bitcoin. Note that the arrow is moving in this direction because Bitcoin Transaction 0 exists irrespective of Bitcoin Transaction 1, so when Bitcoin Transaction 1 is created, it needs to reference a transaction already in existence and proclaim that it wants to spend those funds. We use the word life-cycle because when a UTXO is spent, it is no longer an unspent output. It is destroyed, invalidated, and a new UTXO is spawned. Thus, you are literally destroying money whenever you spend bitcoins.

There are four elements that comprise the INPUT of a Bitcoin transaction:

1. the transaction ID: id of the transaction you are referencing

2. the output index: the index of the UTXO that is being consumed

  • a single transaction can and often has several outputs (UTXO’s). It is important to identity the correct UTXO that is being consumed.

3. an unlocking script: this satisfies the conditions placed on the UTXO being consumed

4. a sequence number: a time-lock restriction for spending the specific UTXO being consumed.

  • this allows the user to restrict when the inputs can be spent either in block number or Unix timestamp
Figure 3. This snippet represents the inputs that are being referenced in a transaction. Notice the “txid’, “vout”, “scriptSig”, “sequence” parameters that are all within a “vin” parameter (vector of inputs).
  • “txid” = transaction ID
  • “vout” = output index
  • “scritpSig” = unlocking script
  • “sequence” = sequence number

There are two elements that comprise the OUTPUT or UTXO of a Bitcoin transaction:

1. The amount of bitcoin: bitcoin value in satoshis (satoshi = the smallest denomination of bitcoins — equivalent to 100 millionth of a bitcoin)

2. The locking script: cryptographic lock that must be satisfied to spend the bitcoins

  • These are the stack-based operators and corresponding values that those opcodes evaluate. These are the order of operations required to spend this transaction output.
  • Typically, the key for this lock is just the private key of the associated public key to which the output is tied.
Figure 4. This snippet represents a transaction output with two outputs. Notice the “value” and “scriptPubKey” parameters that are all within a “vout” parameter (vector of outputs). “value” = amount of bitcoin “scriptPubKey” = locking script

In summation, you can combine the two code snippets together and wrap the whole thing with a few more parameters to get your Bitcoin transaction.

There are two elements that are added to encapsulate the whole transaction:

1. Transaction version number

  • Used for specifying which set of protocol rules this transaction abides by
  • There are currently only two options for transaction version, though future updates to Bitcoin’s consensus rules may add additional options (3 , 4, etc.)
  • “1” is a transaction that does not use a relative lock-time
  • “2” designates a relative time-locked transaction that follows certain time-lock procedures

2. Transaction locktime

  • This time-lock restriction field is very similar to the sequence field we observed in the input part of the Bitcoin transaction above. This time-lock, however, applies to the entire transaction, whereas sequence is specific to the UTXO that is being consumed as a transaction input
Figure 5. This snippet represents the full transaction with its one input and two outputs. Notice that the “version” is defined as 1, and therefore, does not have any relative time-lock restrictions.

Now that we’ve dissected a Bitcoin transaction and explored its individual components and overall construction, let’s delve into complex Bitcoin transactions.

Bitcoin Covenants: Restrictions on bitcoins, the contractual nature of Bitcoin transactions

At this point, we’ve seen that a Bitcoin transaction can have an encumbrance placed on it that restricts when a UTXO can be spent. This restriction can be defined in two of the fields that we’ve identified: locktime (which applies to the entire transaction) and sequence (which applies to an individual UTXO that is being consumed as a transaction input). We also saw that a Bitcoin transaction restricts how the bitcoins can be spent through the scriptPubKey (locking script) that sets out the conditions required to spend the bitcoins.

Covenants, in traditional finance, are mechanisms that enforce conditions on how an object (typically land or property) can be spent at some point in the future. It is a type of debt agreement that enforces a promise on whether certain activities can or cannot happen. For example, a bank can have a loan contract with a company with the requirement that if the company’s cashflow to equity ratio drops to a certain level, then the debt has to be paid back.

Bitcoin Covenants are transactions that are able to enforce restrictions on the composition of subsequent transactions.

Normally, once you satisfy the requirements to spend specific bitcoins, you are free to spend them as you wish; the conditions have been satisfied. With Covenants, however, even if the conditions to spend those bitcoins have been satisfied, those funds can still be only spent in x and/or y way.

Alice has some funds (UTXO’s) in her wallet and Alice wants to send these funds to Bob. She would normally satisfy the conditions to spend them, which simply require her signature. However, in this case, the UTXO she is trying to spend is a Covenant that can only be spent to Charlie. So even though Alice satisfies the conditions to spend the coins, she can still only spend them a certain way. In this case, she can only spend them to Charlie.

Some uses of Covenants include congestion control transactions. When fees are high, bitcoins can be aggregated by a large payment processor and confirmed on-chain. Those bitcoins can only be spent to specific addresses and after a certain amount of time. So that, at some point in the future, when fees are more suitable, those bitcoins can safely be spent.

Other uses include Lightning Channel factories and enhanced HTLC routing.

Covenants have not been possible on Bitcoin and cannot be done using the Scripting language, today. There have been proposals to introduce changes to Bitcoin Script (the scripting / contract language for Bitcoin), that would make Covenants a literal part of Bitcoin’s consensus rules leveraging the security of the Bitcoin base layer. These proposals are OP_COV , OP_CHECKSIGFROMSTACK and OP_CTV (here is a great summary of OP_CTV, formerly known as OP_SECURETHEBAG).

The problem with Covenants today is that there is no way to automatically lock and ensure delivery of a specific UTXO to another transaction without running the counterparty or security risk of the UTXO being consumed in another (different) transaction. In the context of custody, we want bitcoins to be locked in a predictable way. We want to apply predestination to the UTXO and determine its future path. As a result, the community came up with a way to enforce Covenants that can be implemented today through a key-deletion method.

The key deletion process in the context of Bitcoin Covenants means that you pre-sign a transaction and delete the key (remember that the key is what is needed to generate a signature to spend a UTXO - it is how you create a signature on a check that verifies you authorized this transaction). The transaction is now locked to whatever spending conditions you’ve specified and cannot be spent any other way. Even if an attacker tries to modify something in the transaction, the signature would no longer be valid.

There are two transactions that are needed to build Covenants using this method:

  • the Covenant Transaction, and
  • the Deposit Transaction

The Covenant Transaction specifies a template with conditions on the future use of funds. The key for this Transaction is deleted and it is this transaction in which the funds are locked. The Deposit Transaction actually delivers the funds to the Covenant Transaction. It does this by spending some set of UTXO’s and creating new UTXO’s that are consumed as inputs in the Covenant Transaction. They are referenced in the Covenant Transaction and spent only when the Covenant Transaction is broadcast. As it is already signed, the only thing required to spend the funds locked in the Covenant is to broadcast and propagate them to the Bitcoin network. The funds in the Covenant can be thought of as ‘active’ once the Deposit Transaction is broadcast and confirmed on the blockchain.

There are four stages to create a Bitcoin Covenant using this key-deletion method:

  • Preparation: this is where the transaction template is specified
  • Signed: this is where the transaction template is committed to (signed)
  • Key-deletion: this is where the keys for the Covenant Transaction are deleted
  • Activated: this is where the Deposit Transaction associated with this Covenant Transaction is broadcast and confirmed on the blockchain
Figure 6. This is a Covenant Transaction that is referencing three different UTXO’s in three different transactions as inputs. The signing key is deleted before the Deposit Transactions have been broadcast. Once the Deposit Transactions have all been broadcast to the network and confirmed, the Covenant Transaction has become “activated” and the funds, spendable.

This is the simplest Covenant custody process that can be implemented which securely commits to the conditions of the Covenant and cannot be changed thereafter. There are a number of caveats that go into the covenant process, namely how to securely delete keys and how to securely store the Covenant Transactions.

Vaults: Covenants with attitude

Bitcoin Vaults are a specific type of Covenant that use pre-signed transactions with key-deletion to enforce a time-lock on funds. The Vaults enable gated access to funds through an accessible (Active) wallet and also an option to immediately spend those funds to an emergency cold storage wallet. The time-lock buys the custodian time to react to a theft attempt or unauthorized broadcast of funds.

In Custody Protocol Using Vaults, this method of key deletion for Bitcoin Covenants coupled with time-locks is investigated. There are two critical components for this custody protocol to work as intended. The first component is the deletion of the keys. There is no way to prove that signing keys have been deleted and, thus, the possibility that keys were improperly deleted will always exist (see Bitcoin Covenants: Three Ways to Control the Future, Section 4: Recovered-key Covenants).The second component is the secure storage of the Covenant Transaction. This is important in that, the only way to trigger the custody protocol once the Covenants have been activated is to broadcast the transaction.

There are two Covenant transactions in this Vault custody protocol:

1. Vault Tx

2. P2RW Tx (Pay to Recovery Wallet)

There are also three types of multi-signature wallets:

1. Active Wallet

2. Vault Wallet

3. Recovery Wallet

Figure 7. This is the access control of funds between the three different wallets that exist as a part of this protocol. The Deposit Transaction is sent from the Active Wallet to the Vault Wallet. Once the Deposit Transaction is broadcast, the Vault Transaction (the vaulted funds) are “active.” Refer back to Figure 6 to examine the structure and contingent transactional relationships of Covenant Transactions. Once the Vault Transactions are broadcast, they can spent in two paths, one is to the Active Wallet following a time-lock and the other spending path is to a ‘cold’ Recovery Wallet through Pay to Recovery Wallet (P2RW) Tx’s.

The Vault Transaction spends the funds to a pre-defined address (Active Wallet) subsequent to a time-lock, or allows the funds to be redirected to a recovery address (Recovery Wallet) via the P2RW Transaction. The P2RW Transaction is a simple Covenant that spends the alternate spending path in the Vault Transaction to a deep recovery address (Recovery Wallet).

Each wallet also has its own set of Hardware Modules (HM’s) where the required multi-signature keys are individually stored. So when we say “Recovery Wallet,” what is meant is that the funds can be spent to a Recovery Wallet multi-signature address who’s spending keys are persistently stored in separate locations (offline, not connected to the internet, in this case).

Figure 8 This is the UTXO-level topology and workflow of how the transactions relate to each other. Both the Vault and P2RW transaction are constructed, pre-signed and keys deleted prior to broadcasting (spending) the Deposit Tx. The Vault Transaction depends on the Deposit Transaction (it is a child of the Deposit Transaction) and the P2RW Transaction depends on the Vault Transaction. Once the Deposit Transaction is spent, the Vault Transaction becomes valid (active) and can be broadcast (spent) as it has already been signed. If a theft attempt is suspected, the P2RW Transaction is broadcast which spends the alternate spending path of the Vault Transaction. It is critical that the P2RW Transaction is spent prior to the maturation of the time-lock in the Vault Transaction. The transaction’s inside of the dotted green box are the external spend transactions that are possible once either the Vault or the P2RW transactions have been broadcast and confirmed on the blockchain.

This Vault protocol affords customers the benefits of a limited attack surface and a limited loss of funds. Theft of a pre-signed “Vault Tx”, as seen in Figures 7 and 8, does not allow the broadcaster of the transaction to send funds to arbitrary addresses, rather, that pre-signed Vault Transaction can only be spent in one of two spending paths. At best, an attacker will cause the customer the inconvenience of triggering their custody protocol, without actually being able to steal any of the funds. At worst, the attacker will be able to steal limited funds with how ever many of the Vault Transactions they are able to broadcast and/or however many of the Active Wallets they are able to compromise. The Active Wallet, as it relates to the recovery wallet is a wallet that has network access and one that is interacted with frequently relative to the Recovery Wallet. The Recovery Wallet will only be accessed if the emergency spend of the protocol is executed. And the emergency spend of the protocol will only ever be executed if there is suspicion of an ‘unauthorized’ broadcast of the Vaulted funds or if there is suspicion that access to the Active Wallet has been compromised. It is important to note that this protocol likely functions best as a self-custody solution, as having counterparties increases risk in virtually all areas.

Figure 9. The Vault Transaction output script with j of k pubkeys (addresses are hashes of public keys) and p of t pubkeys in the respective spending paths. Note that the OP_ELSE branch requires the broadcasting of a P2RW Transaction (this transaction is pre-signed and securely stored as well).

These severe limitations (cumbersome custody preparation and transaction management) that define the Vault custody protocol are also, by design, the same limitations that disincentivize against theft attempts as the probability of success is so dramatically low, and the rewards are significantly limited with respect to traditional theft of exchange funds that use ‘hot’ wallets or weak multi-signature protocols. There is an inherent trade-off between convenience and security as it relates to custody of bitcoins. The more secure a protocol is, the less convenient it is for a customer to access funds.

To be clear, Covenants are not only meant for custody protocols. However, their applications with respect to Bitcoin Vaults is exclusively in the realm of secure custody of coins. Vaults are an important construct when compared to existing secure custody protocols. With existing custody solutions, namely multi-signature custody protocols (where you, your custody vendor and an attorney, perhaps, have valid signing keys and, thus, control of funds), there is a reliance on probability in that it is highly improbable that an attacker can gain control of more than one signing key. So, in the case of a 2 out of 3 multi-signature scheme, the funds are reasonably safe. The glaring issue with this type of protocol is that keys enable signatures over arbitrary transactions, meaning that an attacker can create new transactions because they have the authorization to do so, via their stolen access to the signing keys of a given set of UTXO’s. (Vault protocols are not superior to multi-signature schemes, there are different trade-offs to consider, see Custody Protocol Using Bitcoin Vaults, Section 4: Threat Model).

Future development roadmap items that can be built on top of and/or in supplement to this Vault custody protocol include custody development kits (CDK) that provide libraries for customized Vault implementations, watchtower services that watch the blockchain for transactions and store Vault Transactions for broadcasting when appropriate, and trading and inheritance protocols for multi-customer access of Vaulted bitcoins. There are several other sub-services that can be built as this market matures and each of the examples mentioned above have their own fundamentals that need to be worked on.

Conclusion

As the consensus layer of Bitcoin is critical to understand from a systems level that can be broken into its constituent parts (i.e. network communication, transaction propagation, mining), Bitcoin should too be understood at its most granular level, the transaction and UTXO level. That is, the construction and maintenance of Bitcoin transactions.

Bitcoin transactions can be architected in complex custody protocols that rely on the behavior of previous transactions and can also enforce conditions on how funds can be spent in subsequent transactions. The implementation (finding community consensus) of these proposals into Bitcoin’s consensus rules is a long and arduous process. Vaults with secure key-deletion is a functional way to enforce Covenants today and expanding this effort in an open-source capacity will benefit the entire community and hopefully lead to more improved and customizable self-custody solutions.

Other Implementations:

https://github.com/JSwambo/bitcoin-vault

https://github.com/re-vault/revault-demo

https://github.com/kanzure/python-vaults

See also:

https://medium.com/@BobMcElrath/re-imagining-cold-storage-with-timelocks-1f293bfe421f

https://github.com/re-vault/revault-demo

https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-May/017835.html

Acknowledgments

The authors of Covenant Protocol Using Bitcoin Vaults and Bitcoin Covenants, Three Ways to Control the Future: Jacob Swambo, Spencer Hommel, Bob McElrath and Bryan Bishop were instrumental in exploring these topics. The resources provided by Andreas Antonopolous and Jimmy Song were also invaluable.

946392.1.0

--

--