X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fscript.h;h=b8cfbac3b9310583a9a813772f86d90191994559;hb=1c4fc9052a444c114d9c1501d2c6d1305de650d0;hp=b13734be41985139b8f0e9bf9dda5ea08d2522a3;hpb=7be8b2ff9c9ea425bdda2ad1a702699b3d2da9f8;p=novacoin.git diff --git a/src/script.h b/src/script.h index b13734b..b8cfbac 100644 --- a/src/script.h +++ b/src/script.h @@ -1,19 +1,31 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef H_BITCOIN_SCRIPT #define H_BITCOIN_SCRIPT -#include "base58.h" - #include #include #include +#include "keystore.h" +#include "bignum.h" + +typedef std::vector valtype; + class CTransaction; -class CKeyStore; + +static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes + +/** IsMine() return codes */ +enum isminetype +{ + MINE_NO = 0, + MINE_WATCH_ONLY = 1, + MINE_SPENDABLE = 2, +}; /** Signature hash types/flags */ enum @@ -24,6 +36,40 @@ enum SIGHASH_ANYONECANPAY = 0x80, }; +/** Script verification flags */ +enum +{ + SCRIPT_VERIFY_NONE = 0, + SCRIPT_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts + SCRIPT_VERIFY_STRICTENC = (1U << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys + SCRIPT_VERIFY_LOW_S = (1U << 2), // enforce low S values in signatures (depends on STRICTENC) + SCRIPT_VERIFY_NOCACHE = (1U << 3), // do not store results in signature cache (but do query it) + SCRIPT_VERIFY_NULLDUMMY = (1U << 4), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length +}; + +// Strict verification: +// +// * force DER encoding; +// * force low S; +// * ensure that CHECKMULTISIG dummy argument is null. +static const unsigned int STRICT_FORMAT_FLAGS = SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_NULLDUMMY; + +// Mandatory script verification flags that all new blocks must comply with for +// them to be valid. (but old blocks may not comply with) Currently just P2SH, +// but in the future other flags may be added, such as a soft-fork to enforce +// strict DER encoding. +// +// Failing one of these tests may trigger a DoS ban - see ConnectInputs() for +// details. +static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH; + +// Standard script verification flags that standard transactions will comply +// with. However scripts violating these flags may still be present in valid +// blocks and we must accept those blocks. +static const unsigned int STRICT_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | STRICT_FORMAT_FLAGS; + +// Soft verifications, no extended signature format checkings +static const unsigned int SOFT_FLAGS = STRICT_FLAGS & ~STRICT_FORMAT_FLAGS; enum txnouttype { @@ -33,6 +79,7 @@ enum txnouttype TX_PUBKEYHASH, TX_SCRIPTHASH, TX_MULTISIG, + TX_NULL_DATA, }; const char* GetTxnOutputType(txnouttype t); @@ -175,6 +222,7 @@ enum opcodetype // template matching params + OP_SMALLDATA = 0xf9, OP_SMALLINTEGER = 0xfa, OP_PUBKEYS = 0xfb, OP_PUBKEYHASH = 0xfd, @@ -320,6 +368,12 @@ public: return *this; } + CScript& operator<<(const CPubKey& key) + { + std::vector vchKey = key.Raw(); + return (*this) << vchKey; + } + CScript& operator<<(const CBigNum& b) { *this << b.getvch(); @@ -357,7 +411,7 @@ public: { // I'm not sure if this should push the script or concatenate scripts. // If there's ever a use for pushing a script onto a script, delete this member fn - assert(!"warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate"); + assert(!"Warning: Pushing a CScript onto a CScript with << is probably not intended, use + to concatenate!"); return *this; } @@ -431,7 +485,7 @@ public: memcpy(&nSize, &pc[0], 4); pc += 4; } - if (end() - pc < nSize) + if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize) return false; if (pvchRet) pvchRet->assign(pc, pc + nSize); @@ -467,7 +521,7 @@ public: opcodetype opcode; do { - while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) + while (end() - pc >= (long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) { erase(pc, pc + b.size()); ++nFound; @@ -491,15 +545,15 @@ public: // CHECKMULTISIGs serialized in scriptSigs are // counted more accurately, assuming they are of the form // ... OP_N CHECKMULTISIG ... - int GetSigOpCount(bool fAccurate) const; + unsigned int GetSigOpCount(bool fAccurate) const; // Accurately count sigOps, including sigOps in // pay-to-script-hash transactions: - int GetSigOpCount(const CScript& scriptSig) const; + unsigned int GetSigOpCount(const CScript& scriptSig) const; bool IsPayToScriptHash() const; - // Called by CTransaction::IsStandard + // Called by CTransaction::IsStandard and P2SH VerifyScript (which makes it consensus-critical). bool IsPushOnly() const { const_iterator pc = begin(); @@ -514,14 +568,11 @@ public: return true; } + // Called by CTransaction::IsStandard. + bool HasCanonicalPushes() const; - void SetBitcoinAddress(const CBitcoinAddress& address); - void SetBitcoinAddress(const std::vector& vchPubKey) - { - SetBitcoinAddress(CBitcoinAddress(vchPubKey)); - } + void SetDestination(const CTxDestination& address); void SetMultisig(int nRequired, const std::vector& keys); - void SetPayToScriptHash(const CScript& subscript); void PrintHex() const @@ -529,7 +580,7 @@ public: printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str()); } - std::string ToString() const + std::string ToString(bool fShort=false) const { std::string str; opcodetype opcode; @@ -545,7 +596,7 @@ public: return str; } if (0 <= opcode && opcode <= OP_PUSHDATA4) - str += ValueString(vch); + str += fShort? ValueString(vch).substr(0, 10) : ValueString(vch); else str += GetOpName(opcode); } @@ -556,20 +607,32 @@ public: { printf("%s\n", ToString().c_str()); } -}; - + CScriptID GetID() const + { + return CScriptID(Hash160(*this)); + } +}; +bool IsCanonicalPubKey(const std::vector &vchPubKey, unsigned int flags); +bool IsCanonicalSignature(const std::vector &vchSig, unsigned int flags); -bool EvalScript(std::vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType); +bool EvalScript(std::vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet); int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions); -bool IsStandard(const CScript& scriptPubKey); -bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); -bool ExtractAddress(const CScript& scriptPubKey, CBitcoinAddress& addressRet); -bool ExtractAddresses(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet); +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); +isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); +isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest); +void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector &vKeys); +bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); +bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet); +bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); -bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType); +bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); + +// Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, +// combine them intelligently and return the result. +CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); #endif