@@ -342,6 +342,35 @@ class ConditionStack {
342342};
343343}
344344
345+ /* * Helper for OP_CHECKSIG and OP_CHECKSIGVERIFY
346+ *
347+ * A return value of false means the script fails entirely. When true is returned, the
348+ * fSuccess variable indicates whether the signature check itself succeeded.
349+ */
350+ static bool EvalChecksig (const valtype& vchSig, const valtype& vchPubKey, CScript::const_iterator pbegincodehash, CScript::const_iterator pend, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror, bool & fSuccess )
351+ {
352+ // Subset of script starting at the most recent codeseparator
353+ CScript scriptCode (pbegincodehash, pend);
354+
355+ // Drop the signature in pre-segwit scripts but not segwit scripts
356+ if (sigversion == SigVersion::BASE) {
357+ int found = FindAndDelete (scriptCode, CScript () << vchSig);
358+ if (found > 0 && (flags & SCRIPT_VERIFY_CONST_SCRIPTCODE))
359+ return set_error (serror, SCRIPT_ERR_SIG_FINDANDDELETE);
360+ }
361+
362+ if (!CheckSignatureEncoding (vchSig, flags, serror) || !CheckPubKeyEncoding (vchPubKey, flags, sigversion, serror)) {
363+ // serror is set
364+ return false ;
365+ }
366+ fSuccess = checker.CheckSig (vchSig, vchPubKey, scriptCode, sigversion);
367+
368+ if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size ())
369+ return set_error (serror, SCRIPT_ERR_SIG_NULLFAIL);
370+
371+ return true ;
372+ }
373+
345374bool EvalScript (std::vector<std::vector<unsigned char > >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror)
346375{
347376 static const CScriptNum bnZero (0 );
@@ -985,25 +1014,8 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
9851014 valtype& vchSig = stacktop (-2 );
9861015 valtype& vchPubKey = stacktop (-1 );
9871016
988- // Subset of script starting at the most recent codeseparator
989- CScript scriptCode (pbegincodehash, pend);
990-
991- // Drop the signature in pre-segwit scripts but not segwit scripts
992- if (sigversion == SigVersion::BASE) {
993- int found = FindAndDelete (scriptCode, CScript () << vchSig);
994- if (found > 0 && (flags & SCRIPT_VERIFY_CONST_SCRIPTCODE))
995- return set_error (serror, SCRIPT_ERR_SIG_FINDANDDELETE);
996- }
997-
998- if (!CheckSignatureEncoding (vchSig, flags, serror) || !CheckPubKeyEncoding (vchPubKey, flags, sigversion, serror)) {
999- // serror is set
1000- return false ;
1001- }
1002- bool fSuccess = checker.CheckSig (vchSig, vchPubKey, scriptCode, sigversion);
1003-
1004- if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size ())
1005- return set_error (serror, SCRIPT_ERR_SIG_NULLFAIL);
1006-
1017+ bool fSuccess = true ;
1018+ if (!EvalChecksig (vchSig, vchPubKey, pbegincodehash, pend, flags, checker, sigversion, serror, fSuccess )) return false ;
10071019 popstack (stack);
10081020 popstack (stack);
10091021 stack.push_back (fSuccess ? vchTrue : vchFalse);
0 commit comments