/* * This file is part of the Flowee project * Copyright (C) 2009-2010 Satoshi Nakamoto * Copyright (C) 2009-2015 The Bitcoin Core developers * Copyright (C) 2016-2021 Tom Zander * Copyright (C) 2018 Jason B. Cox * Copyright (C) 2018 Awemany * Copyright (C) 2018 Amaury Séchet * Copyright (C) 2019 Mark Lundeberg * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "interpreter.h" #include #include #include #include #include "primitives/ScriptBigNum_p.h" #include "primitives/ScriptDefines.h" #include "primitives/FastBigNum_p.h" #include "primitives/transaction.h" #include #include #include #include #include typedef std::vector valtype; using FunctionTable = std::map; struct ControlEntry { enum Type { Conditional, Loop }; Type type; CScript::const_iterator loopPc; }; namespace { int32_t countBits(uint32_t v) { #if HAVE_DECL___BUILTIN_POPCOUNT return __builtin_popcount(v); #else /** * Computes the number of bits set in each group of 8bits then uses a * multiplication to sum all of them in the 8 most significant bits and * return these. * More detailed explanation can be found at * https://www.playingwithpointers.com/blog/swar.html */ v = v - ((v >> 1) & 0x55555555); v = (v & 0x33333333) + ((v >> 2) & 0x33333333); return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; #endif } bool isCashTokenIntrospectionOpcode(opcodetype opcode) { return opcode == OP_UTXOTOKENCATEGORY || opcode == OP_UTXOTOKENCOMMITMENT || opcode == OP_UTXOTOKENAMOUNT || opcode == OP_OUTPUTTOKENCATEGORY || opcode == OP_OUTPUTTOKENCOMMITMENT || opcode == OP_OUTPUTTOKENAMOUNT; } void bitShiftBlob(valtype &data, size_t nbits, bool right) { if (data.empty() || nbits == 0) return; const size_t bitSize = data.size() * 8; if (nbits >= bitSize) { std::fill(data.begin(), data.end(), 0); return; } const size_t bytes = nbits / 8; const unsigned bits = nbits % 8; if (right) { if (bytes != 0) { for (size_t i = data.size(); i-- > bytes;) data[i] = data[i - bytes]; std::fill(data.begin(), data.begin() + bytes, 0); } if (bits != 0) { uint8_t carry = 0; for (uint8_t &byte : data) { const uint8_t original = byte; byte = static_cast((original >> bits) | carry); carry = static_cast(original << (8 - bits)); } } } else { if (bytes != 0) { for (size_t i = 0; i + bytes < data.size(); ++i) data[i] = data[i + bytes]; std::fill(data.end() - bytes, data.end(), 0); } if (bits != 0) { uint8_t carry = 0; for (size_t i = data.size(); i-- > 0;) { const uint8_t original = data[i]; data[i] = static_cast((original << bits) | carry); carry = static_cast(original >> (8 - bits)); } } } } bool readTransactionOutput(const Tx &tx, size_t index, Tx::Output &output) { try { Tx::Iterator iter(tx); output = iter.nextOutput(static_cast(index)); return output.outputValue >= 0; } catch (const std::runtime_error &) { return false; } } valtype tokenCategoryBytes(const Tx::Output &output) { valtype bytes; if (!output.hasToken()) return bytes; const auto token = output.token(); bytes.assign(token.category.begin(), token.category.end()); if (token.isMutableNft() || token.isMintingNft()) bytes.push_back(token.bitfield & 0x0f); return bytes; } valtype tokenCommitmentBytes(const Tx::Output &output) { if (!output.hasToken()) return {}; const auto token = output.token(); if (!token.hasNft()) return {}; return valtype(token.commitment.begin(), token.commitment.end()); } int64_t tokenAmount(const Tx::Output &output) { if (!output.hasToken()) return 0; return static_cast(output.token().amount); } inline bool set_success(ScriptError &ret) { ret = SCRIPT_ERR_OK; return true; } inline bool set_error(ScriptError &ret, const ScriptError serror) { ret = serror; return false; } inline bool VmLimitsEnabled(const Script::State &state) { return (state.flags & SCRIPT_ENABLE_MAY2025) != 0; } inline void TallyOpcodeCost(Script::State &state) { if (VmLimitsEnabled(state)) state.opCost += may2025::OPCODE_COST; } inline void TallyPushCost(Script::State &state, size_t size, uint32_t factor = 1) { if (VmLimitsEnabled(state)) state.opCost += static_cast(size) * factor; } inline void TallyHashCost(Script::State &state, size_t messageLength, bool isTwoRoundHashOp) { if (VmLimitsEnabled(state)) state.hashDigestIterations += may2025::CalcHashIters(static_cast(messageLength), isTwoRoundHashOp); } inline int64_t GetCompositeOpCost(const Script::State &state) { const bool standard = (state.flags & SCRIPT_VM_LIMITS_STANDARD) != 0; return state.opCost + state.hashDigestIterations * may2025::GetHashIterOpCostFactor(standard) + static_cast(state.sigCheckCount) * may2025::SIG_CHECK_COST_FACTOR; } inline bool CheckVmLimits(const Script::State &state, ScriptError &ret) { if (!VmLimitsEnabled(state)) return true; const bool standard = (state.flags & SCRIPT_VM_LIMITS_STANDARD) != 0; if (GetCompositeOpCost(state) > may2025::detail::GetInputOpCostLimit(state.vmLimitScriptSigSize)) return set_error(ret, SCRIPT_ERR_OP_COST); if (state.hashDigestIterations > may2025::detail::GetInputHashItersLimit(standard, state.vmLimitScriptSigSize)) return set_error(ret, SCRIPT_ERR_TOO_MANY_HASH_ITERS); return true; } uint32_t GetHashType(const valtype &vchSig) { if (vchSig.size() == 0) { return 0; } return vchSig[vchSig.size() - 1]; } void static CleanupScriptCode(CScript &scriptCode, const std::vector &vchSig, uint32_t flags) { // Drop the signature in scripts when SIGHASH_FORKID is not used. uint32_t nHashType = GetHashType(vchSig); if (!(flags & SCRIPT_ENABLE_SIGHASH_FORKID) || !(nHashType & SIGHASH_FORKID)) { scriptCode.FindAndDelete(CScript(vchSig)); } } bool static IsDefinedHashtypeSignature(const valtype &vchSig) { if (vchSig.size() == 0) { return false; } const uint32_t nHashType = GetHashType(vchSig) & ~(SIGHASH_ANYONECANPAY | SIGHASH_UTXOS | SIGHASH_FORKID); if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) return false; return true; } bool static CheckSigHashEncoding(const valtype &vchSig, Script::State &state) { const uint32_t hashType = GetHashType(vchSig); if ((state.flags & SCRIPT_ENABLE_SIGHASH_FORKID) && !(hashType & SIGHASH_FORKID)) return set_error(state.error, SCRIPT_ERR_MUST_USE_FORKID); if (hashType & SIGHASH_UTXOS) { if ((state.flags & SCRIPT_ENABLE_SIGHASH_UTXOS) == 0 || (hashType & SIGHASH_FORKID) == 0 || (hashType & SIGHASH_ANYONECANPAY)) return set_error(state.error, SCRIPT_ERR_SIG_HASHTYPE); } if ((state.flags & SCRIPT_VERIFY_STRICTENC) == 0) return true; if (!IsDefinedHashtypeSignature(vchSig)) return set_error(state.error, SCRIPT_ERR_SIG_HASHTYPE); return true; } /** * A canonical signature exists of: <30> <02> <02> * Where R and S are not negative (their first byte has its highest bit not set), and not * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, * in which case a single 0 byte is necessary and even required). * * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 * * This function is consensus-critical since BIP66. */ bool static IsValidSignatureEncoding(const std::vector &sig) { // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] // * total-length: 1-byte length descriptor of everything that follows, // excluding the sighash byte. // * R-length: 1-byte length descriptor of the R value that follows. // * R: arbitrary-length big-endian encoded R value. It must use the shortest // possible encoding for a positive integers (which means no null bytes at // the start, except a single one when the next byte has its highest bit set). // * S-length: 1-byte length descriptor of the S value that follows. // * S: arbitrary-length big-endian encoded S value. The same rules apply. // * sighash: 1-byte value indicating what data is hashed (not part of the DER // signature) // Minimum and maximum size constraints. if (sig.size() < 9) return false; if (sig.size() > 73) return false; // A signature is of type 0x30 (compound). if (sig[0] != 0x30) return false; // Make sure the length covers the entire signature. if (sig[1] != sig.size() - 3) return false; // Extract the length of the R element. unsigned int lenR = sig[3]; // Make sure the length of the S element is still inside the signature. if (5 + lenR >= sig.size()) return false; // Extract the length of the S element. unsigned int lenS = sig[5 + lenR]; // Verify that the length of the signature matches the sum of the length // of the elements. if ((size_t)(lenR + lenS + 7) != sig.size()) return false; // Check whether the R element is an integer. if (sig[2] != 0x02) return false; // Zero-length integers are not allowed for R. if (lenR == 0) return false; // Negative numbers are not allowed for R. if (sig[4] & 0x80) return false; // Null bytes at the start of R are not allowed, unless R would // otherwise be interpreted as a negative number. if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false; // Check whether the S element is an integer. if (sig[lenR + 4] != 0x02) return false; // Zero-length integers are not allowed for S. if (lenS == 0) return false; // Negative numbers are not allowed for S. if (sig[lenR + 6] & 0x80) return false; // Null bytes at the start of S are not allowed, unless S would otherwise be // interpreted as a negative number. if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false; return true; } //! Check signature encoding without sighash byte //! This is a copy of Bitcoin ABC's code, written mainly by deadalnix, from //! revision: f8283a3f284fc4722c1d6583b8746a17831d3bd0 /** * A canonical signature exists of: <30> <02> <02> , where R and S are not negative (their first byte has its * highest bit not set), and not excessively padded (do not start with a 0 byte, * unless an otherwise negative number follows, in which case a single 0 byte is * necessary and even required). * * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 * * This function is consensus-critical since BIP66. */ bool IsValidSignatureEncodingWithoutSigHash(const valtype &sig) { // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] // * total-length: 1-byte length descriptor of everything that follows, // excluding the sighash byte. // * R-length: 1-byte length descriptor of the R value that follows. // * R: arbitrary-length big-endian encoded R value. It must use the // shortest possible encoding for a positive integers (which means no null // bytes at the start, except a single one when the next byte has its // highest bit set). // * S-length: 1-byte length descriptor of the S value that follows. // * S: arbitrary-length big-endian encoded S value. The same rules apply. // Minimum and maximum size constraints. if (sig.size() < 8 || sig.size() > 72) return false; // // Check that the signature is a compound structure of proper size. // // A signature is of type 0x30 (compound). if (sig[0] != 0x30) return false; // Make sure the length covers the entire signature. // Remove: // * 1 byte for the coupound type. // * 1 byte for the length of the signature. if (sig[1] != sig.size() - 2) return false; // // Check that R is an positive integer of sensible size. // // Check whether the R element is an integer. if (sig[2] != 0x02) return false; // Extract the length of the R element. const uint32_t lenR = sig[3]; // Zero-length integers are not allowed for R. if (lenR == 0) return false; // Negative numbers are not allowed for R. if (sig[4] & 0x80) return false; // Make sure the length of the R element is consistent with the signature // size. // Remove: // * 1 byte for the coumpound type. // * 1 byte for the length of the signature. // * 2 bytes for the integer type of R and S. // * 2 bytes for the size of R and S. // * 1 byte for S itself. if (lenR > (sig.size() - 7)) return false; // Null bytes at the start of R are not allowed, unless R would otherwise be // interpreted as a negative number. // // /!\ This check can only be performed after we checked that lenR is // consistent with the size of the signature or we risk to access out of // bound elements. if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false; // // Check that S is an positive integer of sensible size. // // S's definition starts after R's definition: // * 1 byte for the coumpound type. // * 1 byte for the length of the signature. // * 1 byte for the size of R. // * lenR bytes for R itself. // * 1 byte to get to S. const uint32_t startS = lenR + 4; // Check whether the S element is an integer. if (sig[startS] != 0x02) return false; // Extract the length of the S element. const uint32_t lenS = sig[startS + 1]; // Zero-length integers are not allowed for S. if (lenS == 0) return false; // Negative numbers are not allowed for S. if (sig[startS + 2] & 0x80) return false; // Verify that the length of S is consistent with the size of the signature // including metadatas: // * 1 byte for the integer type of S. // * 1 byte for the size of S. if (size_t(startS + lenS + 2) != sig.size()) return false; // Null bytes at the start of S are not allowed, unless S would otherwise be // interpreted as a negative number. // // /!\ This check can only be performed after we checked that lenR and lenS // are consistent with the size of the signature or we risk to access // out of bound elements. if (lenS > 1 && (sig[startS + 2] == 0x00) && !(sig[startS + 3] & 0x80)) return false; return true; } enum CheckType { NoCheckSigHash = 0, CheckSigHash = 1, ECDSAOnly = 2, SchnorrOnly = 4, CheckDataSigChecks = NoCheckSigHash, TransactionCheckSigChecks = CheckSigHash, MultiSigChecksECDSA = CheckSigHash | ECDSAOnly, MultiSigChecksSchnorr = CheckSigHash | SchnorrOnly }; bool static IsLowDERSignature(const valtype &vchSig, ScriptError &serror, const CheckType type) { if (type & CheckSigHash) { if (!IsValidSignatureEncoding(vchSig)) return set_error(serror, SCRIPT_ERR_SIG_DER); } else if (!IsValidSignatureEncodingWithoutSigHash(vchSig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } std::vector vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - ((type & CheckSigHash) ? 1 : 0)); if (!PublicKey::checkLowS(vchSigCopy)) return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); return true; } bool static CheckSignatureEncoding(const std::vector &vchSig, Script::State &state, const CheckType type) { if ((state.flags & SCRIPT_ENABLE_SCHNORR) && (vchSig.size() == (type == CheckDataSigChecks ? 64 : 65))) { // In a generic-signature context, 64-byte signatures are interpreted // as Schnorr signatures (always correctly encoded) when flag set. if (type & ECDSAOnly) return set_error(state.error, SCRIPT_ERR_SIG_BADLENGTH); if ((type & CheckSigHash) && !CheckSigHashEncoding(vchSig, state)) return false; return true; } else if (type & SchnorrOnly) { return set_error(state.error, SCRIPT_ERR_SIG_BADLENGTH); } if (vchSig.size() == 0) return true; if ((state.flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0) { if (type & CheckSigHash) { if (!IsValidSignatureEncoding(vchSig)) return set_error(state.error, SCRIPT_ERR_SIG_DER); } else { if (!IsValidSignatureEncodingWithoutSigHash(vchSig)) return set_error(state.error, SCRIPT_ERR_SIG_DER); } } if ((type & CheckSigHash) && !CheckSigHashEncoding(vchSig, state)) return false; if ((state.flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, state.error, type)) { // serror is set return false; } return true; } /// copy bitfields from bytearray to \a bitfield, and do sanity checks. bool decodeBitfield(const std::vector &vch, int size, uint32_t &bitfield, ScriptError &serror) { if (size > 32 || size < 0) return set_error(serror, SCRIPT_ERR_INVALID_BITFIELD_SIZE); const int bitfield_size = (size + 7) / 8; if (vch.size() != static_cast(bitfield_size)) return set_error(serror, SCRIPT_ERR_INVALID_BITFIELD_SIZE); bitfield = 0; for (int i = 0; i < bitfield_size; i++) { // Decode the bitfield as little endian. bitfield |= uint32_t(vch[size_t(i)]) << (8 * i); } const uint32_t mask = static_cast((uint64_t(1) << size) - 1); if ((bitfield & mask) != bitfield) return set_error(serror, SCRIPT_ERR_INVALID_BIT_RANGE); return true; } bool CastToBool(const valtype& vch) { for (unsigned int i = 0; i < vch.size(); i++) { if (vch[i] != 0) { // Can be negative zero if (i == vch.size()-1 && vch[i] == 0x80) return false; return true; } } return false; } } // anon namespace /** * Script is a stack machine (like Forth) that evaluates a predicate * returning a bool indicating valid or not. There are no loops. */ #define stacktop(i) (stack.at(static_cast(static_cast(stack.size())+(i)))) #define altstacktop(i) (altstack.at(altstack.size()+(i))) static inline void popstack(std::vector& stack) { if (stack.empty()) throw std::runtime_error("popstack(): stack empty"); stack.pop_back(); } bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { if (vchPubKey.size() < PublicKey::COMPRESSED_PUBLIC_KEY_SIZE) { // Non-canonical public key: too short return false; } if (vchPubKey[0] == 0x04) { if (vchPubKey.size() != PublicKey::PUBLIC_KEY_SIZE) { // Non-canonical public key: invalid length for uncompressed key return false; } } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) { if (vchPubKey.size() != PublicKey::COMPRESSED_PUBLIC_KEY_SIZE) { // Non-canonical public key: invalid length for compressed key return false; } } else { // Non-canonical public key: neither compressed nor uncompressed return false; } return true; } bool Script::checkTransactionSignatureEncoding(const std::vector &vchSig, State &state) { return CheckSignatureEncoding(vchSig, state, TransactionCheckSigChecks); } bool static CheckPubKeyEncoding(const valtype &vchSig, Script::State &state) { if ((state.flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { return set_error(state.error, SCRIPT_ERR_PUBKEYTYPE); } return true; } static bool evalInternal(std::vector > &stack, const CScript &script, const BaseSignatureChecker &checker, Script::State &state, std::vector &altstack, FunctionTable &functionTable, size_t invocationDepth) { static const CScriptNum bnZero(0); static const CScriptNum bnOne(1); static const CScriptNum bnFalse(0); static const CScriptNum bnTrue(1); static const valtype vchFalse(0); static const valtype vchZero(0); static const valtype vchTrue(1, 1); CScript::const_iterator pc = script.begin(); CScript::const_iterator pend = script.end(); CScript::const_iterator pbegincodehash = script.begin(); opcodetype opcode; valtype vchPushValue; std::vector vfExec; std::vector controlStack; set_error(state.error, SCRIPT_ERR_UNKNOWN_ERROR); const bool may2025Enabled = (state.flags & SCRIPT_ENABLE_MAY2025) != 0; const bool may2026Enabled = (state.flags & SCRIPT_ENABLE_MAY2026) != 0; const size_t maxScriptElementSize = may2025Enabled ? may2025::MAX_SCRIPT_ELEMENT_SIZE : MAX_SCRIPT_ELEMENT_SIZE_LEGACY; const size_t maxIntegerSize = ScriptBigNum::MAXIMUM_ELEMENT_SIZE_BIG_INT; const ScriptError invalidNumberRangeError = SCRIPT_ERR_INVALID_NUMBER_RANGE_BIG_INT; if (script.size() > MAX_SCRIPT_SIZE) return set_error(state.error, SCRIPT_ERR_SCRIPT_SIZE); if (may2026Enabled && invocationDepth > may2026::MAX_CONTROL_STACK_DEPTH) return set_error(state.error, SCRIPT_ERR_CONTROL_STACK_DEPTH); int nOpCount = 0; bool fRequireMinimal = (state.flags & SCRIPT_VERIFY_MINIMALDATA) != 0; try { while (pc < pend) { bool fExec = !count(vfExec.begin(), vfExec.end(), false); // // Read instruction // if (!script.GetOp(pc, opcode, vchPushValue)) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); if (vchPushValue.size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); TallyOpcodeCost(state); // Note how OP_RESERVED does not count towards the opcode limit. if (!may2025Enabled && opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT_LEGACY) return set_error(state.error, SCRIPT_ERR_OP_COUNT); if ((opcode == OP_INVERT && !may2026Enabled) || (opcode == OP_LSHIFTNUM && !may2026Enabled) || (opcode == OP_RSHIFTNUM && !may2026Enabled) || (opcode == OP_LSHIFTBIN && !may2026Enabled) || (opcode == OP_RSHIFTBIN && !may2026Enabled) || (opcode == OP_MUL && (state.flags & SCRIPT_ENABLE_64_BIT_INTEGERS) == 0)) return set_error(state.error, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes. if (fExec && opcode <= OP_PUSHDATA4) { if (fRequireMinimal && !CheckMinimalPush(vchPushValue, opcode)) { return set_error(state.error, SCRIPT_ERR_MINIMALDATA); } stack.push_back(vchPushValue); TallyPushCost(state, stack.back().size()); } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) switch (opcode) { // // Push value // case OP_1NEGATE: case OP_1: case OP_2: case OP_3: case OP_4: case OP_5: case OP_6: case OP_7: case OP_8: case OP_9: case OP_10: case OP_11: case OP_12: case OP_13: case OP_14: case OP_15: case OP_16: { // ( -- value) CScriptNum bn((int)opcode - (int)(OP_1 - 1)); stack.push_back(bn.getvch()); TallyPushCost(state, stack.back().size()); // The result of these opcodes should always be the minimal way to push the data // they push, so no need for a CheckMinimalPush here. } break; // // Control // case OP_NOP: break; case OP_DEFINE: { if (!may2026Enabled) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype funcId = std::move(stacktop(-1)); valtype funcCode = std::move(stacktop(-2)); if (funcId.size() > may2026::MAX_FUNCTION_IDENTIFIER_SIZE) return set_error(state.error, SCRIPT_ERR_INVALID_FUNCTION_IDENTIFIER); if (funcCode.size() > MAX_SCRIPT_SIZE) return set_error(state.error, SCRIPT_ERR_SCRIPT_SIZE); if (functionTable.find(funcId) != functionTable.end()) return set_error(state.error, SCRIPT_ERR_FUNCTION_OVERWRITE_DISALLOWED); popstack(stack); popstack(stack); const auto result = functionTable.emplace(std::move(funcId), std::move(funcCode)); TallyPushCost(state, result.first->second.size()); break; } case OP_INVOKE: { if (!may2026Enabled) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); if (stack.empty()) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const valtype &funcId = stacktop(-1); if (funcId.size() > may2026::MAX_FUNCTION_IDENTIFIER_SIZE) return set_error(state.error, SCRIPT_ERR_INVALID_FUNCTION_IDENTIFIER); const auto it = functionTable.find(funcId); if (it == functionTable.end()) return set_error(state.error, SCRIPT_ERR_INVOKED_UNDEFINED_FUNCTION); CScript func(it->second.begin(), it->second.end()); popstack(stack); if (!evalInternal(stack, func, checker, state, altstack, functionTable, invocationDepth + 1)) return false; break; } case OP_CHECKLOCKTIMEVERIFY: { if (!(state.flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { // not enabled; treat as a NOP2 if (state.flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { return set_error(state.error, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); } break; } if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); // Note that elsewhere numeric opcodes are limited to // operands in the range -2**31+1 to 2**31-1, however it is // legal for opcodes to produce results exceeding that // range. This limitation is implemented by CScriptNum's // default 4-byte limit. // // If we kept to that limit we'd have a year 2038 problem, // even though the nLockTime field in transactions // themselves is uint32 which only becomes meaningless // after the year 2106. // // Thus as a special case we tell CScriptNum to accept up // to 5-byte bignums, which are good until 2**39-1, well // beyond the 2**32-1 limit of the nLockTime field itself. const CScriptNum nLockTime(stacktop(-1), fRequireMinimal, 5); // In the rare event that the argument may be < 0 due to // some arithmetic being done first, you can always use // 0 MAX CHECKLOCKTIMEVERIFY. if (nLockTime < 0) return set_error(state.error, SCRIPT_ERR_NEGATIVE_LOCKTIME); // Actually compare the specified lock time with the transaction. if (!checker.CheckLockTime(nLockTime)) return set_error(state.error, SCRIPT_ERR_UNSATISFIED_LOCKTIME); break; } case OP_CHECKSEQUENCEVERIFY: { if (!(state.flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) { // not enabled; treat as a NOP3 if (state.flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { return set_error(state.error, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); } break; } if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); // nSequence, like nLockTime, is a 32-bit unsigned integer // field. See the comment in CHECKLOCKTIMEVERIFY regarding // 5-byte numeric operands. const CScriptNum nSequence(stacktop(-1), fRequireMinimal, 5); // In the rare event that the argument may be < 0 due to // some arithmetic being done first, you can always use // 0 MAX CHECKSEQUENCEVERIFY. if (nSequence < 0) return set_error(state.error, SCRIPT_ERR_NEGATIVE_LOCKTIME); // To provide for future soft-fork extensibility, if the // operand has the disabled lock-time flag set, // CHECKSEQUENCEVERIFY behaves as a NOP. if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) break; // Compare the specified sequence number with the input. if (!checker.CheckSequence(nSequence)) return set_error(state.error, SCRIPT_ERR_UNSATISFIED_LOCKTIME); break; } case OP_NOP1: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: { if (state.flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) return set_error(state.error, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); } break; case OP_IF: case OP_NOTIF: { // if [statements] [else [statements]] endif bool fValue = false; if (fExec) { if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONDITIONAL); valtype& vch = stacktop(-1); fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; popstack(stack); } vfExec.push_back(fValue); controlStack.push_back({ControlEntry::Conditional, pc}); } break; case OP_ELSE: { if (vfExec.empty()) return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONDITIONAL); if (controlStack.empty() || controlStack.back().type != ControlEntry::Conditional) return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONTROL_FLOW); vfExec.back() = !vfExec.back(); } break; case OP_ENDIF: { if (vfExec.empty()) return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONDITIONAL); if (controlStack.empty() || controlStack.back().type != ControlEntry::Conditional) return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONTROL_FLOW); vfExec.pop_back(); controlStack.pop_back(); } break; case OP_BEGIN: { if (!may2026Enabled) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); controlStack.push_back({ControlEntry::Loop, pc}); } break; case OP_UNTIL: { if (!may2026Enabled) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); if (controlStack.empty() || controlStack.back().type != ControlEntry::Loop) return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONTROL_FLOW); if (fExec) { if (stack.empty()) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const bool done = CastToBool(stacktop(-1)); popstack(stack); if (!done) { pc = controlStack.back().loopPc; } else { controlStack.pop_back(); } } else { controlStack.pop_back(); } } break; case OP_VERIFY: { // (true -- ) or // (false -- false) and return if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); bool fValue = CastToBool(stacktop(-1)); if (fValue) popstack(stack); else return set_error(state.error, SCRIPT_ERR_VERIFY); } break; case OP_RETURN: { return set_error(state.error, SCRIPT_ERR_OP_RETURN); } break; // // Stack ops // case OP_TOALTSTACK: { if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); altstack.push_back(stacktop(-1)); popstack(stack); } break; case OP_FROMALTSTACK: { if (altstack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION); stack.push_back(altstacktop(-1)); popstack(altstack); } break; case OP_2DROP: { // (x1 x2 -- ) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); popstack(stack); popstack(stack); } break; case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-2); valtype vch2 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack.size() < 3) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-3); valtype vch2 = stacktop(-2); valtype vch3 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); stack.push_back(vch3); } break; case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack.size() < 4) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-4); valtype vch2 = stacktop(-3); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack.size() < 6) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch1 = stacktop(-6); valtype vch2 = stacktop(-5); stack.erase(stack.end()-6, stack.end()-4); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2SWAP: { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack.size() < 4) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-4), stacktop(-2)); swap(stacktop(-3), stacktop(-1)); } break; case OP_IFDUP: { // (x - 0 | x x) if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); if (CastToBool(vch)) stack.push_back(vch); } break; case OP_DEPTH: { // -- stacksize CScriptNum bn(stack.size()); stack.push_back(bn.getvch()); } break; case OP_DROP: { // (x -- ) if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); popstack(stack); } break; case OP_DUP: { // (x -- x x) if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); stack.push_back(vch); } break; case OP_NIP: { // (x1 x2 -- x2) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); stack.erase(stack.end() - 2); } break; case OP_OVER: { // (x1 x2 -- x1 x2 x1) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-2); stack.push_back(vch); } break; case OP_PICK: case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); int n = CScriptNum(stacktop(-1), fRequireMinimal).getint(); popstack(stack); if (n < 0 || n >= (int)stack.size()) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-n-1); if (opcode == OP_ROLL) stack.erase(stack.end()-n-1); stack.push_back(vch); } break; case OP_ROT: { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap if (stack.size() < 3) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-3), stacktop(-2)); swap(stacktop(-2), stacktop(-1)); } break; case OP_SWAP: { // (x1 x2 -- x2 x1) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); swap(stacktop(-2), stacktop(-1)); } break; case OP_TUCK: { // (x1 x2 -- x2 x1 x2) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype vch = stacktop(-1); stack.insert(stack.end()-2, vch); } break; case OP_SIZE: { // (in -- in size) if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); CScriptNum bn(stacktop(-1).size()); stack.push_back(bn.getvch()); TallyPushCost(state, stack.back().size()); } break; // // Bitwise logic // case OP_AND: case OP_OR: case OP_XOR: { // (x1 x2 - out) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype &vch1 = stacktop(-2); const valtype &vch2 = stacktop(-1); // Inputs must be the same size if (vch1.size() != vch2.size()) return set_error(state.error, SCRIPT_ERR_INVALID_OPERAND_SIZE); // To avoid allocating, we modify vch1 in place. if (opcode == OP_AND) for (size_t i = 0; i < vch1.size(); ++i) vch1[i] &= vch2[i]; else if (opcode == OP_OR) for (size_t i = 0; i < vch1.size(); ++i) vch1[i] |= vch2[i]; else if (opcode == OP_XOR) for (size_t i = 0; i < vch1.size(); ++i) vch1[i] ^= vch2[i]; TallyPushCost(state, vch1.size()); // And pop vch2. popstack(stack); break; } case OP_INVERT: { // (in -- out) if (stack.empty()) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype &data = stacktop(-1); for (uint8_t &byte : data) byte = ~byte; TallyPushCost(state, data.size()); break; } case OP_EQUAL: case OP_EQUALVERIFY: //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL { // (x1 x2 - bool) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); bool fEqual = (vch1 == vch2); // OP_NOTEQUAL is disabled because it would be too easy to say // something like n != 1 and have some wiseguy pass in 1 with extra // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) //if (opcode == OP_NOTEQUAL) // fEqual = !fEqual; popstack(stack); popstack(stack); stack.push_back(fEqual ? vchTrue : vchFalse); TallyPushCost(state, stack.back().size()); if (opcode == OP_EQUALVERIFY) { if (fEqual) popstack(stack); else return set_error(state.error, SCRIPT_ERR_EQUALVERIFY); } break; } // // Numeric // case OP_1ADD: case OP_1SUB: case OP_NEGATE: case OP_ABS: case OP_NOT: case OP_0NOTEQUAL: { // (in -- out) if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); FastBigNum bn(stacktop(-1), fRequireMinimal, maxIntegerSize); switch (opcode) { case OP_1ADD: if (!bn.safeIncr()) return set_error(state.error, invalidNumberRangeError); break; case OP_1SUB: if (!bn.safeDecr()) return set_error(state.error, invalidNumberRangeError); break; case OP_NEGATE: bn.negate(); break; case OP_ABS: if (bn < 0) bn.negate(); break; case OP_NOT: bn = FastBigNum::fromIntUnchecked(bn == 0, true); break; case OP_0NOTEQUAL: bn = FastBigNum::fromIntUnchecked(bn != 0, true); break; default: assert(false); break; } popstack(stack); valtype result = bn.getvch(); if (result.size() > maxScriptElementSize) return set_error(state.error, invalidNumberRangeError); stack.push_back(std::move(result)); TallyPushCost(state, stack.back().size()); } break; case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_BOOLAND: case OP_BOOLOR: case OP_NUMEQUAL: case OP_NUMEQUALVERIFY: case OP_NUMNOTEQUAL: case OP_LESSTHAN: case OP_GREATERTHAN: case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: case OP_MAX: { // (x1 x2 -- out) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); FastBigNum bn1(stacktop(-2), fRequireMinimal, maxIntegerSize); const FastBigNum bn2(stacktop(-1), fRequireMinimal, maxIntegerSize); FastBigNum bn = FastBigNum::fromIntUnchecked(0, true); switch (opcode) { case OP_ADD: if (!bn1.safeAddInPlace(bn2)) return set_error(state.error, invalidNumberRangeError); bn = bn1; break; case OP_SUB: if (!bn1.safeSubInPlace(bn2)) return set_error(state.error, invalidNumberRangeError); bn = bn1; break; case OP_MUL: if (!bn1.safeMulInPlace(bn2)) return set_error(state.error, invalidNumberRangeError); bn = bn1; break; case OP_DIV: if (bn2 == 0) return set_error(state.error, SCRIPT_ERR_DIV_BY_ZERO); bn = (bn1 /= bn2); break; case OP_MOD: if (bn2 == 0) return set_error(state.error, SCRIPT_ERR_MOD_BY_ZERO); bn = (bn1 %= bn2); break; case OP_BOOLAND: bn = FastBigNum::fromIntUnchecked(bn1 != 0 && bn2 != 0, true); break; case OP_BOOLOR: bn = FastBigNum::fromIntUnchecked(bn1 != 0 || bn2 != 0, true); break; case OP_NUMEQUAL: bn = FastBigNum::fromIntUnchecked(bn1 == bn2, true); break; case OP_NUMEQUALVERIFY: bn = FastBigNum::fromIntUnchecked(bn1 == bn2, true); break; case OP_NUMNOTEQUAL: bn = FastBigNum::fromIntUnchecked(bn1 != bn2, true); break; case OP_LESSTHAN: bn = FastBigNum::fromIntUnchecked(bn1 < bn2, true); break; case OP_GREATERTHAN: bn = FastBigNum::fromIntUnchecked(bn1 > bn2, true); break; case OP_LESSTHANOREQUAL: bn = FastBigNum::fromIntUnchecked(bn1 <= bn2, true); break; case OP_GREATERTHANOREQUAL: bn = FastBigNum::fromIntUnchecked(bn1 >= bn2, true); break; case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; default: assert(!"invalid opcode"); break; } popstack(stack); popstack(stack); valtype result = bn.getvch(); if (result.size() > maxScriptElementSize) return set_error(state.error, invalidNumberRangeError); stack.push_back(std::move(result)); TallyPushCost(state, stack.back().size()); if (opcode == OP_NUMEQUALVERIFY) { if (CastToBool(stacktop(-1))) popstack(stack); else return set_error(state.error, SCRIPT_ERR_NUMEQUALVERIFY); } } break; case OP_LSHIFTNUM: case OP_RSHIFTNUM: { // (num nbits -- out) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const int32_t nbits = FastBigNum(stacktop(-1), fRequireMinimal, maxIntegerSize).getint32(); if (nbits < 0) return set_error(state.error, SCRIPT_ERR_INVALID_BIT_SHIFT); popstack(stack); FastBigNum bn(stacktop(-1), fRequireMinimal, maxIntegerSize); if (nbits > 0) { const bool valid = opcode == OP_LSHIFTNUM ? bn.checkedLeftShift(static_cast(nbits)) : bn.checkedRightShift(static_cast(nbits)); if (!valid) return set_error(state.error, invalidNumberRangeError); valtype result = bn.getvch(); if (result.size() > maxScriptElementSize) return set_error(state.error, invalidNumberRangeError); stacktop(-1) = std::move(result); } TallyPushCost(state, stacktop(-1).size()); } break; case OP_WITHIN: { // (x min max -- out) if (stack.size() < 3) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const FastBigNum bn1(stacktop(-3), fRequireMinimal, maxIntegerSize); const FastBigNum bn2(stacktop(-2), fRequireMinimal, maxIntegerSize); const FastBigNum bn3(stacktop(-1), fRequireMinimal, maxIntegerSize); bool fValue = (bn2 <= bn1 && bn1 < bn3); popstack(stack); popstack(stack); popstack(stack); stack.push_back(fValue ? vchTrue : vchFalse); TallyPushCost(state, stack.back().size()); } break; // // Crypto // case OP_RIPEMD160: case OP_SHA1: case OP_SHA256: case OP_HASH160: case OP_HASH256: { // (in -- hash) if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype& vch = stacktop(-1); valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) CRIPEMD160().write(begin_ptr(vch), vch.size()).finalize(begin_ptr(vchHash)); else if (opcode == OP_SHA1) CSHA1().write(begin_ptr(vch), vch.size()).finalize(begin_ptr(vchHash)); else if (opcode == OP_SHA256) CSHA256().write(begin_ptr(vch), vch.size()).finalize(begin_ptr(vchHash)); else if (opcode == OP_HASH160) CHash160().write(begin_ptr(vch), vch.size()).finalize(begin_ptr(vchHash)); else if (opcode == OP_HASH256) CHash256().write(begin_ptr(vch), vch.size()).finalize(begin_ptr(vchHash)); TallyHashCost(state, vch.size(), opcode == OP_HASH160 || opcode == OP_HASH256); popstack(stack); stack.push_back(vchHash); TallyPushCost(state, stack.back().size()); } break; case OP_CODESEPARATOR: { // Hash starts after the code separator pbegincodehash = pc; } break; case OP_CHECKSIG: case OP_CHECKSIGVERIFY: { // (sig pubkey -- bool) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype& vchSig = stacktop(-2); valtype& vchPubKey = stacktop(-1); if (!CheckSignatureEncoding(vchSig, state, TransactionCheckSigChecks) || !CheckPubKeyEncoding(vchPubKey, state)) { // state.error is set return false; } // Subset of script starting at the most recent // codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signature, since there's no way for a signature to sign itself CleanupScriptCode(scriptCode, vchSig, state.flags); size_t bytesHashed = 0; bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, state.flags, &bytesHashed); if (!vchSig.empty()) { state.sigCheckCount++; if (bytesHashed > 0) TallyHashCost(state, bytesHashed, true); } if (!fSuccess && (state.flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size()) return set_error(state.error, SCRIPT_ERR_SIG_NULLFAIL); popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); TallyPushCost(state, stack.back().size()); if (opcode == OP_CHECKSIGVERIFY) { if (fSuccess) popstack(stack); else return set_error(state.error, SCRIPT_ERR_CHECKSIGVERIFY); } } break; case OP_CHECKMULTISIG: case OP_CHECKMULTISIGVERIFY: { // ([dummy] [sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) const int idxKeyCount = 1; if (stack.size() < idxKeyCount) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const int nKeysCount = CScriptNum(stacktop(-idxKeyCount), fRequireMinimal).getint(); if (nKeysCount < 0 || nKeysCount > MAX_PUBKEYS_PER_MULTISIG) return set_error(state.error, SCRIPT_ERR_PUBKEY_COUNT); nOpCount += nKeysCount; if (!may2025Enabled && nOpCount > MAX_OPS_PER_SCRIPT_LEGACY) return set_error(state.error, SCRIPT_ERR_OP_COUNT); // stack depth of the top pubkey const int idxTopKey = idxKeyCount + 1; // stack depth of nSigsCount const int idxSigCount = idxTopKey + nKeysCount; if (static_cast(stack.size()) < idxSigCount) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const int nSigsCount = CScriptNum(stacktop(-idxSigCount), fRequireMinimal).getint(); if (nSigsCount < 0 || nSigsCount > nKeysCount) return set_error(state.error, SCRIPT_ERR_SIG_COUNT); // stack depth of the top signature const int idxTopSig = idxSigCount + 1; // stack depth of the dummy element const int idxDummy = idxTopSig + nSigsCount; if (static_cast(stack.size()) < idxDummy) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Assuming success is usually a bad idea, but the schnorr path can only succeed. bool fSuccess = true; if ((state.flags & SCRIPT_ENABLE_SCHNORR_MULTISIG) && stacktop(-idxDummy).size() != 0) { // SCHNORR MULTISIG static_assert(MAX_PUBKEYS_PER_MULTISIG < 32, "Schnorr multisig checkbits implementation assumes < 32 pubkeys."); uint32_t checkBits = 0; // Dummy push is interpreted as a bitfield that represent which pubkeys should be checked. // lets check and copy it into the checkBits 32 bits, much easier to use than a bytearray valtype &vchDummy = stacktop(-idxDummy); if (!decodeBitfield(vchDummy, nKeysCount, checkBits, state.error)) return false; // state.error is set // The required number of signatures (from the output) has to be exactly the amount of bits set. if (countBits(checkBits) != nSigsCount) return set_error(state.error, SCRIPT_ERR_INVALID_BIT_COUNT); const int idxBottomKey = idxTopKey + nKeysCount - 1; const int idxBottomSig = idxTopSig + nSigsCount - 1; // There typically are less signatures than keys. We know how many // keys to skip based on the bits being 0 in checkBits int iKey = 0; for (int iSig = 0; iSig < nSigsCount; iSig++, iKey++) { if ((checkBits >> iKey) == 0) { // no more bits set? // This is a sanity check and should be unreacheable. return set_error(state.error, SCRIPT_ERR_INVALID_BIT_RANGE); } // Find the next suitable key. while (((checkBits >> iKey) & 0x01) == 0) { iKey++; } if (iKey >= nKeysCount) { // This is a sanity check and should be unreacheable. return set_error(state.error, SCRIPT_ERR_PUBKEY_COUNT); } // Check the signature. valtype &vchSig = stacktop(-idxBottomSig + iSig); valtype &vchPubKey = stacktop(-idxBottomKey + iKey); // Note that only pubkeys associated with a signature are checked for validity. if (!CheckSignatureEncoding(vchSig, state, MultiSigChecksSchnorr) || !CheckPubKeyEncoding(vchPubKey, state)) { // state.error is set return false; } // Check signature size_t bytesHashed = 0; if (!checker.CheckSig(vchSig, vchPubKey, scriptCode, state.flags, &bytesHashed)) { // This would fail if the signature is empty, which also is a NULLFAIL error as the // bitfield should have had a false return set_error(state.error, SCRIPT_ERR_SIG_NULLFAIL); } state.sigCheckCount++; if (bytesHashed > 0) TallyHashCost(state, bytesHashed, true); } if ((checkBits >> iKey) != 0) { // This is a sanity check and should be unrecheable. return set_error( state.error, SCRIPT_ERR_INVALID_BIT_COUNT); } } else { // LEGACY MULTISIG (ECDSA / NULL) // A bug causes CHECKMULTISIG to consume one extra argument whose contents were not checked in any way. // // Unfortunately this is a potential source of mutability, so optionally verify it is exactly equal to zero. if ((state.flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-idxDummy).size()) return set_error(state.error, SCRIPT_ERR_SIG_NULLDUMMY); // Remove signature for pre-fork scripts for (int k = 0; k < nSigsCount; k++) { valtype &vchSig = stacktop(-idxTopSig - k); CleanupScriptCode(scriptCode, vchSig, state.flags); } int nSigsRemaining = nSigsCount; int nKeysRemaining = nKeysCount; while (fSuccess && nSigsRemaining > 0) { valtype &vchSig = stacktop(-idxTopSig - (nSigsCount - nSigsRemaining)); valtype &vchPubKey = stacktop(-idxTopKey - (nKeysCount - nKeysRemaining)); // Note how this makes the exact order of pubkey/signature evaluation // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. // See the script_(in)valid tests for details. if (!CheckSignatureEncoding(vchSig, state, MultiSigChecksECDSA) || !CheckPubKeyEncoding(vchPubKey, state)) { // state.error is set return false; } // Check signature size_t bytesHashed = 0; bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode, state.flags, &bytesHashed); if (bytesHashed > 0) TallyHashCost(state, bytesHashed, true); if (fOk) nSigsRemaining--; nKeysRemaining--; // If there are more signatures left than keys // left, then too many signatures have failed. // Exit early, without checking any further // signatures. if (nSigsRemaining > nKeysRemaining) fSuccess = false; } // unless all signatures are null, add the keysCount to our metrics. for (int i = 0; i < nSigsCount; i++) { if (stacktop(-idxTopSig - i).size()) { state.sigCheckCount += nKeysCount; break; } } } // If the operation failed, we require that all // signatures must be empty vector if (!fSuccess && (state.flags & SCRIPT_VERIFY_NULLFAIL)) { for (int i = 0; i < nSigsCount; i++) { if (stacktop(-idxTopSig - i).size()) return set_error(state.error, SCRIPT_ERR_SIG_NULLFAIL); } } // Clean up stack of all arguments for (int i = 0; i < idxDummy; i++) { popstack(stack); } stack.push_back(fSuccess ? vchTrue : vchFalse); TallyPushCost(state, stack.back().size()); if (opcode == OP_CHECKMULTISIGVERIFY) { if (fSuccess) popstack(stack); else return set_error(state.error, SCRIPT_ERR_CHECKMULTISIGVERIFY); } } break; case OP_CHECKDATASIG: case OP_CHECKDATASIGVERIFY: { // Make sure this remains an error before activation. if (!(state.flags & SCRIPT_ENABLE_CHECKDATASIG)) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); // (sig message pubkey -- bool) if (stack.size() < 3) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype &vchSig = stacktop(-3); valtype &vchMessage = stacktop(-2); valtype &vchPubKey = stacktop(-1); if (!CheckSignatureEncoding(vchSig, state, CheckDataSigChecks) || !CheckPubKeyEncoding(vchPubKey, state)) // state.error is set return false; bool fSuccess = false; if (vchSig.size()) { valtype vchHash(32); CSHA256().write(vchMessage.data(), vchMessage.size()).finalize(vchHash.data()); uint256 messagehash(vchHash); PublicKey pubkey(vchPubKey); if ((state.flags & SCRIPT_ENABLE_SCHNORR) && vchSig.size() == 64) fSuccess = pubkey.verifySchnorr(messagehash, vchSig); else fSuccess = pubkey.verifyECDSA(messagehash, vchSig); state.sigCheckCount++; TallyHashCost(state, vchMessage.size(), false); } if (!fSuccess && (state.flags & SCRIPT_VERIFY_NULLFAIL) && vchSig.size()) return set_error(state.error, SCRIPT_ERR_SIG_NULLFAIL); popstack(stack); popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); TallyPushCost(state, stack.back().size()); if (opcode == OP_CHECKDATASIGVERIFY) { if (!fSuccess) return set_error(state.error, SCRIPT_ERR_CHECKDATASIGVERIFY); popstack(stack); } } break; // // Byte string operations // case OP_CAT: { // (x1 x2 -- out) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype &vch1 = stacktop(-2); const valtype &vch2 = stacktop(-1); if (vch1.size() + vch2.size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); vch1.insert(vch1.end(), vch2.begin(), vch2.end()); popstack(stack); TallyPushCost(state, stack.back().size()); break; } case OP_SPLIT: { // (in position -- x1 x2) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const valtype &data = stacktop(-2); // Make sure the split point is apropriate. uint64_t position = CScriptNum(stacktop(-1), fRequireMinimal).getint(); if (position > data.size()) return set_error(state.error, SCRIPT_ERR_INVALID_SPLIT_RANGE); // Prepare the results in their own buffer as `data` // will be invalidated. valtype n1(data.begin(), data.begin() + position); valtype n2(data.begin() + position, data.end()); // Replace existing stack values by the new values. const size_t totalSize = n1.size() + n2.size(); stacktop(-2) = std::move(n1); stacktop(-1) = std::move(n2); TallyPushCost(state, totalSize); break; } case OP_REVERSEBYTES: { if (!(state.flags & SCRIPT_ENABLE_OP_REVERSEBYTES)) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); // (in -- out) if (stack.size() < 1) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype &data = stacktop(-1); std::reverse(data.begin(), data.end()); TallyPushCost(state, data.size()); break; } case OP_LSHIFTBIN: case OP_RSHIFTBIN: { // (in nbits -- out) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const int32_t nbits = FastBigNum(stacktop(-1), fRequireMinimal, maxIntegerSize).getint32(); if (nbits < 0) return set_error(state.error, SCRIPT_ERR_INVALID_BIT_SHIFT); valtype data = std::move(stacktop(-2)); popstack(stack); popstack(stack); bitShiftBlob(data, static_cast(nbits), opcode == OP_RSHIFTBIN); if (data.size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); stack.push_back(std::move(data)); TallyPushCost(state, stack.back().size()); break; } // // Native introspection operations // case OP_INPUTINDEX: case OP_ACTIVEBYTECODE: case OP_TXVERSION: case OP_TXINPUTCOUNT: case OP_TXOUTPUTCOUNT: case OP_TXLOCKTIME: { if (!(state.flags & SCRIPT_ENABLE_NATIVE_INTROSPECTION)) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); if (!checker.hasTransactionContext()) return set_error(state.error, SCRIPT_ERR_CONTEXT_NOT_PRESENT); const CTransaction *tx = checker.transaction(); assert(tx != nullptr); switch (opcode) { case OP_INPUTINDEX: stack.push_back(CScriptNum(checker.inputIndex()).getvch()); break; case OP_ACTIVEBYTECODE: if (static_cast(pend - pbegincodehash) > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); stack.emplace_back(pbegincodehash, pend); break; case OP_TXVERSION: stack.push_back(CScriptNum(tx->nVersion).getvch()); break; case OP_TXINPUTCOUNT: stack.push_back(CScriptNum(static_cast(tx->vin.size())).getvch()); break; case OP_TXOUTPUTCOUNT: stack.push_back(CScriptNum(static_cast(tx->vout.size())).getvch()); break; case OP_TXLOCKTIME: stack.push_back(CScriptNum(static_cast(tx->nLockTime)).getvch()); break; default: assert(!"invalid opcode"); break; } TallyPushCost(state, stack.back().size()); break; } case OP_UTXOVALUE: case OP_UTXOBYTECODE: case OP_OUTPOINTTXHASH: case OP_OUTPOINTINDEX: case OP_INPUTBYTECODE: case OP_INPUTSEQUENCENUMBER: case OP_OUTPUTVALUE: case OP_OUTPUTBYTECODE: case OP_UTXOTOKENCATEGORY: case OP_UTXOTOKENCOMMITMENT: case OP_UTXOTOKENAMOUNT: case OP_OUTPUTTOKENCATEGORY: case OP_OUTPUTTOKENCOMMITMENT: case OP_OUTPUTTOKENAMOUNT: { if (!(state.flags & SCRIPT_ENABLE_NATIVE_INTROSPECTION)) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); if (isCashTokenIntrospectionOpcode(opcode) && !(state.flags & SCRIPT_ENABLE_CASHTOKENS)) return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); if (!checker.hasTransactionContext()) return set_error(state.error, SCRIPT_ERR_CONTEXT_NOT_PRESENT); if (stack.empty()) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const int64_t index = CScriptNum(stacktop(-1), fRequireMinimal, CScriptNum::MAXIMUM_ELEMENT_SIZE_64_BIT).getint64(); popstack(stack); const CTransaction *tx = checker.transaction(); assert(tx != nullptr); const auto validInputIndex = [&]() -> bool { return index >= 0 && static_cast(index) < tx->vin.size(); }; const auto validOutputIndex = [&]() -> bool { return index >= 0 && static_cast(index) < tx->vout.size(); }; const auto inputIndex = static_cast(index); const auto outputIndex = static_cast(index); switch (opcode) { case OP_UTXOVALUE: case OP_UTXOBYTECODE: case OP_UTXOTOKENCATEGORY: case OP_UTXOTOKENCOMMITMENT: case OP_UTXOTOKENAMOUNT: { if (!validInputIndex()) return set_error(state.error, SCRIPT_ERR_INVALID_TX_INPUT_INDEX); if (checker.isLimitedContext() && static_cast(inputIndex) != checker.inputIndex()) return set_error(state.error, SCRIPT_ERR_LIMITED_CONTEXT_NO_SIBLING_INFO); Tx::Output spentOutput; if (!checker.spentOutput(static_cast(inputIndex), spentOutput)) return set_error(state.error, SCRIPT_ERR_CONTEXT_NOT_PRESENT); if (opcode == OP_UTXOVALUE) { stack.push_back(CScriptNum(spentOutput.outputValue).getvch()); } else if (opcode == OP_UTXOBYTECODE) { if (spentOutput.outputScript().size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); stack.emplace_back(spentOutput.outputScript().begin(), spentOutput.outputScript().end()); } else if (opcode == OP_UTXOTOKENCATEGORY) { stack.push_back(tokenCategoryBytes(spentOutput)); } else if (opcode == OP_UTXOTOKENCOMMITMENT) { valtype commitment = tokenCommitmentBytes(spentOutput); if (commitment.size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); stack.push_back(std::move(commitment)); } else { stack.push_back(CScriptNum(tokenAmount(spentOutput)).getvch()); } break; } case OP_OUTPOINTTXHASH: if (!validInputIndex()) return set_error(state.error, SCRIPT_ERR_INVALID_TX_INPUT_INDEX); stack.emplace_back(tx->vin[inputIndex].prevout.hash.begin(), tx->vin[inputIndex].prevout.hash.end()); break; case OP_OUTPOINTINDEX: if (!validInputIndex()) return set_error(state.error, SCRIPT_ERR_INVALID_TX_INPUT_INDEX); stack.push_back(CScriptNum(static_cast(tx->vin[inputIndex].prevout.n)).getvch()); break; case OP_INPUTBYTECODE: if (!validInputIndex()) return set_error(state.error, SCRIPT_ERR_INVALID_TX_INPUT_INDEX); if (tx->vin[inputIndex].scriptSig.size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); stack.emplace_back(tx->vin[inputIndex].scriptSig.begin(), tx->vin[inputIndex].scriptSig.end()); break; case OP_INPUTSEQUENCENUMBER: if (!validInputIndex()) return set_error(state.error, SCRIPT_ERR_INVALID_TX_INPUT_INDEX); stack.push_back(CScriptNum(static_cast(tx->vin[inputIndex].nSequence)).getvch()); break; case OP_OUTPUTVALUE: if (!validOutputIndex()) return set_error(state.error, SCRIPT_ERR_INVALID_TX_OUTPUT_INDEX); stack.push_back(CScriptNum(tx->vout[outputIndex].nValue).getvch()); break; case OP_OUTPUTBYTECODE: if (!validOutputIndex()) return set_error(state.error, SCRIPT_ERR_INVALID_TX_OUTPUT_INDEX); if (state.flags & SCRIPT_ENABLE_CASHTOKENS) { Tx::Output output; if (!readTransactionOutput(checker.tx(), outputIndex, output)) return set_error(state.error, SCRIPT_ERR_UNKNOWN_ERROR); if (output.outputScript().size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); stack.emplace_back(output.outputScript().begin(), output.outputScript().end()); } else { if (tx->vout[outputIndex].scriptPubKey.size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); stack.emplace_back(tx->vout[outputIndex].scriptPubKey.begin(), tx->vout[outputIndex].scriptPubKey.end()); } break; case OP_OUTPUTTOKENCATEGORY: case OP_OUTPUTTOKENCOMMITMENT: case OP_OUTPUTTOKENAMOUNT: { if (!validOutputIndex()) return set_error(state.error, SCRIPT_ERR_INVALID_TX_OUTPUT_INDEX); Tx::Output output; if (!readTransactionOutput(checker.tx(), outputIndex, output)) return set_error(state.error, SCRIPT_ERR_UNKNOWN_ERROR); if (opcode == OP_OUTPUTTOKENCATEGORY) { stack.push_back(tokenCategoryBytes(output)); } else if (opcode == OP_OUTPUTTOKENCOMMITMENT) { valtype commitment = tokenCommitmentBytes(output); if (commitment.size() > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); stack.push_back(std::move(commitment)); } else { stack.push_back(CScriptNum(tokenAmount(output)).getvch()); } break; } default: assert(!"invalid opcode"); break; } TallyPushCost(state, stack.back().size()); break; } // // Conversion operations // case OP_BIN2NUM: { // (in -- out) if (stack.empty()) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); valtype &n = stacktop(-1); CScriptNum::createSmallestFormat(n); TallyPushCost(state, n.size()); // The resulting number must be a valid number. if (!CScriptNum::isSmallestFormat(n, maxIntegerSize)) return set_error(state.error, invalidNumberRangeError); break; } case OP_NUM2BIN: { // (in size -- out) if (stack.size() < 2) return set_error(state.error, SCRIPT_ERR_INVALID_STACK_OPERATION); const uint64_t size = CScriptNum(stacktop(-1), fRequireMinimal, CScriptNum::MAXIMUM_ELEMENT_SIZE_32_BIT).getint64(); if (size > maxScriptElementSize) return set_error(state.error, SCRIPT_ERR_PUSH_SIZE); popstack(stack); valtype &rawnum = stacktop(-1); // Try to see if we can fit that number in the number of // byte requested. CScriptNum::createSmallestFormat(rawnum); if (rawnum.size() > size) // We definitively cannot. return set_error(state.error, SCRIPT_ERR_IMPOSSIBLE_ENCODING); // We already have an element of the right size, we don't need to do anything. if (rawnum.size() == size) { TallyPushCost(state, rawnum.size()); break; } uint8_t signbit = 0x00; if (rawnum.size() > 0) { signbit = rawnum.back() & 0x80; rawnum[rawnum.size() - 1] &= 0x7f; } rawnum.reserve(size); while (rawnum.size() < size - 1) rawnum.push_back(0x00); rawnum.push_back(signbit); TallyPushCost(state, rawnum.size()); break; } default: return set_error(state.error, SCRIPT_ERR_BAD_OPCODE); } // Size limits if (stack.size() + altstack.size() + functionTable.size() > MAX_STACK_SIZE) return set_error(state.error, SCRIPT_ERR_STACK_SIZE); if (may2025Enabled && !may2026Enabled && vfExec.size() > may2025::MAX_CONDITIONAL_STACK_DEPTH) return set_error(state.error, SCRIPT_ERR_CONDITIONAL_STACK_DEPTH); if (may2026Enabled && controlStack.size() + invocationDepth > may2026::MAX_CONTROL_STACK_DEPTH) return set_error(state.error, SCRIPT_ERR_CONTROL_STACK_DEPTH); if (!CheckVmLimits(state, state.error)) return false; } } catch (const scriptnum_error &err) { return set_error(state.error, err.error()); } catch (...) { return set_error(state.error, SCRIPT_ERR_UNKNOWN_ERROR); } if (!controlStack.empty()) { for (const ControlEntry &entry : controlStack) { if (entry.type == ControlEntry::Loop) return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONTROL_FLOW); } return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONDITIONAL); } if (!vfExec.empty()) return set_error(state.error, SCRIPT_ERR_UNBALANCED_CONDITIONAL); return set_success(state.error); } bool Script::eval(std::vector > &stack, const CScript &script, const BaseSignatureChecker &checker, Script::State &state) { std::vector altstack; FunctionTable functionTable; return evalInternal(stack, script, checker, state, altstack, functionTable, 0); } namespace { /** * Wrapper that serializes like CTransaction, but with the modifications * required for the signature hash done in-place */ class CTransactionSignatureSerializer { private: const CTransaction &txTo; //! reference to the spending transaction (the one being serialized) const CScript &scriptCode; //! output script being consumed const unsigned int nIn; //! input index of txTo being signed const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE const bool fHashNone; //! whether the hashtype is SIGHASH_NONE public: CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} /** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */ template void SerializeScriptCode(S &s, int nType, int nVersion) const { CScript::const_iterator it = scriptCode.begin(); CScript::const_iterator itBegin = it; opcodetype opcode; unsigned int nCodeSeparators = 0; while (scriptCode.GetOp(it, opcode)) { if (opcode == OP_CODESEPARATOR) nCodeSeparators++; } ::WriteCompactSize(s, scriptCode.size() - nCodeSeparators); it = itBegin; while (scriptCode.GetOp(it, opcode)) { if (opcode == OP_CODESEPARATOR) { s.write((char*)&itBegin[0], it-itBegin-1); itBegin = it; } } if (itBegin != scriptCode.end()) s.write((char*)&itBegin[0], it-itBegin); } /** Serialize an input of txTo */ template void SerializeInput(S &s, unsigned int nInput, int nType, int nVersion) const { assert(txTo.vin.size() > nInput); // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized if (fAnyoneCanPay) nInput = nIn; // Serialize the prevout ::Serialize(s, txTo.vin[nInput].prevout, nType, nVersion); // Serialize the script if (nInput != nIn) // Blank out other inputs' signatures ::Serialize(s, CScriptBase(), nType, nVersion); else SerializeScriptCode(s, nType, nVersion); // Serialize the nSequence if (nInput != nIn && (fHashSingle || fHashNone)) // let the others update at will ::Serialize(s, (int)0, nType, nVersion); else ::Serialize(s, txTo.vin[nInput].nSequence, nType, nVersion); } /** Serialize an output of txTo */ template void SerializeOutput(S &s, unsigned int nOutput, int nType, int nVersion) const { assert(txTo.vout.size() > nOutput); if (fHashSingle && nOutput != nIn) // Do not lock-in the txout payee at other indices as txin ::Serialize(s, CTxOut(), nType, nVersion); else ::Serialize(s, txTo.vout[nOutput], nType, nVersion); } /** Serialize txTo */ template void Serialize(S &s, int nType, int nVersion) const { // Serialize nVersion ::Serialize(s, txTo.nVersion, nType, nVersion); // Serialize vin unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size(); ::WriteCompactSize(s, nInputs); for (unsigned int nInput = 0; nInput < nInputs; nInput++) SerializeInput(s, nInput, nType, nVersion); // Serialize vout unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size()); ::WriteCompactSize(s, nOutputs); for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) SerializeOutput(s, nOutput, nType, nVersion); // Serialize nLockTime ::Serialize(s, txTo.nLockTime, nType, nVersion); } }; uint256 GetPrevoutHash(const CTransaction &txTo) { CHashWriter ss(SER_GETHASH, 0); for (size_t n = 0; n < txTo.vin.size(); ++n) { ss << txTo.vin[n].prevout; } return ss.finalizeHash(); } uint256 GetSequenceHash(const CTransaction &txTo) { CHashWriter ss(SER_GETHASH, 0); for (size_t n = 0; n < txTo.vin.size(); ++n) { ss << txTo.vin[n].nSequence; } return ss.finalizeHash(); } uint256 GetOutputsHash(const CTransaction &txTo) { CHashWriter ss(SER_GETHASH, 0); for (size_t n = 0; n < txTo.vout.size(); ++n) { ss << txTo.vout[n]; } return ss.finalizeHash(); } uint256 GetUtxosHash(const std::vector &spentOutputs) { CHashWriter ss(SER_GETHASH, 0); for (auto output : spentOutputs) { ss << output.outputValue; auto script = output.rawOutputScript(); WriteCompactSize(ss, script.size()); ss.write(script.begin(), script.size()); } return ss.finalizeHash(); } void WriteCashTokenPrefix(CHashWriter &ss, const std::vector *spentOutputs, unsigned int nIn, uint32_t flags) { if ((flags & SCRIPT_ENABLE_CASHTOKENS) == 0 || spentOutputs == nullptr || nIn >= spentOutputs->size()) return; const Tx::Output &output = spentOutputs->at(nIn); if (!output.hasToken()) return; const auto rawScript = output.rawOutputScript(); const auto lockingScript = output.outputScript(); const auto prefixSize = rawScript.size() - lockingScript.size(); if (prefixSize > 0) ss.write(rawScript.begin(), prefixSize); } } // anon namespace /** * SignatureHash is a helper method to hash a certain subset of the /a txTo transactions content * which is then used to pass to the signing function of a CKey private key, a process used to * prove that he owns the public key and at the same time lock in all the content signed. * * As we sign each input separately, this method takes an \a nIn index to the input we intend to sign. * * \param scriptCode the script from the previous transaction, the one the input is trying to spend. * \param txTo the transactoin that the input we sign is part of. * \param nIn the input index * \param amount the amount of satoshis that the input contains * \param nHashType is a binary flags field indicating what kind of payment this is. See SIGHASH_SINGLE and others. * \param flags a binary flags field indicating the state of the (bitcoin) macro system. * \param spentOutputs only used for (hashType & SIGHASH_UTXO). */ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int64_t amount, int nHashType, uint32_t flags, const std::vector *spentOutputs, size_t *bytesHashed) { if (bytesHashed) *bytesHashed = 0; assert(nIn < txTo.vin.size()); if ((nHashType & SIGHASH_FORKID) && (flags & SCRIPT_ENABLE_SIGHASH_FORKID)) { uint256 hashPrevouts; uint256 hashSequence; uint256 hashOutputs; uint256 hashUtxos; if (!(nHashType & SIGHASH_ANYONECANPAY)) { hashPrevouts = GetPrevoutHash(txTo); } if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { hashSequence = GetSequenceHash(txTo); } // the most overengineerd idea 'sighash-utxo' support. Which adds nothing to users. const bool doTheUtxoCrap = (nHashType & SIGHASH_UTXOS) && (flags & SCRIPT_ENABLE_SIGHASH_UTXOS); if (doTheUtxoCrap) { assert(spentOutputs); if (spentOutputs == nullptr || spentOutputs->size() != txTo.vin.size()) throw std::runtime_error("SIGHASH_UTXOS requires all spent outputs"); hashUtxos = GetUtxosHash(*spentOutputs); } if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { hashOutputs = GetOutputsHash(txTo); } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { CHashWriter ss(SER_GETHASH, 0); ss << txTo.vout[nIn]; hashOutputs = ss.finalizeHash(); } CHashWriter ss(SER_GETHASH, 0); // Version ss << txTo.nVersion; // Input prevouts/nSequence (none/all, depending on flags) ss << hashPrevouts; if (doTheUtxoCrap) ss << hashUtxos; ss << hashSequence; // The input being signed (replacing the scriptSig with scriptCode + amount). // The prevout may already be included in hashPrevout, and the // nSequence may already be included in hashSequence. ss << txTo.vin[nIn].prevout; WriteCashTokenPrefix(ss, spentOutputs, nIn, flags); ss << static_cast(scriptCode); ss << amount; ss << txTo.vin[nIn].nSequence; // Outputs (none/one/all, depending on flags) ss << hashOutputs; // Locktime ss << txTo.nLockTime; // Sighash type ss << nHashType; if (bytesHashed) *bytesHashed = ss.GetNumBytesWritten(); return ss.finalizeHash(); } static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); if (nIn >= txTo.vin.size()) { // nIn out of range return one; } // Check for invalid use of SIGHASH_SINGLE if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if (nIn >= txTo.vout.size()) { // nOut out of range return one; } } // Wrapper to serialize only the necessary parts of the transaction being signed CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType); // Serialize and hash CHashWriter ss(SER_GETHASH, 0); ss << txTmp << nHashType; if (bytesHashed) *bytesHashed = ss.GetNumBytesWritten(); return ss.finalizeHash(); } bool TransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const PublicKey& pubkey, const uint256& sighash, uint32_t flags) const { if ((flags & SCRIPT_ENABLE_SCHNORR) && (vchSig.size() == 64)) { return pubkey.verifySchnorr(sighash, vchSig); } else { return pubkey.verifyECDSA(sighash, vchSig); } } bool TransactionSignatureChecker::CheckSig(const std::vector& vchSigIn, const std::vector& vchPubKey, const CScript& scriptCode, uint32_t flags, size_t *bytesHashed) const { if (bytesHashed) *bytesHashed = 0; PublicKey pubkey(vchPubKey); if (!pubkey.isValid()) return false; // Hash type is one byte tacked on to the end of the signature std::vector vchSig(vchSigIn); if (vchSig.empty()) return false; int nHashType = vchSig.back(); vchSig.pop_back(); if ((nHashType & SIGHASH_UTXOS) && (flags & SCRIPT_ENABLE_SIGHASH_UTXOS) && (spentOutputs == nullptr || spentOutputs->size() != oldTxTo->vin.size())) return false; uint256 sighash = SignatureHash(scriptCode, *oldTxTo, nIn, amount, nHashType, flags, spentOutputs, bytesHashed); if (!VerifySignature(vchSig, pubkey, sighash, flags)) return false; return true; } bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const { // There are two kinds of nLockTime: lock-by-blockheight // and lock-by-blocktime, distinguished by whether // nLockTime < LOCKTIME_THRESHOLD. // // We want to compare apples to apples, so fail the script // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( (oldTxTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || (oldTxTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) )) return false; // Now that we know we're comparing apples-to-apples, the // comparison is a simple numeric one. if (nLockTime > (int64_t)oldTxTo->nLockTime) return false; // Finally the nLockTime feature can be disabled and thus // CHECKLOCKTIMEVERIFY bypassed if every txin has been // finalized by setting nSequence to maxint. The // transaction would be allowed into the blockchain, making // the opcode ineffective. // // Testing if this vin is not final is sufficient to // prevent this condition. Alternatively we could test all // inputs, but testing just this input minimizes the data // required to prove correct CHECKLOCKTIMEVERIFY execution. if (CTxIn::SEQUENCE_FINAL == oldTxTo->vin[nIn].nSequence) return false; return true; } bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const { // Relative lock times are supported by comparing the passed // in operand to the sequence number of the input. const int64_t txToSequence = (int64_t)oldTxTo->vin[nIn].nSequence; // Fail if the transaction's version number is not set high // enough to trigger BIP 68 rules. if (static_cast(oldTxTo->nVersion) < 2) return false; // Sequence numbers with their most significant bit set are not // consensus constrained. Testing that the transaction's sequence // number do not have this bit set prevents using this property // to get around a CHECKSEQUENCEVERIFY check. if (txToSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) return false; // Mask off any bits that do not have consensus-enforced meaning // before doing the integer comparisons const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn::SEQUENCE_LOCKTIME_MASK; const int64_t txToSequenceMasked = txToSequence & nLockTimeMask; const CScriptNum nSequenceMasked = nSequence & nLockTimeMask; // There are two kinds of nSequence: lock-by-blockheight // and lock-by-blocktime, distinguished by whether // nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. // // We want to compare apples to apples, so fail the script // unless the type of nSequenceMasked being tested is the same as // the nSequenceMasked in the transaction. if (!( (txToSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) || (txToSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) )) { return false; } // Now that we know we're comparing apples-to-apples, the // comparison is a simple numeric one. if (nSequenceMasked > txToSequenceMasked) return false; return true; } bool TransactionSignatureChecker::hasTransactionContext() const { return oldTxTo != nullptr && nIn < oldTxTo->vin.size(); } const CTransaction* TransactionSignatureChecker::transaction() const { return oldTxTo; } Tx TransactionSignatureChecker::tx() const { return txTo; } unsigned int TransactionSignatureChecker::inputIndex() const { return nIn; } bool TransactionSignatureChecker::isLimitedContext() const { return spentOutputs == nullptr; } bool TransactionSignatureChecker::spentOutput(unsigned int index, Tx::Output &output) const { if (spentOutputs == nullptr || index >= spentOutputs->size()) return false; output = spentOutputs->at(index); return true; } bool Script::verify(const CScript& scriptSig, const CScript& scriptPubKey, const BaseSignatureChecker& checker, Script::State &state) { set_error(state.error, SCRIPT_ERR_UNKNOWN_ERROR); state.sigCheckCount = 0; state.vmLimitScriptSigSize = scriptSig.size(); state.opCost = 0; state.hashDigestIterations = 0; // If FORKID is enabled, we also ensure strict encoding. if (state.flags & SCRIPT_ENABLE_SIGHASH_FORKID) { state.flags |= SCRIPT_VERIFY_STRICTENC; } if ((state.flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) { return set_error(state.error, SCRIPT_ERR_SIG_PUSHONLY); } std::vector > stack, stackCopy; if (!eval(stack, scriptSig, checker, state)) // serror is set return false; if (state.flags & SCRIPT_VERIFY_P2SH) stackCopy = stack; if (!eval(stack, scriptPubKey, checker, state)) // serror is set return false; if (stack.empty()) return set_error(state.error, SCRIPT_ERR_EVAL_FALSE); if (CastToBool(stack.back()) == false) return set_error(state.error, SCRIPT_ERR_EVAL_FALSE); // Additional validation for spend-to-script-hash transactions: std::vector p2shBytes; if ((state.flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash(&p2shBytes) && ((state.flags & SCRIPT_ENABLE_P2SH_32) != 0 || p2shBytes.size() == 20)) { // scriptSig must be literals-only or validation fails if (!scriptSig.IsPushOnly()) return set_error(state.error, SCRIPT_ERR_SIG_PUSHONLY); // Restore stack. swap(stack, stackCopy); // stack cannot be empty here, because if it was the // P2SH HASH <> EQUAL scriptPubKey would be evaluated with // an empty stack and the EvalScript above would return false. assert(!stack.empty()); const valtype& pubKeySerialized = stack.back(); CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stack); // Bail out early if ALLOW_SEGWIT_RECOVERY is set, the redeem script is // a p2sh segwit program and it was the only item pushed into the stack if ((state.flags & SCRIPT_ALLOW_SEGWIT_RECOVERY) != 0 && stack.empty() && pubKey2.IsWitnessProgram()) return set_success(state.error); if (!eval(stack, pubKey2, checker, state)) // state.error is set return false; if (stack.empty()) return set_error(state.error, SCRIPT_ERR_EVAL_FALSE); if (!CastToBool(stack.back())) return set_error(state.error, SCRIPT_ERR_EVAL_FALSE); } // The CLEANSTACK check is only performed after potential P2SH evaluation, // as the non-P2SH evaluation of a P2SH script will obviously not result in // a clean stack (the P2SH inputs remain). if ((state.flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK // would be possible, which is not a softfork (and P2SH should be one). assert((state.flags & SCRIPT_VERIFY_P2SH) != 0); if (stack.size() != 1) { return set_error(state.error, SCRIPT_ERR_CLEANSTACK); } } return set_success(state.error); } const char *Script::State::errorString() const { return ScriptErrorString(error); }