BitcoinDev Logo

Output Descriptors

Output descriptors (BIP 380, BIP 386) are a standardized, human-readable way to describe which output scripts and addresses a wallet can generate. They encode script type, keys, and derivation paths in a single string, so wallets can interoperate, export watch-only setups, and back up "what to derive" without ambiguity. This guide covers descriptor syntax, common script expressions, key expressions, and how to use them in code. For policies that compile to Script, see Miniscript.

What Descriptors Solve

Traditional backups (e.g. BIP 39 mnemonic) describe keys but not which script types or paths to use. After SegWit and Taproot, "restore from seed" could mean P2PKH, P2WPKH, P2TR, or custom scripts. Descriptors make this explicit: one string describes the script type and key derivation, so different software can derive the same addresses.

Descriptor Structure

A descriptor typically has:

  1. Script expression: e.g. wpkh, wsh, tr, sh(wpkh(...))
  2. Key expression: e.g. xpub with derivation path
  3. Optional checksum: 8 characters after # for error detection

Example (BIP 84 single-sig):

wpkh([d34db33f/84h/0h/0h]xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJk7yd2j1uGcfFG9CP3Xk41B5kkEWpa/0/*)#checksum

Common Script Expressions

ExpressionMeaning
pk(key)Pay to raw public key
pkh(key)Pay to public key hash (P2PKH)
wpkh(key)Pay to witness public key hash (P2WPKH)
sh(script)Pay to script hash (P2SH); inner script can be wpkh, wsh, etc.
wsh(script)Pay to witness script hash (P2WSH)
tr(key) or tr(key, tree)Taproot output (key or key + script tree)
multi(n, key1, key2, ...)M-of-N multisig (inside sh or wsh)

Key expressions can be: raw pubkey, xpub/xprv with path (e.g. /0/* for receive, /1/* for change), or a descriptor (for nested sh(wsh(...))).

Key Expressions and Derivation

  • xpub / xprv: BIP 32 extended key; path like [fingerprint/84h/0h/0h]xpub.../0/* means receive addresses, /1/* means change.
  • Origin: The part in [] (e.g. [d34db33f/84h/0h/0h]) is the key origin; optional but recommended for PSBT and hardware wallets.
  • Checksum: Append # plus 8-character checksum so typos can be detected; Bitcoin Core's getdescriptorinfo adds it.

Parsing and Validating Descriptors

Deriving Addresses from a Descriptor

Bitcoin Core RPCs: getdescriptorinfo (validate and add checksum), deriveaddresses (derive addresses for an index range), importdescriptors (import watch-only or with keys). Other libraries (e.g. BDK, rust-bitcoin with descriptor support) derive addresses locally.

Use Cases

  • Watch-only wallets: Export an xpub descriptor (no private keys); another app can derive addresses and watch the blockchain. See Blockchain Monitoring.
  • Backup and restore: One descriptor string (with origin and path) tells any compatible wallet which script type and derivation to use.
  • Hardware wallet interoperability: Devices like COLDCARD export descriptors; software imports them for receive/change addresses and PSBT signing.
  • Scanning: Bitcoin Core's scantxoutset accepts a descriptor to find UTXOs that match, without importing keys.

Relation to Miniscript

Miniscript compiles policies to Script; the result is often wrapped in a descriptor (e.g. wsh(miniscript_expression) or Taproot). So: policy → Miniscript → Script → descriptor. Descriptors can also contain raw script (e.g. raw(...) in Core) or Miniscript fragments.

  • Key Management - HD keys and derivation paths
  • Address Generation - Address types and encoding
  • Miniscript - Policy to script and descriptors
  • PSBT - Descriptors in PSBT global map and inputs

Resources