dogecoin/src/script/interpreter.h
Peter Todd 03914234b3
Discourage NOPs reserved for soft-fork upgrades
NOP1 to NOP10 are reserved for future soft-fork upgrades. In the event
of an upgrade such NOPs have *VERIFY behavior, meaning that if their
arguments are not correct the script fails. Discouraging these NOPs by
rejecting transactions containing them from the mempool ensures that
we'll never accept transactions, nor mine blocks, with scripts that are
now invalid according to the majority of hashing power even if we're not
yet upgraded. Previously this wasn't an issue as the IsStandard() rules
didn't allow upgradable NOPs anyway, but 7f3b4e95 relaxed the
IsStandard() rules for P2SH redemptions allowing any redeemScript to be
spent.

We *do* allow upgradable NOPs in scripts so long as they are not
executed. This is harmless as there is no opportunity for the script to
be invalid post-upgrade.
2014-11-17 22:22:33 -05:00

105 lines
4 KiB
C++

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_INTERPRETER_H
#define BITCOIN_SCRIPT_INTERPRETER_H
#include "script_error.h"
#include <vector>
#include <stdint.h>
#include <string>
class CPubKey;
class CScript;
class CTransaction;
class uint256;
/** Signature hash types/flags */
enum
{
SIGHASH_ALL = 1,
SIGHASH_NONE = 2,
SIGHASH_SINGLE = 3,
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.
// Passing a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) to checksig causes that pubkey to be
// skipped (not softfork safe: this flag can widen the validity of OP_CHECKSIG OP_NOT).
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.
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7)
};
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
class BaseSignatureChecker
{
public:
virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
{
return false;
}
virtual ~BaseSignatureChecker() {}
};
class SignatureChecker : public BaseSignatureChecker
{
private:
const CTransaction& txTo;
unsigned int nIn;
protected:
virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
public:
SignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
};
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
#endif // BITCOIN_SCRIPT_INTERPRETER_H