BIP 386
Abstract
This document specifies tr() output script
descriptors. tr() descriptors take a key and
optionally a tree of scripts and produces a P2TR output
script.
Copyright
This BIP is licensed under the BSD 2-clause license.
Motivation
Taproot added one additional standard output script format: P2TR. These expressions allow specifying those formats as a descriptor.
Specification
A new script expression is defined: tr(). A new
expression is defined: Tree Expressions
Tree Expression
A Tree Expression (denoted TREE) is an expression
which represents a tree of scripts. The way the tree is
represented in an output script is dependent on the higher level
expressions.
A Tree Expression is:
- Any Script Expression that is allowed at the level this Tree Expression is in.
- A pair of Tree Expressions consisting of:
- An open brace
{ - A Tree Expression
- A comma
, - A Tree Expression
- A closing brace
}
- An open brace
tr()
The tr(KEY) or tr(KEY, TREE)
expression can only be used as a top level expression. All key
expressions under any tr() expression must create
x-only public keys.
tr(KEY) takes a single key expression as an
argument and produces a P2TR output script which does not have a
script path. Each key produced by the key expression is used as
the internal key of a P2TR output as specified by
BIP
341. Specifically, “If the spending conditions do not require
a script path, the output key should commit to an unspendable
script path instead of having no script path. This can be achieved
by computing the output key point as Q = P +
int(hashTapTweak(bytes(P)))G.”
internal_key: lift_x(KEY)
32_byte_output_key: internal_key + int(HashTapTweak(bytes(internal_key)))G
scriptPubKey: OP_1 <32_byte_output_key>
tr(KEY, TREE) takes a key expression as the first
argument, and a tree expression as the second argument and
produces a P2TR output script which has a script path. The keys
produced by the first key expression are used as the internal key
as specified by
BIP
341. The Tree expression becomes the Taproot script tree as
described in BIP 341. A merkle root is computed from this tree and
combined with the internal key to create the Taproot output
key.
internal_key: lift_x(KEY)
merkle_root: HashTapBranch(TREE)
32_byte_output_key: internal_key + int(HashTapTweak(bytes(internal_key) || merkle_root))G
scriptPubKey: OP_1 <32_byte_output_key>
Modified Key Expression
Key Expressions within a tr() expression must only
create x-only public keys. Uncompressed public keys are not
allowed, but compressed public keys would be implicitly converted
to x-only public keys. The keys derived from extended keys must be
serialized as x-only public keys. An additional key expression is
defined only for use within a tr() descriptor:
- A 64 hex character string representing an x-only public key
Test Vectors
Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed.
tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)512077aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11
tr(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)512077aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11
tr(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/0/*,pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/1/*))512078bc707124daa551b65af74de2ec128b7525e10f374dc67b64e00ce0ab8b3e12512001f0a02a17808c20134b78faab80ef93ffba82261ccef0a2314f5d62b6438f11512021024954fcec88237a9386fce80ef2ced5f1e91b422b26c59ccfc174c8d1ad25
tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,pk(669b8afcec803a0d323e9a17f3ea8e68e8abe5a278020a929adbec52421adbd0))512017cf18db381d836d8923b1bdb246cfcd818da1a9f0e6e7907f187f0b2f937754
tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,{pk(xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334/0),``)512071fff39599a7b78bc02623cbe814efebf1a404f5d8ad34ea80f213bd8943f574
tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,pkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))
Invalid Descriptors
- Uncompressed private key:
tr(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss) - Uncompressed public key:
tr(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235) tr()nested inwsh:wsh(tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))tr()nested insh:sh(tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
Backwards Compatibility
tr() descriptors use the format and general
operation specified in
380.
As these are a set of wholly new descriptors, they are not
compatible with any implementation. However the scripts produced
are standard scripts so existing software are likely to be
familiar with them.
Tree Expressions are largely incompatible with existing script
expressions due to the restrictions in those expressions. Of the
script expressions that existed when this BIP was written, only
pk() can be used in a tree expression. Script
expressions specified since then that can be used in a tree
expression are the Miniscript expressions of
379, which
include a pkh() fragment, and the
multi_a() and sortedmulti_a()
expressions of
387.
Reference Implementation
tr() descriptors have been implemented in Bitcoin
Core since version 22.0.
BIP: 387
Layer: Applications
Title: Tapscript Multisig Output Script Descriptors
Authors: Pieter Wuille <pieter@wuille.net>
Ava Chow <me@achow101.com>
Status: Deployed
Type: Specification
Assigned: 2024-04-17
License: BSD-2-Clause
Requires: 380