• BTC$85,821.00+5.80%
  • ETH$2,757.84+5.28%
  • USDT$1.00+0.04%
  • BNB$797.50+5.22%
  • ICP$2.97+4.04%

Wallet Architecture

Output Descriptors

A descriptor is a precise, machine-readable statement of which scripts a wallet can spend. It replaced a collection of ad-hoc import formats that each carried their own assumptions, and it is the piece of information a restore needs alongside the seed itself.

The problem a descriptor solves

A wallet needs to know two things to be useful: the keys it controls, and the scripts those keys are meant to satisfy. The first is supplied by the seed. The second is a description of the spending conditions — a single key, a multisig arrangement, a timelocked path — and it is not contained in the seed. Before descriptors, that second piece of information was conveyed by a set of import formats that each encoded it differently and incompletely.

The practical failure this produced is well known. A user restores a wallet from a seed, the software derives keys, and the balance shows as zero because the software guessed the wrong script type or the wrong branch. The keys are correct and the funds are recoverable, but the wallet does not know what to look for. The import formats could not express the full range of scripts a wallet might use, so the information needed to reconstruct the wallet was simply absent.

A descriptor closes that gap by describing the script directly. It names the function — a single public key, a multisig threshold, a timelock — and supplies the key material or the derivation path for each participant. Because it is a complete statement rather than a partial hint, a wallet that is given the descriptor knows exactly which outputs to watch and how to spend them.

What a descriptor contains

A descriptor is written as a function applied to its arguments. A single-key native SegWit descriptor takes the form wpkh(...), where the argument is either a public key or a derivation path that produces one. A multisig descriptor wraps a threshold and a list of keys in sortedmulti(...) or multi(...), and the difference between the two is whether the keys are sorted before the script is built, which decides whether the descriptor is portable between wallets.

The function name also states the script type. pkh is legacy P2PKH, sh(wpkh(...)) is P2SH-wrapped SegWit, wpkh is native SegWit, and tr is Taproot. Because the script type is explicit, a wallet reading a descriptor does not have to guess which addresses to derive, which is precisely the guess that produced the empty-balance restore.

Descriptors can also carry a range. A descriptor that ends with a wildcard such as /0/* describes not one script but a family of them, one for each address index. That is how a descriptor covers a whole receiving branch rather than a single address, and it is what makes a descriptor a complete description of a wallet rather than of one output.

The checksum

A descriptor ends with an eight-character checksum, separated from the body by a hash. The checksum is not a security measure; it is a transcription guard. A descriptor is long enough that a single mistyped character is easy to miss, and a descriptor with a wrong character would derive a different set of scripts and produce a wallet that watches the wrong outputs. The checksum makes that failure immediate and visible rather than silent.

The checksum is computed from the descriptor body, so any change to the body changes the checksum. A wallet that validates the checksum before using a descriptor will reject a mistyped one outright. That is a small thing, but it is the difference between a restore that fails loudly and one that appears to succeed while showing an empty wallet — and the second is far more dangerous, because the user may conclude the funds are gone.

The checksum does not protect against a descriptor that is internally consistent but wrong — a correct checksum over the wrong derivation path, for instance. It guards transcription, not intention. The path convention covered on the previous page is still the thing that decides whether the descriptor describes the wallet the user actually had.

Sources and references

The description of the descriptor grammar, the function names and the checksum is taken from the Bitcoin Core documentation and the BIPs that define the script types a descriptor can name.