diff options
author | s_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b> | 2010-09-07 01:12:53 +0000 |
---|---|---|
committer | s_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b> | 2010-09-07 01:12:53 +0000 |
commit | f1e1fb4bdef878c8fc1564fa418d44e7541a7e83 (patch) | |
tree | 1f3dcb611059e60f2faa5d75d72186aacfff18df /script.h | |
parent | d743f0355269e2e03fe3f982e250d07999d72b98 (diff) |
cleanup,
catch some recoverable exceptions and continue
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@148 1a98c847-1fd6-4fd8-948a-caf3550aa51b
Diffstat (limited to 'script.h')
-rw-r--r-- | script.h | 178 |
1 files changed, 102 insertions, 76 deletions
@@ -150,18 +150,11 @@ enum opcodetype - - // multi-byte opcodes - OP_SINGLEBYTE_END = 0xF0, - OP_DOUBLEBYTE_BEGIN = 0xF000, - // template matching params - OP_PUBKEY, - OP_PUBKEYHASH, - - + OP_PUBKEYHASH = 0xfd, + OP_PUBKEY = 0xfe, - OP_INVALIDOPCODE = 0xFFFF, + OP_INVALIDOPCODE = 0xff, }; @@ -304,16 +297,13 @@ inline const char* GetOpName(opcodetype opcode) - // multi-byte opcodes - case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END"; - case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN"; - case OP_PUBKEY : return "OP_PUBKEY"; + // template matching params case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; - + case OP_PUBKEY : return "OP_PUBKEY"; case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; default: - return "UNKNOWN_OPCODE"; + return "OP_UNKNOWN"; } }; @@ -325,8 +315,7 @@ inline string ValueString(const vector<unsigned char>& vch) if (vch.size() <= 4) return strprintf("%d", CBigNum(vch).getint()); else - return HexNumStr(vch.begin(), vch.end()); - //return string("(") + HexStr(vch.begin(), vch.end()) + string(")"); + return HexStr(vch); } inline string StackString(const vector<vector<unsigned char> >& vStack) @@ -363,12 +352,12 @@ protected: CBigNum bn(n); *this << bn.getvch(); } - return (*this); + return *this; } CScript& push_uint64(uint64 n) { - if (n == -1 || (n >= 1 && n <= 16)) + if (n >= 1 && n <= 16) { push_back(n + (OP_1 - 1)); } @@ -377,7 +366,7 @@ protected: CBigNum bn(n); *this << bn.getvch(); } - return (*this); + return *this; } public: @@ -398,7 +387,7 @@ public: { CScript ret = a; ret += b; - return (ret); + return ret; } @@ -419,50 +408,43 @@ public: explicit CScript(const vector<unsigned char>& b) { operator<<(b); } - CScript& operator<<(char b) { return (push_int64(b)); } - CScript& operator<<(short b) { return (push_int64(b)); } - CScript& operator<<(int b) { return (push_int64(b)); } - CScript& operator<<(long b) { return (push_int64(b)); } - CScript& operator<<(int64 b) { return (push_int64(b)); } - CScript& operator<<(unsigned char b) { return (push_uint64(b)); } - CScript& operator<<(unsigned int b) { return (push_uint64(b)); } - CScript& operator<<(unsigned short b) { return (push_uint64(b)); } - CScript& operator<<(unsigned long b) { return (push_uint64(b)); } - CScript& operator<<(uint64 b) { return (push_uint64(b)); } + CScript& operator<<(char b) { return push_int64(b); } + CScript& operator<<(short b) { return push_int64(b); } + CScript& operator<<(int b) { return push_int64(b); } + CScript& operator<<(long b) { return push_int64(b); } + CScript& operator<<(int64 b) { return push_int64(b); } + CScript& operator<<(unsigned char b) { return push_uint64(b); } + CScript& operator<<(unsigned int b) { return push_uint64(b); } + CScript& operator<<(unsigned short b) { return push_uint64(b); } + CScript& operator<<(unsigned long b) { return push_uint64(b); } + CScript& operator<<(uint64 b) { return push_uint64(b); } CScript& operator<<(opcodetype opcode) { - if (opcode <= OP_SINGLEBYTE_END) - { - insert(end(), (unsigned char)opcode); - } - else - { - assert(opcode >= OP_DOUBLEBYTE_BEGIN); - insert(end(), (unsigned char)(opcode >> 8)); - insert(end(), (unsigned char)(opcode & 0xFF)); - } - return (*this); + if (opcode < 0 || opcode > 0xff) + throw runtime_error("CScript::operator<<() : invalid opcode"); + insert(end(), (unsigned char)opcode); + return *this; } CScript& operator<<(const uint160& b) { insert(end(), sizeof(b)); insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); - return (*this); + return *this; } CScript& operator<<(const uint256& b) { insert(end(), sizeof(b)); insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); - return (*this); + return *this; } CScript& operator<<(const CBigNum& b) { *this << b.getvch(); - return (*this); + return *this; } CScript& operator<<(const vector<unsigned char>& b) @@ -476,14 +458,20 @@ public: insert(end(), OP_PUSHDATA1); insert(end(), (unsigned char)b.size()); } - else + else if (b.size() <= 0xffff) { insert(end(), OP_PUSHDATA2); unsigned short nSize = b.size(); insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); } + else + { + insert(end(), OP_PUSHDATA4); + unsigned int nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } insert(end(), b.begin(), b.end()); - return (*this); + return *this; } CScript& operator<<(const CScript& b) @@ -491,7 +479,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", false)); - return (*this); + return *this; } @@ -499,41 +487,59 @@ public: { // Wrapper so it can be called with either iterator or const_iterator const_iterator pc2 = pc; - bool fRet = GetOp(pc2, opcodeRet, vchRet); + bool fRet = GetOp2(pc2, opcodeRet, &vchRet); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(iterator& pc, opcodetype& opcodeRet) + { + const_iterator pc2 = pc; + bool fRet = GetOp2(pc2, opcodeRet, NULL); pc = begin() + (pc2 - begin()); return fRet; } bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const { + return GetOp2(pc, opcodeRet, &vchRet); + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const + { + return GetOp2(pc, opcodeRet, NULL); + } + + bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>* pvchRet) const + { opcodeRet = OP_INVALIDOPCODE; - vchRet.clear(); + if (pvchRet) + pvchRet->clear(); if (pc >= end()) return false; // Read instruction + if (end() - pc < 1) + return false; unsigned int opcode = *pc++; - if (opcode >= OP_SINGLEBYTE_END) - { - if (pc + 1 > end()) - return false; - opcode <<= 8; - opcode |= *pc++; - } // Immediate operand if (opcode <= OP_PUSHDATA4) { - unsigned int nSize = opcode; - if (opcode == OP_PUSHDATA1) + unsigned int nSize; + if (opcode < OP_PUSHDATA1) + { + nSize = opcode; + } + else if (opcode == OP_PUSHDATA1) { - if (pc + 1 > end()) + if (end() - pc < 1) return false; nSize = *pc++; } else if (opcode == OP_PUSHDATA2) { - if (pc + 2 > end()) + if (end() - pc < 2) return false; nSize = 0; memcpy(&nSize, &pc[0], 2); @@ -541,14 +547,15 @@ public: } else if (opcode == OP_PUSHDATA4) { - if (pc + 4 > end()) + if (end() - pc < 4) return false; memcpy(&nSize, &pc[0], 4); pc += 4; } - if (pc + nSize > end()) + if (end() - pc < nSize) return false; - vchRet.assign(pc, pc + nSize); + if (pvchRet) + pvchRet->assign(pc, pc + nSize); pc += nSize; } @@ -559,20 +566,34 @@ public: void FindAndDelete(const CScript& b) { + if (b.empty()) + return; iterator pc = begin(); opcodetype opcode; - vector<unsigned char> vchPushValue; - int count = 0; do { while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) - { erase(pc, pc + b.size()); - count++; - } } - while (GetOp(pc, opcode, vchPushValue)); - //printf("FindAndDeleted deleted %d items\n", count); /// debug + while (GetOp(pc, opcode)); + } + + + int GetSigOpCount() const + { + int n = 0; + const_iterator pc = begin(); + while (pc < end()) + { + opcodetype opcode; + if (!GetOp(pc, opcode)) + break; + if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY) + n++; + else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY) + n += 20; + } + return n; } @@ -623,7 +644,7 @@ public: void PrintHex() const { - printf("CScript(%s)\n", HexStr(begin(), end()).c_str()); + printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str()); } string ToString() const @@ -631,12 +652,17 @@ public: string str; opcodetype opcode; vector<unsigned char> vch; - const_iterator it = begin(); - while (GetOp(it, opcode, vch)) + const_iterator pc = begin(); + while (pc < end()) { if (!str.empty()) str += " "; - if (opcode <= OP_PUSHDATA4) + if (!GetOp(pc, opcode, vch)) + { + str += "[error]"; + return str; + } + if (0 <= opcode && opcode <= OP_PUSHDATA4) str += ValueString(vch); else str += GetOpName(opcode); |