So far, we effectively have two levels of “solvability” in descriptors:
addr()
andraw()
which can encode scriptPubKey with effectively no solvability information at all- Everything else, which encodes scriptPubKeys that are fully solvable.
I’ve long held that there shouldn’t be any level in between, in the sense that you shouldn’t be using a descriptor if you don’t know everything about its construction. I’m starting to think that’s not a tenable position:
- Already, key origin information - which may be no less critical than other parts of descriptors for certain roles - is optional. There is no way to force that information to be included, because it may not exist (for non-BIP32-derived keys, for example), but it may also simply be omitted.
- #23480 proposes the introduction of a descriptor like
tr()
, except it encodes the post-tweak key rather than the inner key. This too may be because the information doesn’t exist, but it cannot prevent situations where it is simply omitted. - It has been suggested before (e.g. #21365 (comment)) to permit
tr()
descriptors to contain hashes for omitted script subtrees. That too could represent non-existent information (Merkle path entries that are chosen rather than actual hashes), or omitted information. And it is useful - there are certainly scenarios where one might want to participate in, and sign for, taproot outputs for which certain subtrees are not known. - If we’re going to accept that the previous 3 examples will occur, we might as well bite the bullet and also add a way to encode “pkh with known keyhash, but not known key”.
If all these mechanisms become permitted in descriptors (and miniscript), we get the nice logistical benefit of being able to represent all information extracted from PSBT/SPKM/scripts/… into a descriptor regardless of what is present or missing. I believe this would logistically simplify things later on too: Miniscript would not need separate instantiations for its descriptor-decoding use case and its signing/solving use case. Perhaps even further out, this can mean that many fields in SignatureData
are replaced with just a descriptor object (everything except signatures/preimages), and the signing logic becomes a descriptor method.
Straw man proposal:
- Do #23480 (adding
rawtr(KEY)
), for P2TR outputs with specified tweaked key, but no specified internal key or script tree. - Add a
rawnode(HEX)
fragment, only usable inside P2TR script tree expressions, indicating a tree node with specified hash, but no specified subtree. - Add a
rawpkh(HEX)
fragment, usable whereverpkh(KEY)
is usable, indicating a PKH script (DUP HASH160 <hex> EQUALVERIFY CHECKSIG
), without specified public key. Post-miniscript this would also add arawpk_h(HEX)
fragment, corresponding topk_h(KEY)
.