B++ Logo

Segregated Witness (SegWit)

Segregated Witness (SegWit) is a major Bitcoin protocol upgrade activated in August 2017 (block 481,824). It separates signature (witness) data from transaction data, fixing transaction malleability and effectively increasing block capacity. SegWit was designed primarily by Pieter Wuille (BIP 141). SegWit separates the "witness" (signature data) from the transaction body, storing it in a separate structure. This fundamental change enables:

  • Malleability fix: Transaction IDs can no longer be changed after signing
  • Capacity increase: Effective block size up to ~4 MB (from 1 MB)
  • Fee reduction: Witness data costs less than transaction data
  • Lightning Network: Enables payment channels and off-chain scaling

The Problem SegWit Solved

Transaction Malleability

Before SegWit, anyone could modify a transaction's signature without invalidating it, changing the transaction ID:

Original Transaction:
TXID: abc123...

Modified (malleated) Transaction:
TXID: def456... (different ID, same validity)

Impact:

  • Made it impossible to build transactions that depend on unconfirmed transactions
  • Blocked development of payment channels (Lightning Network)
  • Created uncertainty in transaction tracking

Block Size Limit

The 1 MB block size limit created congestion:

Before SegWit:
- Block size: 1 MB maximum
- Transactions per block: ~2,000-3,000
- Network capacity: ~7 transactions/second

How SegWit Works

Transaction Structure

SegWit transactions have two parts:

Transaction:
├── Base Transaction (traditional structure)
│   ├── Version
│   ├── Inputs (without signatures)
│   ├── Outputs
│   └── Locktime
└── Witness Data (new, separate)
    └── Witness for each input

Witness Structure

Each input can have witness data:

Witness:
├── Number of witness elements (varint)
└── Witness elements (stack items)
    ├── Element 1 length (varint)
    ├── Element 1 data
    ├── Element 2 length (varint)
    └── Element 2 data

Weight Units

SegWit introduced weight units instead of bytes:

Weight = (Base Size × 4) + Total Size

Where:
- Base Size: Transaction without witness data
- Total Size: Transaction with witness data
- Block limit: 4,000,000 weight units

Effective capacity:

  • Non-SegWit: ~1 MB per block
  • All SegWit: ~2-4 MB per block (depending on witness ratio)

Address Types

P2WPKH (Pay-to-Witness-Pubkey-Hash)

Native SegWit addresses starting with bc1q:

Format: bc1q + 32 characters
Example: bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

P2WSH (Pay-to-Witness-Script-Hash)

SegWit version of P2SH for complex scripts:

Format: bc1q + 32 characters (longer)
Example: bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3

P2SH-P2WPKH (Nested SegWit)

Wrapped SegWit for backward compatibility:

Format: Starts with '3' (like P2SH)
Example: 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy

Code Examples

Creating a SegWit Transaction

Calculating Transaction Weight


Transaction ID vs. Witness Transaction ID

Before SegWit

TXID = SHA256D(serialized transaction)

Problem: Signature changes → TXID changes (malleability)

After SegWit

TXID = SHA256D(serialized transaction WITHOUT witness)
wtxid = SHA256D(serialized transaction WITH witness)

Key insight: TXID no longer includes witness data, so it can't be changed by signature modifications.


Benefits

1. Malleability Fix

Transactions can now safely reference unconfirmed transactions:

Before SegWit:
Parent TX: abc123... (unconfirmed)
Child TX: references abc123...
→ Parent gets malleated → def456...
→ Child TX becomes invalid!

After SegWit:
Parent TX: abc123... (TXID fixed, can't be changed)
Child TX: references abc123...
→ Always valid!

2. Effective Capacity Increase

Block Weight Limit: 4,000,000 weight units

Example block:
- Base size: 1,000,000 bytes
- Witness size: 1,500,000 bytes
- Total size: 2,500,000 bytes
- Weight: (1,000,000 × 4) + 2,500,000 = 6,500,000 weight units

But wait... that's over the limit!

Actual calculation:
- Base: 1,000,000 bytes = 4,000,000 weight units
- Witness: 1,500,000 bytes = 1,500,000 weight units
- Total weight: 5,500,000 (over limit)

Realistic SegWit block:
- Base: 1,000,000 bytes = 4,000,000 weight units
- Witness: 1,000,000 bytes = 1,000,000 weight units
- Total: 5,000,000 weight units (over limit)

Optimal SegWit block:
- Base: 1,000,000 bytes = 4,000,000 weight units
- Witness: 0 bytes = 0 weight units
- Total: 4,000,000 weight units (at limit)

With mixed transactions:
- ~2-3 MB effective capacity

3. Fee Savings

Witness data costs 1/4 the weight of base data:

Legacy transaction:
- 250 bytes total
- Fee: 250 bytes × fee_rate

SegWit transaction:
- 100 bytes base + 150 bytes witness
- Weight: (100 × 4) + 250 = 650 weight units
- Virtual size: 650 / 4 = 162.5 vbytes
- Fee: 162.5 vbytes × fee_rate (35% savings!)

Adoption

Current Usage

As of 2024:

  • ~80% of transactions use SegWit
  • Most wallets support SegWit addresses
  • Lightning Network requires SegWit

Migration Path

  1. P2SH-P2WPKH (wrapped): Backward compatible, starts with '3'
  2. P2WPKH (native): Best efficiency, starts with 'bc1q'
  3. P2TR (Taproot): Latest standard, starts with 'bc1p'

Technical Details

Witness Version

SegWit uses witness version 0:

Witness Program:
├── Version (1 byte): 0x00
└── Program (20 or 32 bytes)
    ├── 20 bytes: P2WPKH
    └── 32 bytes: P2WSH

Script Execution

SegWit changes script execution:

  1. Old: ScriptSig + ScriptPubKey executed together
  2. New: Witness script replaces ScriptSig, ScriptPubKey is minimal
P2WPKH ScriptPubKey:
OP_0 <20-byte hash>

Witness (replaces ScriptSig):
<signature> <pubkey>


Resources