On August 24, 2017, at 01:57 UTC, Bitcoin miner BTCC Pool mined block 481,824—the block at which Segregated Witness activated. Among its transactions was one that carried, in an OP_RETURN output, a message for posterity:
BIP141 o/ Hello SegWit :-) keep it strong! LLAP Bitcoin
That transaction—our specimen for this chapter—was the first SegWit transaction ever confirmed on the Bitcoin network. It marked the most significant upgrade to Bitcoin's transaction format since the genesis block: the separation of witness data from the transaction structure that the witness authenticates.
To understand why SegWit was necessary, we must understand what it fixed.
In pre-SegWit transactions, the scriptSig (unlocking script) is part of the serialized transaction data that gets hashed to produce the txid. But the scriptSig contains the signature—and ECDSA signatures have a property that makes this dangerous: for any valid signature \((r, s)\), the pair \((r, n - s)\) is also valid (where \(n\) is the curve order). A DER-encoded signature can also be padded or reformatted in ways that change the bytes without changing the mathematical validity.
This means a third party—a miner, a relay node, anyone who sees the transaction before it is confirmed—can modify the scriptSig, producing a valid transaction with a different txid.
Pre-SegWit, anyone could take a valid unconfirmed transaction, modify its scriptSig encoding (without invalidating the signature), recompute the txid, and rebroadcast it. Both the original and the mutated version are valid—only one can be confirmed, but the sender cannot predict which one. The sender's expected txid may never appear in the blockchain, even though the payment went through.
This was not merely a theoretical concern. Transaction malleability:
In February 2014, the Mt. Gox exchange cited transaction malleability as a factor in the loss of approximately 850,000 BTC. The precise role of malleability in the collapse remains debated—internal fraud appears to have been the primary cause—but the incident focused the Bitcoin community's attention on the malleability problem and accelerated the search for a solution.
Our specimen is the first SegWit transaction ever confirmed on Bitcoin, from block 481,824 (August 24, 2017). It is a P2SH-P2WPKH transaction—a SegWit spend wrapped in a P2SH shell for backward compatibility (explored in Chapter 10).
Txid:
8f907925d2ebe48765103e6845c06f1f2bb77c6adc1cc002865865eb5cfd5c1c†
This 302-byte transaction introduced a new element to Bitcoin's serialization: the two bytes between the version and the input count—the marker and flag—and the violet witness data between the outputs and the locktime. These are the hallmarks of a SegWit transaction.00 01
Pre-SegWit, a transaction was serialized as:
[version][inputs][outputs][locktime]
SegWit transactions add three new elements:
[version] [marker][flag][inputs][outputs] [witness][locktime]
The marker byte (0x00) and flag byte (0x01) appear immediately after the version field. Together they signal that this transaction contains witness data.
In a pre-SegWit transaction, the byte after the version is the input count (a varint). A zero input count (0x00) is invalid in legacy transactions—no transaction can have zero inputs. SegWit exploits this: when a parser encounters 0x00 as the "input count," it recognizes this as the SegWit marker and reads the next byte as the flag. This design ensures that SegWit transactions are unambiguously distinguishable from legacy ones without any protocol negotiation.
Old nodes that do not understand SegWit receive a stripped version of the transaction: the marker, flag, and witness fields are removed. What remains is a valid legacy transaction:
[version][inputs][outputs][locktime]
The stripped transaction has the same txid as the full SegWit transaction—because the txid is computed from the stripped form. This backward compatibility was the key design insight that allowed SegWit to be deployed as a soft fork: old nodes accept SegWit transactions without understanding the witness.
The witness field sits between the last output and the locktime. It contains one witness stack per input, in the same order as the inputs.
For our specimen (one input), the witness structure is:
| Hex | Element | Size |
|---|---|---|
02 | Item count | 2 items in this witness stack |
48 | Item 0 length | 72 bytes |
3045… c57401 | DER signature + SIGHASH_ALL | 72 bytes |
21 | Item 1 length | 33 bytes |
021e… c74fb | Compressed public key | 33 bytes |
Total witness: \(1 + 1 + 72 + 1 + 33 = 108\) bytes. In a pre-SegWit P2PKH transaction, these 105 bytes of signature and public key would sit inside the scriptSig. SegWit moves them to the witness, outside the data that determines the txid.
Every input in a SegWit transaction has its own witness stack, even if it is empty. A transaction with three inputs has three witness stacks. A legacy (non-SegWit) input has a witness stack with zero items: just the byte 00. This structure ensures that the witness field is always parseable regardless of input types.
SegWit introduced a second transaction identifier:
| Identifier | Computed From | Purpose |
|---|---|---|
| txid | Stripped transaction (no marker, flag, witness) | Backward-compatible identifier |
| wtxid | Full serialized transaction (including witness) | Witness commitment in blocks |
The txid is computed by double-SHA-256 hashing the stripped transaction—the same data that old nodes see. Modifying the witness (e.g., re-encoding a signature) does not change the txid. This is the malleability fix: the signature is no longer part of the txid preimage.
The wtxid hashes the full serialized transaction, including witness data. It is used in the witness commitment—a hash tree embedded in the coinbase transaction of each block—ensuring that miners commit to the exact witness data.
SegWit eliminates third-party malleability—an observer cannot change the txid by modifying the witness. But the transaction's creator can still produce a different signature (and therefore a different wtxid) before broadcasting. SegWit does not, and cannot, prevent the signer from changing their own signature.
SegWit replaced the simple "transaction size in bytes" with a more nuanced metric: weight.
weight = stripped_size × 3 + total_size
where:
stripped_size = serialized size without marker, flag, and witness (in bytes)total_size = full serialized size including all fields (in bytes)Equivalently, non-witness bytes count 4 weight units (WU) each, while witness bytes count 1 WU each. The maximum block weight is 4,000,000 WU (replacing the old 1,000,000-byte block size limit).
| Component | Value |
|---|---|
| Total size | 302 bytes |
| Marker + flag | 2 bytes |
| Witness data | 108 bytes |
| Stripped size | \(302 - 2 - 108 = 192\) bytes |
| Weight | \(192 \times 3 + 302 = 576 + 302 = 878\) WU |
| Virtual size (vsize) | \(\lceil 878/4 \rceil = 220\) vbytes |
Virtual size (vsize) converts weight back to a byte-like unit for fee estimation:
\[ \text{vsize} = \left\lceil \frac{\text{weight}}{4} \right\rceil \]
Fee rates are quoted in sat/vbyte. Our specimen paid \(189{,}000 \div 220 \approx 859\) sat/vbyte—an extraordinarily high fee rate, befitting the first SegWit transaction in history.
The 4:1 ratio between non-witness and witness weight units is not arbitrary. It reflects a deliberate economic design.
The UTXO set—the set of all unspent transaction outputs—must be held in memory by every full node. It is the most expensive data structure in Bitcoin. Non-witness data (outputs, scriptPubKeys) contributes to the UTXO set. Witness data (signatures, public keys) does not—it is validated once and can be pruned.
By making witness data 4\(\times\) cheaper in weight, SegWit incentivizes transaction structures that minimize UTXO-set growth. Signatures, which are large and can be discarded after validation, cost less. Outputs, which persist in every node's memory, cost more.
The practical impact is significant. A P2PKH transaction's scriptSig contains approximately 107 bytes: a push opcode and 72-byte DER signature, plus a push opcode and 33-byte compressed public key. A P2WPKH transaction moves the signature and public key to the witness, where they cost \(14\) the weight. For a standard 1-input, 2-output payment, this produces a fee savings of roughly 38%—the vsize drops from 226 to approximately 141 vbytes.
SegWit was specified across three BIPs,† each addressing a different layer:
| BIP | Layer | Purpose |
|---|---|---|
| 141 | Consensus | Defines witness structure, weight formula, witness programs, and validation rules. The core of SegWit. |
| 143 | Consensus | Defines a new transaction digest algorithm for signature verification. Fixes quadratic hashing and enables efficient signing. |
| 144 | Peer Services | Defines how SegWit transactions are serialized on the network, including the marker/flag bytes and witness field. |
BIP 143 deserves special attention because it solved a second problem beyond malleability: quadratic hashing. In pre-SegWit transactions, computing the signature hash required serializing the entire transaction for each input. For a transaction with \(n\) inputs, this produced \(O(n^2)\) hashing work—a denial-of-service vector for large transactions.
BIP 143 introduced a new digest algorithm where each input's signature hash can be computed in \(O(n)\) time by precomputing shared components (hash of all prevouts, hash of all sequences, hash of all outputs). These precomputed hashes are reused across inputs, eliminating the quadratic blowup.
0x00) and flag (0x01) bytes signal SegWit serialization. Old nodes receive a stripped transaction without these fields.This chapter introduced SegWit's format and economics. The next three chapters examine the transaction types it enables. Chapter 9 covers P2WPKH—native SegWit for single-key payments, with empty scriptSigs and bech32 addresses. Chapter 10 presents P2WSH—SegWit's replacement for P2SH, with larger script limits and witness-discounted multisig. Chapter 11 explores the backward-compatible wrappers (P2SH-P2WPKH and P2SH-P2WSH) that our specimen uses—the bridge between the legacy and SegWit worlds.
Exercises
0x00 used as the marker byte?Solutions
L1. The marker byte 0x00 and the flag byte 0x01.
L2. Because 0x00 as an input count is invalid in legacy transactions (no transaction can have zero inputs). When a parser encounters 0x00 after the version, it unambiguously identifies the transaction as SegWit, without protocol negotiation.
L3. 4 WU. Witness bytes cost 1 WU.
L4. 4,000,000 WU. This replaced the legacy 1,000,000-byte block size limit.
L5. The witness data (marker, flag, and per-input witness stacks). The txid is computed from the stripped transaction (without these fields).
H1. From the 302-byte hex:
00 01).02) + push 72 (48) + 72-byte sig + push 33 (21) + 33-byte pubkey \(= 1+1+72+1+33 = 108\) bytes.H2. The OP_RETURN payload (424950313431…) decodes to ASCII:
BIP141 o/ Hello SegWit :-) keep it strong! LLAP Bitcoin twitter.com/khs9ne
"LLAP" stands for Live Long and Prosper—the Vulcan salutation from Star Trek, popularized by Leonard Nimoy.
H3. Legacy P2PKH (226 bytes, no witness):
P2WPKH (223 bytes total, 113 bytes stripped):
Savings: \(226 - 141 = 85\) vbytes, a 37.6% reduction. At the same sat/vbyte fee rate, P2WPKH costs roughly 38% less.
H4. Fee: 189,000 sats. vsize: 220 vbytes. Fee rate: \(189{,}000 \div 220 \approx 859\) sat/vbyte.
P1. SegWit is a soft fork because old nodes can validate SegWit transactions without understanding the witness. A SegWit output's scriptPubKey (e.g., OP_0 <20 bytes>) is valid under old rules as an "anyone-can-spend" script—it evaluates to TRUE because the version byte (OP_0) pushes a value and the witness program is a data push, leaving a truthy value on the stack. Old nodes accept these transactions. New nodes apply additional validation rules (checking the witness). Since old nodes accept everything new nodes accept, no chain split occurs. This is a soft fork: a tightening of the rules, not a loosening.
P2. Pre-SegWit, signing input \(i\) required serializing the entire transaction (all inputs and outputs) with modifications for input \(i\). For \(n\) inputs, this required \(n\) full serializations, each \(O(n)\) in size, for a total of \(O(n^2)\) hashing work.
BIP 143 precomputes three hashes that are shared across all inputs:
hashPrevouts: double-SHA-256 of all input outpoints (txid + vout).hashSequence: double-SHA-256 of all input sequence numbers.hashOutputs: double-SHA-256 of all outputs (value + scriptPubKey).These three hashes are computed once (each \(O(n)\)) and reused for every input. Each input's signature hash then requires only \(O(1)\) additional work (combining the precomputed hashes with input-specific data). Total: \(O(n) + n \times O(1) = O(n)\).
P3. The txid is defined as the double-SHA-256 hash of the stripped transaction: version, inputs, outputs, and locktime. The witness data is not part of this serialization. Any modification to the witness (different signature encoding, different public key format) changes the witness bytes but not the stripped transaction. Since SHA-256 is deterministic, the same stripped bytes always produce the same hash. The txid is invariant under witness modifications.
C1. A Lightning payment channel is built on a 2-of-2 multisig funding transaction. Before SegWit, the funding txid could be malleated by a third party, invalidating all pre-signed commitment transactions (which reference the funding txid). With SegWit, the funding transaction's txid is immune to third-party modification (signatures are in the witness, excluded from the txid). Commitment transactions that reference this txid remain valid regardless of witness modifications. This stability is what makes trustless, pre-signed transaction chains possible.
C2. P2SH 2-of-3 multisig (from Chapter 7):
P2WSH 2-of-3 equivalent:
The witness data alone saves \(1,016 - 254 = 762\) WU, a 75% reduction in the signature/script weight.
B1. In native P2WPKH: (a) the scriptSig would be empty (0 bytes) instead of containing the 23-byte witness program push; (b) the prevout scriptPubKey would be OP_0 <20-byte key hash> (22 bytes) instead of a P2SH script (OP_HASH160 <20-byte script hash> OP_EQUAL, 23 bytes); (c) the address would start with bc1q (bech32) instead of 3 (Base58Check). The witness data (signature + pubkey) would be identical.
B2. Witness version 1 (Taproot, BIP 341†) enables: (a) Schnorr signatures (64 bytes, no DER encoding, batch-verifiable); (b) x-only public keys (32 bytes, saving 1 byte per key); (c) key-path spending (a single signature validates against the output key, with no script revealed); (d) script-path spending via a Merkle tree of TapScripts, revealing only the executed script leaf. Together, these allow complex spending conditions (multisig, timelocks, hash-locks) to be hidden behind a single public key that, in the common case, looks indistinguishable from a simple single-signature spend.