Authors: Jeffrey HU & Harper LI, HashKey Capital
A recent discussion has sparked in the Bitcoin community regarding the reintroduction of operation codes such as OP_CAT. Taproot Wizard has also attracted attention by launching Quantum Cats NFT and claiming to have obtained the BIP-420 number. Supporters claim that enabling OP_CAT can achieve “covenants” and enable smart contracts or programmability in Bitcoin.
If you pay attention to the term “covenants” and do a quick search, you’ll discover a whole new world. Developers have been discussing various technologies for implementing covenants for many years, including OP_CTV, APO, OP_VAULT, and more.
So, what exactly are Bitcoin’s “covenants”? Why have they attracted the continuous attention and discussion of developers for years? What programmability does it offer for Bitcoin? What are the underlying design principles? This article aims to provide an overview and discussion of these questions.
What are “covenants”?
Covenants are mechanisms that allow conditions to be set for future Bitcoin transactions. The current Bitcoin script already includes conditions such as requiring a valid signature or a matching script for spending. However, as long as the user can unlock it, they can spend the UTXO wherever they want.
Covenants, on the other hand, add additional restrictions based on how the unlocking is done. For example, they can restrict spending after the UTXO, achieving a “special-purpose” effect, or impose additional input conditions in a transaction. In essence, covenants can directly limit further spending in Bitcoin scripts, thereby enabling transaction rules similar to smart contracts.
To be more precise, the current Bitcoin script already has certain covenant-like features, such as time locks based on operation codes, which restrict spending before a certain time based on the nLock or nSequence fields of the transaction. However, these restrictions are mainly limited to time.
So why do developers and researchers design these covenant checks? It’s because covenants are not just about restrictions, but also about setting rules for transaction execution. This way, users can only execute transactions according to predetermined rules, completing the intended business processes.
This is counterintuitive, but it unlocks more application scenarios.
Application scenarios for covenants
Ensuring Staking Penalties
One of the most straightforward examples of covenants is the slash transaction in the Babylon Bitcoin staking process.
In Babylon’s Bitcoin staking process, users send their BTC assets on the main chain to a special script, with two spending conditions:
– Happy ending: After a certain period of time, users can unlock the assets with their own signatures, completing the unstaking process.
– Bad ending: If a user engages in malicious behavior, such as double-spending, on a PoS chain secured by Babylon, the assets can be unlocked using extractable one-time signatures (EOTS) and a portion of the assets can be sent to a burning address (slash) by the network’s executing roles.
Note the term “forced sending” here, which means that even if the UTXO can be unlocked, the assets cannot be sent anywhere else and can only be burned. This ensures that malicious users cannot use their known signatures to transfer the assets back to themselves and escape punishment.
This functionality can be implemented in the “bad ending” branch of the staking script using opcode such as OP_CTV after it is enabled. Before OP_CTV is enabled, Babylon needs to simulate the enforcement of covenant restrictions through alternative methods, executed jointly by users and committees.
Congestion Control
Congestion refers to the situation where the Bitcoin network has high transaction fees and the transaction pool accumulates a large number of transactions waiting to be included in blocks. To ensure quick confirmation of transactions, users need to increase the transaction fees.
However, if a user needs to send multiple transactions to multiple recipients, they have to increase the fees and bear high costs. This also further increases the overall network’s transaction fees.
With covenants, one solution is for the sender to make a commitment to a batch transaction. This commitment allows all recipients to believe that the final transactions will take place and can be sent when the transaction fees are low.
When there is high demand for block space, transactions become very expensive. By using OP_CHECKTEMPLATEVERIFY, large payment processors can aggregate all their payments into a single transaction with complexity O(1) for confirmation. Then, after a certain period of time, when the demand for block space decreases, payments can be extended from the UTXO.
This scenario is a typical application case proposed by OP_CTV. The website https://utxos.org/uses/ provides more application cases, including Soft Fork Bets, Decentralized options, Drivechains, Batch Channels, Non Interactive Channels, Trustless Coordination-Free Mining Pools, Vaults, and Safer Hashed Time Locked Contracts (HTLCS) Limits.
Vaults for Custody
Vaults are widely discussed applications in the Bitcoin space, especially within the realm of covenants. Balancing between the custody of funds and the need to use them is a challenge, and people hope to have a type of vault application that can guarantee fund security and limit fund usage even if the account is compromised (private key leaked).
Based on covenant technologies, vault applications can be easily built. Taking the design proposal of OP_VAULT as an example, when spending funds in a vault, a transaction needs to be sent to the blockchain. This transaction indicates the intention to spend from the vault, the “trigger,” and sets conditions:
– If everything is normal, the second transaction is the final withdrawal transaction. After waiting for N blocks, the funds can be further spent anywhere.
– If the trigger transaction is stolen (or compelled during a “wrench attack”) before the withdrawal transaction after N blocks, it can be immediately sent to another secure address (safer custody) instead of waiting for the withdrawal transaction.
It should be noted that without covenants, a custody application can still be built. One feasible method is to prepare the spending signatures with private keys and then destroy the private keys. However, there are still many restrictions, such as ensuring the private key is destroyed (similar to the trusted setup process in zero-knowledge proofs), determining the amount and fees in advance (due to pre-signing), and lack of flexibility.
More Robust and Flexible State Channels
Generally, state channels, including the Lightning Network, are considered to have security comparable to the main chain (as long as the latest state is observable and can be properly published on-chain). However, with covenants, new design ideas for state channels can make them more robust or flexible on top of the Lightning Network. Some well-known examples include Eltoo and Ark.
Eltoo (also known as LN-Symmetry) is a typical example. This technology proposal, pronounced similar to “L2,” introduces an execution layer for the Lightning Network that allows any subsequent channel state to replace the previous state without the need for a punishment mechanism. This avoids the need for Lightning Network nodes to store multiple previous states to prevent malicious behavior. To achieve this, Eltoo proposes the SIGHASH_NOINPUT signing 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 protocol in the form of a join pool, allowing multiple users to accept a service provider as a trading partner for a certain period of time and conduct off-chain transactions with virtual UTXOs (vUTXOs) while sharing a UTXO on-chain to reduce costs. Similar to vaults, Ark can also be implemented on the current Bitcoin network. However, with the introduction of covenants, Ark can reduce the required interaction based on transaction templates, achieving more trustless unilateral exits.
Overview of Covenant Technologies
From the above applications, it can be seen that covenants are more of a desired effect rather than a specific technology, leading to various implementation methods. If classified, they can include:
– Type: General-purpose, Special-purpose
– Implementation: Opcode-based, Signature-based
– Recursion: Recursive, Non-recursive
Recursion refers to the ability of some covenant implementations to restrict the spending of the next output, thereby limiting the spending of subsequent outputs and achieving higher transaction depth.
Some mainstream covenant designs include:
– BIP-118: SIGHASH_NOINPUT
– BIP-119: OP_CAT
– BIP-120: OP_CHECKTEMPLATEVERIFY
– BIP-121: OP_CHECKOUTPUTSHASHVERIFY
– BIP-122: OP_CHECKOUTPUTSHASHVERIFY
– BIP-123: OP_CHECKOUTPUTSHASHVERIFY
Covenant Design
From the previous introduction, it can be seen that the current Bitcoin script mainly restricts the unlocking conditions, without limiting how the UTXO can be further spent. To implement covenants, we need to think the other way around: Why can’t the current Bitcoin script implement covenant restrictions?
The main reason is that the current script is stack-based, making it difficult to implement covenant restrictions. The introduction of new operation codes and the redesign of the Bitcoin script are necessary to support covenants.
Conclusion
Covenants bring programmability to Bitcoin by enabling restrictions and setting rules for transaction execution. They have various applications such as ensuring staking penalties, congestion control, custody vaults, and more robust state channels. The implementation of covenants requires new operation codes and the redesign of the Bitcoin script. With the adoption of covenants, Bitcoin can unlock more potential use cases and expand its capabilities.Bitcoin Script is unable to read the content of a transaction itself, meaning it cannot perform “introspection” on the transaction.
If we could achieve introspection of a transaction – the ability to examine any content of the transaction, including its outputs – we could implement restriction clauses.
Therefore, the design of restriction clauses primarily revolves around how to achieve introspection.
Based on Opcode vs Signature
The simplest and most straightforward idea is to add one or more opcodes (i.e., one opcode with multiple parameters or multiple opcodes with different functionalities) to directly read the content of the transaction. This is the approach based on opcodes.
Another approach is to not directly read and check the content of the transaction itself in the script, but to use the transaction’s content hash. If this hash has already been signed, then by modifying operations such as OP_CHECKSIG in the script, we can indirectly achieve transaction introspection and restriction clauses. This approach is based on signatures and includes APO (SIGHASH_ANYPREVOUT) and OP_CSFS.
APO
SIGHASH_ANYPREVOUT (APO) is a proposed Bitcoin signature scheme. The simplest way to sign a transaction is to commit to both the inputs and outputs of the transaction. However, Bitcoin offers a more flexible way, known as SIGHASH, to selectively commit to the inputs or outputs of a transaction.
Currently, SIGHASH and its combinations have different signature scopes for transaction inputs and outputs (source: “Mastering Bitcoin, 2nd Edition”).
As shown in the above image, besides the ALL mode, which applies to all data, the NONE signature mode applies only to inputs and not outputs. The SINGLE mode builds upon this, applying only to outputs with the same input index. Additionally, SIGHASH can be combined with the ANYONECANPAY modifier, which applies to a single input.
APO’s SIGHASH only signs the outputs and not the inputs. This means that a transaction signed with APO can be attached to any UTXO that meets the conditions.
This flexibility forms the theoretical basis for implementing restriction clauses with APO:
– Pre-create one or more transactions.
– Construct a public key that can only produce one signature based on the information from these transactions.
– Any assets sent to this public key address can only be spent using the pre-created transactions.
It is worth noting that because there is no corresponding private key for this public key, it ensures that these assets can only be spent through the pre-created transactions. Thus, we can specify the destination of the assets in these pre-created transactions to implement restriction clauses.
To further understand, we can compare it to Ethereum’s smart contracts, which also restrict withdrawals from contract addresses based on certain conditions, rather than allowing arbitrary spending based on an EOA signature. In this sense, Bitcoin’s improved signature mechanism can achieve this effect.
However, the problem with the above process is that there is a circular dependency in the calculations because the input’s content needs to be known to pre-sign and create the transaction.
The significance of APO and SIGHASH_NOINPUT in implementing this signature scheme is that it can solve this circular dependency issue. It only requires knowing (specifying) all the outputs of the transaction during the calculation.
OP_CTV
OP_CHECKTEMPLATEVERIFY (CTV), also known as BIP-119, adopts an improved opcode approach. It takes a commitment hash as a parameter and requires any transaction executing the opcode to include a set of outputs that match this commitment. Through CTV, Bitcoin users will be able to limit how they use Bitcoin.
The proposal was initially introduced as OP_CHECKOUTPUTSHASHVERIFY (COSHV) and early criticism of the proposal focused on its lack of generality and its specific focus on congestion control use cases.
In the congestion control use case mentioned earlier, the sender, Alice, can create 10 outputs and hash these outputs. She can then use the generated digest to create a tapleaf script that includes COSHV. Alice can also use the participants’ public keys to form internal keys within the Taproot to allow them to cooperate in spending without revealing the Taproot script path.
Alice then gives each recipient a copy of all 10 outputs so that each recipient can verify Alice’s setup transaction. When any of them want to spend this payment in the future, any one of them can create a transaction that includes the committed outputs.
Throughout the process, when Alice creates and sends the setup transaction, she can send copies of the 10 outputs through existing asynchronous communication methods such as email or cloud drives. This means that the recipients do not need to be online or interact with each other.
Similar to APO, addresses can also be constructed based on spending conditions, and different methods can be used to create “locks,” including adding additional keys, time locks, and combinable logic.
CTV proposes the ability to check if the spending transaction, after being hashed, matches the defined commitment, using the transaction data as the key to unlock.
We can further extend the example of the 10 recipients. The recipients can set their address keys to be signed but unbroadcasted transactions that are sent to the next batch of recipient addresses, and so on, forming a tree-like structure as shown in the above image. Alice can construct an account balance change involving multiple users with only 1 UTXO’s block space on-chain.
If one of the leaves is a lightning channel, cold storage, or another payment path, the tree expands from a single-dimensional multi-layer spending tree to a multi-dimensional multi-layer spending tree, supporting more diverse and flexible scenarios.
Since its proposal, CTV has undergone several developments, including being renamed from COSHV to BIP-119 in 2019. It has also seen discussions, updates, and debates on its activation plan in the community in 2022 and 2023, making it one of the most discussed soft fork upgrade proposals.
OP_CAT
As mentioned earlier, OP_CAT is a currently popular upgrade proposal that concatenates two elements in the stack. Although it seems simple, OP_CAT can be flexibly used to achieve many functionalities in a script.
The most direct example is related to Merkle tree operations. A Merkle tree can be understood as concatenating two elements and then hashing them. Bitcoin’s current script includes hash opcodes such as OP_SHA256, so if OP_CAT can be used to concatenate two elements in a script, it can implement Merkle tree verification and, to some extent, enable lightweight client verification.
Another implementation basis is the enhancement of Schnorr signatures. The spending signature conditions of a script can be set as the concatenation of the user’s public key and a publicly known nonce. If the signer wants to spend the funds to another place by signing another transaction, they would have to use the same nonce, which would result in the leakage of the private key. OP_CAT thus enables a commitment to the nonce, ensuring the validity of the signed transaction.
Other applications of OP_CAT include Bistream, tree signatures, quantum-resistant Lamport signatures, and custody libraries.
OP_CAT itself is not a new functionality; it existed in the earliest versions of Bitcoin but was disabled in 2010 due to the possibility of being exploited. For example, the repeated use of OP_DUP and OP_CAT can easily cause a stack explosion when processing such scripts by full nodes, as demonstrated in this demo.
However, would re-enabling OP_CAT now cause the stack explosion issue mentioned earlier? The current OP_CAT proposal only involves enabling it in tapscript, which limits each stack element to be no more than 520 bytes, so the previous stack explosion issue would not occur. Some developers also believe that Satoshi Nakamoto’s direct disabling of OP_CAT may have been too strict. But due to the flexibility of OP_CAT, there may indeed be some application scenarios that could lead to vulnerabilities that cannot be exhaustively enumerated at present.
Considering the application scenarios and potential risks, OP_CAT has recently received much attention and has undergone PR reviews. It is one of the most popular upgrade proposals at the moment.
Conclusion
“Self-discipline brings freedom.” From the above introduction, it can be seen that restriction clauses can be implemented in Bitcoin scripts to further limit the spending of transactions, thereby achieving transaction rules similar to smart contracts. Compared to off-chain methods like BitVM, this programming method can be natively verified on Bitcoin and can also improve on-chain applications (congestion control), off-chain applications (state channels), and other new application directions (staking penalties, etc.).
If the implementation of restriction clauses 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 reviews can be combined with proposed OP_TLUV or other restriction clauses to enable programming based on the amount of satoshis in transaction outputs.
However, restriction clauses may also lead to unintended abuses or vulnerabilities, so the community approaches them with caution. Additionally, upgrading restriction clauses would require a soft fork consensus rule upgrade. Given the circumstances during the Taproot upgrade, it may take some time to complete the upgrade related to restriction clauses.