{"number":346,"title":"OP_TXHASH","authors":["Steven Roose","Brandon Black"],"status":"Draft","type":"Specification","layer":"Consensus (soft fork)","created":"2024-04-24","license":"BSD-3-Clause","requires":[],"replaces":[],"replacedBy":[],"discussion":[],"abstract":"This BIP proposes a new opcode OP_TXHASH , to be activated as a change to the semantics of OP_SUCCESS189 in tapscript contexts. This opcode provides a generalized method for introspecting certain details of the spending transaction, which enables non-interactive enforcement of certain properties of the transaction spending a certain UTXO. Together with an opcode like OP_CHECKSIGFROMSTACK , this opcode effectively provides a fully generalized signature hash construction, fully supporting all existing SIGHASH flags, the proposed sighash flags from BIP-118 ( SIGHASH_ANYPREVOUT ) and many other new signature hash combinations. The constructions specified in this BIP also open up the way for other potential updates; see Motivation section for more details.","eli5":"Proposes a new script instruction, OP_TXHASH, that lets a script look at selected details of the transaction trying to spend it, such as its outputs or amounts. Combined with a way to check signatures over arbitrary data, it could support flexible spending restrictions (covenants) and new kinds of second-layer protocols.","categories":["consensus"],"filename":"bip-0346.md","githubUrl":"https://github.com/bitcoin/bips/blob/master/bip-0346.md","format":"markdown","readingMinutes":11,"inbound":1,"revisions":2,"impact":28,"core":false,"references":[118,119,345,347,348,443],"lastModified":"2026-02-04","html":"<h1>Abstract</h1>\n<p>This BIP proposes a new opcode <code>OP_TXHASH</code>, to be activated as a change to the\nsemantics of <code>OP_SUCCESS189</code> in tapscript contexts.</p>\n<p>This opcode provides a generalized method for introspecting certain details of\nthe spending transaction, which enables non-interactive enforcement of certain\nproperties of the transaction spending a certain UTXO.</p>\n<p>Together with an opcode like <code>OP_CHECKSIGFROMSTACK</code>, this opcode effectively\nprovides a fully generalized signature hash construction, fully supporting\nall existing SIGHASH flags, the proposed sighash flags from\n<a href=\"/bip/118\">BIP-118</a> (<code>SIGHASH_ANYPREVOUT</code>) and many other new signature hash\ncombinations.</p>\n<p>The constructions specified in this BIP also open up the way for other\npotential updates; see Motivation section for more details.</p>\n<h1>Specification</h1>\n<h2 id=\"op-txhash\">OP_TXHASH</h2>\n<p><code>OP_TXHASH</code> redefines the <code>OP_SUCCESS189</code> tapscript opcode (<code>0xbd</code>) as a soft\nfork upgrade. This opcode is only active in tapscript contexts.</p>\n<p>Note that <code>OP_SUCCESS187</code> is used by <a href=\"/bip/443\">BIP-443</a> (<code>OP_CHECKCONTRACTVERIFY</code>) and\n<code>OP_SUCCESS188</code> was used by <a href=\"/bip/345\">BIP-345</a> (<code>OP_VAULT</code>) at the time of first draft\nof this BIP, making <code>OP_SUCCESS189</code> the next available opcode for this purpose.</p>\n<p>It has the following semantics:</p>\n<ul>\n<li>There is at least one element on the stack, fail otherwise.</li>\n<li>The element is interpreted as the TxFieldSelector and is popped off the stack.</li>\n<li>The TxFieldSelector must be valid, fail otherwise.</li>\n<li>The 32-byte TxHash of the transaction at the current input index, calculated\nusing the given TxFieldSelector is pushed onto the stack.</li>\n</ul>\n<h2 id=\"txfieldselector\">TxFieldSelector</h2>\n<p>The TxFieldSelector has the following encoding. We will give a brief conceptual\nsummary, followed by a reference implementation of the CalculateTxHash function.</p>\n<p>In the following specifications, the <code>|</code> operator is used for the bitwise OR\noperation.</p>\n<ul>\n<li>There are two special cases for the TxFieldSelector:<ul>\n<li><p>the empty value, zero bytes long: it is set equal to <code>TXFS_SPECIAL_TEMPLATE</code>,\nthe de-facto default value which means everything except the prevouts and\nthe prevout scriptPubkeys and amounts.</p>\n<p>Special case <code>TXFS_SPECIAL_TEMPLATE</code> is 4 bytes long, as follows:</p>\n<ul>\n<li>1: <code>TXFS_VERSION | TXFS_LOCKTIME | TXFS_CURRENT_INPUT_IDX</code></li>\n<li>2: <code>TXFS_INPUTS_SEQUENCES | TXFS_INPUTS_SCRIPTSIGS | TXFS_OUTPUTS_ALL</code></li>\n<li>3: <code>TXFS_INOUT_NUMBER | TXFS_INOUT_SELECTION_ALL</code></li>\n<li>4: <code>TXFS_INOUT_NUMBER | TXFS_INOUT_SELECTION_ALL</code></li>\n</ul>\n</li>\n<li><p>If the TxFieldSelector has exactly 1 byte, we use a <em>short notation</em>.\nIt has its 8 bits assigned as follows, from lowest to highest:</p>\n<ul>\n<li>2/1: Inputs<ul>\n<li>00: <code>TXFS_INOUT_SELECTION_NONE</code></li>\n<li>01: <code>TXFS_INOUT_SELECTION_CURRENT</code></li>\n<li>11: <code>TXFS_INOUT_SELECTION_ALL</code></li>\n</ul>\n</li>\n<li>4/3: Outputs<ul>\n<li>00: <code>TXFS_INOUT_SELECTION_NONE</code></li>\n<li>01: <code>TXFS_INOUT_SELECTION_CURRENT</code></li>\n<li>11: <code>TXFS_INOUT_SELECTION_ALL</code></li>\n</ul>\n</li>\n<li>5: <code>TXFS_INPUTS_PREVOUTS</code></li>\n<li>6: <code>TXFS_INPUTS_PREV_SCRIPTPUBKEYS | TXFS_INPUTS_PREV_VALUES</code></li>\n<li>7: <code>TXFS_CURRENT_INPUT_CONTROL_BLOCK | TXFS_CURRENT_INPUT_SPENTSCRIPT | TXFS_CURRENT_INPUT_LAST_CODESEPARATOR_POS</code></li>\n<li>8: <code>TXFS_CURRENT_INPUT_IDX</code></li>\n</ul>\n<p>Additionally, it includes <code>TXFS_VERSION | TXFS_LOCKTIME | TXFS_CONTROL | TXFS_CURRENT_INPUT_TAPROOT_ANNEX</code>\nas global fields and <code>TXFS_INPUTS_SEQUENCES | TXFS_INPUTS_SCRIPTSIGS | TXFS_OUTPUTS_ALL</code>\nas input and output fields.</p>\n<p>These 1-byte selections allow the TxFieldSelector to emulate current\nsignature hashing modes and those defined in <a href=\"/bip/118\">BIP-118</a>:</p>\n</li>\n</ul>\n</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th align=\"left\">BIP-341/118 sighash type</th>\n<th align=\"left\">1-byte TxFieldSelector</th>\n</tr>\n</thead>\n<tbody><tr>\n<td align=\"left\"><code>ALL</code></td>\n<td align=\"left\"><code>0b11111111</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>SINGLE</code></td>\n<td align=\"left\"><code>0b11110111</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>NONE</code></td>\n<td align=\"left\"><code>0b11110011</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>ALL|ANYONECANPAY</code></td>\n<td align=\"left\"><code>0b11111101</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>SINGLE|ANYONECANPAY</code></td>\n<td align=\"left\"><code>0b11110101</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>NONE|ANYONECANPAY</code></td>\n<td align=\"left\"><code>0b11110001</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>ALL|ANYPREVOUT</code></td>\n<td align=\"left\"><code>0b11101101</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>SINGLE|ANYPREVOUT</code></td>\n<td align=\"left\"><code>0b11100101</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>NONE|ANYPREVOUT</code></td>\n<td align=\"left\"><code>0b11100001</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>ALL|ANYPREVOUTANYSCRIPT</code></td>\n<td align=\"left\"><code>0b11001101</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>SINGLE|ANYPREVOUTANYSCRIPT</code></td>\n<td align=\"left\"><code>0b11000101</code></td>\n</tr>\n<tr>\n<td align=\"left\"><code>NONE|ANYPREVOUTANYSCRIPT</code></td>\n<td align=\"left\"><code>0b11000001</code></td>\n</tr>\n</tbody></table>\n<ul>\n<li><p>If the TxFieldSelector is longer than one byte, the first byte of the TxFieldSelector\nhas its 8 bits assigned as follows, from lowest to highest:</p>\n<ul>\n<li>1: version (<code>TXFS_VERSION</code>)</li>\n<li>2: locktime (<code>TXFS_LOCKTIME</code>)</li>\n<li>3: current input index (<code>TXFS_CURRENT_INPUT_IDX</code>)</li>\n<li>4: current input control block (<code>TXFS_CURRENT_INPUT_CONTROL_BLOCK</code>)</li>\n<li>5: current input spent script (<code>TXFS_CURRENT_INPUT_SPENTSCRIPT</code>)</li>\n<li>6: current script last <code>OP_CODESEPARATOR</code> position (or 0xffffffff)\n(<code>TXFS_CURRENT_INPUT_LAST_CODESEPARATOR_POS</code>)</li>\n<li>7: current input annex including prefix byte (or empty) (<code>TXFS_CURRENT_INPUT_TAPROOT_ANNEX</code>)</li>\n<li>8: <code>TXFS_CONTROL</code> (i.e. include TxFieldSelector into hash)</li>\n</ul>\n</li>\n<li><p>The highest bit of the first byte (<code>TXFS_CONTROL</code>), we will call the\n&quot;control bit&quot;, and it can be used to control the behavior of the opcode. For\n<code>OP_TXHASH</code>, the control bit is used to determine\nwhether the TxFieldSelector itself has to be included in the resulting hash.\n(For potential other uses of the TxFieldSelector (like a hypothetical\n<code>OP_TX</code>), this bit can be repurposed.)</p>\n</li>\n<li><p>The second byte will be used to indicate fields from the inputs and outputs.\nThe 8 bits are assigned the following variables, from lowest to highest:</p>\n<ul>\n<li><p>Specifying which fields of the inputs will be selected:</p>\n<ul>\n<li>1: prevouts (<code>TXFS_INPUTS_PREVOUTS</code>)</li>\n<li>2: sequences (<code>TXFS_INPUTS_SEQUENCES</code>)</li>\n<li>3: scriptSigs (<code>TXFS_INPUTS_SCRIPTSIGS</code>)</li>\n<li>4: prevout scriptPubkeys (<code>TXFS_INPUTS_PREV_SCRIPTPUBKEYS</code>)</li>\n<li>5: prevout values (<code>TXFS_INPUTS_PREV_VALUES</code>)</li>\n<li>6: taproot annexes (<code>TXFS_INPUTS_TAPROOT_ANNEXES</code>)</li>\n</ul>\n</li>\n<li><p>Specifying which fields of the outputs will be selected:</p>\n<ul>\n<li>7: scriptPubkeys (<code>TXFS_OUTPUTS_SCRIPTPUBKEYS</code>)</li>\n<li>8: values (<code>TXFS_OUTPUTS_VALUES</code>)</li>\n</ul>\n</li>\n</ul>\n</li>\n<li><p>We define as follows:</p>\n<ul>\n<li><code>TXFS_ALL = TXFS_VERSION | TXFS_LOCKTIME | TXFS_CURRENT_INPUT_IDX | TXFS_CURRENT_INPUT_CONTROL_BLOCK | TXFS_CURRENT_INPUT_LAST_CODESEPARATOR_POS | TXFS_CONTROL</code></li>\n<li><code>TXFS_INPUTS_ALL = TXFS_INPUTS_PREVOUTS | TXFS_INPUTS_SEQUENCES | TXFS_INPUTS_SCRIPTSIGS | TXFS_INPUTS_PREV_SCRIPTPUBKEYS | TXFS_INPUTS_PREV_VALUES | TXFS_INPUTS_TAPROOT_ANNEXES</code></li>\n<li><code>TXFS_OUTPUTS_ALL = TXFS_OUTPUTS_SCRIPTPUBKEYS | TXFS_OUTPUTS_VALUES</code></li>\n</ul>\n</li>\n<li><p>For both inputs and then outputs, expect an additional byte as follows:</p>\n<ul>\n<li><p>The highest bit (<code>TXFS_INOUT_NUMBER</code>) indicates whether the &quot;number of\nin-/outputs&quot; should be committed to.</p>\n</li>\n<li><p>For the remaining bits, there are three exceptional values:</p>\n<ul>\n<li>0x00 (<code>TXFS_INOUT_SELECTION_NONE</code>) means &quot;no in/outputs&quot; (hence only the\nnumber of them as <code>0x80</code> (<code>TXFS_INOUT_NUMBER</code>)).</li>\n<li><code>0x40</code> (<code>TXFS_INOUT_SELECTION_CURRENT</code>) means &quot;select only the in/output\nof the current input index&quot; (it is invalid when current index exceeds\nnumber of outputs).</li>\n<li><code>0x3f</code> (<code>TXFS_INOUT_SELECTION_ALL</code>) means &quot;select all in/outputs&quot;.</li>\n</ul>\n</li>\n<li><p>The second highest bit (<code>TXFS_INOUT_SELECTION_MODE</code>) is the &quot;specification mode&quot;:</p>\n<ul>\n<li>Set to 0 it means &quot;leading mode&quot;.</li>\n<li>Set to 1 it means &quot;individual mode&quot;.</li>\n</ul>\n</li>\n<li><p>In &quot;leading mode&quot;, the third highest bit (<code>TXFS_INOUT_LEADING_SIZE</code>) is\nused to indicate the &quot;index size&quot;, i.e. the number of bytes will be used to\nrepresent the number of in/output.</p>\n<ul>\n<li>With &quot;index size&quot; set to 0, the remaining lowest 5 bits of the first byte\nwill be interpreted as the number of leading in/outputs to select.</li>\n<li>With &quot;index size&quot; set to 1, the remaining lowest 5 bits of the first byte\ntogether with the 8 bits of the next byte will be interpreted as the\nnumber of leading in/outputs to select.</li>\n</ul>\n</li>\n<li><p>In &quot;individual mode&quot;, the third highest bit (<code>TXFS_INOUT_INDIVIDUAL_MODE</code>)\nindicates whether we are passing absolute indices (0) or indices relative\nto the current input (1), the remaining lowest 5 bits will be interpreted\nas <code>n</code>, the number of individual in/outputs follow.</p>\n<ul>\n<li>In absolute mode (second highest bit is 0), for each of the <code>n</code> indices,\nat least one extra byte is expected.<ul>\n<li>If that byte&#39;s highest bit is set to 0, the remaining 7 bits represent\nthe absolute index to select.</li>\n<li>If that byte&#39;s highest bit is set to 1, the remaining 7 bits, together\nwith the next byte&#39;s 8 bits represent the absolute index to select.</li>\n</ul>\n</li>\n<li>In relative mode (second highest bit is 1), for each of the <code>n</code> indices,\nat least one extra byte is expected.<ul>\n<li>If that byte&#39;s highest bit is set to 0, the remaining 7 bits represent\nthe relative index in two&#39;s complement.</li>\n<li>If that byte&#39;s highest bit is set to 1, the remaining 7 bits, together\nwith the next byte&#39;s 8 bits represent the relative index in two&#39;s\ncomplement.</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<p>Effectively, this allows a user to select</p>\n<ul>\n<li>all in/outputs</li>\n<li>the current input index</li>\n<li>the leading in/outputs up to 8,191</li>\n<li>up to 32 individually selected in/outputs\n** using absolute indices up to 32,767\n** using indices relative to the current input index from -16382 to +16383.</li>\n</ul>\n<h3 id=\"txfieldselector-malleability\">TxFieldSelector malleability</h3>\n<p>It is possible to represent the same selected data using multiple different\nTxFieldSelectors. For this reason, users are advised to always set the\n<code>TXFS_CONTROL</code> field flag that commits to the TxFieldSelector that was used\nto get the hash.</p>\n<h3 id=\"visualization\">Visualization</h3>\n<ul>\n<li>first byte</li>\n</ul>\n<pre><code>1 1 1 1 1 1 1 1\n| | | | | | | ^ version\n| | | | | | ^ locktime\n| | | | | ^ current input index\n| | | | ^ current input control block\n| | | ^ current input spent script\n| | ^ current script last OP_CODESEPARATOR\n| ^ current input taproot annex\n^ control bit (ie. include TXFS in hash)\n</code></pre>\n<ul>\n<li>second byte</li>\n</ul>\n<pre><code>&lt;-&gt; outputs\n| | &lt;---------&gt; inputs\n1 1 1 1 1 1 1 1\n| | | | | | | ^ prevouts\n| | | | | | ^ sequences\n| | | | | ^ scriptSigs\n| | | | ^ prevout scriptPubkeys\n| | | ^ prevout values\n| | ^ taproot annexes\n| ^ scriptPubkeys\n^ values\n</code></pre>\n<ul>\n<li>in/output selector byte</li>\n</ul>\n<p>&quot;leading 3 in/outputs&quot;</p>\n<pre><code>1 0 0 0 0 0 1 1\n| | | &lt;-------&gt; integer 0b00011 == 3\n| | ^ index size: single byte\n| ^ leading mode\n^ commit the number of in/outputs\n</code></pre>\n<p>&quot;leading 257 in/outputs&quot;</p>\n<pre><code>1 0 1 0 0 0 0 1  0 0 0 0 0 0 0 1\n| | | &lt;------------------------&gt; integer 0b00001 00000001 == 257\n| | ^ index size 1: two bytes\n| ^ leading mode\n^ commit the number of in/outputs\n</code></pre>\n<p>&quot;indices 1 and 3&quot;</p>\n<pre><code>0 1 0 0 0 0 1 0  0 0 0 0 0 0 0 1  0 0 0 0 0 0 1 1\n| | | |                           &lt;--------------&gt; second idx: 3\n| | | |          &lt;-------------&gt; first idx: 1\n| | | | &lt;-----&gt; selection count: 0b0010 == 2 indices\n| | | ^ index size: single byte per index\n| | ^ absolute index\n| ^ individual mode\n^ don&#39;t commit the number of in/outputs\n</code></pre>\n<ul>\n<li>total example</li>\n</ul>\n<pre><code>ff ff c2 01 03 83\n |  |           ^ commit number of outputs + leading 3 outputs\n |  | &lt;------&gt; commit number of inputs + inputs at indices 1 and 3\n |  ^ all input and output fields\n ^ all regular fields\n</code></pre>\n<h2 id=\"resource-limits\">Resource limits</h2>\n<p>Using the same validation budget (&quot;sigops budget&quot;) introduced in BIP-0342,\neach TransactionHash decreases the validation budget by 25. If this brings the\nbudget below zero, the script fails immediately.<br>The following\nconsiderations should be made:</p>\n<ul>\n<li>All fields that can be of arbitrary size are cacheable as TransactionHash\nalways hashes their hashed values.</li>\n<li>In &quot;individual mode&quot;, a user can at most commit 32 inputs or outputs,\nwhich we don&#39;t consider excessive for potential repeated use.</li>\n<li>In &quot;leading mode&quot;, a caching strategy can be used where the SHA256 context\nis stored every N in/outputs so that multiple executions of the\nTransactionHash function can use the caches and only have to hash an\nadditional N-1 items at most.</li>\n</ul>\n<h1>Motivation</h1>\n<p>This BIP specifies a basic transaction introspection primitive that is useful\nto either reduce interactivity in multi-user protocols or to enforce some basic\nconstraints on transactions.</p>\n<p>Additionally, the constructions specified in this BIP can lay the groundwork for\nsome potential future upgrades:</p>\n<ul>\n<li>The TxFieldSelector construction would work well with a hypothetical opcode\n<code>OP_TX</code> that allows for directly introspecting the transaction by putting the\nfields selected on the stack instead of hashing them together.</li>\n<li>The TransactionHash obtained by <code>OP_TXHASH</code> can be combined with <code>OP_CHECKSIGFROMSTACK</code>\n(see <a href=\"/bip/348\">BIP-348</a>) to effectively create an\nincredibly flexible signature hash, which would enable constructions like\n<code>SIGHASH_ANYPREVOUT</code>.</li>\n<li>The TransactionHash obtained by <code>OP_TXHASH</code> can be introduced as a native\nsighash calculation in a future segwit upgrade, so that signatures using the\nTransactionHash as their sighash can be used in keyspend context.</li>\n</ul>\n<h2 id=\"comparing-with-some-alternative-proposals\">Comparing with some alternative proposals</h2>\n<ul>\n<li><p>This proposal strictly generalizes BIP-119&#39;s <code>OP_CHECKTEMPLATEVERIFY</code>, as the\ndefault mode of our TxFieldSelector is semantically the same (though not\nbyte-for-byte identical) as what <code>OP_CTV</code> accomplishes, without costing any\nadditional bytes. Additionally, using <code>OP_TXHASH</code> allows for more\nflexibility which can help in the case for</p>\n<ul>\n<li>enabling adding fees to a transaction without breaking a multi-tx protocol;</li>\n<li>multi-user protocols where users are only concerned about their own inputs and outputs.</li>\n</ul>\n</li>\n<li><p>Constructions like <code>OP_IN_OUT_VALUE</code> used with <code>OP_EQUALVERIFY</code> can be\nemulated by two <code>OP_TXHASH</code> instances by using the TxFieldSelector to select\na single input value first and a single output value second and enforcing\nequality on the hashes. Neither of these alternatives can be used to enforce\nsmall value differences without the availability of 64-bit arithmetic in\nScript.</p>\n</li>\n<li><p>Like mentioned above, <code>SIGHASH_ANYPREVOUT</code> can be emulated using <code>OP_TXHASH</code>\nwhen combined with <code>OP_CHECKSIGFROMSTACK</code>: \n<code>&lt;txfs&gt; OP_TXHASH &lt;pubkey&gt; OP_CHECKSIGFROMSTACK</code> effectively emulates <code>SIGHASH_ANYPREVOUT</code>.</p>\n</li>\n</ul>\n<h1>Reference Implementation</h1>\n<p>A reference implementation in Rust is provided attached as part of this BIP\ntogether with a JSON file of test vectors generated using the reference\nimplementation.</p>\n<h1>Design Considerations</h1>\n<p>This specification in in <em>Draft</em> and there is definitely still room for feedback\nand improvements. Some considerations that were made but could be revisited:</p>\n<ul>\n<li>The <code>0b10</code> in/output selector for the shorthand is unused.\nCould possibly be filled in with &quot;current + next&quot;, &quot;current + previous&quot; or\nany other semantics.</li>\n<li>The individual index selection semantics allow for absolute indices up to ~32k\nand relative ones up to +/- ~16k, which is probably excessive. When removing\nthe second byte there would reduce that to just 256 and +/- 128 respectively.</li>\n<li>Similar to <code>OP_TEMPLATEHASH</code> (BIP number to be assigned, <a href=\"https://github.com/bitcoin/bips/pull/1974\">PR</a>),\nwe could not support <code>scriptSigs</code> anymore and remove\n<code>TXFS_INPUTS_SCRIPTSIGS</code>. This field could then possibly be repurposed.</li>\n</ul>\n<h1>Backwards Compatibility</h1>\n<p><code>OP_TXHASH</code> replaces <code>OP_SUCCESS189</code>. The <code>SUCCESS</code> opcodes were\nintroduced in taproot (BIP-342) to support changing the semantics of opcodes in\nways that do allow the new semantics to change the stack. For this reason,\n<code>OP_TXHASH</code> only works in tapscript context. Since it is overriding a <code>SUCCESS</code>\nopcode, any older version of the software will always accept any script that\nuses the opcode, while the new versions of the software will validate the\nscripts according to the semantics outlined in this BIP. As such, this is also a\nsoft fork change.</p>\n<h2 id=\"interactions-with-other-bips\">Interactions with other BIPs</h2>\n<p>This proposal interacts with several other BIPs:</p>\n<ul>\n<li><p><strong><a href=\"/bip/118\">BIP-118</a> (SIGHASH_ANYPREVOUT)</strong>: <code>OP_TXHASH</code> can be combined with\n<code>OP_CHECKSIGFROMSTACK</code> (BIP-348) to emulate <code>SIGHASH_ANYPREVOUT</code> and other\nsignature hash modes defined in BIP-118. The 1-byte TxFieldSelector format\nexplicitly supports these modes.</p>\n</li>\n<li><p><strong><a href=\"/bip/119\">BIP-119</a> (OP_CHECKTEMPLATEVERIFY)</strong>: <code>OP_TXHASH</code> with the empty\nTxFieldSelector produces a hash semantically equivalent to BIP-119&#39;s\n<code>OP_CHECKTEMPLATEVERIFY</code>, making this proposal a generalization of BIP-119.</p>\n</li>\n<li><p><strong><a href=\"/bip/347\">BIP-347</a> (OP_CAT)</strong>: When combined with <code>OP_CAT</code>, <code>OP_TXHASH</code> enables\npowerful transaction introspection capabilities. The bit encoding format is\ndesigned to be explicit about endianness to ensure correct interaction with\nconcatenation operations.</p>\n</li>\n<li><p><strong><a href=\"/bip/348\">BIP-348</a> (OP_CHECKSIGFROMSTACK)</strong>: Together with <code>OP_CHECKSIGFROMSTACK</code>,\n<code>OP_TXHASH</code> provides a fully generalized signature hash construction,\nenabling flexible covenant designs and multi-user protocols.</p>\n</li>\n</ul>\n<h1>Implementation</h1>\n<p>A reference implementation is included as part of the BIP, see\n<a href=\"https://github.com/bitcoin/bips/blob/master/bip-0346/ref-impl/src/main.rs\">here</a>. This implementation focusses on clarity\nand correctness, not on efficiency. A rudimentary set of test vectors is also\ngenerated from this implementation and included\n<a href=\"https://github.com/bitcoin/bips/blob/master/bip-0346/ref-impl/txhash_vectors.json\">here</a>.</p>\n<p>Furthermore, following other implementation attempts exist:</p>\n<ul>\n<li>A proposed implementation for Bitcoin Core is available here:\n<a href=\"https://github.com/bitcoin/bitcoin/pull/29050\">https://github.com/bitcoin/bitcoin/pull/29050</a></li>\n<li>A proposed implementation for rust-bitcoin is available here:\n<a href=\"https://github.com/rust-bitcoin/rust-bitcoin/pull/2275\">https://github.com/rust-bitcoin/rust-bitcoin/pull/2275</a></li>\n</ul>\n<p>NOTE: These implementations are slightly outdated as they were made for an\nearlier version of this specification. Updates are in progress.</p>\n<p>Both of the above implementations perform effective caching to avoid potential\ndenial-of-service attack vectors.</p>\n<h1>Deployment</h1>\n<p>This BIP can be deployed using a BIP 9 VersionBits deployment. The specific\nstrategy and bit assignment are left unspecified and can later be amended to the\nBIP depending on community preference.</p>\n<h1>Acknowledgement</h1>\n<p>Credit for this proposal mostly goes to Jeremy Rubin for his work on BIP-119&#39;s\n<code>OP_CHECKTEMPLATEVERIFY</code> and to Russell O&#39;Connor for the original idea of\ngeneralizing <code>OP_CHECKTEMPLATEVERIFY</code> into <code>OP_TXHASH</code>.</p>\n<p>Additional thanks to Andrew Poelstra, Greg Sanders, Rearden Code, Rusty Russell\nand others for their feedback on the specification.</p>\n<h1>Copyright</h1>\n<p>This document is licensed under the 3-clause BSD license.</p>\n","toc":[{"id":"op-txhash","title":"OP_TXHASH","level":2},{"id":"txfieldselector","title":"TxFieldSelector","level":2},{"id":"txfieldselector-malleability","title":"TxFieldSelector malleability","level":3},{"id":"visualization","title":"Visualization","level":3},{"id":"resource-limits","title":"Resource limits","level":2},{"id":"comparing-with-some-alternative-proposals","title":"Comparing with some alternative proposals","level":2},{"id":"interactions-with-other-bips","title":"Interactions with other BIPs","level":2}],"history":{"totalCommits":2,"firstCommit":"2023-09-06T16:16:35+01:00","lastUpdated":"2026-02-04T16:39:50-06:00","events":[{"sha":"10c78888857fc5609a9b0ea1bf360407e3a5f203","date":"2026-02-04T16:39:50-06:00","author":"Paul Miller","message":"Escape pipe character in markdown table (#2095)","url":"https://github.com/bitcoin/bips/commit/10c78888857fc5609a9b0ea1bf360407e3a5f203","kind":"edit"},{"sha":"6a0636da32ff34e100e887df21eb0d8ec1d4b834","date":"2023-09-06T16:16:35+01:00","author":"Steven Roose","message":"Add BIP-346: OP_TXHASH","url":"https://github.com/bitcoin/bips/commit/6a0636da32ff34e100e887df21eb0d8ec1d4b834","kind":"edit"}]}}