SegWit as a Soft Fork

Todays newsletter continues chapter 3 from Bitcoin: A Work in Progress.

The first Bitcoin, Explained episode of 2023 talks about timelocks.

Next month I’m flying to London to attend Advancing Bitcoin. If you’re also attending, be sure to use referral code libsecp256k1.

Little addendum from last week. As a reader pointed out, SegWit did not remove all malleability. The witness itself can still be manipulated, but this doesn’t change the transaction hash, and so doesn’t break a protocol like Lightning. But it can still cause headaches.

Meanwhile, I’m syncing the blockchain once again for debugging reasons.

SegWit as a Soft Fork

How could SegWit be deployed as a soft fork (backward-compatible upgrade)? The book dives more deeply into how soft forks work in chapter 12, but the basic idea is that upgraded nodes are aware of the new rules, while un-upgraded nodes don’t perceive a violation of the rules.

With SegWit this is achieved by appending data to the end of a block, kind of like a subblock, and not sending that data to legacy nodes. A hash of this data is added to the coinbase transaction in an OP_RETURN statement.

An OP_RETURN typically signifies that transaction verification is done, but it can be followed by text, which is then ignored. So old nodes just see an OP_RETURN statement, they don’t care what follows, and they won’t ask for the additional data. New nodes make an exception to this rule when it comes to the coinbase transaction, they do check the hash. A SegWit node verifies that the witness data is correct by comparing it to this hash. It also expects this extra data to be present, and will request it from other SegWit aware nodes if necessary.

Block Size Limit

Before SegWit, blocks had a one-megabyte limit, and that limit included the transaction data, plus all the signatures, plus a little bit of block header data. Today, because SegWit transactions put their signature data in a separate place that old nodes won’t see, blocks can be larger. Theoretically, they can be up to four megabytes, but in practice with typical transactions, it’s closer to two and a half.

Because the signature (witness) data is in a place that old nodes don’t see, we can bypass the one-megabyte block size limit without a hard fork. Old nodes will keep seeing a block with no more than one megabyte in it, but new nodes are aware of the witness data, which takes the total size well over one megabyte.

However the increase isn’t unlimited. SegWit nodes use a new way of calculating how data is counted, which gives a 75 percent discount to this segregated signature data. The percentage is somewhat arbitrary — enough to make SegWit transactions cheaper than their pre-SegWit counterparts, but not so much to incentivize abuse.

Future SegWit Versions, e.g. Taproot

The book coversTaproot in depth in chapter 11. But what’s important to know here is SegWit’s script versioning allows for easier upgrades to new transaction types, and the recent Taproot upgrade is the first example of this feature.

The versioning works as follows, which we touched on a few weeks ago in chapter 1. The output of each transaction contains the amount and something called the scriptPubKey. The latter is a piece of Bitcoin script that constrains how to spend this coin, as we briefly mentioned in chapter 1 and will explain in more detail in chapter 10. With SegWit, the scriptPubKey always starts with a number, which is interpreted as the SegWit version. The rules for interpreting SegWit version 0 are set in stone, as are those for interpreting SegWit version 1, aka Taproot. But anything following a 2 or higher is up for grabs: Those rules may be written later.

Before a new soft fork activates, anything following an unknown version number is ignored, thus it’s anyone-can-spend. As we’ll explain in chapter 12 one of the things that could go wrong with soft fork activation is that a majority of miners aren’t actually enforcing the new rules. But as long as most miners do enforce the new rules, they’ll ensure that these anyone-can-spend outputs, from the perspective of old nodes, won’t actually get spent.

Miners that run updated node software consider blocks that spend these coins invalid. And as long as they’re in the majority, they’ll also create the longest chain. So now the new nodes are happy because all the new rules are being followed, and the old nodes are happy because no rules are being broken from their perspective and they just follow the longest chain. So the network stays in consensus.