|
| 1 | +<pre> |
| 2 | + BIP: tbd |
| 3 | + Layer: Consensus (soft fork) |
| 4 | + Title: OP_TXHASH and OP_CHECKTXHASHVERIFY |
| 5 | + Author: Steven Roose < [email protected]> |
| 6 | + Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-tbd |
| 7 | + Status: Draft |
| 8 | + Type: Standards Track |
| 9 | + Created: 2023-09-03 |
| 10 | + License: BSD-3-Clause |
| 11 | +</pre> |
| 12 | + |
| 13 | +==Abstract== |
| 14 | + |
| 15 | +This BIP proposes two new opcodes, OP_CHECKTXHASHVERIFY, to be activated |
| 16 | +as a change to the semantics of OP_NOP4 in legacy script, segwit and tapscript; |
| 17 | +and OP_TXHASH, to be activated as a change to the semantics of OP_SUCCESS189 |
| 18 | +in tapscript only. |
| 19 | + |
| 20 | +These new opcodes allow for non-interactive enforcement of certain properties |
| 21 | +of transactions spending a certain UTXO. Together with something like |
| 22 | +OP_CHECKSIGFROMSTACK (and maybe OP_CAT) it would also enable the emulation of |
| 23 | +arbitrarily complex sighash types. More on the use cases in the Motivation |
| 24 | +section of this BIP. |
| 25 | + |
| 26 | + |
| 27 | +==Summary== |
| 28 | + |
| 29 | +OP_CHECKTXHASHVERIFY uses opcode OP_NOP4 (0xb3) as a soft fork upgrade. |
| 30 | + |
| 31 | +OP_CHECKTXHASHVERIFY does the following: |
| 32 | + |
| 33 | +* There is at least one element on the stack, fail otherwise. |
| 34 | +* The element on the stack is at least 32 bytes long, fail otherwise. |
| 35 | +* The first 32 bytes are interpreted as the TxHash and the remaining suffix |
| 36 | + bytes specify the TxFieldSelector. |
| 37 | +* If ValidateTxFieldSelector fails for the provided TxFieldSelector, fail. |
| 38 | +* The actual TxHash of the transaction at the current input index, calculated |
| 39 | + using the given TxFieldSelector must be equal to the first 32 bytes of the |
| 40 | + element on the stack, fail otherwise. |
| 41 | +
|
| 42 | + |
| 43 | +OP_TXHASH uses tapscript opcode OP_SUCCESS189 (0xbd) as a soft fork upgrade. |
| 44 | + |
| 45 | +OP_TXHASH does the following: |
| 46 | + |
| 47 | +* There is at least one element on the stack, fail otherwise. |
| 48 | +* The element is interpreted as the TxFieldSelector and is popped off the stack. |
| 49 | +* If ValidateTxFieldSelector fails for the provided TxFieldSelector, fail. |
| 50 | +* The 32-byte TxHash of the transaction at the current input index, |
| 51 | + calculated using the given TxFieldSelector is pushed onto the stack. |
| 52 | +
|
| 53 | + |
| 54 | +The TxFieldSelector has the following semantics. We will give a brief conceptual |
| 55 | +summary, followed by a reference implementation of the CalculateTxHash function. |
| 56 | + |
| 57 | +* If the TxFieldSelector is zero bytes long, it is set equal to |
| 58 | + 0xff|0xf6|0x3f|0x3f, the de-facto default value which means everything except |
| 59 | + the prevouts and the prevout scriptPubkeys. |
| 60 | +* The first byte of the TxFieldSelector has its 8 bits assigned as follows, |
| 61 | + from lowest to highest: |
| 62 | + 1. version |
| 63 | + 2. locktime |
| 64 | + 3. nb_inputs |
| 65 | + 4. nb_outputs |
| 66 | + 5. current input index |
| 67 | + 6. current input control block (only in case of tapscript spend) |
| 68 | + 7. inputs |
| 69 | + 8. outputs |
| 70 | +
|
| 71 | +* If either "inputs" or "outputs" is set to 1, expect another byte with its 8 |
| 72 | + bits assigning the following variables, from lowest to highest: |
| 73 | + * Specifying which fields of the inputs will be selected: |
| 74 | + 1. prevouts |
| 75 | + 2. sequences |
| 76 | + 3. scriptSigs |
| 77 | + 4. prevout scriptPubkeys |
| 78 | + 5. prevout values |
| 79 | + 6. taproot annexes (only in case of tapscript spend) |
| 80 | + * Specifying which fields of the outputs will be selected: |
| 81 | + 7. scriptPubkeys |
| 82 | + 8. values |
| 83 | +
|
| 84 | +For both inputs and then outputs, do the following: |
| 85 | + |
| 86 | +* If the "in/outputs" field is set to 1, another additional byte is expected: |
| 87 | + * There are two exceptional values: |
| 88 | + - 0x00 means "select only the in/output of the current input index". |
| 89 | + - 0x3f means "select all in/outputs". //TODO(stevenroose) make this 0xff? |
| 90 | + * The highest bit is the "specification mode": |
| 91 | + - Set to 0 it means "prefix mode". |
| 92 | + - Set to 1 it means "individual mode". |
| 93 | + * The second highest bit is used to indicate the "index size", i.e. the number |
| 94 | + of bytes will be used to represent in/output indices. |
| 95 | + * In "prefix mode", |
| 96 | + - With "index size" set to 0, the remaining lowest 6 bits of the first byte |
| 97 | + will be interpreted as the number of leading in/outputs to select. |
| 98 | + - With "index size" set to 1, the remaining lowest 6 bits of the first byte |
| 99 | + together with the 8 bits of the next byte will be interpreted as the |
| 100 | + number of leading in/outputs to select. |
| 101 | + * In "individual mode", the remaining lowest 6 bits of the first byte will be |
| 102 | + interpreted as `n`, the number of individual in/outputs to select. |
| 103 | + - With "index size" set to 0, interpret the following `n` individual bytes |
| 104 | + as the indices of an individual in/outputs to select. |
| 105 | + - With "index size" set to 1, interpret the next `n` pairs of two bytes as |
| 106 | + the indices of individual in/outputs to select. |
| 107 | +
|
| 108 | + |
| 109 | +The function ValidateTxFieldSelector has the following semantics, it |
| 110 | +effectively checks that the TxFieldSelector value is valid according to |
| 111 | +above rules: |
| 112 | + |
| 113 | +* If there are 0 bytes, it becomes the default of 0xff|0xf6|0xff|0xff; succeed. |
| 114 | +* If the first byte is exactly 0x00, the Script execution succeeds immediately. |
| 115 | + //TODO(stevenroose) is this valuable? it's the only "exception case" that |
| 116 | + could potentially be hooked for some future upgrade |
| 117 | +* If in the first byte, "inputs" and "outputs" is 0, no additional bytes can be |
| 118 | + present, otherwise fail. |
| 119 | +* If the "inputs" bit is set to 1, one of the lowest 6 bits in the second byte |
| 120 | + must be set to 1, otherwise fail. |
| 121 | +* If the "outputs" bit is set to 1, one of the highest 2 bits in the second byte |
| 122 | + must be set to 1, otherwise fail. |
| 123 | +* If in the first byte, "inputs" or "outputs" is 1, do the following, once for |
| 124 | + each: |
| 125 | + * Expect an additional byte. |
| 126 | + * If this byte is either 0x00 or 0x3f, no additional bytes are expected for |
| 127 | + this section. |
| 128 | + * Interpret the top 2 bits of this byte as per above, setting the |
| 129 | + "specification" mode and "index size". |
| 130 | + * In "prefix mode": |
| 131 | + * with "index size" 0, no additional bytes are expected, otherwise fail; |
| 132 | + * with "index size" 1, one additional byte are expected, otherwise fail. |
| 133 | + * In "individual mode", interpret the lowest 6 bits of this byte as integer n, |
| 134 | + so that |
| 135 | + * with "index size" 0, n additional bytes are expected, otherwise fail; |
| 136 | + * with "index size" 1, two times n additional bytes are expected, otherwise |
| 137 | + fail. |
| 138 | +* If any additional bytes are present after this, fail. |
| 139 | +
|
| 140 | + |
| 141 | +The recommended standardness rules additionally: |
| 142 | + |
| 143 | +* Reject non-empty pushes starting with the 0 byte preceding OP_TXHASH as |
| 144 | + SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS. |
| 145 | +
|
| 146 | + |
| 147 | +===Resource limits=== |
| 148 | + |
| 149 | +* For legacy scripts and segwit, we don't add any extra resource limitations, |
| 150 | + with the argumentation that OP_CHECKTXHASHVERIFY already requires the user to |
| 151 | + provide at least 32 bytes of extra transaction size, either in the input |
| 152 | + scriptSig, or the witness. Additional more complex hashes require additional |
| 153 | + witness bytes. Given that OP_CAT is not available in this context, if a |
| 154 | + malicious user tries to increase the number of TransactionHashes being |
| 155 | + calculated by using opcodes like OP_DUP, the TxFieldSelector for all these |
| 156 | + calculations is identical, so the calculation can be cached within the same |
| 157 | + transaction. |
| 158 | +
|
| 159 | +* For tapscript, primarily motivated by the cheaper opcode OP_TXHASH (that |
| 160 | + doesn't require an additional 32 witness bytes be provided) and the potential |
| 161 | + future addition of byte manipulation opcodes like OP_CAT, an additional cost |
| 162 | + is specified per TransactionHash execution. |
| 163 | + Using the same validation budget ("sigops budget") introduced in BIP-0342, |
| 164 | + each TransactionHash decreases the validation budget by 10. |
| 165 | +
|
| 166 | + * Additionally, in "individual mode", the validation budget is decreased by 1 |
| 167 | + for every 5 in/outputs selected above the first 10. |
| 168 | + * NB: For "prefix mode" selectors, a caching strategy can be used where the |
| 169 | + SHA256 context is stored every N in/outputs so that multiple executions |
| 170 | + of the TransactionHash function can use the caches and only have to hash an |
| 171 | + additional N-1 items at most. |
| 172 | +
|
| 173 | + If either budget requriement brings the budget below zero, the script fails |
| 174 | + immediately. |
| 175 | +
|
| 176 | + |
| 177 | +==Motivation== |
| 178 | + |
| 179 | +This BIP specifies a basic transaction introspection primitive that is useful |
| 180 | +to either reduce interactivity in multi-user protocols or to enforce some basic |
| 181 | +constraints on transactions. |
| 182 | + |
| 183 | +Additionally, the constructions specified in this BIP can lay the groundwork for |
| 184 | +some potential future upgrades: |
| 185 | +* The TxFieldSelector construction would work well with a hypothetical opcode |
| 186 | + OP_TX that allows for directly introspecting the transaction by putting the |
| 187 | + fields selected on the stack instead of hashing them together. |
| 188 | +* The TransactionHash obtained by OP_TXHASH can be combined with a hypothetical |
| 189 | + opcode OP_CHECKSIGFROMSTACK to effectively create an incredibly flexible |
| 190 | + signature hash, which would enable constructions like SIGHASH_ANYPREVOUT. |
| 191 | +
|
| 192 | +===Comparing with some alternative proposals=== |
| 193 | + |
| 194 | +* This proposal strictly supercedes BIP-119's OP_CHECKTEMPLATEVERIFY, as the |
| 195 | + default mode of our TxFieldSelector is effectively (though not byte-for-byte |
| 196 | + identical) the same as what OP_CTV acomplishes, without costing any additional |
| 197 | + bytes. Additionally, using OP_CHECKTXHASHVERIFY allows for more flexibility |
| 198 | + which can help in the case for |
| 199 | + * enabling adding fees to a transaction without breaking a multi-tx protocol; |
| 200 | + * multi-user protocols where users are only concerned about their own inputs |
| 201 | + and outputs. |
| 202 | +
|
| 203 | +* Constructions like OP_IN_OUT_VALUE used with OP_EQUALVERIFY can be emulated by |
| 204 | + two OP_TXHASH instances by using the TxFieldSelector to select a single input |
| 205 | + value first and a single output value second and enforcing equality on the |
| 206 | + hashes. Neither of these alternatives can be used to enforce small value |
| 207 | + differencials without the use of 64-bit arithmetic. |
| 208 | +
|
| 209 | +* Like mentioned above, SIGHASH_ANYPREVOUT can be emulated using OP_TXHASH when |
| 210 | + combined with OP_CHECKSIGFROMSTACK and OP_CAT. |
| 211 | + `OP_DUP OP_TXHASH OP_CAT <"some_tag"> OP_SWAP OP_SHA256 <pubkey> |
| 212 | + OP_CHECKSIGFROMSTACK` effectively emulates SIGHASH_ANYPREVOUT. |
| 213 | +
|
| 214 | + |
| 215 | + |
| 216 | + |
| 217 | +==Detailed Specification== |
| 218 | + |
| 219 | +<source lang="rust"> |
| 220 | +wip |
| 221 | +</source> |
| 222 | + |
| 223 | + |
| 224 | + |
| 225 | + |
| 226 | +==Acknowledgement== |
| 227 | + |
| 228 | +Credit for this proposal mostly goes to Jeremy Rubin for his work on BIP-119's |
| 229 | +OP_CHECKTEMPLATEVERIFY and to Russell O'Connor for the original idea of |
| 230 | +OP_TXHASH. |
| 231 | + |
| 232 | +Additional thanks to Andrew Poelstra, Rearden Code, Rusty Russell and |
| 233 | +others for their feedback on the specification. |
| 234 | + |
0 commit comments