Last week I had the pleasure of spending 5 days with many of the best minds in bitcoin at @btcplusplus
in Austin, Texas. Prior to the conference itself, niftynei
organized a 1-day Covenants Pre-summit where many of the conference speakers gathered to discuss the future of bitcoin. This pre-summit fed directly into the conference itself, the "Script Edition".
The topic at hand: how best to improve bitcoin's script to continue what Satoshi started 15 years ago. Coming into the conference, each of us had our own expectations, preconceptions, preferences, and biases. I, for example, was of the mindset that a minimal few opcodes (LNHANCE) is the best way to improve script. I was growing comfortable with the idea that LNHAHCE+CAT might be the conference-local consensus on a path forward with broad developer support. I had seen rusty_twit
's talk about "The Great Script Restoration" on the agenda but didn't really think much about it. I said to myself, "there's no way such an ambitious project is going forward".
High Level Takeaways
In the spectrum of next upgrades for bitcoin, there's a wide range of ambition. From the smallest part of the Great Consensus Cleanup and CTV, through various combinations of upgrades and the Great Script Restoration, and all the way up to Simplicity. Among that group it was agreed that Simplicity is well off the right edge of the chart. My take-away from this conversation is covered here
. Briefly, aiming small because some folks are afraid of change is what has made it so hard to find broad support for upgrading bitcoin in the past 3 years. It's time to aim bigger.
It's impossible for bitcoin protocol developers to control how the protocol will be used. This has been in stark relief of late with Ordinals, Inscriptions, and Runes. What we can do is ensure that node resource consumption is constrained, and that bitcoin's fundamental properties that make it suitable for use as money are retained or enhanced. Bitcoin will be better money if more people can hold their own keys. Bitcoin will be better money if people holding their keys have better choices about their security model.
While some bitcoiners are concerned about the risks of changing bitcoin's script system, many others (myself included) are much more concerned about the risks of not changing it. Right now people are building protocols such as BitVM on top of existing bitcoin script. They're building custodial systems. They're building federations. All of these things represent risks to the stability and long term viability of bitcoin. If we improve bitcoin's scripting capabilities, we can enable these and other builders to instead build (for example) CatVMs, non-custodial Arks, shared custody coin pools, and more that reduce these risks.
Great Script Restoration
Next, let's take a closer look at the Great Script Restoration itself. I summarized it here
but now I'd like to take a closer look at what it entails and why. First and foremost, the Great Script Restoration is an effort to finish the work that was started back in 2010 in response to the LSHIFT CVE
. In 2010, Satoshi removed many opcodes from script not because they weren't useful but because several of them did and other could have had DOS vectors. The removed opcodes were: CAT, SUBSTR, LEFT, RIGHT, INVERT, AND, OR, XOR, 2MUL, 2DIV, MUL, DIV, MOD, LSHIFT, RSHIFT. If a design can be proffered that made these opcodes safe for bitcoin nodes, they can be re-enabled, making bitcoin script much more useful in building tools for bitcoiners.
Rusty proposes a combined cost-based model that he calls "varops" to limit these opcodes' worst case validation cost to no worse than the existing sigops limit or budget applied to prevent similar DOS attacks using signature checking operations. Assuming that such a limit can be reasonably applied with similar properties to the sigops limit (never to be hit in practice except by an attacker), this would significantly expand the locking conditions possible in bitcoin script, without in any way increasing validation cost for nodes. To exercise this varops limit, I wrote an example script for performing RSA decryption on 4096-bit keys and it used about 1/4 of its varops limit.
Minor detail: LSHIFT and RSHIFT are poorly named due to big/little endian storage of numbers, so Rusty recommends renaming them to UP/DOWNSHIFT.
With these previously removed opcodes re-enabled and thanks to CAT and Schnorr Tricks
, bitcoin users will have the ability to lock their bitcoin based on the contents of the transaction spending it. This enables what are commonly called covenants. The problem is that the scripts to access these covenant locking conditions look like a crazy cat lady and a hoarder moved in together (yes, rot13maxi
, I'm looking at you). The only responsible thing to do now is to enable better ways to access the details of a spending transaction from script. Enter TX, TXHASH, and TXHASHVERIFY.
These opcodes help users of bitcoin script not to need expensive security audits just to know if they are validating the correct parts of a transaction.
Next on the agenda is a sighash system for this improved bitcoin script. Bitcoin currently has 6 signature hashing modes: ALL, SINGLE, and NONE; each with or without ANYONECANPAY. BIP118
has been trying for years to add 6 more (additional modes ANYPREVOUT and ANYPREVOUTANYSCRIPT alongside ANYONECANPAY). Why should bitcoin be so restrictive in how a user can sign their inputs for spending. Of course most wallets should use one of the common modes (typically ALL, also called DEFAULT in taproot), but additional flexibility has no real downside. If you can be tricked into signing a new mode, you could just as well have been tricked into signing your coins directly over to an attacker. The same field selectors used for TX, TXHASH, TXHASHVERIFY are proposed to be used for signature hashing, enabling granular selection of transaction fields to sign (with new 1-byte modes similar to existing signature hash modes).
On to numbers. Bitcoin's original scripts could operate on variable length integers, but currently they're limited to 32-bit signed integers. There's a proposal
to add 64-bit integer arithmetic, but Rusty proposes ditching signed numbers entirely in favor of variable length whole numbers. This eliminates the need for 3 opcodes (1NEGATE, NEGATE, ABS) and fits nicely into the varops cost model.
A few more details:
Originally bitcoin scripts could have constrained future output scripts, but taproot requires an elliptic curve operation and lexicographic sorting of big endian bytes to do that. Let's add TWEAKADD and BYTEREV (or just CHECKCONTRACTVERIFY
).
There are times where data other than parts of the transaction need to be signed, let's add CHECKSIGFROMSTACK
.
Finally, where will these new scripts fit into bitcoin? In the heady pre-conference summit, there was pretty wide agreement on using 33-byte segwit v1, defined to be identical to BIP341
except for having 33-byte keys with the lowest bit defining the key's parity, and the 2nd to lowest indicating that no internal key was used (i.e. the lower 32-bytes of the witness program are a taptree root hash, not a key). This idea seemed great, but subsequent discussions
are pushing me to think that restored script fits really well as a new leaf version in the existing taproot outputs. In that case, we'd add one more opcode INTERNALKEY
to mitigate the 32-byte "penalty" for using taproot with scripts only.
Conclusion?
Bitcoin is an amazing success story in open source software and community. Let's not let it stagnate, but keep it vibrant by improving its already amazing properties with restored (and renewed) script!
That's about all I've got. Thanks to everyone who was there for the amazing conference! Special thanks to Lisa, Walton, and Exfrog for putting on the amazing conference; Theresa and Jack for making lunch happen; Rusty Russel for inspiring everyone; and Jesse Posner for teaching me about FROST's DKG.