Unfuckening is a very tricky business. There is a lot that got fucked in ten long years and some things are so badly broken that they simply can’t be unbroken cleanly. The Bitcoin SV team has done an enormous amount of research, studying the existing and the original code extensively and it’s been a really steep learning curve. But we are feeling pretty confident in the roadmap we need to implement now. There are some pragmatic caveats though.
Let me give you one example. Arithmetic op codes. The original BitCoin used a number implementation that allowed numbers of arbitrary size. That is, it wasn’t restricted to 32 or 64 bit numbers like many systems are. 256 bit (and larger) numbers, which are really useful for cryptographic functions, were also able to be used. Quite early in Bitcoin’s history this was changed and restricted to 32 bit numbers along with the introduction of the horrific CScriptnum class. The removal of capability to do crypto math directly in script (without huge overhead) was a great loss to Bitcoin and it’s something we will unfuck next February. But the question is how?
Our next roadmap article will describe the upcoming changes to OP_RETURN because this is a change we want the Bitcoin ecosystem to be aware of as far in advance as possible. The mechanism of that change is what this post is about and the reason we explain it separately is because it is a concept we will be reusing in many ways. I could have incorporated it into the next post but it’s a subject that will come up over and over again so it’s worth giving it’s own post…
Converting an arithmetic system in a backward compatible way is a tricky thing to do with certainty. We can build tests until we are blue in the face but how will be sure we’ve covered every single edge case? Is it even possible to ensure all cases CAN be backward compatible? We don’t know. But we certainly care because one of the rules we live and breathe by in Bitcoin, the GOLDEN rule, is never make a spendable Bitcoin unspendable. NEVER. Not even by accident.
If you look at the history of Bitcoin this problem may not be as big as we think it is. There are less than 100 transactions in bitcoin history that actually use arithmetic op codes – that we can see. So couldn’t we just write tests to make sure all of those are spendable? Possibly (not in all cases though) but the bigger problem is pay to script hash transactions. P2SH has the interesting property that the content of the output script does not become visible on the blockchain until the time it is spent. That is in stark contrast to the original design where the locking script had to be posted publicly in the blockchain when it’s created. This causes some difficulty in respecting the ‘never make a spendable bitcoin unspendable’ principle. Because we cannot assume what is in P2SH scripts. We HAVE to assume that some of them contain arithmetic op codes and as such to be sure we need to write tests for every single possible usage and edge case to ensure backward compatibility. Many of those edge cases will not exist, in fact likely most. But we have no way of knowing which so we have no choice but to test for them all.
As I said earlier this is hard, maybe impossible to provably do.
The simple way around this is a principle that is in fact useful to us for many features beyond just the specific case of arithmetic op codes. Don’t even try to be backward compatible. We simply accept that a part of Bitcoin’s history has some broken stuff in it. We continue to support it with the view that one day, eventually, all of those broken outputs will be spent. Maybe that’s decades away but in time we will be able to deprecate the old code.
But how do we fix it if we keep supporting the old rules? Simple, we implement the new rules as of a certain point in time. Everything after that follows the new rules. Everything before follows the old rules. Most Bitcoin consensus changes use what we call ‘height based activation’. That is after the blockchain reaches a certain block height the new rules kick in. But this potentially breaks old transactions that follow the old rules. That imposes a huge burden on developers of a new change that effectively locks them into a set of restrictions that would look very much like what Bitcoin Core have previously called a “soft fork”. Soft forks are for numpties and we aren’t going to buy into that because they are unnecessarily restrictive when you’re trying to undo 10 years worth of damage.
So instead of just blanket implementing the new rules we make them conditional not on the current block height, but on the block height at the time the script was created. More specifically the block height at which the input UTXO you are trying to spend was mined into a block. This a very flexible activation mechanism. It means that all outputs created with arithmetic op codes will continue to be executed using the code that existed at the time they were created. If they were valid then, they are valid for all time regardless of which rule set they were designed for. Fortunately there isn’t a lot of tooling changes required for this in the ecosystem since arithmetic op codes are rarely used. But it is not the only change we plan to activate in this way. Pay to script hash itself will be deprecated this way. Old P2SH outputs will still be able to be spent using the P2SH semantics but after the sunset date (4th Feb 2020) new ones will be invalid (strictly speaking they will actually become a hash puzzle but that’s another story). These are two examples of how we will use UTXO height based activation to ensure a smooth and fully backward compatible pathway back to Genesis.