Witness Program
A witness program is the data field in a SegWit output that specifies spending conditions and version for segregated witness transactions.
Key Takeaways
- A witness program is the core data structure inside a SegWit output: it consists of a version byte (0 through 16) followed by 2 to 40 bytes of program data that define how the output can be spent.
- Version 0 supports two output types: P2WPKH (20-byte hash of a public key) and P2WSH (32-byte hash of a witness script). Version 1 introduced Taproot (P2TR) with key-path and script-path spending.
- The witness program design enables soft fork upgrades: versions 2 through 16 are reserved for future script systems, allowing Bitcoin to evolve without breaking older nodes.
What Is a Witness Program?
A witness program is the data payload inside a native Segregated Witness output that tells Bitcoin nodes how to validate spending conditions. Defined in BIP-141, it replaced the older script-based approach to encoding spending rules with a compact, versioned format that separates signature data (the "witness") from the transaction's main body.
Every native SegWit address encodes a witness program. When you see an address starting with bc1q or bc1p, the characters after the prefix represent a witness version followed by the witness program data. The version tells nodes which validation rules to apply, and the program data specifies the cryptographic conditions that must be satisfied to spend the output.
How It Works
A witness program lives inside a transaction output's scriptPubKey. Unlike legacy outputs that embed complex script logic, a witness program scriptPubKey contains only two elements:
- A version opcode:
OP_0(0x00) for version 0,OP_1(0x51) throughOP_16(0x60) for versions 1 through 16 - A direct data push of 2 to 40 bytes containing the witness program itself
When a node encounters a scriptPubKey matching this exact pattern, it recognizes it as a witness output and routes validation through the SegWit rules for the corresponding version, rather than executing the scriptPubKey as traditional Bitcoin Script.
scriptPubKey Structure
The encoding is minimal by design. Here is how the three standard witness program types appear in a transaction:
| Type | Version Opcode | Program Size | Hex Prefix | Total Size |
|---|---|---|---|---|
| P2WPKH | OP_0 (0x00) | 20 bytes | 0014 | 22 bytes |
| P2WSH | OP_0 (0x00) | 32 bytes | 0020 | 34 bytes |
| P2TR | OP_1 (0x51) | 32 bytes | 5120 | 34 bytes |
The scriptPubKey contains no other opcodes: no OP_CHECKSIG, no OP_EQUAL. The witness program pattern itself triggers special validation logic defined by the version number.
Example: Decoding a P2WPKH Output
# scriptPubKey (hex): 0014751e76e8199196d454941c45d1b3a323f1433bd6
#
# Breakdown:
# 00 -> OP_0 (witness version 0)
# 14 -> push 20 bytes (0x14 = 20 in decimal)
# 751e76... -> 20-byte HASH160 of the compressed public key
#
# This is a P2WPKH output. To spend it, the witness must
# contain exactly two items: <signature> <compressed-pubkey>
# where HASH160(pubkey) matches the 20-byte program.Version 0: P2WPKH and P2WSH
Witness version 0, activated with the SegWit soft fork in August 2017, defines two output types based on the length of the witness program data.
P2WPKH: 20-Byte Programs
A Pay-to-Witness-Public-Key-Hash output uses a 20-byte witness program containing the HASH160 (RIPEMD-160 of SHA-256) of a compressed public key. To spend it, the witness must contain exactly two items: a digital signature and the corresponding compressed public key. The node hashes the provided public key and verifies it matches the 20-byte program, then validates the signature.
P2WPKH is the SegWit equivalent of legacy P2PKH outputs but with lower transaction weight because the signature data moves to the witness section, which receives a 75% discount on fees.
P2WSH: 32-Byte Programs
A Pay-to-Witness-Script-Hash output uses a 32-byte witness program containing the SHA-256 hash of a witness script. To spend it, the witness includes the input stack items followed by the serialized witness script itself. The node hashes the provided script, verifies it matches the 32-byte program, then deserializes and executes the script against the stack.
P2WSH enables complex spending conditions like multisig, HTLCs, and timelocks within SegWit outputs. It is the SegWit equivalent of legacy P2SH, but uses SHA-256 instead of HASH160 for the script hash, providing 128-bit collision resistance instead of 80-bit.
Strict Length Rules
Version 0 enforces strict validation: if the witness program is not exactly 20 or 32 bytes, the transaction is invalid. This is a consensus rule that prevents ambiguous interpretation of version 0 outputs.
Version 1: Taproot (P2TR)
Witness version 1 was activated by the Taproot soft fork in November 2021 (block 709,632), defined across BIP-340, BIP-341, and BIP-342. A P2TR output contains a 32-byte witness program representing a tweaked x-only public key, and it supports two distinct spending paths.
Key-Path Spending
The simplest way to spend a P2TR output is key-path spending. The witness contains a single element: a 64- or 65-byte Schnorr signature that validates against the 32-byte output key. On-chain, this looks identical regardless of whether the output is backed by a single key, a MuSig2 aggregate key, or a FROST threshold signature: all produce the same compact, privacy-preserving single signature.
# P2TR key-path spend witness:
# [<64-or-65-byte Schnorr signature>]
#
# 64 bytes implies SIGHASH_DEFAULT (0x00)
# 65 bytes = 64-byte signature + explicit sighash byteScript-Path Spending
When the key-path is not usable (for example, when multiple parties must reveal their specific spending condition), a script-path spend reveals one leaf of a Taproot tree. The witness contains the script inputs, the script itself, and a control block:
# P2TR script-path spend witness:
# [<script input items> <script> <control block>]
#
# Control block (33 + 32m bytes, where m = Merkle path depth):
# Byte 0: (leaf_version & 0xFE) | output_key_parity_bit
# Bytes 1-32: internal public key (x-only, 32 bytes)
# Bytes 33+: Merkle proof (0 to 128 sibling hashes)The node verifies the Merkle proof by hashing the leaf (version + script), walking the path upward, computing the tweak, and confirming the result matches the output key. Only the executed script leaf is revealed on-chain: all other branches of the Taproot tree remain hidden.
Future Witness Versions (2 through 16)
BIP-141 reserves witness versions 2 through 16 for future upgrades. Under current consensus rules, outputs with these versions are treated as "anyone can spend": nodes accept them without inspecting the witness data. This design enables new script systems to be introduced via soft fork without requiring older nodes to upgrade.
When a new version activates, upgraded nodes begin enforcing the new rules while non-upgraded nodes continue treating those outputs as valid. This is the same mechanism that allowed Taproot (version 1) to activate smoothly in 2021: pre-Taproot nodes saw v1 outputs as spendable by anyone, while Taproot-aware nodes enforced the Schnorr signature and Merkle proof rules.
Address Encoding
Witness programs are encoded into human-readable addresses using Bech32 (version 0) or Bech32m (versions 1 through 16), as defined in BIP-173 and BIP-350. The address format embeds the witness version as the first data character and the witness program as the remaining characters.
| Version | Encoding | Address Prefix (mainnet) | Example Output Type |
|---|---|---|---|
| 0 | Bech32 | bc1q | P2WPKH, P2WSH |
| 1 | Bech32m | bc1p | P2TR |
| 2-16 | Bech32m | bc1z, bc1r, ... | Reserved for future use |
Bech32m was introduced by BIP-350 to fix a weakness in the original Bech32 checksum where inserting or deleting certain characters near the end of an address could go undetected. All witness versions above 0 use the corrected Bech32m checksum, while version 0 addresses retain the original Bech32 format for backward compatibility.
Why It Matters
The witness program design is foundational to Bitcoin's scalability and upgrade path. By separating the version from the program data, BIP-141 created a framework where entirely new script systems can be deployed through soft forks, each identified by a single version byte. This is how Bitcoin evolved from basic SegWit to Taproot without a contentious hard fork.
For Layer 2 protocols like the Lightning Network and Spark, witness programs are essential infrastructure. Lightning channels use P2WSH witness programs for commitment transactions and HTLCs, while Taproot's P2TR outputs enable more efficient simple Taproot channels that look like ordinary single-key spends when cooperatively closed. The witness discount applied to SegWit transactions also reduces the on-chain cost of these Layer 2 constructions.
Understanding witness programs is key to working with modern Bitcoin address types. For a deeper exploration of how address formats have evolved from P2PKH through P2TR, see the research article on Bitcoin address types from P2PKH to Taproot.
Use Cases
- Standard payments: every modern Bitcoin wallet generates witness program outputs (P2WPKH or P2TR) by default, benefiting from lower fees and improved privacy compared to legacy output types
- Complex spending conditions: P2WSH witness programs enable on-chain multisig, timelocked contracts, and hash-locked payments without revealing the script until spending time
- Taproot privacy: P2TR witness programs make all cooperative spends look identical on-chain, whether backed by a single key, a multisig aggregate, or an entire script tree
- Protocol upgrades: the versioned witness program framework allows Bitcoin to adopt new cryptographic schemes (such as post-quantum signatures) through future soft forks on versions 2 through 16
- Layer 2 efficiency: Lightning channels and other off-chain protocols use witness programs to minimize the on-chain footprint of funding and settlement transactions via the witness discount
Risks and Considerations
Version Confusion
Wallets and services must correctly identify the witness version to apply the right validation rules. Sending to a future witness version (2 through 16) that has not yet been activated means those funds are anyone-can-spend under current consensus: a miner could claim them. Most wallets refuse to send to unrecognized witness versions to prevent accidental fund loss.
Address Encoding Compatibility
The split between Bech32 (version 0) and Bech32m (version 1+) means that software must support both checksum algorithms. Older wallets that only implement Bech32 cannot send to P2TR addresses, which has caused compatibility friction during the Taproot adoption period. Services handling Bitcoin addresses should validate the encoding scheme against the witness version.
Strict Validation Asymmetry
Version 0 witness programs enforce strict length rules: only 20 or 32 bytes are valid, and any other length causes the transaction to fail. Version 1 currently only defines rules for 32-byte programs. This asymmetry means that the validation behavior differs across versions, and developers building on witness programs must understand which rules apply to each version.
This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.