|
| 1 | +<pre> |
| 2 | + BIP: ??? |
| 3 | + Layer: Applications |
| 4 | + Title: raw() as subscript in Output Script Descriptors |
| 5 | + Author: Pieter Wuille [email protected] |
| 6 | + Matias Furszyfer [email protected] |
| 7 | + Comments-Summary: No comments yet. |
| 8 | + Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-??? |
| 9 | + Status: Draft |
| 10 | + Type: Informational |
| 11 | + Created: 2024-12-16 |
| 12 | + License: BSD-2-Clause |
| 13 | +</pre> |
| 14 | + |
| 15 | +==Abstract== |
| 16 | + |
| 17 | +This document specifies `raw()` as subscript for output script descriptors. |
| 18 | +`raw()` encapsulates a raw hex script. This BIP allows `raw()` to be used in |
| 19 | +the context of other descriptors. |
| 20 | + |
| 21 | +==Copyright== |
| 22 | + |
| 23 | +This BIP is licensed under the BSD 2-clause license. |
| 24 | + |
| 25 | +==Motivation== |
| 26 | + |
| 27 | +Allowing arbitrary hex data to be wrapped in `sh()`, `wsh()`, or even within the `TREE` |
| 28 | +argument of a `tr(KEY, TREE)` descriptor enables the representation of currently |
| 29 | +inexpressible information in the descriptors' language. |
| 30 | + |
| 31 | +Specifically, the absence of this feature limits the representation of non-standard redeem |
| 32 | +and witness scripts. This occurs because they can currently only be represented as top-level |
| 33 | +`raw(HEX)` descriptors, which retain only the output script information and lack the ability |
| 34 | +to preserve the actual script. |
| 35 | + |
| 36 | +Additionally, as noted [https://github.com/bitcoin/bitcoin/issues/24114#issuecomment-1127978154 here], |
| 37 | +there are other useful scenarios for this feature. For example, it allows representing |
| 38 | +in a descriptor that we lack full knowledge of all solvability paths but can still solve |
| 39 | +the output, such as a taproot tree where we know only one of its paths, or even also |
| 40 | +participating in signing a script without knowing all participants' keys, relying solely |
| 41 | +on the script structure. |
| 42 | + |
| 43 | +==Specification== |
| 44 | + |
| 45 | +### For `sh()` and `wsh()` descriptors: |
| 46 | +`raw(HEX)` must represent the arbitrary script data within the provided context. |
| 47 | +This for example means that a P2SH output script (OP_HASH160 <hash160(HEX_script)> OP_EQUAL) |
| 48 | +must be created from the provided hex data when a `sh(raw(HEX))` descriptor is provided. |
| 49 | + |
| 50 | +Parallely, a P2WSH output script (OP_0 <hash160(HEX_script)>) must be created from the provided |
| 51 | +hex data when a `wsh(raw(HEX))` descriptor is provided. |
| 52 | + |
| 53 | +### For `tr(KEY, TREE)` descriptors: |
| 54 | +Two new fragments are allowed within the taproot `TREE` context: `rawnode(HEX)` and `raw(HEX)`. |
| 55 | + |
| 56 | +#### `rawnode(HEX)`: |
| 57 | +Indicating a tree node with specified 32-bit hash, but no specified subtree. |
| 58 | +This can serve as either a tree branch or the root of the Merkle tree. |
| 59 | + |
| 60 | +#### `raw(HEX)`: |
| 61 | +Defines a tree leaf containing the specified script in hex. |
| 62 | +Note: The leaf version must be internally fixed at the existing `0xC0` to prevent introducing |
| 63 | +unsupported or undefined functionality. |
| 64 | +If a different version is required for any use case, a new BIP could introduce `raw(HEX, VERSION)` |
| 65 | +in the future. |
| 66 | + |
| 67 | +==Test Vectors== |
| 68 | + |
| 69 | +Valid descriptors followed by the scripts they produce. |
| 70 | + |
| 71 | +* `sh(raw(5387))` |
| 72 | +** `a9149e02f205612b4d7fe9466a789764b0eafe7eb07287` |
| 73 | +* `sh(wsh(raw(5387)))` |
| 74 | +** `a9140d1a6a9fd7e20b6e4091e2c10284fb1130afd46787` |
| 75 | +* `wsh(raw(5387))` |
| 76 | +** `00205c5fc1afc3d712a8e8602cee8590234ab2213be58943fca65436439f08017a64` |
| 77 | +# TODO: Complete examples: |
| 78 | + 1) tr(key, rawnode()) |
| 79 | + 2) tr(key, {pk(), raw()}) |
| 80 | + 3) tr(key, {pk(), rawnode()}) |
| 81 | + 4) tr(key, {pk(), sortedmulti_a(2,key1,key2,raw())}) |
| 82 | + 5) tr(key, {pk(raw())}) |
| 83 | +
|
| 84 | +Invalid descriptors |
| 85 | + |
| 86 | +* Non-hex script: `sh(raw(asdf))` |
| 87 | +* Non 32-bit hash in `rawnode`: `tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd, rawnode(kjke))` |
| 88 | +* Non-hex in `rawnode`: `tr(a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd, rawnode(<complete me with a 32-bit non-hex hash>))` |
| 89 | +* `raw` in the key path `tr`: `tr(raw(asdf), pk(key))` |
| 90 | +
|
| 91 | +==Backwards Compatibility== |
| 92 | + |
| 93 | +`raw()` as a subscript descriptors use the format and general operation specified in [[bip-0380.mediawiki|380]]. |
| 94 | +As this is a wholly new descriptor, it is not compatible with any implementation. |
| 95 | + |
| 96 | +==Reference Implementation== |
| 97 | + |
| 98 | +# TODO: add Bitcoin-Core PR.. |
0 commit comments