MCPcopy Create free account
hub / github.com/Bitcoin-ABC/bitcoin-abc / VerifyScript

Function VerifyScript

src/script/interpreter.cpp:1785–1903  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1783template class GenericTransactionSignatureChecker<CMutableTransaction>;
1784
1785bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey,
1786 uint32_t flags, const BaseSignatureChecker &checker,
1787 ScriptExecutionMetrics &metricsOut, ScriptError *serror) {
1788 set_error(serror, ScriptError::UNKNOWN);
1789
1790 // If FORKID is enabled, we also ensure strict encoding.
1791 if (flags & SCRIPT_ENABLE_SIGHASH_FORKID) {
1792 flags |= SCRIPT_VERIFY_STRICTENC;
1793 }
1794
1795 if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) {
1796 return set_error(serror, ScriptError::SIG_PUSHONLY);
1797 }
1798
1799 ScriptExecutionMetrics metrics = {};
1800
1801 // scriptSig and scriptPubKey must be evaluated sequentially on the same
1802 // stack rather than being simply concatenated (see CVE-2010-5141)
1803 std::vector<valtype> stack, stackCopy;
1804 if (!EvalScript(stack, scriptSig, flags, checker, metrics, serror)) {
1805 // serror is set
1806 return false;
1807 }
1808 if (flags & SCRIPT_VERIFY_P2SH) {
1809 stackCopy = stack;
1810 }
1811 if (!EvalScript(stack, scriptPubKey, flags, checker, metrics, serror)) {
1812 // serror is set
1813 return false;
1814 }
1815 if (stack.empty()) {
1816 return set_error(serror, ScriptError::EVAL_FALSE);
1817 }
1818 if (CastToBool(stack.back()) == false) {
1819 return set_error(serror, ScriptError::EVAL_FALSE);
1820 }
1821
1822 // Additional validation for spend-to-script-hash transactions:
1823 if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) {
1824 // scriptSig must be literals-only or validation fails
1825 if (!scriptSig.IsPushOnly()) {
1826 return set_error(serror, ScriptError::SIG_PUSHONLY);
1827 }
1828
1829 // Restore stack.
1830 swap(stack, stackCopy);
1831
1832 // stack cannot be empty here, because if it was the P2SH HASH <> EQUAL
1833 // scriptPubKey would be evaluated with an empty stack and the
1834 // EvalScript above would return false.
1835 assert(!stack.empty());
1836
1837 const valtype &pubKeySerialized = stack.back();
1838 CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
1839 popstack(stack);
1840
1841 // Bail out early if SCRIPT_DISALLOW_SEGWIT_RECOVERY is not set, the
1842 // redeem script is a p2sh segwit program, and it was the only item

Callers

nothing calls this directly

Calls 13

CastToBoolFunction · 0.85
popstackFunction · 0.85
set_successFunction · 0.85
IsPushOnlyMethod · 0.80
backMethod · 0.80
IsPayToScriptHashMethod · 0.80
IsWitnessProgramMethod · 0.80
set_errorFunction · 0.70
EvalScriptFunction · 0.70
emptyMethod · 0.45
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected