I read in the Bitcoin Core doc an example of a taproot output descriptor with 2 script paths :


I tried to pass a descriptor with a third script path, but I'm met with an error tr(): expected ')' after script expression

That makes sense since I read in the same doc that the syntax for taproot descriptor is tr(KEY,TREE), and that TREE is defined as:

* any SCRIPT expression
* An open brace {, a TREE expression, a comma ,, a TREE expression, and a closing brace }

This is consistent with what I saw in the rust-bitcoin library, where a TAPTREE is either a leaf, or 2 trees.

My question is what if I wanted to commit a third script, a very simple one like the 2 in the example?

I think I could compute the root of my tree myself and use the rawtr() descriptor with the output pubkey, but what if I want to prove there's no hidden commitment?

I guess I could give all the scripts and that one could figure it out by recreating the scriptpubkey and check it's the same, but that's cumbersome.


1 Answer 1


If you want a Merkle tree with script paths S1 and S2 on the second level of the Merkle tree and script path S3 on the first level of the Merkle tree the descriptor notation is:


where KEY can be any key expression including public key, x-only public key, WIF private key, xpub, xprv or xpub/xprv with derivation path.

Pull request #22051 added support for tr(KEY,{{S1,{{S2,S3},...}},...}) descriptors and the notation was confirmed in pull request #21365.

  • 1
    Thanks, how didn't I think of it facepalm Maybe we should update the descriptor documentation with an example
    – Sosthène
    Sep 14, 2022 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.