Skip to content

Commit 35d7d94

Browse files
committed
Merge #14096: Add reference documentation for descriptors language
2b5d6f8 Replace duplcate reference with reference to reference doc (Pieter Wuille) 89709db Adjust TODO link (Pieter Wuille) 9254ffc Add descriptor reference documentation (Pieter Wuille) Pull request description: Tree-SHA512: 1ca0d537f9bcbb23266e9a4a02a60013ef8309958fb701f638283887585b5ddea6bc9dab859454ec3a373b1a12a4fd69836e7030417bb2ca43fef26b104c0d65
2 parents a6aca8d + 2b5d6f8 commit 35d7d94

File tree

3 files changed

+127
-50
lines changed

3 files changed

+127
-50
lines changed

doc/descriptors.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Support for Output Descriptors in Bitcoin Core
2+
3+
Since Bitcoin Core v0.17, there is support for Output Descriptors in the
4+
`scantxoutset` RPC call. This is a simple language which can be used to
5+
describe collections of output scripts.
6+
7+
This document describes the language. For the specifics on usage for scanning
8+
the UTXO set, see the `scantxoutset` RPC help.
9+
10+
## Features
11+
12+
Output descriptors currently support:
13+
- Pay-to-pubkey scripts (P2PK), through the `pk` function.
14+
- Pay-to-pubkey-hash scripts (P2PKH), through the `pkh` function.
15+
- Pay-to-witness-pubkey-hash scripts (P2WPKH), through the `wpkh` function.
16+
- Pay-to-script-hash scripts (P2SH), through the `sh` function.
17+
- Pay-to-witness-script-hash scripts (P2WSH), through the `wsh` function.
18+
- Multisig scripts, through the `multi` function.
19+
- Any type of supported address through the `addr` function.
20+
- Raw hex scripts through the `raw` function.
21+
- Public keys (compressed and uncompressed) in hex notation, or BIP32 extended pubkeys with derivation paths.
22+
23+
## Examples
24+
25+
- `pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)` represents a P2PK output.
26+
- `pkh(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)` represents a P2PKH output.
27+
- `wpkh(02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9)` represents a P2WPKH output.
28+
- `sh(wpkh(03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))` represents a P2SH-P2WPKH output.
29+
- `combo(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)` represents a P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH output.
30+
- `sh(wsh(pkh(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13)))` represents a (overly complicated) P2SH-P2WSH-P2PKH output.
31+
- `multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)` represents a bare *1-of-2* multisig.
32+
- `sh(multi(2,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe))` represents a P2SH *2-of-2* multisig.
33+
- `wsh(multi(2,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,03774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a))` represents a P2WSH *2-of-3* multisig.
34+
- `sh(wsh(multi(1,03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8,03499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e)))` represents a P2SH-P2WSH *1-of-3* multisig.
35+
- `pk(xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8)` refers to a single P2PK output, using the public key part from the specified xpub.
36+
- `pkh(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1'/2)` refers to a single P2PKH output, using child key *1'/2* of the specified xpub.
37+
- `wsh(multi(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/1/0/*))` refers to a chain of *1-of-2* P2WSH multisig outputs, using public keys taken from two HD chains with corresponding derivation paths.
38+
39+
## Reference
40+
41+
Descriptors consist of several types of expressions. The top level expression is always a `SCRIPT`.
42+
43+
`SCRIPT` expressions:
44+
- `sh(SCRIPT)` (top level only): P2SH embed the argument.
45+
- `wsh(SCRIPT)` (not inside another 'wsh'): P2WSH embed the argument.
46+
- `pk(KEY)` (anywhere): P2PK output for the given public key.
47+
- `pkh(KEY)` (anywhere): P2PKH output for the given public key (use `addr` if you only know the pubkey hash).
48+
- `wpkh(KEY)` (not inside `wsh`): P2WPKH output for the given compressed pubkey.
49+
- `combo(KEY)` (top level only): an alias for the collection of `pk(KEY)` and `pkh(KEY)`. If the key is compressed, it also includes `wpkh(KEY)` and `sh(wpkh(KEY))`.
50+
- `multi(k,KEY_1,KEY_2,...,KEY_n)` (anywhere): k-of-n multisig script.
51+
- `addr(ADDR)` (top level only): the script which ADDR expands to.
52+
- `raw(HEX)` (top level only): the script whose hex encoding is HEX.
53+
54+
`KEY` expressions:
55+
- Hex encoded public keys (66 characters starting with `02` or `03`, or 130 characters starting with `04`).
56+
- Inside `wpkh` and `wsh`, only compressed public keys are permitted.
57+
- [WIF](https://en.bitcoin.it/wiki/Wallet_import_format) encoded private keys may be specified instead of the corresponding public key, with the same meaning.
58+
-`xpub` encoded extended public key or `xprv` encoded private key (as defined in [BIP 32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)).
59+
- Followed by zero or more `/NUM` unhardened and `/NUM'` hardened BIP32 derivation steps.
60+
- Optionally followed by a single `/*` or `/*'` final step to denote all (direct) unhardened or hardened children.
61+
- The usage of hardened derivation steps requires providing the private key.
62+
- Instead of a `'`, the suffix `h` can be used to denote hardened derivation.
63+
64+
`ADDR` expressions are any type of supported address:
65+
- P2PKH addresses (base58, of the form `1...`). Note that P2PKH addresses in descriptors cannot be used for P2PK outputs (use the `pk` function instead).
66+
- P2SH addresses (base58, of the form `3...`, defined in [BIP 13](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki)).
67+
- Segwit addresses (bech32, of the form `bc1...`, defined in [BIP 173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)).
68+
69+
## Explanation
70+
71+
### Single-key scripts
72+
73+
Many single-key constructions are used in practice, generally including
74+
P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH. Many more combinations are
75+
imaginable, though they may not be optimal: P2SH-P2PK, P2SH-P2PKH,
76+
P2WSH-P2PK, P2WSH-P2PKH, P2SH-P2WSH-P2PK, P2SH-P2WSH-P2PKH.
77+
78+
To describe these, we model these as functions. The functions `pk`
79+
(P2PK), `pkh` (P2PKH) and `wpkh` (P2WPKH) take as input a public key in
80+
hexadecimal notation (which will be extended later), and return the
81+
corresponding *scriptPubKey*. The functions `sh` (P2SH) and `wsh` (P2WSH)
82+
take as input a script, and return the script describing P2SH and P2WSH
83+
outputs with the input as embedded script. The names of the functions do
84+
not contain "p2" for brevity.
85+
86+
### Multisig
87+
88+
Several pieces of software use multi-signature (multisig) scripts based
89+
on Bitcoin's OP_CHECKMULTISIG opcode. To support these, we introduce the
90+
`multi(k,key_1,key_2,...,key_n)` function. It represents a *k-of-n*
91+
multisig policy, where any *k* out of the *n* provided public keys must
92+
sign.
93+
94+
### BIP32 derived keys and chains
95+
96+
Most modern wallet software and hardware uses keys that are derived using
97+
BIP32 ("HD keys"). We support these directly by permitting strings
98+
consisting of an extended public key (commonly referred to as an *xpub*)
99+
plus derivation path anywhere a public key is expected. The derivation
100+
path consists of a sequence of 0 or more integers (in the range
101+
*0..2<sup>31</sup>-1*) each optionally followed by `'` or `h`, and
102+
separated by `/` characters. The string may optionally end with the
103+
literal `/*` or `/*'` (or `/*h`) to refer to all unhardened or hardened
104+
child keys instead.
105+
106+
Whenever a public key is described using a hardened derivation step, the
107+
script cannot be computed without access to the corresponding private
108+
key.
109+
110+
### Including private keys
111+
112+
Often it is useful to communicate a description of scripts along with the
113+
necessary private keys. For this reason, anywhere a public key or xpub is
114+
supported, a private key in WIF format or xprv may be provided instead.
115+
This is useful when private keys are necessary for hardened derivation
116+
steps, or for dumping wallet descriptors including private key material.
117+
118+
### Compatibility with old wallets
119+
120+
In order to easily represent the sets of scripts currently supported by
121+
existing Bitcoin Core wallets, a convenience function `combo` is
122+
provided, which takes as input a public key, and constructs the P2PK,
123+
P2PKH, P2WPKH, and P2SH-P2WPH scripts for that key. In case the key is
124+
uncompressed, it only constructs P2PK and P2PKH.

src/rpc/blockchain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2058,7 +2058,7 @@ UniValue scantxoutset(const JSONRPCRequest& request)
20582058
"or more path elements separated by \"/\", and optionally ending in \"/*\" (unhardened), or \"/*'\" or \"/*h\" (hardened) to specify all\n"
20592059
"unhardened or hardened child keys.\n"
20602060
"In the latter case, a range needs to be specified by below if different from 1000.\n"
2061-
"For more information on output descriptors, see the documentation at TODO\n"
2061+
"For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n"
20622062
"\nArguments:\n"
20632063
"1. \"action\" (string, required) The action to execute\n"
20642064
" \"start\" for starting a scan\n"

src/script/descriptor.h

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -22,55 +22,8 @@
2222
// they can be included inside by changing public keys to private keys (WIF
2323
// format), and changing xpubs by xprvs.
2424
//
25-
// 1. Examples
26-
//
27-
// A P2PK descriptor with a fixed public key:
28-
// - pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)
29-
//
30-
// A P2SH-P2WSH-P2PKH descriptor with a fixed public key:
31-
// - sh(wsh(pkh(02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13)))
32-
//
33-
// A bare 1-of-2 multisig descriptor:
34-
// - multi(1,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc)
35-
//
36-
// A chain of P2PKH outputs (this needs the corresponding private key to derive):
37-
// - pkh(xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw/1'/2/*)
38-
//
39-
// 2. Grammar description:
40-
//
41-
// X: xpub or xprv encoded extended key
42-
// I: decimal encoded integer
43-
// H: Hex encoded byte array
44-
// A: Address in P2PKH, P2SH, or Bech32 encoding
45-
//
46-
// S (Scripts):
47-
// * pk(P): Pay-to-pubkey (P2PK) output for public key P.
48-
// * pkh(P): Pay-to-pubkey-hash (P2PKH) output for public key P.
49-
// * wpkh(P): Pay-to-witness-pubkey-hash (P2WPKH) output for public key P.
50-
// * sh(S): Pay-to-script-hash (P2SH) output for script S
51-
// * wsh(S): Pay-to-witness-script-hash (P2WSH) output for script S
52-
// * combo(P): combination of P2PK, P2PKH, P2WPKH, and P2SH-P2WPKH for public key P.
53-
// * multi(I,L): k-of-n multisig for given public keys
54-
// * addr(A): Output to address
55-
// * raw(H): scriptPubKey with raw bytes
56-
//
57-
// P (Public keys):
58-
// * H: fixed public key (or WIF-encoded private key)
59-
// * E: extended public key
60-
// * E/*: (ranged) all unhardened direct children of an extended public key
61-
// * E/*': (ranged) all hardened direct children of an extended public key
62-
//
63-
// L (Comma-separated lists of public keys):
64-
// * P
65-
// * L,P
66-
//
67-
// E (Extended public keys):
68-
// * X
69-
// * E/I: unhardened child
70-
// * E/I': hardened child
71-
// * E/Ih: hardened child (alternative notation)
72-
//
73-
// The top level is S.
25+
// Reference documentation about the descriptor language can be found in
26+
// doc/descriptors.md.
7427

7528
/** Interface for parsed descriptor objects. */
7629
struct Descriptor {

0 commit comments

Comments
 (0)