Let's be clear: Bitcoin's scripting language is a fortress of deliberate limitation. Of 256 possible opcodes, only 117 are currently enabled. Two of the disabled ones—OP_CAT (disabled in 2010 for potential DoS concerns) and a never-activated OP_CSFS—are quietly gaining traction in core developer discussions. Why now? Because the combination of these two opcodes unlocks a capability that has eluded Bitcoin since its inception: native covenants without pre-signed key management.
I've spent years trading the inefficiencies between Layer 2 solutions. In 2023, I allocated $30k to early EigenLayer restaking, spending two weeks auditing slash conditions. That experience taught me that trust-minimized state verification is the holy grail for decentralized finance. Bitcoin's current covenant proposals are trying to achieve the same thing, but with a much stricter safety budget. This is not another Ethereum EIP; it's a fundamental shift in what Bitcoin can verify on its own chain.
Context: The Covenant Problem
Covenants are restrictions on how a specific output can be spent. Think of a vault that only allows withdrawals to a whitelisted address after a timelock. Or a mortgage that auto-refinances when certain interest rate conditions are met. On Ethereum, you just write a smart contract. On Bitcoin, you need to embed these constraints directly into script without introducing new consensus rules that could create attack vectors.
Current workarounds rely on pre-signed transactions using SIGHASH flags like SIGHASH_ANYONECANPAY. This works for simple cases—like Lightning Network channels—but it's a kludge. You need to coordinate off-chain, manage multiple signatures, and the resulting logic is brittle. Every time you want to change a condition, you need a new round of signing. That's not programmable money; it's programmable friction.
Enter OP_CSFS (CheckSigFromStack) and OP_CAT (Concatenation). OP_CSFS allows the script to verify a signature against arbitrary data on the stack, not just the current transaction. OP_CAT merges two stack elements into one. Together, they let you construct a transaction template, sign it, and then later verify that the spending transaction matches that template. The result? You can enforce spending conditions without any off-chain coordination.
Core: How the Oatmeal and Scissors Work
Here's the technical breakdown. I'll keep it concrete.
OP_CSFS takes three stack arguments: a public key, a signature, and a message. It verifies that the signature is valid for that message under that public key. That's standard ECDSA verification. The twist: the message is whatever you push onto the stack. Not the transaction hash—any arbitrary byte string.
OP_CAT concatenates the top two stack items into one. So if you have [0x01] and [0x02] on the stack, OP_CAT outputs [0x0102].
Now, to create a covenant:
- You construct a spending transaction template. You hash it using OP_SHA256 or OP_HASH256. The hash becomes the committed message.
- You push the intended spending transaction's components (inputs, outputs, amounts) onto the stack in the correct order.
- You use OP_CAT to assemble them into a serialized transaction.
- You hash that serialized transaction.
- You use OP_CSFS to verify a signature over that hash. The signature comes from a public key that's embedded in the UTXO's script.
The spending transaction must produce a hash that matches the one signed. If the spender tries to change even one satoshi's destination, the hash changes, the signature verification fails, and the transaction is invalid.
Practical Example: A Simple Vault
Let's imagine a vault that can only send to address A after block 800,000, or to address B before that block. Without OP_CSFS+OP_CAT, you'd need two pre-signed transactions with different timelocks. With the opcodes, you can write a single script:
// Check if spending to address A after 800000
OP_CHECKLOCKTIMEVERIFY
OP_DROP
<push address A>
OP_EQUAL
OP_IF
// Verify signature that proves the output is address A
// (using OP_CSFS on the output commitment)
OP_ELSE
// Check spending to address B before 800000
<push address B>
OP_EQUALVERIFY
OP_CLTV <800000> OP_NOTIF
// ... similar verification
OP_ENDIF
This script does not rely on any off-chain key management. The covenant is enforced purely by the script and the signatures included in the spending transaction. The only new thing is that the script can now introspect its own spending context.
Contrarian: The Oatmeal Might Get Cold
Here's the sharp edge: every protocol upgrade that adds expressiveness also adds attack surface. OP_CAT was disabled because a clever script could cause the node to allocate unbounded memory. The reactivation proposal includes a limit on stack element size (520 bytes for OP_CAT's concatenated result), but the combinatorial logic of multiple OP_CSFS checks could lead to unexpected validation loops.
More critically, there's an alternative proposal gaining momentum: OP_TXHASH (BIP 118). OP_TXHASH extracts the hash of the current transaction from the context, allowing covenants without concatenation. It's simpler, with less risk of script explosion. Bitcoin Core maintainers like Pieter Wuille have expressed preference for this approach. --- Scenario: Reacting to a hack in an un-audited covenant implementation? If the community rushes to activate OP_CSFS+OP_CAT without thorough testing, we could see a repeat of the 2015 OP_RETURN spam attacks, but on steroids. The Bitcoin maximist in me says: move slow, don't break things.
Another blind spot: even if activated, adoption will be glacial. Wallets need to support parsing the new opcodes. L2 protocols need to rewrite their bridging logic. The first usable covenant application might take three years to appear. Meanwhile, the Ethereum ecosystem will have shipped another upgrade.
But the bigger contrarian truth is that this debate is a proxy for a philosophical war. The 'conservative' camp wants minimal changes (CTV, TXHASH) that replicate existing patterns. The 'expansionist' camp wants maximal expressiveness (CSFS+CAT) to future-proof Bitcoin. Neither is wrong, but the expansionist path is riskier. My experience in DeFi has taught me that the safest protocol is the one that never upgrades. But it's also the one that dies.
Takeaway: The Real Signal
I don't care which opcode gets activated. I care about the direction. Bitcoin is finally discussing how to make its script layer programmable without breaking its security model. That's the real signal. The noise is about which combination of opcodes wins the BIP lottery.
Watch the GitHub repos. Track the BIP status of OP_CSFS (not yet assigned) and OP_TXHASH (BIP 118). If one of these reaches 'Draft' and gets a reference implementation, the market will start pricing in a more capable Bitcoin. But for now, the only actionable takeaway is: don't bet on a timeline. Bitcoin upgrades are glacial. The last one (Taproot) took four years from BIP to activation.
If you're building on top of Bitcoin, start prototyping with simulators. If you're trading, ignore the hype. When the first covenant-enabled vault actually locks BTC, then we'll have something to trade.