Segwit was an upgrade to bitcoin that happened in 2017 at the climax of the block size wars. The block size wars had a bunch of conflicting voices, some of whom used inconsistent and false messaging. The consensus that emerged was basically "no hard fork, yes soft fork."
Some of the messaging of the block size wars gave this impression: a group of "big blockers" wanted to scale up on the base layer by raising the max block size from 1mb to 4mb. A second group of "small blockers" didn't want that, they wanted to scale in layers enabled by segwit. But this messaging was false because segwit also increased the max block size to ~4mb. But, importantly, segwit did that via a soft fork instead of a hard fork.
(Also, there was a group who wanted segwit without its block size increase. But this group didn't achieve consensus, and some of its members like to point out that, from their perspective, the liars won -- the liars being people said there would be no block size increase with segwit, even though there was, but these liars -- according to this group -- convinced the masses to run the bigger-blocks segwit soft fork through misleading narratives.)
As a refresher on what counts as a hard fork, a hard fork relaxes restrictions and a soft fork tightens them. Here's an analogy I found helpful back in the day: imagine you work at a company that requires everyone to wear a tie. One group of workers at this company decides to start a "red tie club." The club grows and grows and eventually everyone in the company joins it and they all wear red ties. The club is a soft fork -- an additional rule on top of the corporate rules, but it's perfectly compatible with the old rules. Non-members of the club don't think there's any difference -- everyone is still wearing a tie, which is all the corporation requires -- but club members know that if they want to stay in the club it has to be a red tie. If the group wanted to start a "no tie club" instead, that would require a hard fork: the company would have to lift the restriction that makes everyone wear a tie, otherwise the club couldn't form.
When block size increases were first proposed they were thought of as a hard fork. "Old nodes" reject blocks that are larger than 1mb. They would keep doing that unless their owners relaxed the rules (by downloading new software) -- and that's a hard fork. But the segwit people proposed a way to do a block size increase without relaxing the rules, and thus without a hard fork.
A block size increase can be a soft fork as long as unupgraded nodes only "see" 1mb of data. This was achieved in segwit by sending different blocks to segwit nodes and old nodes. If you run an old pre-segwit node, miners and segwit nodes send you a block that only contains part of each segwit transaction -- specifically, the part without the script that unlocks the money and lets the spender spend it. Sometimes I call the part they send you the "skeleton" of the transaction -- because it's missing the meat, which is the unlocking script.
Bitcoin transactions usually require the spender to supply a script that unlocks the money they want to spend. But this is not always required -- some people send their bitcoins to "anyone can spend" addresses which do not require a script to unlock them. There are several types of "anyone can spend" addresses, and the segwit soft fork took one of those "anyone can spend" address types and placed an additional restriction on it: instead of being "anyone can spend," you could only spend from it if you supplied a segwit script. Old nodes didn't see this rule, so they still think anyone can spend from the address. But they are fine with that -- someone who spends from it using a segwit script is still part of the "anyone" group, so from their perspective no rule was broken.
To recap, segwit did two things: first, it changed one of the "anyone can spend" address types into a "segwit address" type so that -- if you run a segwit node -- your node will only accept blocks containing transactions that spend from segwit addresses if the spending transaction uses a segwit script. Second, if an old node asks a segwit node for a block, it doesn't send it the real block, it sends it a block containing the skeletons of segwit transactions. Old nodes see these skeletons as perfectly valid, they just see people sending money out of "anyone can spend" addresses without a script (which is fine because you don't "need" a script to spend money from an "anyone can spend" address).
With these two changes in hand, it was safe to increase the block size for upgraded nodes. The scripts in segwit transactions can be pretty large, and if you do it carefully a single block can hold almost 4 mb of segwit script data. But this data isn't sent to old nodes, they only ever see 1 mb of "skeleton" transactions that are missing the large segwit scripts. By this method segwit achieved a block size increase without a hard fork.
Which is also why segwit literally means "segregated witness" funfact
reply
This is an exceptional piece of writing - I finally understand what happened back then. Out of curiosity, how would you describe Bitcoin Cash? A hard fork? Or something else entirely?
reply
It depends on who asked me to describe bitcoin cash and what the context was. In the context of this essay, bitcoin cash was activated via a hard fork. The bitcoin cash software is a modified fork of bitcoin which has changed several times since it was created. It now has 8mb blocks (I think) as well as single-sig covenants.
In the previous paragraph, the word fork is used in two different ways. When I say "modified fork of bitcoin" I mean what git users mean by the term fork: a piece of software that starts as a copy of another piece of software, but which can be modified without affecting the original. This meaning of fork has little in common with what the word fork means in the essay above, where it refers to modifying a set of rules.
reply
Thanks! I genuinely appreciate your detailed response - I learn something new on SN every day :)
reply
For those interested, the code for the soft fork in bitcoin core was merged in this code change in 2016.
When github displays a code change it highlights any code that was removed in red and it highlights any code that was added in green. The code that was removed says this:
/** The maximum allowed size for a serialized block, in bytes (network rule) */ static const unsigned int MAX_BLOCK_SIZE = 1000000;
The code that was added says this:
/** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */ static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4000000;
Notice that the block size used to be 1 megabyte but it changed to 4 megabytes. Segwit definitely included a block size increase.
reply
Turns out, when we say 1MB in bitcoin, we really mean 1MB (not 1 MiB).
I always thought it's using powers of 2 even though it's using MB instead of MiB.
Interesting!
reply