7 #ifndef H_ANONCOIN_SCRIPT
8 #define H_ANONCOIN_SCRIPT
18 #include <boost/foreach.hpp>
19 #include <boost/variant.hpp>
25 static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520;
26 static const unsigned int MAX_OP_RETURN_RELAY = 40;
49 explicit CScriptNum(
const std::vector<unsigned char>& vch)
52 throw scriptnum_error(
"CScriptNum(const std::vector<unsigned char>&) : overflow");
80 assert(
m_value != std::numeric_limits<int64_t>::min());
92 assert(rhs == 0 || (rhs > 0 &&
m_value <= std::numeric_limits<int64_t>::max() - rhs) ||
93 (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs));
100 assert(rhs == 0 || (rhs > 0 &&
m_value >= std::numeric_limits<int64_t>::min() + rhs) ||
101 (rhs < 0 &&
m_value <= std::numeric_limits<int64_t>::max() + rhs));
108 if (
m_value > std::numeric_limits<int>::max())
109 return std::numeric_limits<int>::max();
110 else if (
m_value < std::numeric_limits<int>::min())
111 return std::numeric_limits<int>::min();
115 std::vector<unsigned char>
getvch()
const
120 static std::vector<unsigned char>
serialize(
const int64_t& value)
123 return std::vector<unsigned char>();
125 std::vector<unsigned char> result;
126 const bool neg = value < 0;
127 uint64_t absvalue = neg ? -value : value;
131 result.push_back(absvalue & 0xff);
146 if (result.back() & 0x80)
147 result.push_back(neg ? 0x80 : 0);
149 result.back() |= 0x80;
157 static int64_t
set_vch(
const std::vector<unsigned char>& vch)
163 for (
size_t i = 0; i != vch.size(); ++i)
164 result |= static_cast<int64_t>(vch[i]) << 8*i;
168 if (vch.back() & 0x80)
169 return -(result & ~(0x80 << (8 * (vch.size() - 1))));
385 inline std::string
ValueString(
const std::vector<unsigned char>& vch)
393 inline std::string
StackString(
const std::vector<std::vector<unsigned char> >& vStack)
396 BOOST_FOREACH(
const std::vector<unsigned char>& vch, vStack)
413 class CScript :
public std::vector<unsigned char>
418 if (n == -1 || (n >= 1 && n <= 16))
420 push_back(n + (
OP_1 - 1));
431 CScript(const_iterator pbegin, const_iterator pend) :
std::vector<unsigned char>(pbegin, pend) { }
433 CScript(
const unsigned char* pbegin,
const unsigned char* pend) :
std::vector<unsigned char>(pbegin, pend) { }
438 insert(end(), b.begin(), b.end());
462 if (opcode < 0 || opcode > 0xff)
463 throw std::runtime_error(
"CScript::operator<<() : invalid opcode");
464 insert(end(), (
unsigned char)opcode);
470 insert(end(),
sizeof(b));
471 insert(end(), (
unsigned char*)&b, (
unsigned char*)&b +
sizeof(b));
477 insert(end(),
sizeof(b));
478 insert(end(), (
unsigned char*)&b, (
unsigned char*)&b +
sizeof(b));
485 insert(end(), (
unsigned char)key.
size());
486 insert(end(), key.
begin(), key.
end());
496 CScript& operator<<(const std::vector<unsigned char>& b)
500 insert(end(), (
unsigned char)b.size());
502 else if (b.size() <= 0xff)
505 insert(end(), (
unsigned char)b.size());
507 else if (b.size() <= 0xffff)
510 unsigned short nSize = b.size();
511 insert(end(), (
unsigned char*)&nSize, (
unsigned char*)&nSize +
sizeof(nSize));
516 unsigned int nSize = b.size();
517 insert(end(), (
unsigned char*)&nSize, (
unsigned char*)&nSize +
sizeof(nSize));
519 insert(end(), b.begin(), b.end());
527 assert(!
"Warning: Pushing a CScript onto a CScript with << is probably not intended, use + to concatenate!");
535 const_iterator pc2 = pc;
536 bool fRet =
GetOp2(pc2, opcodeRet, &vchRet);
537 pc = begin() + (pc2 - begin());
543 const_iterator pc2 = pc;
544 bool fRet =
GetOp2(pc2, opcodeRet, NULL);
545 pc = begin() + (pc2 - begin());
549 bool GetOp(const_iterator& pc,
opcodetype& opcodeRet, std::vector<unsigned char>& vchRet)
const
551 return GetOp2(pc, opcodeRet, &vchRet);
556 return GetOp2(pc, opcodeRet, NULL);
559 bool GetOp2(const_iterator& pc,
opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet)
const
570 unsigned int opcode = *pc++;
575 unsigned int nSize = 0;
591 memcpy(&nSize, &pc[0], 2);
598 memcpy(&nSize, &pc[0], 4);
601 if (end() - pc < 0 || (
unsigned int)(end() - pc) < nSize)
604 pvchRet->assign(pc, pc + nSize);
617 assert(opcode >=
OP_1 && opcode <=
OP_16);
618 return (
int)opcode - (int)(
OP_1 - 1);
622 assert(n >= 0 && n <= 16);
633 iterator pc = begin();
637 while (end() - pc >= (
long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
639 erase(pc, pc + b.size());
643 while (
GetOp(pc, opcode));
650 for (const_iterator pc = begin(); pc != end() &&
GetOp(pc, opcode);)
680 return (size() > 0 && *begin() ==
OP_RETURN);
684 void SetMultisig(
int nRequired,
const std::vector<CPubKey>& keys);
696 std::vector<unsigned char> vch;
697 const_iterator pc = begin();
702 if (!
GetOp(pc, opcode, vch))
757 bool Compress(std::vector<unsigned char> &out)
const;
759 bool Decompress(
unsigned int nSize,
const std::vector<unsigned char> &out);
764 std::vector<unsigned char> compr;
768 return script.size() +
VARINT(nSize).GetSerializeSize(nType, nVersion);
771 template<
typename Stream>
772 void Serialize(Stream &s,
int nType,
int nVersion)
const {
773 std::vector<unsigned char> compr;
775 s <<
CFlatData(&compr[0], &compr[compr.size()]);
780 s <<
CFlatData(&script[0], &script[script.size()]);
783 template<
typename Stream>
785 unsigned int nSize = 0;
787 if (nSize < nSpecialScripts) {
794 script.resize(nSize);
795 s >>
REF(
CFlatData(&script[0], &script[script.size()]));
799 bool IsCanonicalPubKey(
const std::vector<unsigned char> &vchPubKey,
unsigned int flags);
802 bool EvalScript(std::vector<std::vector<unsigned char> >& stack,
const CScript& script,
const CTransaction& txTo,
unsigned int nIn,
unsigned int flags,
int nHashType);
803 bool Solver(
const CScript& scriptPubKey,
txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
bool IsToKeyID(CKeyID &hash) const
bool operator!=(const int64_t &rhs) const
static int64_t set_vch(const std::vector< unsigned char > &vch)
static int DecodeOP_N(opcodetype opcode)
bool GetOp2(const_iterator &pc, opcodetype &opcodeRet, std::vector< unsigned char > *pvchRet) const
bool operator>(const int64_t &rhs) const
CScriptNum operator-() const
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CTransaction &txTo, unsigned int nIn, unsigned int flags, int nHashType)
CScript & operator<<(const uint160 &b)
bool IsCanonicalPubKey(const std::vector< unsigned char > &vchPubKey, unsigned int flags)
CScript(const CScript &b)
CScriptNum(const int64_t &n)
bool Compress(std::vector< unsigned char > &out) const
bool IsPayToScriptHash() const
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, const CTransaction &txTo, unsigned int nIn, unsigned int flags, int nHashType)
CScriptNum & operator-=(const int64_t &rhs)
const char * GetTxnOutputType(txnouttype t)
unsigned int GetSpecialSize(unsigned int nSize) const
unsigned int size() const
bool IsToPubKey(CPubKey &pubkey) const
CScript & push_int64(int64_t n)
bool operator<(const int64_t &rhs) const
Compact serializer for scripts.
friend bool operator==(const CNoDestination &a, const CNoDestination &b)
pruned version of CTransaction: only retains metadata and unspent transaction outputs ...
uint160 Hash160(const T1 pbegin, const T1 pend)
bool IsCanonicalSignature(const std::vector< unsigned char > &vchSig, unsigned int flags)
friend CScript operator+(const CScript &a, const CScript &b)
CScriptNum operator-(const CScriptNum &rhs) const
int ScriptSigArgsExpected(txnouttype t, const std::vector< std::vector< unsigned char > > &vSolutions)
CScriptNum & operator=(const int64_t &rhs)
CScript(const std::vector< unsigned char > &b)
bool GetOp(const_iterator &pc, opcodetype &opcodeRet) const
static std::vector< unsigned char > serialize(const int64_t &value)
std::string ToString() const
CScriptNum operator+(const CScriptNum &rhs) const
const char * GetOpName(opcodetype opcode)
CScriptNum & operator+=(const CScriptNum &rhs)
void SetDestination(const CTxDestination &address)
bool operator==(const CScriptNum &rhs) const
bool operator<=(const int64_t &rhs) const
isminetype
IsMine() return codes.
std::string ValueString(const std::vector< unsigned char > &vch)
void Serialize(Stream &s, int nType, int nVersion) const
CScript & operator<<(const CScriptNum &b)
CScript & operator<<(opcodetype opcode)
friend bool operator<(const CNoDestination &a, const CNoDestination &b)
opcodetype
Script opcodes.
CScript(const CScriptNum &b)
CScript & operator<<(const CScript &b)
unsigned int GetSerializeSize(int nType, int nVersion) const
CScriptCompressor(CScript &scriptIn)
unsigned int GetSigOpCount(bool fAccurate) const
bool IsToScriptID(CScriptID &hash) const
CScriptNum operator-(const int64_t &rhs) const
An encapsulated public key.
CScript(const unsigned char *pbegin, const unsigned char *pend)
bool operator==(const int64_t &rhs) const
bool operator>=(const int64_t &rhs) const
bool IsUnspendable() const
scriptnum_error(const std::string &str)
bool GetOp(iterator &pc, opcodetype &opcodeRet)
bool Solver(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< std::vector< unsigned char > > &vSolutionsRet)
uint8_t isminefilter
used for bitflags of isminetype
static const size_t nMaxNumSize
const unsigned char * begin() const
CScriptNum & operator-=(const CScriptNum &rhs)
bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CTransaction &txTo, unsigned int nIn, int nHashType=SIGHASH_ALL)
std::string StackString(const std::vector< std::vector< unsigned char > > &vStack)
static const unsigned int nSpecialScripts
CScript(const uint256 &b)
CScript(const_iterator pbegin, const_iterator pend)
static opcodetype EncodeOP_N(int n)
bool operator<=(const CScriptNum &rhs) const
Serialized script, used inside transaction inputs and outputs.
bool Decompress(unsigned int nSize, const std::vector< unsigned char > &out)
CScript & operator+=(const CScript &b)
void * memcpy(void *a, const void *b, size_t c)
A virtual base class for key stores.
void SetMultisig(int nRequired, const std::vector< CPubKey > &keys)
isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey)
A reference to a CKey: the Hash160 of its serialized public key.
CScriptNum operator+(const int64_t &rhs) const
std::vector< unsigned char > getvch() const
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
int FindAndDelete(const CScript &b)
CScript & operator<<(int64_t b)
CScript CombineSignatures(CScript scriptPubKey, const CTransaction &txTo, unsigned int nIn, const CScript &scriptSig1, const CScript &scriptSig2)
bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< CTxDestination > &addressRet, int &nRequiredRet)
CScriptNum & operator+=(const int64_t &rhs)
A reference to a CScript: the Hash160 of its serialization (see script.h)
void ExtractAffectedKeys(const CKeyStore &keystore, const CScript &scriptPubKey, std::vector< CKeyID > &vKeys)
bool GetOp(const_iterator &pc, opcodetype &opcodeRet, std::vector< unsigned char > &vchRet) const
CScript & operator<<(const uint256 &b)
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
bool GetOp(iterator &pc, opcodetype &opcodeRet, std::vector< unsigned char > &vchRet)
The basic transaction that is broadcasted on the network and contained in blocks. ...
bool operator!=(const CScriptNum &rhs) const
CScriptNum(const std::vector< unsigned char > &vch)
bool operator>=(const CScriptNum &rhs) const
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
bool HasCanonicalPushes() const
bool IsStandard(const CScript &scriptPubKey, txnouttype &whichType)
CScript & operator<<(const CPubKey &key)
const unsigned char * end() const
Wrapper for serializing arrays and POD.
int Find(opcodetype op) const
void Unserialize(Stream &s, int nType, int nVersion)