pk(KEY)BIP381 · DeployedProducesP2PK — <KEY> OP_CHECKSIG
Takes a single key expression and produces a pay-to-pubkey output script.
NestingAny context: top level, inside sh() or wsh(), and the original script expression allowed inside tr() TREEs.
Bitcoin accepted at checkout | Ships from Montreal, QC, Canada | Expert support since 2016
Descriptors are how modern Bitcoin wallets describe themselves: a compact text expression that names the exact script type, keys and derivation a wallet watches. They are also the piece most backups are missing. This reference covers every descriptor expression standardized in BIP-380 through BIP-392 — what each produces, where it may nest, and how mature its BIP is — plus the checksum and key-expression grammar underneath them all. It slots into our self-custody set beside the wallet recovery matrix and the address-types reference.
Quick answer
An output script descriptor is the modern, standardized way to tell Bitcoin software exactly which outputs a wallet can see and spend — a small text function like wpkh(xpub.../0/*) that replaces the old guesswork about script types. This reference covers every expression defined across BIP-380 through BIP-392 (17 entries): the output script each produces, its nesting rules, the defining BIP and that BIP's status — from the universally deployed pk()/wpkh()/tr() to the draft musig() (MuSig2) and sp() (silent payments) expressions. rawtr() is included and flagged for what it is: a Bitcoin Core extension no BIP defines.
The quick test: if your wallet backup does not contain its descriptors (or the information to reconstruct them), it is incomplete — a seed alone does not tell restoring software which scripts to look for. Export descriptors alongside the seed. Free CSV/JSON under CC BY 4.0; BIP statuses as of 2026-07-26.
Download CSV Download JSON REST API →
pk(KEY)BIP381 · DeployedProducesP2PK — <KEY> OP_CHECKSIG
Takes a single key expression and produces a pay-to-pubkey output script.
NestingAny context: top level, inside sh() or wsh(), and the original script expression allowed inside tr() TREEs.
pkh(KEY)BIP381 · DeployedProducesP2PKH — OP_DUP OP_HASH160 <KEY_hash160> OP_EQUALVERIFY OP_CHECKSIG
Takes a single key expression and produces a pay-to-pubkey-hash output script.
NestingTop level, or inside sh() or wsh(). Not allowed inside tr() trees.
sh(SCRIPT)BIP381 · DeployedProducesP2SH — OP_HASH160 <SCRIPT_hash160> OP_EQUAL
Takes a script expression and produces a P2SH output script; its argument's output script is the redeemScript needed to spend.
NestingTop level ONLY.
wpkh(KEY)BIP382 · DeployedProducesP2WPKH — OP_0 <KEY_hash160>
Takes a single key expression and produces a P2WPKH output script. Only compressed public keys are allowed.
NestingTop level, or inside sh() (P2SH-P2WPKH). Not allowed inside wsh().
wsh(SCRIPT)BIP382 · DeployedProducesP2WSH — OP_0 <SCRIPT_sha256>
Takes a script expression and produces a P2WSH output script; its argument's output script is the witnessScript. All keys under it must be compressed.
NestingTop level, or inside sh() (P2SH-P2WSH). Cannot nest inside another wsh().
multi(k,KEY_1,...,KEY_n)BIP383 · DeployedProducesMultisig — k KEY_1 ... KEY_n n OP_CHECKMULTISIG
Threshold multisig: k of n keys must sign, keys in the order given. Extended keys derive in lockstep (same child index).
NestingTop level (max 3 keys), inside sh() (max 15 compressed keys), or inside wsh() (max 20 keys).
sortedmulti(k,KEY_1,...,KEY_n)BIP383 · DeployedProducesSame multisig template as multi()
Identical to multi() except public keys are sorted lexicographically before script creation (after derivation).
NestingSame as multi(): top level, inside sh(), or inside wsh().
combo(KEY)BIP384 · DeployedProduces2 or 4 scripts: P2PK + P2PKH always; plus P2WPKH + P2SH-P2WPKH if the key is compressed
Compatibility descriptor producing every script traditionally generated by key-based wallets for one key.
NestingTop level ONLY.
raw(HEX)BIP385 · DeployedProducesThe literal script encoded by HEX
Encapsulates an arbitrary raw output script, given as hex, as a descriptor.
NestingTop level ONLY.
addr(ADDR)BIP385 · DeployedProducesThe output script produced by the address ADDR
Encapsulates any Bitcoin address as a descriptor.
NestingTop level ONLY.
tr(KEY) / tr(KEY,TREE)BIP386 · DeployedProducesP2TR — OP_1 <32_byte_output_key>
Produces a taproot output. tr(KEY) uses KEY as the BIP-341 internal key with an unspendable script path; tr(KEY,TREE) additionally commits to a taproot script tree whose merkle root tweaks the internal key. All keys must produce x-only keys; uncompressed keys are forbidden.
NestingTop level ONLY. TREE is either an allowed script expression or {TREE,TREE} pairs.
multi_a(k,KEY_1,...,KEY_n)BIP387 · DeployedProducesTapscript multisig — KEY_1 OP_CHECKSIG KEY_2 OP_CHECKSIGADD ... k OP_NUMEQUAL
Threshold multisig for tapscript using OP_CHECKSIGADD. Max 999 keys; extended keys derive in lockstep.
NestingONLY inside a tr() descriptor; invalid at top level, in sh(), or in wsh().
sortedmulti_a(k,KEY_1,...,KEY_n)BIP387 · DeployedProducesSame tapscript multisig template as multi_a()
Identical to multi_a() except x-only keys are sorted lexicographically before script creation (after derivation).
NestingONLY inside tr().
sp(KEY) / sp(KEY,KEY)BIP392 · DraftProducesP2TR outputs as computed for silent payments (BIP-352)
Descriptor for BIP-352 silent payments. sp(KEY) takes a Bech32m-encoded spscan (watch-only) or spspend key; sp(KEY,KEY) takes a private scan key plus any single-key spend expression (musig() allowed). Uncompressed keys forbidden.
NestingTop level ONLY.
rawtr(KEY)— (no BIP) · Bitcoin Core extension (since v24.0)ProducesP2TR — OP_1 <KEY as the output key directly>
Uses KEY directly as the taproot output key with no tweaking — no BIP defines it, but BIP-390 references it as a valid musig() context and Bitcoin Core supports it.
NestingTop level ONLY.
musig(KEY,...,KEY)BIP390 · DraftProducesNot a script — a key expression producing a BIP-327 MuSig2 aggregate public key
Aggregates the listed participant keys with BIP-327 KeyAgg after derivation, with mandatory KeySort before aggregation. A /NUM/.../* suffix does further unhardened BIP-328 derivation on the aggregate key (participants must then be xpubs without their own /* or multipath).
NestingKey-expression position only, inside tr(), rawtr(), or sp(); cannot nest inside another musig().
KEY/<NUM;NUM;...> (multipath)BIP389 · DraftProducesNot a script — expands one descriptor into N descriptors (one per tuple value)
One derivation step in an extended-key path may be a tuple; the descriptor is treated as multiple descriptors, commonly /<0;1> for receive/change. All multipath expressions in one descriptor must have equal tuple lengths; duplicates forbidden; one multipath specifier per key expression; not allowed in key origins.
NestingA modification of BIP-380 key expressions — usable wherever ranged extended keys are.
A top-level descriptor may end in # plus an 8-character checksum drawn from the bech32 charset — a BCH code that always detects 1 error, and up to 3 errors on descriptors as long as 49,154 characters. It is optional when parsing, but applications may reject checksumless descriptors. Key expressions accept: a compressed public key (66 hex, 02/03), uncompressed (130 hex, 04), a WIF private key, or an xpub/xprv with /NUM derivation steps (hardened: h or '), optionally ending /* (ranged: one script per child index) — all optionally preceded by a [fingerprint/path] key origin. tr() adds the 64-hex x-only form; BIP-389 adds multipath tuples; BIP-390 adds musig(); BIP-392 adds the Bech32m spscan/spspend encodings.
Source: the raw BIP texts (bitcoin/bips, bip-0380 through bip-0392, fetched 2026-07-26); statuses transcribed from the BIP headers. BIP-388 (wallet policies) defines no descriptor functions and BIP-391 is Closed — both deliberately excluded. Pairs with the wallet recovery matrix, the address-types reference and the P2P message reference.
Last reviewed July 26, 2026.
We use cookies to improve your experience and analyze site traffic. Privacy Policy
Choose which cookies you allow. Essential cookies are required for the site to function and cannot be disabled.
Required for basic site functionality, shopping cart, and security. Always active.
Help us understand how visitors use our site so we can improve your experience. Includes Google Analytics.
Used to deliver relevant ads and track campaign performance across platforms.