@@ -591,7 +591,42 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
591
591
break ;
592
592
}
593
593
594
- case OP_NOP1: case OP_NOP4: case OP_NOP5:
594
+ case OP_CHECKTEMPLATEVERIFY:
595
+ {
596
+ if (flags & SCRIPT_VERIFY_DISCOURAGE_CHECK_TEMPLATE_VERIFY_HASH) {
597
+ return set_error (serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
598
+ }
599
+
600
+ // if flags not enabled; treat as a NOP4
601
+ if (!(flags & SCRIPT_VERIFY_DEFAULT_CHECK_TEMPLATE_VERIFY_HASH)) {
602
+ break ;
603
+ }
604
+
605
+ if (stack.size () < 1 ) {
606
+ return set_error (serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
607
+ }
608
+
609
+ // If the argument was not 32 bytes, treat as OP_NOP4:
610
+ switch (stack.back ().size ()) {
611
+ case 32 :
612
+ {
613
+ const Span<const unsigned char > hash{stack.back ()};
614
+ if (!checker.CheckDefaultCheckTemplateVerifyHash (hash)) {
615
+ return set_error (serror, SCRIPT_ERR_TEMPLATE_MISMATCH);
616
+ }
617
+ break ;
618
+ }
619
+ default :
620
+ // future upgrade can add semantics for this opcode with different length args
621
+ // so discourage use when applicable
622
+ if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_CHECK_TEMPLATE_VERIFY_HASH) {
623
+ return set_error (serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
624
+ }
625
+ }
626
+ }
627
+ break ;
628
+
629
+ case OP_NOP1: case OP_NOP5:
595
630
case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
596
631
{
597
632
if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
@@ -1377,6 +1412,18 @@ uint256 GetSpentAmountsSHA256(const std::vector<CTxOut>& outputs_spent)
1377
1412
HashWriter ss{};
1378
1413
for (const auto & txout : outputs_spent) {
1379
1414
ss << txout.nValue ;
1415
+
1416
+ }
1417
+ return ss.GetSHA256 ();
1418
+ }
1419
+
1420
+ /* * Compute the (single) SHA256 of the concatenation of all scriptSigs in a tx. */
1421
+ template <class T >
1422
+ uint256 GetScriptSigsSHA256 (const T& txTo)
1423
+ {
1424
+ HashWriter ss{};
1425
+ for (const auto & in : txTo.vin ) {
1426
+ ss << in.scriptSig ;
1380
1427
}
1381
1428
return ss.GetSHA256 ();
1382
1429
}
@@ -1391,9 +1438,63 @@ uint256 GetSpentScriptsSHA256(const std::vector<CTxOut>& outputs_spent)
1391
1438
return ss.GetSHA256 ();
1392
1439
}
1393
1440
1441
+ /* Not Exported, just convenience */
1442
+ template <typename TxType>
1443
+ uint256 GetDefaultCheckTemplateVerifyHashWithScript (const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1444
+ const uint256& scriptSig_hash, const uint32_t input_index) {
1445
+ auto h = HashWriter{}
1446
+ << tx.version
1447
+ << tx.nLockTime
1448
+ << scriptSig_hash
1449
+ << uint32_t (tx.vin .size ())
1450
+ << sequences_hash
1451
+ << uint32_t (tx.vout .size ())
1452
+ << outputs_hash
1453
+ << input_index;
1454
+ return h.GetSHA256 ();
1455
+ }
1456
+
1457
+ template <typename TxType>
1458
+ uint256 GetDefaultCheckTemplateVerifyHashEmptyScript (const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1459
+ const uint32_t input_index) {
1460
+ auto h = HashWriter{}
1461
+ << tx.version
1462
+ << tx.nLockTime
1463
+ << uint32_t (tx.vin .size ())
1464
+ << sequences_hash
1465
+ << uint32_t (tx.vout .size ())
1466
+ << outputs_hash
1467
+ << input_index;
1468
+ return h.GetSHA256 ();
1469
+ }
1394
1470
1395
1471
} // namespace
1396
1472
1473
+ template <typename TxType>
1474
+ uint256 GetDefaultCheckTemplateVerifyHash (const TxType& tx, uint32_t input_index) {
1475
+ return GetDefaultCheckTemplateVerifyHash (tx, GetOutputsSHA256 (tx), GetSequencesSHA256 (tx), input_index);
1476
+ }
1477
+
1478
+ template <typename TxType>
1479
+ static bool NoScriptSigs (const TxType& tx)
1480
+ {
1481
+ return std::all_of (tx.vin .begin (), tx.vin .end (), [](const CTxIn& c) { return c.scriptSig .empty (); });
1482
+ }
1483
+
1484
+ template <typename TxType>
1485
+ uint256 GetDefaultCheckTemplateVerifyHash (const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1486
+ const uint32_t input_index) {
1487
+ return NoScriptSigs (tx) ? GetDefaultCheckTemplateVerifyHashEmptyScript (tx, outputs_hash, sequences_hash, input_index) :
1488
+ GetDefaultCheckTemplateVerifyHashWithScript (tx, outputs_hash, sequences_hash, GetScriptSigsSHA256 (tx), input_index);
1489
+ }
1490
+
1491
+ template
1492
+ uint256 GetDefaultCheckTemplateVerifyHash (const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1493
+ const uint32_t input_index);
1494
+ template
1495
+ uint256 GetDefaultCheckTemplateVerifyHash (const CMutableTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1496
+ const uint32_t input_index);
1497
+
1397
1498
template <class T >
1398
1499
void PrecomputedTransactionData::Init (const T& txTo, std::vector<CTxOut>&& spent_outputs, bool force)
1399
1500
{
@@ -1405,6 +1506,8 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& spent
1405
1506
m_spent_outputs_ready = true ;
1406
1507
}
1407
1508
1509
+ // TODO: Improve this heuristic
1510
+ bool uses_bip119_ctv = true ;
1408
1511
// Determine which precomputation-impacting features this transaction uses.
1409
1512
bool uses_bip143_segwit = force;
1410
1513
bool uses_bip341_taproot = force;
@@ -1427,11 +1530,16 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& spent
1427
1530
if (uses_bip341_taproot && uses_bip143_segwit) break ; // No need to scan further if we already need all.
1428
1531
}
1429
1532
1430
- if (uses_bip143_segwit || uses_bip341_taproot) {
1533
+ if (uses_bip143_segwit || uses_bip341_taproot || uses_bip119_ctv ) {
1431
1534
// Computations shared between both sighash schemes.
1432
1535
m_prevouts_single_hash = GetPrevoutsSHA256 (txTo);
1433
1536
m_sequences_single_hash = GetSequencesSHA256 (txTo);
1434
1537
m_outputs_single_hash = GetOutputsSHA256 (txTo);
1538
+
1539
+ // 0 hash used to signal if we should skip scriptSigs
1540
+ // when re-computing for different indexes.
1541
+ m_scriptSigs_single_hash = NoScriptSigs (txTo) ? uint256{} : GetScriptSigsSHA256 (txTo);
1542
+ m_bip119_ctv_ready = true ;
1435
1543
}
1436
1544
if (uses_bip143_segwit) {
1437
1545
hashPrevouts = SHA256Uint256 (m_prevouts_single_hash);
@@ -1781,6 +1889,22 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
1781
1889
return true ;
1782
1890
}
1783
1891
1892
+ template <class T >
1893
+ bool GenericTransactionSignatureChecker<T>::CheckDefaultCheckTemplateVerifyHash(const Span<const unsigned char >& hash) const
1894
+ {
1895
+ // Should already be checked before calling...
1896
+ assert (hash.size () == 32 );
1897
+ if (txdata && txdata->m_bip119_ctv_ready ) {
1898
+ assert (txTo != nullptr );
1899
+ uint256 hash_tmpl = txdata->m_scriptSigs_single_hash .IsNull () ?
1900
+ GetDefaultCheckTemplateVerifyHashEmptyScript (*txTo, txdata->m_outputs_single_hash , txdata->m_sequences_single_hash , nIn) :
1901
+ GetDefaultCheckTemplateVerifyHashWithScript (*txTo, txdata->m_outputs_single_hash , txdata->m_sequences_single_hash ,
1902
+ txdata->m_scriptSigs_single_hash , nIn);
1903
+ return std::equal (hash_tmpl.begin (), hash_tmpl.end (), hash.data ());
1904
+ } else {
1905
+ return HandleMissingData (m_mdb);
1906
+ }
1907
+ }
1784
1908
// explicit instantiation
1785
1909
template class GenericTransactionSignatureChecker <CTransaction>;
1786
1910
template class GenericTransactionSignatureChecker <CMutableTransaction>;
0 commit comments