Files

260 lines
8.9 KiB
C++
Raw Permalink Normal View History

2017-11-09 19:34:51 +01:00
/*
* This file is part of the Flowee project
* Copyright (C) 2009-2010 Satoshi Nakamoto
* Copyright (C) 2009-2015 The Bitcoin Core developers
*
* 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 <http://www.gnu.org/licenses/>.
*/
2014-08-27 20:11:41 +02:00
2018-01-16 10:47:52 +00:00
#ifndef FLOWEE_SCRIPT_INTERPRETER_H
#define FLOWEE_SCRIPT_INTERPRETER_H
2014-08-27 20:11:41 +02:00
#include "script_error.h"
2026-05-12 15:46:48 +02:00
#include "../primitives/Tx.h"
2021-01-20 19:21:53 +01:00
#include <cstdint>
#include <vector>
2022-07-06 21:56:34 +02:00
class PublicKey;
2014-08-27 20:11:41 +02:00
class CScript;
2021-01-20 18:22:34 +01:00
class CScriptNum;
2014-08-27 20:11:41 +02:00
class CTransaction;
class uint256;
2014-08-27 20:11:41 +02:00
/** Signature hash types/flags */
enum
{
SIGHASH_ALL = 1,
SIGHASH_NONE = 2,
SIGHASH_SINGLE = 3,
2026-05-09 08:29:15 +02:00
SIGHASH_UTXOS = 0x20,
2017-07-24 22:40:28 +02:00
SIGHASH_FORKID = 0x40,
2014-08-27 20:11:41 +02:00
SIGHASH_ANYONECANPAY = 0x80,
};
/** Script verification flags */
enum
{
SCRIPT_VERIFY_NONE = 0,
// Evaluate P2SH subscripts (softfork safe, BIP16).
SCRIPT_VERIFY_P2SH = (1U << 0),
// Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure.
// Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure.
// (softfork safe, but not used or intended as a consensus rule).
SCRIPT_VERIFY_STRICTENC = (1U << 1),
// Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1)
SCRIPT_VERIFY_DERSIG = (1U << 2),
// Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure
// (softfork safe, BIP62 rule 5).
SCRIPT_VERIFY_LOW_S = (1U << 3),
// verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7).
SCRIPT_VERIFY_NULLDUMMY = (1U << 4),
// Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2).
SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5),
// Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct
// pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating
// any other push causes the script to fail (BIP62 rule 3).
// In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4).
// (softfork safe)
SCRIPT_VERIFY_MINIMALDATA = (1U << 6),
// Discourage use of NOPs reserved for upgrades (NOP1-10)
//
// Provided so that nodes can avoid accepting or mining transactions
// containing executed NOP's whose meaning may change after a soft-fork,
// thus rendering the script invalid; with this flag set executing
// discouraged NOPs fails the script. This verification flag will never be
// a mandatory flag applied to scripts in a block. NOPs that are not
// executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected.
2014-10-12 18:39:47 -07:00
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7),
2014-10-12 18:39:47 -07:00
// Require that only a single stack element remains after evaluation. This changes the success criterion from
// "At least one stack element must remain, and when interpreted as a boolean, it must be true" to
// "Exactly one stack element must remain, and when interpreted as a boolean, it must be true".
// (softfork safe, BIP62 rule 6)
// Note: CLEANSTACK should never be used without P2SH.
SCRIPT_VERIFY_CLEANSTACK = (1U << 8),
// Verify CHECKLOCKTIMEVERIFY
//
// See BIP65 for details.
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
2015-09-25 16:18:51 -07:00
// support CHECKSEQUENCEVERIFY opcode
//
// See BIP112 for details
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10),
2017-07-24 22:40:28 +02:00
// Signature(s) must be empty vector if an CHECK(MULTI)SIG operation failed
//
SCRIPT_VERIFY_NULLFAIL = (1U << 14),
2017-07-24 22:40:28 +02:00
// Do we accept signature using SIGHASH_FORKID
//
SCRIPT_ENABLE_SIGHASH_FORKID = (1U << 16),
2018-11-04 12:07:17 +01:00
// If OP_CHECKDATASIG* are allowed.
SCRIPT_ENABLE_CHECKDATASIG = (1U << 17),
2019-04-17 16:20:05 +02:00
SCRIPT_ENABLE_SCHNORR = (1U << 18),
2020-04-11 18:35:43 +02:00
2019-10-10 20:51:34 +02:00
SCRIPT_ENABLE_SCHNORR_MULTISIG = (1U << 19),
2019-04-17 16:20:05 +02:00
// Allows the miner to appropriate coins sent to p2sh segwit addresses
2019-10-10 20:51:34 +02:00
SCRIPT_ALLOW_SEGWIT_RECOVERY = (1U << 20),
2020-04-10 14:14:42 +02:00
// Whether the new OP_REVERSEBYTES opcode can be used.
SCRIPT_ENABLE_OP_REVERSEBYTES = (1U << 21),
2026-05-07 13:50:12 +02:00
// Enable pay-to-script-hash using OP_HASH256 with a 32-byte script hash.
SCRIPT_ENABLE_P2SH_32 = (1U << 22),
2026-05-07 17:51:05 +02:00
// Enable CHIP-2024-07-BigInt high-precision script integer arithmetic.
SCRIPT_ENABLE_MAY2025 = (1U << 23),
// Enable May 2022 native transaction introspection opcodes.
SCRIPT_ENABLE_NATIVE_INTROSPECTION = (1U << 24),
2026-05-09 08:29:15 +02:00
// Enable May 2023 SIGHASH_UTXOS signing serialization.
SCRIPT_ENABLE_SIGHASH_UTXOS = (1U << 25),
2026-05-14 08:15:38 +02:00
// Enable May 2023 CashTokens script introspection.
SCRIPT_ENABLE_CASHTOKENS = (1U << 26),
// Use May 2025 VM-limit relay costing rules.
SCRIPT_VM_LIMITS_STANDARD = (1U << 27),
// Enable May 2026 script upgrades.
SCRIPT_ENABLE_MAY2026 = (1U << 28),
2026-05-14 22:43:01 +02:00
// Enable May 2022 64-bit script integer arithmetic.
SCRIPT_ENABLE_64_BIT_INTEGERS = (1U << 29),
};
2014-08-27 20:11:41 +02:00
2026-05-09 08:29:15 +02:00
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int64_t amount, int nHashType,
2026-05-14 14:18:07 +02:00
uint32_t flags = SCRIPT_ENABLE_SIGHASH_FORKID, const std::vector<Tx::Output> *spentOutputs = nullptr,
size_t *bytesHashed = nullptr);
2014-09-10 14:42:22 +02:00
2014-09-10 16:16:09 +02:00
class BaseSignatureChecker
{
public:
2026-05-14 14:18:07 +02:00
virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey,
const CScript& scriptCode, uint32_t flags, size_t *bytesHashed = nullptr) const
2014-09-10 16:16:09 +02:00
{
2026-05-14 14:18:07 +02:00
if (bytesHashed)
*bytesHashed = 0;
2014-09-10 16:16:09 +02:00
return false;
}
virtual bool CheckLockTime(const CScriptNum& nLockTime) const
{
return false;
}
2015-09-25 16:18:51 -07:00
virtual bool CheckSequence(const CScriptNum& nSequence) const
{
return false;
}
virtual bool hasTransactionContext() const
{
return false;
}
virtual const CTransaction* transaction() const
{
return nullptr;
}
2026-05-14 12:45:20 +02:00
virtual Tx tx() const
{
return Tx();
}
virtual unsigned int inputIndex() const
{
return 0;
}
virtual bool isLimitedContext() const
{
return true;
}
2026-05-12 15:46:48 +02:00
virtual bool spentOutput(unsigned int, Tx::Output&) const
{
return false;
}
2014-09-10 16:16:09 +02:00
virtual ~BaseSignatureChecker() {}
};
class TransactionSignatureChecker : public BaseSignatureChecker
2014-09-10 14:42:22 +02:00
{
private:
2026-05-14 12:45:20 +02:00
const CTransaction* oldTxTo;
const Tx &txTo;
2014-09-10 14:42:22 +02:00
unsigned int nIn;
2021-01-20 19:21:53 +01:00
int64_t amount;
2026-05-12 15:46:48 +02:00
const std::vector<Tx::Output> *spentOutputs;
2014-09-10 14:42:22 +02:00
2014-09-10 16:16:09 +02:00
protected:
2022-07-06 21:56:34 +02:00
virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const PublicKey& vchPubKey, const uint256& sighash, uint32_t flags) const;
2014-09-10 16:16:09 +02:00
2014-09-10 14:42:22 +02:00
public:
2026-05-14 12:45:20 +02:00
TransactionSignatureChecker(const CTransaction* oldTxToIn, const Tx &txToIn, unsigned int nInIn, int64_t amountIn,
2026-05-12 15:46:48 +02:00
const std::vector<Tx::Output> *spentOutputsIn = nullptr)
2026-05-14 12:45:20 +02:00
: oldTxTo(oldTxToIn), txTo(txToIn), nIn(nInIn), amount(amountIn), spentOutputs(spentOutputsIn) {}
2026-05-14 14:18:07 +02:00
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey,
const CScript& scriptCode, uint32_t flags, size_t *bytesHashed = nullptr) const override;
2019-10-10 19:20:04 +02:00
bool CheckLockTime(const CScriptNum& nLockTime) const override;
bool CheckSequence(const CScriptNum& nSequence) const override;
bool hasTransactionContext() const override;
const CTransaction* transaction() const override;
2026-05-14 12:45:20 +02:00
Tx tx() const override;
unsigned int inputIndex() const override;
bool isLimitedContext() const override;
2026-05-12 15:46:48 +02:00
bool spentOutput(unsigned int index, Tx::Output &output) const override;
2014-09-10 14:42:22 +02:00
};
2020-04-11 18:35:43 +02:00
namespace Script {
struct State {
State() = default;
State(uint32_t flags) : flags(flags) {}
uint32_t flags = SCRIPT_VERIFY_NONE; // validation flags
uint32_t sigCheckCount = 0;
uint64_t vmLimitScriptSigSize = 0;
int64_t opCost = 0;
int64_t hashDigestIterations = 0;
2020-04-11 18:35:43 +02:00
ScriptError error = SCRIPT_ERR_OK;
const char* errorString() const;
};
bool eval(std::vector<std::vector<unsigned char> > &stack, const CScript &script, const BaseSignatureChecker &checker, Script::State &state);
bool verify(const CScript& scriptSig, const CScript& scriptPubKey, const BaseSignatureChecker& checker, Script::State &state);
bool checkTransactionSignatureEncoding(const std::vector<unsigned char> &vchSig, State &state);
}
2014-08-27 20:11:41 +02:00
2018-01-16 10:47:52 +00:00
#endif