Progress pill
Creation of Bitcoin Wallets

Output script descriptors

Bitcoin Wallet Architecture

Output script descriptors

  • What is a "descriptor"?
  • Construction of a descriptor
You are often told that the mnemonic phrase alone is sufficient to recover access to a wallet. In reality, things are a bit more complex. In the previous chapter, we looked at the derivation structure of the HD wallet, and you may have noticed that this process is quite complex. Derivation paths tell software which direction to follow to derive the user's keys. However, when recovering a Bitcoin wallet, if one does not know these paths, the mnemonic phrase alone is not enough. It allows obtaining the master key and the master chain code, but it is then necessary to know the indexes used to reach the child keys.
Theoretically, it would be necessary to save not only the mnemonic phrase of our wallet but also the paths to the accounts we use. In practice, it is often possible to regain access to the child keys without this information, provided that the standards have been followed. By testing each standard one by one, it is generally possible to regain access to the bitcoins. However, this is not guaranteed and it's especially complicated for beginners. Also, with the diversification of script types and the emergence of more complex configurations, this information could become difficult to extrapolate, thus turning this data into private information and difficult to recover by brute force. This is why an innovation has recently been introduced and is starting to be integrated into your favorite wallet software: the output script descriptors.

What is a "descriptor"?

The "output script descriptors", or simply "descriptors", are structured expressions that fully describe an output script (scriptPubKey) and provide all the necessary information to follow the transactions associated with a particular script. They facilitate the management of keys in HD wallets by offering a standardized and complete description of the wallet structure and the types of addresses used.
The main advantage of descriptors lies in their ability to encapsulate all the essential information to restore a wallet in a single string (in addition to the recovery phrase). By saving a descriptor with the associated mnemonic phrases, it becomes possible to restore the private keys by knowing precisely their position in the hierarchy. For multisig wallets, whose backup was initially more complex, the descriptor includes the xpub of each factor, thus ensuring the possibility of regenerating the addresses in case of a problem.

Construction of a descriptor

A descriptor consists of several elements:
  • Script functions such as pk (Pay-to-PubKey), pkh (Pay-to-PubKey-Hash), wpkh (Pay-to-Witness-PubKey-Hash), sh (Pay-to-Script-Hash), wsh (Pay-to-Witness-Script-Hash), tr (Pay-to-Taproot), multi (Multisignature), and sortedmulti (Multisignature with sorted keys);
  • Derivation paths, for example, [d34db33f/44h/0h/0h] which indicates a derived account path and a specific master key fingerprint;
  • Keys in various formats such as hexadecimal public keys or extended public keys (xpub);
  • A checksum, preceded by a hash sign, to verify the integrity of the descriptor.
For example, a descriptor for a P2WPKH (SegWit v0) wallet could look like:
wpkh([cdeab12f/84h/0h/0h]xpub6CUGRUonZSQ4TWtTMmzXdrXDtyPWKiKbERr4d5qkSmh5h17C1TjvMt7DJ9Qve4dRxm91CDv6cNfKsq2mK1rMsJKhtRUPZz7MQtp3y6atC1U/<0;1>/*)#jy0l7nr4
In this descriptor, the derivation function wpkh indicates a script type Pay-to-Witness-Public-Key-Hash. It is followed by the derivation path that contains:
  • cdeab12f: the master key fingerprint;
  • 84h: which signifies the use of a BIP84 purpose, intended for SegWit v0 addresses;
  • 0h: which indicates that it is a BTC currency on the mainnet;
  • 0h: which refers to the specific account number used in the wallet.
The descriptor also includes the extended public key used in this wallet:
xpub6CUGRUonZSQ4TWtTMmzXdrXDtyPWKiKbERr4d5qkSmh5h17C1TjvMt7DJ9Qve4dRxm91CDv6cNfKsq2mK1rMsJKhtRUPZz7MQtp3y6atC1U
The notation /<0;1>/* indicates that the descriptor can generate addresses from both the external chain (0) and the internal chain (1). The wildcard character (*) at the end of the path means that, sequentially, all non-hardened (“unhardened”) child keys can be derived from this position, whether they are external or internal addresses. This syntax does not directly imply the concept of gap limit, which is part of a wallet-specific mechanism for address detection, but here only serves to indicate that all possible derivations at this position are considered.
Finally, #jy0l7nr4 represents the checksum to verify the integrity of the descriptor.
You now know everything about the operation of HD wallets in Bitcoin and the process of deriving key pairs. However, in the last chapters, we limited ourselves to the generation of private and public keys, without addressing the construction of receiving addresses. This will precisely be the subject of the next chapter!
Quiz
Quiz1/5
What does the notation /<0;1>/* in a descriptor correspond to?