1010#include < crypto/sha256.h>
1111#include < pubkey.h>
1212#include < script/script.h>
13+ #include < script/sigversion.h>
1314#include < uint256.h>
1415
1516typedef std::vector<unsigned char > valtype;
@@ -253,6 +254,20 @@ int FindAndDelete(CScript& script, const CScript& b)
253254 return nFound;
254255}
255256
257+ CScriptNum GetCScriptNum (const valtype& num, const bool fRequireMinimal , const SigVersion& sigversion)
258+ {
259+ switch (sigversion)
260+ {
261+ case SigVersion::BASE:
262+ case SigVersion::WITNESS_V0:
263+ case SigVersion::TAPROOT:
264+ case SigVersion::TAPSCRIPT:
265+ return CScriptNum (num,fRequireMinimal ,/* nMaximumSize=*/ 4 );
266+ case SigVersion::TAPSCRIPT_64BIT:
267+ return CScriptNum (num,fRequireMinimal ,/* nMaximumSize=*/ 8 );
268+ }
269+ }
270+
256271namespace {
257272/* * A data type to abstract out the condition stack during script execution.
258273 *
@@ -395,6 +410,7 @@ static bool EvalChecksig(const valtype& sig, const valtype& pubkey, CScript::con
395410 case SigVersion::WITNESS_V0:
396411 return EvalChecksigPreTapscript (sig, pubkey, pbegincodehash, pend, flags, checker, sigversion, serror, success);
397412 case SigVersion::TAPSCRIPT:
413+ case SigVersion::TAPSCRIPT_64BIT:
398414 return EvalChecksigTapscript (sig, pubkey, execdata, flags, checker, sigversion, serror, success);
399415 case SigVersion::TAPROOT:
400416 // Key path spending in Taproot has no script, so this is unreachable.
@@ -414,7 +430,7 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
414430 static const valtype vchTrue (1 , 1 );
415431
416432 // sigversion cannot be TAPROOT here, as it admits no script execution.
417- assert (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0 || sigversion == SigVersion::TAPSCRIPT);
433+ assert (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0 || sigversion == SigVersion::TAPSCRIPT || sigversion == SigVersion::TAPSCRIPT_64BIT );
418434
419435 CScript::const_iterator pc = script.begin ();
420436 CScript::const_iterator pend = script.end ();
@@ -925,7 +941,8 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
925941 // (in -- out)
926942 if (stack.size () < 1 )
927943 return set_error (serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
928- CScriptNum bn (stacktop (-1 ), fRequireMinimal );
944+
945+ CScriptNum bn = GetCScriptNum (stacktop (-1 ), fRequireMinimal , sigversion);
929946 switch (opcode)
930947 {
931948 case OP_1ADD: bn += bnOne; break ;
@@ -958,19 +975,17 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
958975 // (x1 x2 -- out)
959976 if (stack.size () < 2 )
960977 return set_error (serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
961- CScriptNum bn1 (stacktop (-2 ), fRequireMinimal );
962- CScriptNum bn2 (stacktop (-1 ), fRequireMinimal );
978+ CScriptNum bn1 = GetCScriptNum (stacktop (-2 ), fRequireMinimal , sigversion );
979+ CScriptNum bn2 = GetCScriptNum (stacktop (-1 ), fRequireMinimal , sigversion );
963980 CScriptNum bn (0 );
964981 switch (opcode)
965982 {
966983 case OP_ADD:
967984 bn = bn1 + bn2;
968985 break ;
969-
970986 case OP_SUB:
971987 bn = bn1 - bn2;
972988 break ;
973-
974989 case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break ;
975990 case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break ;
976991 case OP_NUMEQUAL: bn = (bn1 == bn2); break ;
@@ -987,7 +1002,6 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
9871002 popstack (stack);
9881003 popstack (stack);
9891004 stack.push_back (bn.getvch ());
990-
9911005 if (opcode == OP_NUMEQUALVERIFY)
9921006 {
9931007 if (CastToBool (stacktop (-1 )))
@@ -1938,6 +1952,13 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
19381952 execdata.m_validation_weight_left_init = true ;
19391953 return ExecuteWitnessScript (stack, exec_script, flags, SigVersion::TAPSCRIPT, checker, execdata, serror);
19401954 }
1955+ if ((control[0 ] & TAPROOT_LEAF_MASK) == TAPROOT_LEAF_TAPSCRIPT_64BIT) {
1956+ // Tapscript (leaf version 0x66)
1957+ exec_script = CScript (script.begin (), script.end ());
1958+ execdata.m_validation_weight_left = ::GetSerializeSize (witness.stack ) + VALIDATION_WEIGHT_OFFSET;
1959+ execdata.m_validation_weight_left_init = true ;
1960+ return ExecuteWitnessScript (stack, exec_script, flags, SigVersion::TAPSCRIPT_64BIT, checker, execdata, serror);
1961+ }
19411962 if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION) {
19421963 return set_error (serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION);
19431964 }
0 commit comments