@@ -163,7 +163,8 @@ forming a "Payment Pool".
163
163
164
164
The below code is the main logic for verifying CHECKTEMPLATEVERIFY, described
165
165
in pythonic pseduocode. The canonical specification for the semantics of
166
- OP_CHECKTEMPLATEVERIFY can be seen in the reference implementations.
166
+ OP_CHECKTEMPLATEVERIFY as implemented in C++ in the context of Bitcoin Core can
167
+ be seen in the reference implementation.
167
168
168
169
The execution of the opcode is as follows:
169
170
def execute_bip_119(self):
@@ -236,128 +237,6 @@ optimization.
236
237
return sha256(r)
237
238
238
239
239
-
240
- The C++ is below:
241
-
242
- case OP_CHECKTEMPLATEVERIFY:
243
- {
244
- // if flags not enabled; treat as a NOP4
245
- if (!(flags & SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH)) {
246
- if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
247
- return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
248
- break;
249
- }
250
-
251
- if (stack.size() < 1)
252
- return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
253
-
254
- // If the argument was not 32 bytes, treat as OP_NOP4:
255
- switch (stack.back().size()) {
256
- case 32:
257
- if (!checker.CheckDefaultCheckTemplateVerifyHash(stack.back())) {
258
- return set_error(serror, SCRIPT_ERR_TEMPLATE_MISMATCH);
259
- }
260
- break;
261
- default:
262
- // future upgrade can add semantics for this opcode with different length args
263
- // so discourage use when applicable
264
- if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
265
- return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
266
- }
267
- }
268
- }
269
- break;
270
-
271
- Where
272
-
273
- bool CheckDefaultCheckTemplateVerifyHash(const std::vector<unsigned char>& hash) {
274
- return GetDefaultCheckTemplateVerifyHash(current_tx, current_input_index) == uint256(hash);
275
- }
276
-
277
- The hash is computed as follows, where the outputs_hash and sequences_hash are computed as defined in BIP-341.
278
-
279
- /** Compute the (single) SHA256 of the concatenation of all scriptSigs in a tx. */
280
- template <class T>
281
- uint256 GetScriptSigsSHA256(const T& txTo)
282
- {
283
- CHashWriter ss(SER_GETHASH, 0);
284
- for (const auto& in : txTo.vin) {
285
- ss << in.scriptSig;
286
- }
287
- return ss.GetSHA256();
288
- }
289
- // not DoS safe, for reference/testing!
290
- uint256 GetDefaultCheckTemplateVerifyHash(const CTransaction& tx, uint32_t input_index) {
291
- return GetDefaultCheckTemplateVerifyHash(tx, GetOutputsSHA256(tx), GetSequenceSHA256(tx), input_index);
292
- }
293
- // not DoS safe for reference/testing!
294
- uint256 GetDefaultCheckTemplateVerifyHash(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
295
- const uint32_t input_index) {
296
- bool skip_scriptSigs = std::find_if(tx.vin.begin(), tx.vin.end(),
297
- [](const CTxIn& c) { return c.scriptSig != CScript(); }) == tx.vin.end();
298
- return skip_scriptSigs ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) :
299
- GetDefaultCheckTemplateVerifyHashWithScript(tx, outputs_hash, sequences_hash, GetScriptSigsSHA256(tx), input_index);
300
- }
301
- // DoS safe, fixed length hash!
302
- uint256 GetDefaultCheckTemplateVerifyHashWithScript(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
303
- const uint256& scriptSig_hash, const uint32_t input_index) {
304
- auto h = CHashWriter(SER_GETHASH, 0)
305
- << tx.nVersion
306
- << tx.nLockTime
307
- << scriptSig_hash
308
- << uint32_t(tx.vin.size())
309
- << sequences_hash
310
- << uint32_t(tx.vout.size())
311
- << outputs_hash
312
- << input_index;
313
- return h.GetSHA256();
314
- }
315
- // DoS safe, fixed length hash!
316
- uint256 GetDefaultCheckTemplateVerifyHashEmptyScript(const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
317
- const uint32_t input_index) {
318
- auto h = CHashWriter(SER_GETHASH, 0)
319
- << tx.nVersion
320
- << tx.nLockTime
321
- << uint32_t(tx.vin.size())
322
- << sequences_hash
323
- << uint32_t(tx.vout.size())
324
- << outputs_hash
325
- << input_index;
326
- return h.GetSHA256();
327
- }
328
-
329
-
330
-
331
- case OP_CHECKTEMPLATEVERIFY:
332
- {
333
- // if flags not enabled; treat as a NOP4
334
- if (!(flags & SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH)) {
335
- if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
336
- return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
337
- break;
338
- }
339
-
340
- if (stack.size() < 1)
341
- return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
342
-
343
- // If the argument was not 32 bytes, treat as OP_NOP4:
344
- switch (stack.back().size()) {
345
- case 32:
346
- if (!checker.CheckDefaultCheckTemplateVerifyHash(stack.back())) {
347
- return set_error(serror, SCRIPT_ERR_TEMPLATE_MISMATCH);
348
- }
349
- break;
350
- default:
351
- // future upgrade can add semantics for this opcode with different length args
352
- // so discourage use when applicable
353
- if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
354
- return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
355
- }
356
- }
357
- }
358
-
359
-
360
-
361
240
A PayToBareDefaultCheckTemplateVerifyHash output matches the following template:
362
241
363
242
bool CScript::IsPayToBareDefaultCheckTemplateVerifyHash() const
0 commit comments