Segregated Witness (SegWit), activated in August 2017, changed the transaction format, the block limit, and the upgrade path simultaneously; no other soft fork has touched as many consensus structures at once. It fixed the long-standing transaction malleability bug, increased effective block capacity, enabled second-layer protocols, and established a framework for future upgrades. Within this volume, SegWit is also evidence: the existence proof for Chapter 26's theory of forks, a live consensus-critical change deployed as a strict restriction of the valid block set (Proposition 28.1). Its activation, from the stall of BIP-9 signaling to the BIP-91/BIP-148 endgame, played out the governance dynamics that Chapter 33 analyzes. This chapter provides a comprehensive technical analysis of SegWit's design, implementation, and implications.
28.1 The Malleability Problem
To understand SegWit, we must first understand the problem it solved: transaction malleability.
Definition 28.1 (Transaction Malleability)
Transaction malleability is the ability to modify a transaction's identifier (txid) without invalidating it. A transaction T' is a malleated version of T if:
- T and T' spend the same inputs
- T and T' create the same outputs
- Both are valid according to consensus rules
- txid(T) ≠ txid(T')
Remark 28.1 (Pre-SegWit Malleability Sources)
In pre-SegWit Bitcoin, the txid was computed over the entire transaction including signatures. Several malleability vectors existed:
- ECDSA signature malleability: (r, s) and (r, n−s) are both valid
- Script push opcodes: Multiple ways to push same data
- Extra data in scriptSig: Additional stack elements
- SIGHASH_SINGLE bug: Edge case producing predictable signatures
Example 28.1 (ECDSA Signature Malleability)
An ECDSA signature is a pair (r, s) where s can be replaced with n − s (mod n) to produce an equivalent valid signature:
Original: sig = (r, s) where s < n/2 Malleated: sig = (r, n − s) where n − s > n/2 Verification computes: R = (z·s⁻¹)·G + (r·s⁻¹)·P With s' = n − s: R' = (z·s'⁻¹)·G + (r·s'⁻¹)·P = −R Since R'.x = R.x (negation preserves x), both pass.
Bitcoin Core's low-S standardness rule (proposed for consensus as BIP-146, which never activated) requires s ≤ n/2 as relay policy; SegWit removed signatures from the txid entirely.
Remark 28.2 (Impact of Malleability)
Malleability caused real problems:
- Mt. Gox claims: Blamed malleability for losses (disputed)
- Lightning Network: Impossible without txid stability
- Atomic swaps: Broken by malleated refund transactions
- Blockchain analysis: Complicated transaction tracking
28.2 The SegWit Solution
SegWit's key insight is to remove signature data from the txid computation by segregating it into a separate structure.
Definition 28.2 (Witness)
The witness is a new transaction component containing signature and script data. For each input i:
- Legacy: Signature in scriptSig
- SegWit: Signature in witness[i], scriptSig empty
Definition 28.3 (SegWit Transaction Structure)
A SegWit transaction has the following serialization:
[version] 4 bytes [marker] 1 byte (0x00) - indicates SegWit [flag] 1 byte (0x01) [input count] varint [inputs] variable [output count] varint [outputs] variable [witness] variable (one stack per input) [locktime] 4 bytes
Theorem 28.1 (SegWit Malleability Fix)
For transactions whose inputs all spend witness programs, the txid is computed excluding witness data:
txid = SHA256d(version || inputs || outputs || locktime)
Since all signatures are in the witness (not included), third-party malleability is impossible. (A transaction with even one legacy input keeps that input's malleable scriptSig inside the txid.) The transaction creator can still change their own signatures, but this is by design.
28.3 Witness Programs and Script Versioning
SegWit introduced a new output type identified by a specific pattern.
Definition 28.4 (Witness Program)
A witness program is a scriptPubKey of the form:
OP_n <data> where: OP_n = witness version (OP_0 through OP_16) data = 2-40 byte push
Definition 28.5 (Native SegWit Output Types)
Version 0 (BIP-141) defines two program types:
- P2WPKH: OP_0 <20-byte-key-hash>
- P2WSH: OP_0 <32-byte-script-hash>
Version 1 (BIP-341, Taproot) defines:
- P2TR: OP_1 <32-byte-x-only-pubkey>
Remark 28.3 (Script Versioning and Future Soft Forks)
Witness versions enable future soft forks:
- Old nodes see "OP_n <data>" as anyone-can-spend (but do not relay)
- New nodes interpret based on version number
- New versions can be given semantics by a tightening soft fork without breaking old nodes—an activation is still required (Taproot activated witness v1 via Speedy Trial), but never a hard fork
Versions 2–16 are reserved for future upgrades that remain backwards-compatible with existing nodes.
28.4 Block Weight and Capacity
SegWit replaced the block size limit with a more nuanced "weight" system.
Definition 28.6 (Block Weight)
Block weight is calculated as:
weight = 3 × base_size + total_size
Equivalently:
weight = base_size × 4 + witness_size × 1
Maximum block weight: 4,000,000 weight units (WU).
Definition 28.7 (Virtual Bytes)
Virtual bytes (vbytes) convert weight to a size metric:
vbytes = ⌈weight / 4⌉
Maximum block: 4,000,000 / 4 = 1,000,000 vbytes.
Example 28.2 (Weight Calculation)
Consider a SegWit transaction:
| Component | Size (bytes) | Weight Factor | Weight (WU) |
|---|---|---|---|
| Version | 4 | ×4 | 16 |
| Marker + Flag | 2 | ×1 | 2 |
| Inputs (no scriptSig) | 41 | ×4 | 164 |
| Outputs | 34 | ×4 | 136 |
| Witness | 107 | ×1 | 107 |
| Locktime | 4 | ×4 | 16 |
| Total | 192 | 441 |
vbytes = ⌈441/4⌉ = 111 vbytes (vs 192 actual bytes). (Input/output count varints are omitted for clarity; a complete serialization adds 2 base bytes.)
Remark 28.4 (SegWit Capacity Increase)
SegWit increases effective block capacity:
- All legacy: ~1 MB (1,000,000 bytes = 4,000,000 WU)
- All P2WPKH: ~2.1 MB (~7,000 transactions)
- All P2WSH multisig: ~3.7 MB
- Theoretical max: ~4 MB (all witness data)
Real-world blocks average 1.5–2 MB with current usage patterns.
Remark 28.5 (Discount Rationale)
The 75% witness discount serves multiple purposes:
- UTXO efficiency: Witness data is not stored in the UTXO set
- Verification efficiency: Witness data only validated once
- Adoption incentive: SegWit transactions are cheaper
- Backward compatibility: Old nodes see ~1 MB base size
28.5 The Witness Commitment
Witness data must be committed to in blocks for validation, but the existing Merkle tree is computed over txids (which exclude witness data).
Definition 28.8 (Witness Root)
The witness root is a Merkle root computed from wtxids (witness transaction IDs), which include witness data:
wtxid = SHA256d(serialized tx with witness)
For the coinbase: wtxid = 0x00...00 (32 zero bytes).
Definition 28.9 (Witness Commitment)
The witness commitment is placed in an OP_RETURN output of the coinbase transaction:
scriptPubKey = 0x6a 0x24 0xaa21a9ed || commitment
│ │ │
│ │ └─ 4-byte commitment header
│ └─ push of 36 bytes
└─ OP_RETURN
commitment = SHA256(SHA256(witness_root || witness_reserved_value))
28.6 The Soft Fork Mechanism
SegWit was deployed as a soft fork through careful design that made SegWit outputs appear spendable to old nodes.
Proposition 28.1 (SegWit as Soft Fork)
SegWit is a soft fork in the sense of Definition 26.5: every block valid under SegWit rules is valid under pre-SegWit rules, so Rnew ⊂ Rold.
Proof.
As seen by a pre-SegWit node (which receives blocks with witness data stripped), a SegWit-valid block differs from a pre-SegWit block only in two places. First, spends of witness programs (OP_0 <data>) carry an empty scriptSig; the old node evaluates the scriptPubKey as two pushes, leaving a non-zero top stack element, so the script succeeds ("anyone can spend"). Second, the witness commitment is an OP_RETURN output in the coinbase, which old rules permit. Since SegWit rules only add constraints (a valid witness must be supplied; weight ≤ 4,000,000 WU implies base size ≤ 1,000,000 bytes), every SegWit-valid block satisfies all old rules: Rnew ⊆ Rold. The containment is strict because a block spending a witness program without a valid witness lies in Rold but not Rnew. □
Miners with majority hash power enforce the new rules, rejecting invalid SegWit spends; old nodes accept the resulting chain since all of its blocks are valid under the old rules (Theorem 26.2).
Remark 28.6 (Policy Protection)
Before SegWit activation, Bitcoin Core made SegWit outputs non-standard as policy. This prevented anyone from claiming "anyone can spend" outputs before new consensus rules were enforced.
Example 28.3 (SegWit Activation Timeline)
| Date | Event |
|---|---|
| December 2015 | BIP-141/143/144 proposed |
| October 2016 | Bitcoin Core 0.13.1 released (SegWit ready) |
| November 2016 | BIP-9 signaling begins |
| March 2017 | Signaling stalls at ~30% |
| May 2017 | UASF (BIP-148) announced |
| July 2017 | Signaling rapidly reaches 95% |
| August 8, 2017 | SegWit locks in (block 479,808) |
| August 24, 2017 | SegWit activates (block 481,824) |
28.7 Sighash Changes (BIP-143)
SegWit introduced an improved signature hash algorithm addressing several issues.
Definition 28.10 (BIP-143 Sighash)
For SegWit inputs, the sighash is computed as:
SHA256d(
nVersion ||
hashPrevouts || ← SHA256d of all input outpoints
hashSequence || ← SHA256d of all input sequences
outpoint || ← this input's outpoint
scriptCode || ← spending script
amount || ← value being spent (not committed pre-SegWit)
nSequence || ← this input's sequence
hashOutputs || ← SHA256d of all outputs
nLocktime ||
sighashType
)
Remark 28.7 (BIP-143 Improvements)
BIP-143 sighash fixes multiple issues:
- O(n²) hashing eliminated: Pre-computed hashes reused
- Amount committed: Prevents value manipulation attacks
- Script committed: Prevents scriptPubKey substitution
- Consistent algorithm: Same process for all input types
Example 28.4 (O(n²) Attack Prevention)
In legacy sighash, each signature hashes the entire transaction. A transaction with n inputs requires n signatures, each hashing O(n) data → O(n²) total hashing.
An attacker could create transactions with many inputs to DoS nodes. BIP-143 pre-computes hashPrevouts and hashOutputs once, making the cost O(n).
28.8 Wrapped SegWit (P2SH-P2WPKH/WSH)
For backward compatibility with wallets that could not generate bech32 addresses, SegWit can be wrapped in P2SH.
Definition 28.11 (P2SH-Wrapped SegWit)
P2SH-P2WPKH wraps a SegWit program in P2SH:
scriptPubKey: OP_HASH160 <hash> OP_EQUAL redeemScript: OP_0 <20-byte-key-hash> witness: <sig> <pubkey>
Address format: starts with '3' (vs 'bc1' for native).
Remark 28.8 (Wrapped vs Native Efficiency)
Wrapped SegWit is less efficient than native:
| Type | vbytes (1-in-2-out) | Address Format |
|---|---|---|
| P2PKH (legacy) | ~226 | 1... |
| P2SH-P2WPKH | ~167 | 3... |
| P2WPKH (native) | ~141 | bc1q... |
| P2TR (Taproot) | ~154 | bc1p... |
28.9 SegWit Adoption
SegWit adoption has been gradual but substantial.
Example 28.5 (Adoption Metrics)
| Date | SegWit TX % | SegWit Spend % |
|---|---|---|
| August 2017 | 0% | 0% |
| January 2018 | ~15% | ~10% |
| January 2020 | ~50% | ~60% |
| January 2024 | ~85% | ~90% |
Percentages are approximate, per transactionfee.info (accessed 2026).
Remark 28.9 (Adoption Drivers)
SegWit adoption accelerated due to:
- Fee savings: ~26–38% reduction for single-signature transactions at equal feerate (from the vbyte figures of Remark 28.8), up to ~70% for multisig-heavy usage
- Exchange adoption: Major exchanges added bech32
- Wallet updates: Most wallets now default to SegWit
- Lightning requirement: LN channels require SegWit
- Taproot momentum: Taproot requires SegWit foundation
28.10 Enabling Layer 2
Beyond malleability fixes, SegWit was essential for second-layer protocols.
Remark 28.10 (Lightning Network Prerequisite)
Lightning Network channels require non-malleable transaction IDs because:
- Funding transaction creates 2-of-2 multisig output
- Commitment transactions spend this output (reference funding txid)
- If funding txid could be malleated, commitments become invalid
- Funds locked in the channel become hostage to the counterparty's cooperation
SegWit's fixed txid makes channels safe to open before funding confirms.
Remark 28.11 (Other Layer 2 Benefits)
SegWit enables multiple second-layer constructions:
- Lightning Network: Payment channels
- Statechains: UTXO ownership transfer
- DLCs: Discreet Log Contracts
- Submarine Swaps: On/off-chain atomic swaps
- Channel Factories: Multi-party channels
Exercises
Exercise 28.1
Calculate the weight and vbytes for a transaction with 2 P2WPKH inputs and 2 P2WPKH outputs. Assume standard sizes: 32-byte txid, 4-byte vout, 4-byte sequence, 71-byte signature, 33-byte pubkey.
Exercise 28.2
Explain why P2WSH uses SHA256 (32 bytes) while P2WPKH uses HASH160 (20 bytes). What security consideration drives this difference?
Exercise 28.3
Show that the pre-SegWit sighash algorithm has O(n²) complexity for n inputs. Then show how BIP-143 achieves O(n).
Exercise 28.4
Design an attack that would have been possible against Lightning without SegWit. How much could an attacker steal?
Exercise 28.5
If the witness discount were 90% instead of 75% (i.e., witness weight factor of 0.4 instead of 1), what would be the maximum possible block size? What are the tradeoffs?