aboutsummaryrefslogtreecommitdiff
path: root/src/script/interpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/interpreter.cpp')
-rw-r--r--src/script/interpreter.cpp50
1 files changed, 31 insertions, 19 deletions
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 083022fbdd..50f7806ba5 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -342,6 +342,35 @@ public:
};
}
+/** Helper for OP_CHECKSIG and OP_CHECKSIGVERIFY
+ *
+ * A return value of false means the script fails entirely. When true is returned, the
+ * fSuccess variable indicates whether the signature check itself succeeded.
+ */
+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)
+{
+ // Subset of script starting at the most recent codeseparator
+ CScript scriptCode(pbegincodehash, pend);
+
+ // Drop the signature in pre-segwit scripts but not segwit scripts
+ if (sigversion == SigVersion::BASE) {
+ int found = FindAndDelete(scriptCode, CScript() << vchSig);
+ if (found > 0 && (flags & SCRIPT_VERIFY_CONST_SCRIPTCODE))
+ return set_error(serror, SCRIPT_ERR_SIG_FINDANDDELETE);
+ }
+
+ if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) {
+ //serror is set
+ return false;
+ }
+ fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion);
+
+ if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size())
+ return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
+
+ return true;
+}
+
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror)
{
static const CScriptNum bnZero(0);
@@ -985,25 +1014,8 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
valtype& vchSig = stacktop(-2);
valtype& vchPubKey = stacktop(-1);
- // Subset of script starting at the most recent codeseparator
- CScript scriptCode(pbegincodehash, pend);
-
- // Drop the signature in pre-segwit scripts but not segwit scripts
- if (sigversion == SigVersion::BASE) {
- int found = FindAndDelete(scriptCode, CScript() << vchSig);
- if (found > 0 && (flags & SCRIPT_VERIFY_CONST_SCRIPTCODE))
- return set_error(serror, SCRIPT_ERR_SIG_FINDANDDELETE);
- }
-
- if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, sigversion, serror)) {
- //serror is set
- return false;
- }
- bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, sigversion);
-
- if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size())
- return set_error(serror, SCRIPT_ERR_SIG_NULLFAIL);
-
+ bool fSuccess = true;
+ if (!EvalChecksig(vchSig, vchPubKey, pbegincodehash, pend, flags, checker, sigversion, serror, fSuccess)) return false;
popstack(stack);
popstack(stack);
stack.push_back(fSuccess ? vchTrue : vchFalse);