@@ -167,31 +167,40 @@ OP_CHECKTEMPLATEVERIFY as implemented in C++ in the context of Bitcoin Core can
167
167
be seen in the reference implementation.
168
168
169
169
The execution of the opcode is as follows:
170
- def execute_bip_119(self):
171
- # Before soft-fork activation / failed activation
172
- if not self.flags.script_verify_default_check_template_verify_hash:
173
- # Potentially set for node-local policy to discourage premature use
174
- if self.flags.script_verify_discourage_upgradable_nops:
175
- return self.errors_with(errors.script_err_discourage_upgradable_nops)
176
- return self.return_as_nop()
177
- # CTV always requires at least one stack argument
178
- if len(self.stack) < 1:
179
- return self.errors_with(errors.script_err_invalid_stack_operation)
180
- # CTV only verifies the hash against a 32 byte argument
181
- if len(self.stack[-1]) == 32:
182
- # Ensure the precomputed data required for anti-DoS is available,
183
- # or cache it on first use
184
- if self.context.precomputed_ctv_data == None:
185
- self.context.precomputed_ctv_data = self.context.tx.get_default_check_template_precomputed_data()
186
- if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data)
187
- return self.errors_with(errors.script_err_template_mismatch)
188
- return self.return_as_nop()
189
- # future upgrade can add semantics for this opcode with different length args
190
- # so discourage use when applicable
170
+ <source lang="python">
171
+ def execute_bip_119(self):
172
+ # Before soft-fork activation / failed activation
173
+ # continue to treat as NOP4
174
+ if not self.flags.script_verify_default_check_template_verify_hash:
175
+ # Potentially set for node-local policy to discourage premature use
191
176
if self.flags.script_verify_discourage_upgradable_nops:
192
177
return self.errors_with(errors.script_err_discourage_upgradable_nops)
193
- else:
194
- return self.return_as_nop()
178
+ return self.return_as_nop()
179
+
180
+ # CTV always requires at least one stack argument
181
+ if len(self.stack) < 1:
182
+ return self.errors_with(errors.script_err_invalid_stack_operation)
183
+
184
+ # CTV only verifies the hash against a 32 byte argument
185
+ if len(self.stack[-1]) == 32:
186
+ # Ensure the precomputed data required for anti-DoS is available,
187
+ # or cache it on first use
188
+ if self.context.precomputed_ctv_data == None:
189
+ self.context.precomputed_ctv_data = self.context.tx.get_default_check_template_precomputed_data()
190
+
191
+ # If the hashes do not match, return error
192
+ if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data)
193
+ return self.errors_with(errors.script_err_template_mismatch)
194
+
195
+ return self.return_as_nop()
196
+
197
+ # future upgrade can add semantics for this opcode with different length args
198
+ # so discourage use when applicable
199
+ if self.flags.script_verify_discourage_upgradable_nops:
200
+ return self.errors_with(errors.script_err_discourage_upgradable_nops)
201
+ else:
202
+ return self.return_as_nop()
203
+ </source>
195
204
196
205
The computation of this hash can be implemented as specified below (where self
197
206
is the transaction type). Care must be taken that in any validation context,
@@ -202,46 +211,50 @@ including hashes of the scriptsigs, sequences, and outputs. See the section
202
211
"Denial of Service and Validation Costs" below. This is not a performance
203
212
optimization.
204
213
205
- def get_default_check_template_precomputed_data(self):
206
- result = {}
207
- # If there are no scriptSigs we do not need to precompute a hash
208
- if any(inp.scriptSig for inp in self.vin):
209
- result["scriptSigs"] = sha256(b"".join(ser_string(inp.scriptSig) for inp in self.vin))
210
- # The same value is also pre-computed for and defined in BIP-341 and can be shared
211
- result["sequences"] = sha256(b"".join(struct.pack("<I", inp.nSequence) for inp in self.vin))
212
- # The same value is also pre-computed for and defined in BIP-341 and can be shared
213
- result["outputs"] = sha256(b"".join(out.serialize() for out in self.vout))
214
- return result
215
-
216
- # parameter precomputed must be passed in for DoS resistance
217
- def get_default_check_template_hash(self, nIn, precomputed = None):
218
- if precomputed == None:
219
- precomputed = self.get_default_check_template_precomputed_data()
220
- r = b""
221
- # pack as 4 byte signed integer
222
- r += struct.pack("<i", self.nVersion)
223
- # pack as 4 byte unsigned integer
224
- r += struct.pack("<I", self.nLockTime)
225
- # we do not include the hash in the case where there is no
226
- # scriptSigs
227
- if "scriptSigs" in precomputed:
228
- r += precomputed["scriptSigs"]
229
- # pack as 4 byte unsigned integer
230
- r += struct.pack("<I", len(self.vin))
231
- r += precomputed["sequences"]
232
- # pack as 4 byte unsigned integer
233
- r += struct.pack("<I", len(self.vout))
234
- r += precomputed["outputs"]
235
- # pack as 4 byte unsigned integer
236
- r += struct.pack("<I", nIn)
237
- return sha256(r)
214
+ <source lang ="python" >
215
+ def get_default_check_template_precomputed_data(self):
216
+ result = {}
217
+ # If there are no scriptSigs we do not need to precompute a hash
218
+ if any(inp.scriptSig for inp in self.vin):
219
+ result["scriptSigs"] = sha256(b"".join(ser_string(inp.scriptSig) for inp in self.vin))
220
+ # The same value is also pre-computed for and defined in BIP-341 and can be shared
221
+ result["sequences"] = sha256(b"".join(struct.pack("<I", inp.nSequence) for inp in self.vin))
222
+ # The same value is also pre-computed for and defined in BIP-341 and can be shared
223
+ result["outputs"] = sha256(b"".join(out.serialize() for out in self.vout))
224
+ return result
225
+
226
+ # parameter precomputed must be passed in for DoS resistance
227
+ def get_default_check_template_hash(self, nIn, precomputed = None):
228
+ if precomputed == None:
229
+ precomputed = self.get_default_check_template_precomputed_data()
230
+ r = b""
231
+ # pack as 4 byte signed integer
232
+ r += struct.pack("<i", self.nVersion)
233
+ # pack as 4 byte unsigned integer
234
+ r += struct.pack("<I", self.nLockTime)
235
+ # we do not include the hash in the case where there is no
236
+ # scriptSigs
237
+ if "scriptSigs" in precomputed:
238
+ r += precomputed["scriptSigs"]
239
+ # pack as 4 byte unsigned integer
240
+ r += struct.pack("<I", len(self.vin))
241
+ r += precomputed["sequences"]
242
+ # pack as 4 byte unsigned integer
243
+ r += struct.pack("<I", len(self.vout))
244
+ r += precomputed["outputs"]
245
+ # pack as 4 byte unsigned integer
246
+ r += struct.pack("<I", nIn)
247
+ return sha256(r)
248
+ </source >
238
249
239
250
240
251
A PayToBareDefaultCheckTemplateVerifyHash output matches the following template:
241
252
242
- # Extra-fast test for pay-to-basic-standard-template CScripts:
243
- def is_pay_to_bare_default_check_template_verify_hash(self):
244
- return len(self) == 34 and self[0] == 0x20 and self[-1 ] == OP_CHECKTEMPLATEVERIFY
253
+ <source lang ="python" >
254
+ # Extra-fast test for pay-to-basic-standard-template CScripts:
255
+ def is_pay_to_bare_default_check_template_verify_hash(self):
256
+ return len(self) == 34 and self[0] == 0x20 and self[-1] == OP_CHECKTEMPLATEVERIFY
257
+ </source >
245
258
246
259
247
260
==Deployment ==
0 commit comments