@@ -163,7 +163,8 @@ forming a "Payment Pool".
163163
164164The below code is the main logic for verifying CHECKTEMPLATEVERIFY, described
165165in 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.
167168
168169The execution of the opcode is as follows:
169170 def execute_bip_119(self):
@@ -236,128 +237,6 @@ optimization.
236237 return sha256(r)
237238
238239
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-
361240A PayToBareDefaultCheckTemplateVerifyHash output matches the following template:
362241
363242 bool CScript::IsPayToBareDefaultCheckTemplateVerifyHash() const
0 commit comments