The following syndicated article was originally published by ReardenCode on X. Titled “Cursed Recursive Covenants,” it’s right on the edge of the technical discussion regarding softforks such as OP_CAT/CTV/etc but we think it’s relevant especially given our conference in Boston this coming Saturday. You can also find Rearden himself at OP_NEXT!
By the way, it’s not too late to grab a ticket to OP_NEXT! VIP is sold out but GA is still available.
For the nontechnical reader: a “covenant” is a broad term to describe a wallet setup that restricts the spending conditions for future UTXOs. Covenants would greatly expand the types of things you can build with Bitcoin and dramatically improve the self-custody landscape. But developers and bitcoin power users are still discussing the full scope and ramifications of covenants – what, for example, if a covenant could be used to harm Bitcoin users?
A lot of this discussion hinges on the definition of “recursive covenants” and evaluating how we should categorize different covenant proposals – the topic of today’s article
Cursed recursive covenants
Halloween week was haunted by the curse of recursive covenants and devilishly difficult definitions. It began on Wednesday with my spooky claim that recursion does not change the potential for trickery from any particular covenant opcode. On Halloween itself, I had a sometimes vexing discussion about this with Bitcoin Core contributor Matt Corallo.
At the root of this whole conversation is really the question of what it means for a covenant to be recursive (and how this relates to the computer science definition of the term).
The TL;DR: the most interesting dimension to consider when discussing the risks and benefits of a covenant proposal is its granularity. It may also be interesting to discuss other auxiliary functionality it enables (such as OP_CAT’s probably 31-bit multiplication and Merkle tree verification).
So please stop talking about whether a covenant design is recursive. It doesn’t matter (other than potentially as a programming convenience). I explain why below.
Defining Recursive
Colloquial definition of recursive
Let’s start with one of the most widely applied heuristics for whether a covenant is recursive in bitcoin: Can this covenant be used to forever constrain some bitcoin to only being spent in compliance with some rule (e.g. a government whitelist)?
This requires a covenant that can be inserted into a bitcoin spend script and enforce that that same condition is applied in all outputs produced by spending that script. In programming terms, this requires a covenant that is a quine in addition to enforcing another condition.
Matt Corallo’s definition of recursive
In my conversation with Matt, we dove into an alternative definition of recursive that I had not previously heard: a covenant is recursive if it can consume some state, constrain its spending transaction based on that state, and then propagate a modified version of that state to a new UTXO.
There are two important differences between Matt’s definition and the colloquial definition:
- It does not require the covenant to self-replicate (i.e. it does not require it to be a quine)
- It does require that the covenant be able to capture state and then enforce changing state
Programming definition of recursive
Unfortunately for all of us, neither of these definitions matches the common computer science definition of recursive. In computer science, a function is recursive if it calls itself, regardless of whether or not it self-replicates and whether or not it can capture state from its inputs to act on at its termination.
Under the programming definition, OP_CHECKTEMPLATEVERIFY is recursive. It would allow you to first define one or more base cases and then have each prior step in the recursion call OP_CHECKTEMPLATEVERIFY to reach those base cases. The opcode can be used to call itself.
The recursive Venn diagram
The Venn diagram of which potential covenant designs might meet each definition of recursive looks like this:
As the diagram shows, the programming definition of recursive includes all covenants that meet the colloquial definition, Matt’s definition, and more, but not all covenants that meet Matt’s definition are included in the colloquial definition or vice versa.
All of this tells me that we need better definitions and terms to talk about these things.
Exorcizing the semantics
I stand by the claim that whether a covenant design is recursive (according to the colloquial definition) or not is simply not a useful distinction when considering the risks or benefits of a given design. Instead, I think we should use terminology that is more descriptive and therefore more helpful for discussing these things.
A given covenant design can be either state transforming or self propagating. These roughly correspond to Matt’s definition of recursive and the colloquial one respectively. Additionally, we need to consider the granularity of the proposal.
Self Propagating
Whether or not a covenant is self propagating is probably not an important design consideration.
There have been many discussions over the years as to whether such a self propagating covenant could be used to enforce government whitelists on bitcoin, and the answer is consistently that it’s a fundamentally worse tool for the job than existing multisig opcodes or cryptographic constructions. Self propagation is a programming convenience when designing covenant-based protocols, so I suspect that many proposals will end up being self propagating (e.g. OP_CHECKCONTRACTVERIFY, OP_CAT, OP_VAULT).
State transforming
Whether a covenant is state transforming is the next dimension to consider in terms of the risks and benefits of the design. Hashrate escrows are the quintessential example of a protocol that can be built as soon as a state transforming covenant is available (regardless of whether the design is self propagating or not).
Granularity
Finally, we come to what I consider the most important design consideration for a covenant system, and one of the reasons that I have long preferred OP_CHECKTEMPLATEVERIFY to SIGHASH_ANYPREVOUT as a next step for bitcoin: granularity. I’m using the word granularity here to define how specific the covenant design is regarding what portions of the transaction it constrains.
Where a state transforming covenant design enables hashrate escrows, only a high granularity, state transforming covenant design enables CatVM, AMMs, or DEXs. It so happens that it’s nearly impossible to design a high granularity covenant system that is not also state transforming, and many will also be self propagating; but neither of those are the fundamental dimension that opens up the design space for bitcoin script-based protocol design. Once a covenant design is sufficiently granular, it will enable the construction of many new protocols based on bitcoin script. At a lower level of granularity it will already have enabled state transforms.
Conclusion
The fundamental dial that matters in bitcoin covenant design is granularity. We can see this in stark relief by comparing OP_CHECKTEMPLATEVERIFY, SIGHASH_ANYPREVOUT, OP_TXHASH, and OP_CAT. OP_CHECKTEMPLATEVERIFY is not granular (it includes exactly one hashing mode), and it enables neither hashrate escrows nor AMMs. SIGHASH_ANYPREVOUT enables spookchain hashrate escrows due to its higher (6 hash modes) granularity. OP_TXHASH is highly granular (but not self propagating) and enables hashrate escrows and (barring possibly the need for additional math opcodes) AMMs. OP_CAT can be used to emulate OP_TXHASH (and a bit more via ancestor hash construction) and probably also to emulate 31 bit multiplication; it is therefore both highly granular as a covenant and enables some additional functionality that can augment its capabilities. Important to this discussion, the fact that OP_CAT is the only one of these proposals that is self propagating has no real bearing on what it does or does not enable.