BIP 341 (Taproot)
Defines Taproot - SegWit version 1 outputs that use a tweaked x-only public key directly as the address, with no hash layer in front of the key.
BIP-341 defines Taproot - SegWit version 1 outputs that use a tweaked x-only public key directly as the address. Activated as a soft fork in November 2021 at block height 709,632, alongside BIP-340 (Schnorr signatures) and BIP-342 (Tapscript).
The headline structural choice: there is no hash layer in front of the public key. The bech32m address (the part starting with bc1p...) IS a 32-byte tweaked x-only pubkey, presented directly to anyone reading the chain. Earlier hashed-address types (P2PKH, P2WPKH) hide the pubkey behind a 160-bit hash until the address is spent. P2TR does not. Every P2TR output puts its key on chain at creation.
This choice is what makes every P2TR output look identical on the wire until it is spent - the script tree commitment is folded into the tweak rather than appearing as a separate hash layer - and it is also why P2TR outputs are "always-exposed" in post-quantum terms: the public key is forensically reachable from the moment the output is created, regardless of whether the output is ever spent.
The two spending paths
A P2TR output always commits to a public key (the "internal key") and optionally to a tree of alternative spending scripts (the "script paths"); a wallet that wants script-only spending uses an internal key nobody can sign for. The taproot tweak combines them into a single output key that doesn't reveal which paths exist.
- Key-path spend. A single Schnorr signature over the tweaked key. The witness contains a single 64-byte signature (65 bytes if a non-default sighash type is appended). Observers cannot tell whether script paths existed or what they would have been. This is the common case and the cheapest standard spend in Bitcoin: about 57.5 vbytes per input against 68 for P2WPKH.
- Script-path spend. Reveals one leaf of a Merkleized script tree, proves it was committed to in the tweak, and executes the leaf script under Tapscript. Other branches stay hidden. Pay for the branch you actually use.
Authored by Pieter Wuille, Jonas Nick, and Anthony Towns. The activation followed a "Speedy Trial" signaling window that opened on April 24, 2021 with an August 11 deadline; miners locked it in on June 12, 2021, and it took effect in November.
Spec: BIP-341.
See How Taproot Actually Works for the construction with a diagram and what each spending path reveals.
Key takeaways
- Defines the P2TR output type, where the bech32m address IS the tweaked public key
- Two spending paths: cooperative key-path (single Schnorr signature) or script-path (Merkle proof of one branch)
- Activated as a soft fork in November 2021 alongside BIP-340 (Schnorr) and BIP-342 (Tapscript)
Related chapters
On the mailing list
BIP 341 came up in 35 threads on bitcoin-dev between February 2020 and September 2026. Read them in the archive.
The topic timeline: Taproot and Schnorr (270 threads).
Corrected
-
Was: The entry said a key-path witness is 'exactly 64 bytes', called Speedy Trial an 'extended' signaling period, and said key-path and script-path spends look identical on the wire.
Now: BIP-341 allows a 64-byte signature, or 65 bytes when a non-default sighash type is appended, and it set the Speedy Trial signaling window to run only from April 24 to August 11, 2021. The corrected entry says both, and says it is the P2TR outputs that look identical until they are spent, not the two kinds of spend. Details
Sources (6)
- BIP-341 - Taproot: SegWit version 1 spending rules
- BIP-340 - Schnorr Signatures for secp256k1
- BIP-350 - Bech32m format for v1+ witness addresses
- Bitcoin Core - 0.21.1 release notes: Speedy Trial activation parameters for taproot (May 2021)
- Bitcoin Optech - Newsletter #153: Taproot locked in (June 16, 2021)
- Bitcoin Optech - Preparing for taproot: input sizes, 57.5 vbytes for P2TR key path against 68 for P2WPKH (2021)
External references (3)
Related terms (12)
Published . Revised . One correction logged for this page.
Edit this page on GitHub