Skip to content

Commit 6af28b9

Browse files
committed
Add BIP for OP_TXHASH and OP_CHECKTXHASHVERIFY
1 parent e643d24 commit 6af28b9

File tree

1 file changed

+234
-0
lines changed

1 file changed

+234
-0
lines changed

bip-txhash.mediawiki

+234
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
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

Comments
 (0)