Miniscript is great, but:
- Can’t represent many wallet types inside descriptor (lightning wallet, multisigs re-using keys in different branches)
- Do not yet supports tapscript
- Still not stable, i.e. not durable enough for long storage of wallet descriptor backups
As of today, there is no standard way to write a descriptor covering all forms of UTXOs which may be present in bitcoin transactions. This standards aims to bridge that gap. It also defines a canonical form of a wallet descriptor, which is unique for each wallet and allows to commit to the wallet structure in a non-ambigous way, which may be important for wallet comparison, identification, especially in multi-party protocols.
Standard proposes new script()
fragment for wallet descriptors. It takes the following variants of a single argument:
- Templated opcode form, in which script composed of opcodes and tempaltes separated with whitespaces
- Templated hex form, in which script consists of hexacecimal fragments and templates without whitespace
Templates are defined as <>
pattern can has the following forms:
- Push representing OP_FALSE (i.e. empty string)
<>
- Push of a pubkey derivable from a pubkey or privkey descriptor
- Push of a decimal integer in its little-endian representation, like
<495>
- Push of a hexadecimal integer (binary string), which must be prefixed with
0x
, like<0xff>
- Push of a ASCII string, kept in double quotation marks, like
<“some string to push”>
- Push of a value or derived public key presented by a named variable, like
<pk>
. The variable name can be composed of alphanumeric,-
,_
and.
characters and can’t start with a digit. It should be prefixed with decimal prefix specifying the length of the variable, if it has a fixed length, like<33:pk>
, which helps in static analysis of the script size.
- Script must be converted into templated hex form
- All public keys SHOULD be formatted as templates even if they are parts of non-template script
- All private keys must be converted into public key form
Manually provided in parallel with the descriptor in a form defined by other standards, or, otherwise, analyzed by parsing script fragment content with miniscript and by utilizing its satisfaction analysis capabilities.
Descriptor for a lightning to_local
outputs defined by BOLT-3:
wsh(script(
<key_local> OP_CHECKSIG OP_NOTIF
<key_revocation> OP_CHECKSIG
OP_ELSE
<0xF003> OP_CHECKSEQUENCEVERIFY
OP_ENDIF
))
As it can be see, it literally works with the code provided in BOLT-3 with just a single modification to hexadecimal value representation.
wsh(script(
<3> <signer.1> <signer.2> <signer.3> <3> OP_CHECKMULTISIG
OP_IFNOT
<0xE801> OP_CHECKTIMELOCKVERIFY
<3> <signer.1> <signer.2> <signer.3> <2> OP_CHECKMULTISIG
OP_ENDIF
))