// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef H_BITCOIN_SCRIPTUTILS #define H_BITCOIN_SCRIPTUTILS #include "key.h" #include "script/script.h" #include "script/interpreter.h" #include #include #include #include class CKeyStore; class CTransaction; struct CMutableTransaction; static const unsigned int MAX_OP_RETURN_RELAY = 40; // bytes /** IsMine() return codes */ enum isminetype { ISMINE_NO = 0, ISMINE_WATCH_ONLY = 1, ISMINE_SPENDABLE = 2, ISMINE_ALL = ISMINE_WATCH_ONLY | ISMINE_SPENDABLE }; /** used for bitflags of isminetype */ typedef uint8_t isminefilter; // 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 CheckInputs() 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 STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_NULLDUMMY; // For convenience, standard but not mandatory verify flags. static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; enum txnouttype { TX_NONSTANDARD, // 'standard' transaction types: TX_PUBKEY, TX_PUBKEYHASH, TX_SCRIPTHASH, TX_MULTISIG, TX_NULL_DATA, }; const char* GetTxnOutputType(txnouttype t); /** Compact serializer for scripts. * * It detects common cases and encodes them much more efficiently. * 3 special cases are defined: * * Pay to pubkey hash (encoded as 21 bytes) * * Pay to script hash (encoded as 21 bytes) * * Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes) * * Other scripts up to 121 bytes require 1 byte + script length. Above * that, scripts up to 16505 bytes require 2 bytes + script length. */ class CScriptCompressor { private: // make this static for now (there are only 6 special scripts defined) // this can potentially be extended together with a new nVersion for // transactions, in which case this value becomes dependent on nVersion // and nHeight of the enclosing transaction. static const unsigned int nSpecialScripts = 6; CScript &script; protected: // These check for scripts for which a special case with a shorter encoding is defined. // They are implemented separately from the CScript test, as these test for exact byte // sequence correspondences, and are more strict. For example, IsToPubKey also verifies // whether the public key is valid (as invalid ones cannot be represented in compressed // form). bool IsToKeyID(CKeyID &hash) const; bool IsToScriptID(CScriptID &hash) const; bool IsToPubKey(CPubKey &pubkey) const; bool Compress(std::vector &out) const; unsigned int GetSpecialSize(unsigned int nSize) const; bool Decompress(unsigned int nSize, const std::vector &out); public: CScriptCompressor(CScript &scriptIn) : script(scriptIn) { } unsigned int GetSerializeSize(int nType, int nVersion) const { std::vector compr; if (Compress(compr)) return compr.size(); unsigned int nSize = script.size() + nSpecialScripts; return script.size() + VARINT(nSize).GetSerializeSize(nType, nVersion); } template void Serialize(Stream &s, int nType, int nVersion) const { std::vector compr; if (Compress(compr)) { s << CFlatData(compr); return; } unsigned int nSize = script.size() + nSpecialScripts; s << VARINT(nSize); s << CFlatData(script); } template void Unserialize(Stream &s, int nType, int nVersion) { unsigned int nSize = 0; s >> VARINT(nSize); if (nSize < nSpecialScripts) { std::vector vch(GetSpecialSize(nSize), 0x00); s >> REF(CFlatData(vch)); Decompress(nSize, vch); return; } nSize -= nSpecialScripts; script.resize(nSize); s >> REF(CFlatData(script)); } }; bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet); int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions); 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, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); // 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 // H_BITCOIN_SCRIPT