{"number":391,"title":"Binary Output Descriptors","authors":["SeedHammer"],"status":"Closed","type":"Specification","layer":"Applications","created":"2026-01-27","license":"BSD-2-Clause","requires":[],"replaces":[],"replacedBy":[393],"discussion":[],"abstract":"This document proposes an efficient container format for encoding an output descriptor as defined by BIP 380 and its extensions. Based on key-value maps as defined by BIP 174 , the encoding supports descriptor and key metadata.","eli5":"Proposes a compact binary format for storing and transferring output descriptors, the text descriptions of a wallet's addresses. It can also carry extra information about the descriptor and its keys, making it suitable for QR codes, hardware devices, and other space-constrained uses.","categories":["wallets"],"filename":"bip-0391.mediawiki","githubUrl":"https://github.com/bitcoin/bips/blob/master/bip-0391.mediawiki","format":"mediawiki","readingMinutes":5,"inbound":0,"revisions":1,"impact":0,"core":false,"references":[174,380,389],"lastModified":"2026-04-23","html":"<h2 id=\"introduction\">Introduction</h2>\n<h3 id=\"abstract\">Abstract</h3>\n<p>This document proposes an efficient container format for encoding an output descriptor as defined by <a href=\"/bip/380\">BIP 380</a> and its extensions. Based on key-value maps as defined by <a href=\"/bip/174\">BIP 174</a>, the encoding supports descriptor and key metadata.</p>\n<h3 id=\"copyright\">Copyright</h3>\n<p>This BIP is licensed under the BSD 2-clause license.</p>\n<h3 id=\"motivation\">Motivation</h3>\n<p>A BIP 380 output descriptor is a textual representation of a set of output scripts, such that Bitcoin wallets may agree on the scripts and addresses to provide the user. However, a descriptor string by itself is not ideal for transferring between wallets: it lacks a machine-recognizable header, cannot represent metadata such as name and birth block, and its use of base58 for extended keys is inefficient.</p>\n<p>BIP 174 gives us a self-describing file format, metadata, and a compact, binary representation of keys. Assuming most wallets already implement the PSBT format, the implementation overhead of this BIP is expected to be low <sup class=\"footnote-ref\"><a href=\"#fn-1\" id=\"fnref-1\">[1]</a></sup> <sup class=\"footnote-ref\"><a href=\"#fn-2\" id=\"fnref-2\">[2]</a></sup> <ref><strong>Why not use the new Blockchain Commons BCR-2023-010 format?</strong> The <a href=\"https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2023-010-output-descriptor.md\">BCR-2023-010 format</a> is roughly equivalent to this proposal, but was designed and released outside of the usual BIP proposal process.</p>\n<p>In particular, we believe BCR-2023-010 would have faced opposition in the BIP process because it is based on the <a href=\"https://cbor.io/spec.html\">CBOR encoding</a>. CBOR is designed for generality and compactness and is therefore significantly more complex than the PSBT encoding. In contrast, the PSBT key-value maps are supported by all wallet software that interact with PSBT files, are easier to review, and they fit in embedded devices.</p>\n<p>Released in late 2023, BCR-2023-010 doesn't have the advantage of widespread support at the time of this writing.</ref>.</p>\n<h2 id=\"specification\">Specification</h2>\n<p>The Binary Output Descriptor (BOD) format consists of a fixed header, a key-value map describing the output descriptor, and a key-value map for each key.</p>\n<pre><code>&lt;bod&gt; := &lt;magic&gt; &lt;global-map&gt; &lt;key-map&gt;*\n&lt;magic&gt; := 0x62 0x6F 0x64 0xFF\n&lt;global-map&gt; := &lt;keypair&gt;* 0x00\n&lt;key-map&gt; := &lt;keypair&gt;* 0x00</code></pre>\n<p>The definition for <code>&lt;keypair&gt;</code> follows <a href=\"/bip/174#specification\">BIP 174</a>.</p>\n<p>The defined global types are as follows:</p>\n<div class=\"table-wrap\"><table><tbody><tr><th>Name</th><th><code>&lt;keytype&gt;</code></th><th><code>&lt;keydata&gt;</code></th><th><code>&lt;keydata&gt;</code> Description</th><th><code>&lt;valuedata&gt;</code></th><th><code>&lt;valuedata&gt;</code> Description</th></tr><tr><td>Output Descriptor</td><td><code>BOD_GLOBAL_OUTPUT_DESCRIPTOR = 0x00</code></td><td><code>&lt;compact size uint birth block&gt;&lt;bytes&gt;</code></td><td>The earliest block height that may contain transactions for the descriptor, optionally followed by the UTF-8 encoded name of the descriptor.</td><td><code>&lt;bytes descriptor&gt;</code></td><td>The output descriptor in BIP 380 format without inline keys<sup class=\"footnote-ref\"><a href=\"#fn-3\" id=\"fnref-3\">[3]</a></sup>.</td></tr><tr><td>Proprietary Use Type</td><td><code>BOD_GLOBAL_PROPRIETARY = 0xFC</code></td><td><code>&lt;compact size uint identifier length&gt; &lt;bytes identifier&gt; &lt;compact size uint subtype&gt; &lt;bytes subkeydata&gt;</code></td><td>A compact size unsigned integer of the length of the identifier, followed by an identifier prefix, followed by a compact size unsigned integer subtype, followed by the key data itself.</td><td><code>&lt;bytes data&gt;</code></td><td>Any value data as defined by the proprietary type user.</td></tr></tbody></table></div>\n<p>It is an error to omit the BOD_GLOBAL_OUTPUT_DESCRIPTOR entry.</p>\n<p>All key expressions in the BOD_GLOBAL_OUTPUT_DESCRIPTOR descriptor string must be specified as references in the form of <code>@&lt;index&gt;</code> where <code>index</code> is the 0-based index into the ordered list of <code>&lt;key-map&gt;</code> entries. An index out of range is invalid.</p>\n<p>A BOD_GLOBAL_OUTPUT_DESCRIPTOR with inline keys is invalid<sup class=\"footnote-ref\"><a href=\"#fn-4\" id=\"fnref-4\">[4]</a></sup><sup class=\"footnote-ref\"><a href=\"#fn-5\" id=\"fnref-5\">[5]</a></sup>.</p>\n<p>Key references may be followed by derivation paths as specified in <a href=\"/bip/389#specification\">BIP 389</a>.</p>\n<p>The defined key types are as follows:</p>\n<div class=\"table-wrap\"><table><tbody><tr><th>Name</th><th><code>&lt;keytype&gt;</code></th><th><code>&lt;keydata&gt;</code></th><th><code>&lt;keydata&gt;</code> Description</th><th><code>&lt;valuedata&gt;</code></th><th><code>&lt;valuedata&gt;</code> Description</th></tr><tr><td>Extended Public Key</td><td><code>BOD_KEY_XPUB = 0x00</code></td><td><code>&lt;bytes xpub&gt;</code></td><td>The 78-byte serialized extended public key, as defined by BIP 32.</td><td><code>&lt;4 byte fingerprint&gt; &lt;32-bit little endian uint path element&gt;*</code></td><td>The master key fingerprint, as defined by BIP 32, concatenated with the derivation path of the public key. The derivation path is represented as 32-bit little endian unsigned integer indexes concatenated with each other. The number of 32-bit unsigned integer indexes must match the depth provided in the extended public key.</td></tr><tr><td>Proprietary Use Type</td><td><code>BOD_KEY_PROPRIETARY = 0xFC</code></td><td><code>&lt;compact size uint identifier length&gt; &lt;bytes identifier&gt; &lt;compact size uint subtype&gt; &lt;bytes subkeydata&gt;</code></td><td>A compact size unsigned integer of the length of the identifier, followed by an identifier prefix, followed by a compact size unsigned integer subtype, followed by the key data itself.</td><td><code>&lt;bytes data&gt;</code></td><td>Any value data as defined by the proprietary type user.</td></tr></tbody></table></div>\n<h2 id=\"test-vectors\">Test Vectors</h2>\n<h3 id=\"invalid-cases\">Invalid Cases</h3>\n<p>A descriptor with a key reference out of bounds.</p>\n<pre><code>Descriptor: wpkh(@0/*)\nHex encoded BOD: 70736274ff0207000a77706b682840302f2a29000000</code></pre>\n<p>A descriptor with an invalid UTF-8 name.</p>\n<pre><code>Hex-encoded BOD: 70736274ff05070061c57a0a77706b682840302f2a2953010488b21e041c0ae906800000025afed56d755c088320ec9bc6acd84d33737b580083759e0a0ff8f26e429e0b77028342f5f7773f6fab374e1c2d3ccdba26bc0933fc4f63828b662b4357e4cc3791bec0fbd814c5d8729748000080000000800000008002000080000000</code></pre>\n<p>A descriptor with an inline key.   Hex-encoded BOD: 70736274ff0207008e77706b68285b64633536373237362f3438682f30682f30682f32685d7870756236446959726652774e6e6a655834764873574d616a4a56464b726245456e753867415739764475517a675457457345484531367347576558585556314c42575145317943546d657072534e63715a3357373468715664674462745948557633654d3457325445556870616e2f2a29000000</p>\n<h3 id=\"valid-cases\">Valid Cases</h3>\n<p>A 2-of-3 multisig descriptor</p>\n<pre><code>Descriptor: wsh(sortedmulti(2,@0/&lt;0;1&gt;/*,@1/&lt;0;1&gt;/*,@2/&lt;0;1&gt;/*))\nName: Satoshi's Stash\nBirth block: 123456789012345\nKey 0: [dc567276/48h/0h/0h/2h]xpub6DiYrfRwNnjeX4vHsWMajJVFKrbEEnu8gAW9vDuQzgTWEsEHE16sGWeXXUV1LBWQE1yCTmeprSNcqZ3W74hqVdgDbtYHUv3eM4W2TEUhpan\nKey 1: [f245ae38/48h/0h/0h/2h]xpub6DnT4E1fT8VxuAZW29avMjr5i99aYTHBp9d7fiLnpL5t4JEprQqPMbTw7k7rh5tZZ2F5g8PJpssqrZoebzBChaiJrmEvWwUTEMAbHsY39Ge\nKey 2: [c5d87297/48h/0h/0h/2h]xpub6DjrnfAyuonMaboEb3ZQZzhQ2ZEgaKV2r64BFmqymZqJqviLTe1JzMr2X2RfQF892RH7MyYUbcy77R7pPu1P71xoj8cDUMNhAMGYzKR4noZ\nHex-encoded BOD: 70736274ff1907ff79df0d86487000005361746f73686927732053746173683477736828736f727465646d756c746928322c40302f3c303b313e2f2a2c40312f3c303b313e2f2a2c40322f3c303b313e2f2a292953010488b21e0418f8c2e7800000026b3a4cfb6a45f6305efe6e0e976b5d26ba27f7c344d7fc7abef7be2d06d52dfd021c0b479ecf6e67713ddf0c43b634592f51c037b6f951fb1dc6361a98b1e5735e0f8b515314dc5672764800008000000080000000800200008053010488b21e04221eb5a080000002c887c72d9d8ac29cddd5b2b060e8b0239039a149c784abe6079e24445db4aa8a0397fcf2274abd243d42d42d3c248608c6d1935efca46138afef43af08e971289657009d2b14f245ae384800008000000080000000800200008053010488b21e041c0ae906800000025afed56d755c088320ec9bc6acd84d33737b580083759e0a0ff8f26e429e0b77028342f5f7773f6fab374e1c2d3ccdba26bc0933fc4f63828b662b4357e4cc3791bec0fbd814c5d8729748000080000000800000008002000080000000</code></pre>\n<h2 id=\"rationale\">Rationale</h2>\n<ol class=\"footnotes\"><li id=\"fn-1\"> <strong>Why not extend BIP 174?</strong> The PSBT format is not a general-purpose container format, and descriptors are useful outside of signing flows (backup, initializing wallet software). <a href=\"#fnref-1\" class=\"footnote-back\" aria-label=\"Back to text\">↩</a></li><li id=\"fn-2\"> <strong>Why not use the older Blockchain Commons BCR-2020-010 format?</strong> The format was <a href=\"https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md#deprecated-superseded-by-version-3-output-descriptors\">recently deprecated</a>, due to its use of reserved CBOR tags. <a href=\"#fnref-2\" class=\"footnote-back\" aria-label=\"Back to text\">↩</a></li><li id=\"fn-3\"><strong>Why not encode the descriptor in binary?</strong>\nDesigning and maintaining a compact binary representation of the complex and evolving BIP 380 descriptor\nlanguage entail significant effort and introduce a time lag from the introduction of new BIP 380 features\nto the specification of the binary counterpart. We don't believe the space savings outweigh the disadvantages.\n\nThe major source of bloat, base58-encoded keys, are binary encoded for compactness and\ncan be re-used multiple times in a single descriptor.\n <a href=\"#fnref-3\" class=\"footnote-back\" aria-label=\"Back to text\">↩</a></li><li id=\"fn-4\"><strong>Why not allow inline keys?</strong> Allowing inline keys risks incompatible implementations that omit parsing of referenced keys. <a href=\"#fnref-4\" class=\"footnote-back\" aria-label=\"Back to text\">↩</a></li><li id=\"fn-5\"><strong>What about named <code>pk(NAME)</code> references?</strong> Named references would allow Miniscript descriptors as-is in BOD_GLOBAL_OUTPUT_DESCRIPTOR. They are left out because they complicate decoders and can trivially be replaced by indexed references. <a href=\"#fnref-5\" class=\"footnote-back\" aria-label=\"Back to text\">↩</a></li></ol>\n<h2 id=\"compatibility\">Compatibility</h2>\n<p>This is a new format and as such has no compatibility burden.</p>\n<h2 id=\"reference-implementation\">Reference Implementation</h2>\n<p>There is a <a href=\"https://github.com/seedhammer/bip-bod-descriptors\">Go implementation</a> for development and testing purposes. Don't use it in production, because it only validates the BOD format, not the descriptor itself.</p>\n<h2 id=\"changelog\">Changelog</h2>\n<ul><li>\n<strong>0.0.2</strong> (2026-04-21):\n<ul><li>\nWithdrawn after BIP393 proposed an alternative method of handling wallet metadata.\n</li></ul>\n</li><li>\n<strong>0.0.1</strong> (2026-02-02):\n<ul><li>\nInitial draft.\n</li></ul>\n</li></ul>\n<h2 id=\"acknowledgments\">Acknowledgments</h2>\n<p>This specification builds upon the draft BIP 388 by specifying a serialization format for compact descriptors. It also uses the indexed key references from that BIP, as well as examples and test vectors.</p>","toc":[{"id":"introduction","title":"Introduction","level":2},{"id":"abstract","title":"Abstract","level":3},{"id":"copyright","title":"Copyright","level":3},{"id":"motivation","title":"Motivation","level":3},{"id":"specification","title":"Specification","level":2},{"id":"test-vectors","title":"Test Vectors","level":2},{"id":"invalid-cases","title":"Invalid Cases","level":3},{"id":"valid-cases","title":"Valid Cases","level":3},{"id":"rationale","title":"Rationale","level":2},{"id":"compatibility","title":"Compatibility","level":2},{"id":"reference-implementation","title":"Reference Implementation","level":2},{"id":"changelog","title":"Changelog","level":2},{"id":"acknowledgments","title":"Acknowledgments","level":2}],"history":{"totalCommits":1,"firstCommit":"2026-04-23T20:17:01+02:00","lastUpdated":"2026-04-23T20:17:01+02:00","events":[{"sha":"9eb67f5764763746fcfd8aedd205bb9f4a6590a6","date":"2026-04-23T20:17:01+02:00","author":"SeedHammer","message":"Merge pull request #1548 from seedhammer/master","url":"https://github.com/bitcoin/bips/commit/9eb67f5764763746fcfd8aedd205bb9f4a6590a6","kind":"edit"}]}}