# Descriptors

Descriptors are a compact and semi-standard way to easily encode, or "describe", how scripts (and subsequently, addresses) of a wallet should be generated. They can be especially helpful when working with multisigs or even more complex scripts, where the structure of the script itself is not trivial. They are a big step forward in making wallets more portable across different tools and apps, because for the first time they create a common language to describe a full bitcoin script that developers can use and integrate in their software.

The ecosystem around descriptors is still very much in its early stage, but they are starting to see some adoption in Bitcoin Core (opens new window) and other projects. BDK aims to produce the first "Native Descriptor" Bitcoin library that can be used by developers to build their own "Native Descriptor Wallets" (opens new window).

# Compatibility Matrix

Below are some tables to highlight the differences between Bitcoin Core's descriptor support, rust-miniscript's one and BDK's.

# Key Types

Key Type BDK rust-miniscript Bitcoin Core
Hex PublicKey
WIF PrivateKey
Extended Keys (xpub/xprv)

# Script Types (top level)

Script Type BDK rust-miniscript Bitcoin Core
pk()
pkh()
wpkh()
sh(wpkh())
sh()
wsh()
sh(wsh())
combo()
addr()
raw()
Bare scripts

# Operators

Operator BDK rust-miniscript Bitcoin Core
pk()
pkh()
older()
after()
sha256()
hash256()
ripemd160()
hash160()
andor()
and_{v,b,n}()
or_{b,c,d,i}()
multi()
thresh()
sortedmulti()

# Modifiers

Script Type BDK rust-miniscript Bitcoin Core
a:
s:
c:
t:
d:
v:
j:
n:
l:
u:

For a more thorough description of these operators and modifiers see Sipa's Miniscript Page (opens new window) and Bitcoin Core's (opens new window).

# Examples

Some examples of valid BDK descriptors are:

Spending Policy Descriptor Address 0 Address 1
Static P2PKH pkh(cSQPHDBwXGjVzWRqAHm6zfvQhaTuj1f2bFH58h55ghbjtFwvmeXR) mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr
Static P2PKH, watch-only pkh(02e96fe52ef0e22d2f131dd425ce1893073a3c6ad20e8cac36726393dfb4856a4c) mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr mrkwtj5xpYQjHeJe5wsweNjVeTKkvR5fCr
P2WSH 2-of-2 with one private key wsh(multi(2,tprv8ZgxMBicQKsPePmENhT9N9yiSfTtDoC1f39P7nNmgEyCB6Nm4Qiv1muq4CykB9jtnQg2VitBrWh8PJU8LHzoGMHTrS2VKBSgAz7Ssjf9S3P/0/*,tpubDBYDcH8P2PedrEN3HxWYJJJMZEdgnrqMsjeKpPNzwe7jmGwk5M3HRdSf5vudAXwrJPfUsfvUPFooKWmz79Lh111U51RNotagXiGNeJe3i6t/1/*)) tb1qqsat6c82fvdy73rfzye8f7nwxcz3xny7t56azl73g95mt3tmzvgs9a8vjs tb1q7sgx6gscgtau57jduend6a8l445ahpk3dt3u5zu58rx5qm27lhkqgfdjdr
P2WSH-P2SH one key + 10 days timelock sh(wsh(and_v(vc:pk_h(tprv8ZgxMBicQKsPePmENhT9N9yiSfTtDoC1f39P7nNmgEyCB6Nm4Qiv1muq4CykB9jtnQg2VitBrWh8PJU8LHzoGMHTrS2VKBSgAz7Ssjf9S3P/0/*),older(1440)))) 2Mtk2nyS98MCi2P7TkoBGLaJviBy956XxB1 2MuEStKzYhqb5HCFgHz9153tZsL5sVqV5xC

# Implementation Details

BDK extends the capabilities of rust-miniscript (opens new window) by introducing the concept of an ExtendedDescriptor: it represents a descriptor that contains one or more "derivable keys" like xpubs or xprvs and can be "derived" from a normal Descriptor by deriving every single one of its keys. It is currently called "StringDescriptor" in the code, because it's implemented as a wrapped miniscript::Descriptor<String>.

ExtendedDescriptors are derived using a single index instead of a full derivation path: this is because normally most of the path is fixed and can be represented right after the xpub/xprv itself, and only the final index changes for each address. This is what's normally called a DescriptorExtendedKey in the codebase, it is represented with a similar syntax to Bitcoin Core's, such as:

[d34db33f/44'/0'/0']xpub6ERApfZwUNrhL.......rBGRjaDMzQLcgJvLJuZZvRcEL/0/*