BIP 394: rawtr() Output Script Descriptors
2026-09-09
View on GitHub
  BIP: 394
  Layer: Applications
  Title: rawtr() Output Script Descriptors
  Authors: jeanpablojp <me@jeanpablo.jp>
  Status: Draft
  Type: Specification
  Assigned: 2026-09-09
  License: BSD-2-Clause
  Discussion: 2026-03-02: https://github.com/bitcoin/bips/pull/2050#issuecomment-3986205616
              2026-08-06: https://groups.google.com/g/bitcoindev/c/CCZN_qQ5C1s
  Requires: 341, 380

Abstract

This document specifies rawtr() output script descriptors. A rawtr() descriptor expresses a Pay-to-Taproot output by its output key directly, without stating an internal key or a script tree.

Motivation

A taproot output key is derived from an internal key and an optional script tree, as described in BIP 341. The tr() descriptor specified in BIP 386 takes the internal key and the tree, and computes the output key from them. There is no way to use tr() for an output whose internal structure isn't known, for example an output key received from another party, or one whose script tree the holder does not wish to reveal. The rawtr() descriptor covers that case by taking the output key itself.

This expression has been implemented in Bitcoin Core since version 24.0, and BIP 390 permits musig() inside rawtr() and uses it in its test vectors. This document gives the expression a specification of its own.

Specification

A new script expression is defined: rawtr().

The rawtr(KEY) expression can only be used as a top level descriptor. It takes a single key expression as an argument and produces a P2TR output script. Unlike tr(), it does not take a tree expression, and the key is used directly as the taproot output key, with no BIP 341 tweak applied.

The output script produced is:

OP_1 <KEY>

Key expressions within a rawtr() expression must only create x-only public keys, as in tr() expressions. Uncompressed public keys are not allowed. Compressed public keys are allowed, but will be implicitly converted to x-only public keys. The keys derived from extended keys must be serialized as x-only public keys.

If the private key corresponding to the output key is known, the output can be spent via the key path. Note that a rawtr() descriptor cannot show whether a script path exists for the output: nothing in it proves that the output key does not commit to a script tree. Software importing a rawtr() descriptor from an untrusted source should warn that other spending paths may exist.

Rationale

No BIP 341 tweak is applied to the key, since tweaking it would describe a different output than the one the descriptor is for. The expression is top level only, because a P2TR output script is a complete scriptPubKey and there is no context in which it can appear as a sub-expression.

Key expressions are restricted to x-only public keys because a taproot output key is an x-only key. Compressed public keys are accepted and converted implicitly, as in tr(), so a key expression written for one of the two also works in the other.

The absence of a specification has already produced divergence outside Bitcoin Core. rust-miniscript renders these outputs as rawtr_not_supported_yet(KEY) and does not parse them back, and the bdk-ffi descriptor tests describe rawtr() as BIP 386, which specifies tr().

Test Vectors

Valid descriptors followed by the scripts they produce. Descriptors involving derived child keys will have the 0th, 1st, and 2nd scripts listed. These vectors were generated with Bitcoin Core's descriptor implementation. Note that the first vector uses the same key as the first tr() vector of BIP 386: with rawtr() the key appears in the script unchanged, while tr() tweaks it. The third vector takes the output key that the BIP 386 vector produced and reproduces its script.

  • rawtr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
    • 5120a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd
  • rawtr(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)
    • 5120a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd
  • rawtr(77aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11)
    • 512077aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11
  • rawtr(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
    • 5120a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd
  • rawtr(02a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)
    • 5120a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd
  • rawtr(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/0/*)
    • 51208145454b87fc9ec3557478d6eadc2aea290b50f3c469b828abeb542ae8f8849d
    • 5120377ad06450813b5f7e10bc94b8b662513398c2d83086f8e67349a00909a5a5a4
    • 51200a862a965e930b917327d4d08e6309aeb6a4fb0970e133c8ea0d034de04cc3b0
  • rawtr(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc/<0;1>/*), a multipath descriptor as specified in BIP 389, expanding into two descriptors:
    • rawtr(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/0/*)
      • 51208145454b87fc9ec3557478d6eadc2aea290b50f3c469b828abeb542ae8f8849d
      • 5120377ad06450813b5f7e10bc94b8b662513398c2d83086f8e67349a00909a5a5a4
      • 51200a862a965e930b917327d4d08e6309aeb6a4fb0970e133c8ea0d034de04cc3b0
    • rawtr(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*)
      • 5120095e95d8c50ae3f3fea93fa8e983f710489f60ff681a658c06eba64622c824b1
      • 51207512d6bd74e24eeb1ad752d5be800adc5886ded11c5293a9a701db83658b526a
      • 5120cc9fd211dc0a1c8bb7a106ff831be0e253bc992f21d08fb8a6fd43fae51b9b89
  • rawtr(musig(KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74sHUHy8S,03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66)), from the BIP 390 test vectors
    • 5120789d937bade6673538f3e28d8368dda4d0512f94da44cf477a505716d26a1575
  • rawtr(musig(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y)/0/*), from the BIP 390 test vectors
    • 51209508c08832f3bb9d5e8baf8cb5cfa3669902e2f2da19acea63ff47b93faa9bfc
    • 51205ca1102663025a83dd9b5dbc214762c5a6309af00d48167d2d6483808525a298
    • 51207dbed1b89c338df6a1ae137f133a19cae6e03d481196ee6f1a5c7d1aeb56b166

Invalid Descriptors

  • rawtr() nested in sh: sh(rawtr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
  • rawtr() nested in wsh: wsh(rawtr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
  • Script expression instead of a key expression: rawtr(pk(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))
  • More than one key: rawtr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,77aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11)
  • Tree expression, which rawtr() does not take: rawtr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd,pk(77aab6e066f8a7419c5ab714c12c67d25007ed55a43cadcacb4d7a970a093f11))
  • Uncompressed private key: rawtr(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss)
  • Uncompressed public key: rawtr(04a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd5b8dec5235a0fa8722476c7709c02559e3aa73aa03918ba2d492eea75abea235)
  • No key: rawtr()
  • X-only key with no point on the curve: rawtr(0000000000000000000000000000000000000000000000000000000000000005)

Backwards Compatibility

rawtr() descriptors use the format and general operation specified in 380. This is a wholly new descriptor, and as such is not compatible with any implementation that predates it. The scripts produced are standard Pay-to-Taproot scripts, so existing software is likely to be familiar with them.

Reference Implementation

rawtr() descriptors have been implemented in Bitcoin Core since version 24.0.

Copyright

This BIP is licensed under the BSD 2-clause license.


Updated

2026-11-07

See an issue with rendering or formatting? Submit an issue on GitHub

Do you find this site useful? Please consider donating some sats to support ongoing development.

bips.dev is presented by nickmonad

All content is owned and licensed by the respective author(s). This website makes no claim of ownership.