Detailed Explanation of Covenants: How to Achieve Bitcoin's Programmability?
Authors: Jeffrey HU, Harper LI, HashKey Capital
Recently, there has been a wave of discussions in the Bitcoin community regarding the re-enabling of operation codes such as OPCAT. Taproot Wizard has also attracted considerable attention by launching Quantum Cats NFTs and claiming to have obtained the BIP-420 number. Supporters claim that enabling OPCAT can achieve "covenants," enabling smart contracts or programmability for Bitcoin.
If you notice the term "covenants" and do a little search, you'll find that this is another significant rabbit hole. Developers have been discussing various technologies for years to implement covenants, including OPCTV, APO, OPVAULT, and more.
So, what exactly are Bitcoin's "covenants"? Why have they attracted the continuous attention and discussion of so many developers for years? What programmability can they achieve for Bitcoin? What are the underlying design principles? This article aims to provide an overview and discussion.
What are "Covenants"
Covenants, sometimes translated as "covenants" or "contracts," are mechanisms that can set conditions for future Bitcoin transactions.
Current Bitcoin scripts also include conditions for restrictions, such as requiring valid signatures when spending or conforming to specific scripts. However, as long as a user can unlock it, they can spend that UTXO anywhere they wish.
Covenants, on the other hand, impose further restrictions on how to unlock, such as limiting the spending of UTXOs afterward, achieving effects similar to "earmarked funds"; or other input conditions in a transaction.
More rigorously, current Bitcoin scripts also have certain covenant-like features, such as time locks based on opcodes, which implement time restrictions before spending a transaction through introspection of the transaction's nLock or nSequence fields, but these are primarily limited to time-based restrictions.
So why do developers and researchers want to design these restriction checks? Because covenants are not just about restriction for its own sake; they also set rules for transaction execution. This way, users can only execute transactions according to pre-set rules, thus completing predetermined business processes.
Therefore, somewhat counterintuitively, this can unlock more application scenarios.
Application Scenarios
Ensuring Staking Penalties
One of the most straightforward examples of covenants is the slash transaction in Babylon's Bitcoin staking process.
Babylon's Bitcoin staking process involves users sending their BTC assets to a special script on the main chain, with two spending conditions:
- Happy ending: After a certain period, users can unlock it with their signature, completing the unstake process.
- Bad ending: If a user engages in malicious behavior, such as double-signing on a PoS chain rented by Babylon, the assets can be unlocked through EOTS (extractable one-time signatures), and a portion of the assets will be forcibly sent to a burn address (slash) by executing roles in the network.
Source: Bitcoin Staking: Unlocking 21M Bitcoins to Secure the Proof-of-Stake Economy
Note the term "forcibly sent" here; this means that even if this UTXO can be unlocked, the asset cannot be sent anywhere else arbitrarily, but only burned. This ensures that malicious users cannot preemptively use their known signatures to transfer the assets back to themselves to escape punishment.
If implemented after OPCTV and other covenant features, this functionality could add OPCTV and other opcodes to the "bad ending" branch of the staking script to enforce restrictions.
Before OP_CTV was enabled, Babylon had to use workarounds to simulate the enforcement of covenants through a method executed jointly by users and a committee.
Congestion Control
Generally, congestion refers to a situation where transaction fees are very high on the Bitcoin network, and many transactions are piled up in the transaction pool waiting to be packed. Therefore, if users want to confirm transactions quickly, they need to increase the fees.
At this time, if a user must send multiple transactions to multiple recipients, they have to raise the fees, incurring higher costs. This, in turn, further drives up the overall network fee rate.
With covenants, one solution is that the sender can first commit to a batch transaction. This commitment allows all recipients to believe that the final transactions will occur, and they can wait until the fee rate is lower to send the specific transactions.
As shown in the figure below, when demand for block space is high, making transactions becomes very expensive. By using OP_CHECKTEMPLATEVERIFY, large payment processors can aggregate all their payments into a single O(1) transaction for confirmation. Then, after a while, when demand for block space decreases, payments can be expanded from that UTXO.
Source: https://utxos.org/uses/scaling/
This scenario is a typical application case proposed by OP_CTV for congestion control. More application cases can be found at https://utxos.org/uses/. In addition to the aforementioned congestion control, this webpage lists Soft Fork Bets, Decentralized options, Drivechains, Batch Channels, Non-Interactive Channels, Trustless Coordination-Free Mining Pools, Vaults, Safer Hashed Time Locked Contracts (HTLCS) Limits, etc.
Vaults
Vaults are a widely discussed application scenario in Bitcoin, especially in the field of covenants. Since daily operations inevitably need to balance between fund custody and fund usage needs, people hope to have a type of vault application: one that can ensure fund security, and even if the account is hacked (private key leaked), it can restrict the use of funds.
Based on the technology that implements covenants, vault applications can be relatively easily constructed.
Taking the OP_VAULT design as an example: when spending funds from the vault, a transaction must first be sent on-chain. This transaction indicates the intention to spend from the vault, i.e., "trigger," and sets conditions:
- If everything is normal, then the second transaction is the final withdrawal transaction. After waiting for N blocks, the funds can be further spent anywhere.
- If it is discovered that this transaction was stolen (or coerced during a "wrench attack"), it can be immediately sent to another secure address (a safer custody for the user) before the withdrawal transaction is sent after N blocks.
OP_VAULT process, source: BIP-345
It is important to note that a vault application can also be constructed without covenants. One feasible method is to prepare signatures for future spending with a private key and then destroy that private key. However, there are still many restrictions, such as needing to ensure that the private key has been destroyed (similar to the trusted setup process in zero-knowledge proofs), and the amounts and fees must be predetermined (since pre-signing is required), which lacks flexibility.
Comparison of OP_VAULT and pre-signed vault processes, source: BIP-345
More Robust and Flexible State Channels
Generally, state channels, including the Lightning Network, can be considered to have nearly equivalent security to the main chain (as long as nodes can observe the latest state and can normally publish the latest state on-chain). However, with the introduction of covenants, some new design ideas for state channels can be made more robust or flexible on top of the Lightning Network. Notable examples include Eltoo and Ark.
Eltoo (also known as LN-Symmetry) is a typical example. This technical solution proposes an execution layer for the Lightning Network that allows any subsequent channel state to replace previous states without a penalty mechanism, thus avoiding the need for Lightning Network nodes to retain multiple previous states to prevent adversarial actions. To achieve this effect, Eltoo proposes the SIGHASH_NOINPUT signature method, i.e., APO (BIP-118).
Ark aims to reduce the difficulty of inbound liquidity and channel management in the Lightning Network. It is a joinpool-type protocol where multiple users can accept a service provider as a trading partner for a certain period, conducting virtual UTXO (vUTXO) transactions off-chain while sharing a UTXO on-chain to reduce costs. Similar to vaults, Ark can be implemented on the current Bitcoin network; however, with the introduction of covenants, Ark can reduce the required interaction based on transaction templates, achieving a more trustless unilateral exit.
Overview of Covenant Technologies
From the above applications, it can be seen that covenants are more like an effect rather than a specific technology, so there are many ways to implement them. If categorized, they can include:
- Type: General, Specific
- Implementation Method: Based on Opcode, Based on Signature
- Recursion: Recursive, Non-Recursive
Among them, recursion refers to some implementations of covenants that can limit the next output by restricting the current output, allowing added restrictions to exceed a single transaction and achieve greater transaction depth.
Some mainstream covenant designs include:
Design of Covenants
From the previous introduction, it can be seen that current Bitcoin scripts mainly restrict the conditions for unlocking, without limiting how that UTXO can be further spent. To implement covenants, we need to think in reverse: why can't current Bitcoin scripts implement covenants?
The main reason is that current Bitcoin scripts cannot read the contents of the transaction itself, i.e., the "introspection" of the transaction.
If we could achieve transaction introspection—checking any content of the transaction (including outputs)—then we could implement covenants.
Thus, the design idea of covenants mainly revolves around how to achieve introspection.
Based on Opcode vs Based on Signature
The simplest and most straightforward idea is to add one or more opcodes (i.e., one opcode + multiple parameters, or multiple opcodes with different functions) to directly read the contents of the transaction. This is the idea based on opcodes.
Another idea is that we can avoid directly reading and checking the contents of the transaction in the script but can utilize the hash of the transaction content—if this hash has been signed, then by modifying the script, such as OPCHECKSIG, we can indirectly achieve transaction introspection and covenants. This idea is the signature-based design approach, mainly including APO and OPCSFS.
APO
SIGHASH_ANYPREVOUT (APO) is a proposed Bitcoin signature method. The simplest way to sign is to commit to both the inputs and outputs of the transaction, but Bitcoin also has a more flexible method, i.e., SIGHASH, which selectively commits to either inputs or outputs in a transaction.
Current SIGHASH and its combinations for signing transaction inputs and outputs (source: "Mastering Bitcoin, 2nd")
As shown in the figure above, in addition to ALL, which applies to all data, the NONE signing method applies only to all inputs and not outputs; SINGLE is based on this, applying only to outputs corresponding to the same input index. Additionally, SIGHASH can be combined, and when the ANYONECANPAY modifier is added, it applies only to one input.
The SIGHASH of APO only signs the outputs and does not sign the input part. This means that after signing a transaction using APO, it can be attached to any UTXO that meets the conditions later.
This flexibility is the theoretical basis for APO to implement covenants:
- Multiple transactions can be pre-created.
- A public key can be constructed that can only derive a single signature based on the information from these transactions.
- Thus, any assets sent to the address of that public key can only be spent through the pre-created transactions.
It is worth noting that because this public key does not have a corresponding private key, it ensures that these assets can only be spent through the pre-created transactions. Therefore, we can specify the destination of the assets in these pre-created transactions, thus implementing covenants.
We can further understand this by comparing it to Ethereum's smart contracts: through smart contracts, we can also achieve that withdrawals from the contract address can only occur under certain conditions, rather than relying on an EOA signature to spend arbitrarily. In this regard, Bitcoin can achieve this effect through improvements in the signature mechanism.
However, the problem in the above process is that there is a circular dependency in computation, as it requires knowing the input content to pre-sign and create transactions.
The significance of APO and SIGHASH_NOINPUT in implementing this signature method is that it can solve this circular dependency problem, as it only needs to know (specify) all outputs of the transaction during computation.
OP_CTV
OP_CHECKTEMPLATEVERIFY (CTV), i.e., BIP-119, adopts an improved opcode approach. It takes the commitment hash as a parameter and requires that any transaction executing the opcode must include a set of outputs that match that commitment. Through CTV, it will allow Bitcoin users to restrict how they use Bitcoin.
This proposal was initially introduced under the name OP_CHECKOUTPUTSHASHVERIFY (COSHV) and early on focused on creating congestion control transactions, so criticisms of the proposal centered on its lack of generality and being overly specific to congestion control use cases.
In the aforementioned congestion control use case, the sender, Alice, can create 10 outputs, hash these 10 outputs, and use the generated hash to create a tapleaf script containing COSHV. Alice can also use the public keys of the participants to form a Taproot internal key, allowing them to cooperate in spending without revealing the Taproot script path.
Then, Alice will provide each recipient with a copy of all 10 outputs so that each of them can verify Alice's setup transaction. When they later want to spend this payment, any of them can create a transaction containing the committed outputs.
Throughout the process, when Alice creates and sends the setup transaction, she can send these 10 output copies through existing asynchronous communication methods (such as email or cloud drives). This means that recipients do not need to be online or interact with each other.
Source: https://bitcoinops.org/en/newsletters/2019/05/29/#proposed-transaction-output-commitments
Similar to APO, addresses can also be constructed based on spending conditions, and various methods can be used to create "locks," including adding other keys, time locks, and combinable logic.
Source: https://twitter.com/OwenKemeys/status/1741575353716326835
CTV proposes that it can check whether the spending transaction, after hashing, matches the defined outputs, effectively using the transaction data as a key to "unlock."
We can extend the example of the 10 recipients further, where the recipient can further set their address key as a signed but unbroadcasted tx sent to the next batch of recipient addresses, and so on, forming a tree structure as shown below. Alice can construct a balance change involving multiple users using only 1 UTXO of block space on-chain.
Source: https://twitter.com/OwenKemeys/status/1741575353716326835
And what if one of the leaves is a Lightning channel, cold storage, or another payment path? Then this tree will expand from a single-dimensional multi-layer spending tree to a multi-dimensional multi-layer spending tree, supporting richer and more flexible scenarios.
Source: https://twitter.com/OwenKemeys/status/1744181234417140076
Since its proposal, CTV has undergone a renaming from COSHV in 2019, was assigned BIP-119 in 2020, and has seen the emergence of programming languages like Sapio that support CTV contracts. In 2022 and 2023, it has received much community discussion, updates, and debates over its activation plan, and it remains one of the most discussed soft fork upgrade proposals in the community.
OP_CAT
As introduced at the beginning, OPCAT is also a currently highly regarded upgrade proposal that performs concatenation on two elements in the stack. Although it seems simple, OPCAT can flexibly implement many functions in scripts.
The most direct example is operations related to Merkle trees. A Merkle tree can be understood as concatenating two elements and then hashing them. Currently, Bitcoin scripts have hash opcodes like OPSHA256, so if OPCAT can be used to concatenate two elements, it can implement Merkle tree verification functionality in scripts, thus possessing a certain degree of light client verification capability.
Another foundational implementation includes enhancements for Schnorr signatures: the spending signature conditions of the script can be set as the concatenation of the user's public key and public nonce; if the signer wants to sign another transaction to spend these funds elsewhere, they must use the same nonce, which would lead to a private key leak. Thus, OP_CAT achieves a commitment to the nonce, ensuring the validity of the signed transaction.
Other application scenarios for OP_CAT include: Bistream, tree signatures, quantum-resistant Lamport signatures, vaults, and more.
OPCAT itself is not a new feature; it existed in the early versions of Bitcoin but was disabled in 2010 due to potential exploitation risks. For example, repeatedly using OPDUP and OP_CAT could easily cause stack overflow when processing such scripts in full nodes; refer to this demo.
But will re-enabling OPCAT now lead to the previously mentioned stack overflow issues? Because the current OPCAT proposal only involves enabling it in tapscript, which limits each stack element to no more than 520 bytes, so the previous stack overflow issues will not occur. Some developers believe that Satoshi's outright disabling of OPCAT may have been too harsh. However, due to the flexibility of OPCAT, there may indeed be some application scenarios that could lead to vulnerabilities that cannot be fully anticipated at present.
Therefore, considering the application scenarios and potential risks, OP_CAT has recently received a lot of attention and has undergone PR review, making it one of the hottest upgrade proposals currently.
Conclusion
"Self-discipline brings freedom." From the above introduction, it can be seen that covenants can directly implement restrictions on further spending of transactions in Bitcoin scripts, thus achieving transaction rules similar to smart contracts. Compared to off-chain methods like BitVM, this programming approach can verify more natively on Bitcoin while also improving applications on the main chain (congestion control), off-chain applications (state channels), and other new application directions (staking penalties, etc.).
If the implementation technology of covenants can be combined with some underlying upgrades, it will further unleash the potential for programmability. For example, the recent proposal for 64-bit operators in the review could further integrate with the proposed OP_TLUV or other covenants, allowing programming based on the number of satoshis in transaction outputs.
However, covenants may also lead to some unintended abuses or vulnerabilities, so the community is cautious about them. Additionally, the upgrade of covenants also needs to involve a soft fork upgrade of consensus rules. Given the situation during the taproot upgrade, upgrades related to covenants may also take time to complete.