]> Git Repo - VerusCoin.git/blob - src/script.h
Fix signed/unsigned warnings in {script,serialize}.h (fixes #1541)
[VerusCoin.git] / src / script.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef H_BITCOIN_SCRIPT
6 #define H_BITCOIN_SCRIPT
7
8 #include <string>
9 #include <vector>
10
11 #include <boost/foreach.hpp>
12 #include <boost/variant.hpp>
13
14 #include "keystore.h"
15 #include "bignum.h"
16
17 class CTransaction;
18
19 /** Signature hash types/flags */
20 enum
21 {
22     SIGHASH_ALL = 1,
23     SIGHASH_NONE = 2,
24     SIGHASH_SINGLE = 3,
25     SIGHASH_ANYONECANPAY = 0x80,
26 };
27
28
29 enum txnouttype
30 {
31     TX_NONSTANDARD,
32     // 'standard' transaction types:
33     TX_PUBKEY,
34     TX_PUBKEYHASH,
35     TX_SCRIPTHASH,
36     TX_MULTISIG,
37 };
38
39 class CNoDestination {
40 public:
41     friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; }
42     friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
43 };
44
45 /** A txout script template with a specific destination. It is either:
46  *  * CNoDestination: no destination set
47  *  * CKeyID: TX_PUBKEYHASH destination
48  *  * CScriptID: TX_SCRIPTHASH destination
49  *  A CTxDestination is the internal data type encoded in a CBitcoinAddress
50  */
51 typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
52
53 const char* GetTxnOutputType(txnouttype t);
54
55 /** Script opcodes */
56 enum opcodetype
57 {
58     // push value
59     OP_0 = 0x00,
60     OP_FALSE = OP_0,
61     OP_PUSHDATA1 = 0x4c,
62     OP_PUSHDATA2 = 0x4d,
63     OP_PUSHDATA4 = 0x4e,
64     OP_1NEGATE = 0x4f,
65     OP_RESERVED = 0x50,
66     OP_1 = 0x51,
67     OP_TRUE=OP_1,
68     OP_2 = 0x52,
69     OP_3 = 0x53,
70     OP_4 = 0x54,
71     OP_5 = 0x55,
72     OP_6 = 0x56,
73     OP_7 = 0x57,
74     OP_8 = 0x58,
75     OP_9 = 0x59,
76     OP_10 = 0x5a,
77     OP_11 = 0x5b,
78     OP_12 = 0x5c,
79     OP_13 = 0x5d,
80     OP_14 = 0x5e,
81     OP_15 = 0x5f,
82     OP_16 = 0x60,
83
84     // control
85     OP_NOP = 0x61,
86     OP_VER = 0x62,
87     OP_IF = 0x63,
88     OP_NOTIF = 0x64,
89     OP_VERIF = 0x65,
90     OP_VERNOTIF = 0x66,
91     OP_ELSE = 0x67,
92     OP_ENDIF = 0x68,
93     OP_VERIFY = 0x69,
94     OP_RETURN = 0x6a,
95
96     // stack ops
97     OP_TOALTSTACK = 0x6b,
98     OP_FROMALTSTACK = 0x6c,
99     OP_2DROP = 0x6d,
100     OP_2DUP = 0x6e,
101     OP_3DUP = 0x6f,
102     OP_2OVER = 0x70,
103     OP_2ROT = 0x71,
104     OP_2SWAP = 0x72,
105     OP_IFDUP = 0x73,
106     OP_DEPTH = 0x74,
107     OP_DROP = 0x75,
108     OP_DUP = 0x76,
109     OP_NIP = 0x77,
110     OP_OVER = 0x78,
111     OP_PICK = 0x79,
112     OP_ROLL = 0x7a,
113     OP_ROT = 0x7b,
114     OP_SWAP = 0x7c,
115     OP_TUCK = 0x7d,
116
117     // splice ops
118     OP_CAT = 0x7e,
119     OP_SUBSTR = 0x7f,
120     OP_LEFT = 0x80,
121     OP_RIGHT = 0x81,
122     OP_SIZE = 0x82,
123
124     // bit logic
125     OP_INVERT = 0x83,
126     OP_AND = 0x84,
127     OP_OR = 0x85,
128     OP_XOR = 0x86,
129     OP_EQUAL = 0x87,
130     OP_EQUALVERIFY = 0x88,
131     OP_RESERVED1 = 0x89,
132     OP_RESERVED2 = 0x8a,
133
134     // numeric
135     OP_1ADD = 0x8b,
136     OP_1SUB = 0x8c,
137     OP_2MUL = 0x8d,
138     OP_2DIV = 0x8e,
139     OP_NEGATE = 0x8f,
140     OP_ABS = 0x90,
141     OP_NOT = 0x91,
142     OP_0NOTEQUAL = 0x92,
143
144     OP_ADD = 0x93,
145     OP_SUB = 0x94,
146     OP_MUL = 0x95,
147     OP_DIV = 0x96,
148     OP_MOD = 0x97,
149     OP_LSHIFT = 0x98,
150     OP_RSHIFT = 0x99,
151
152     OP_BOOLAND = 0x9a,
153     OP_BOOLOR = 0x9b,
154     OP_NUMEQUAL = 0x9c,
155     OP_NUMEQUALVERIFY = 0x9d,
156     OP_NUMNOTEQUAL = 0x9e,
157     OP_LESSTHAN = 0x9f,
158     OP_GREATERTHAN = 0xa0,
159     OP_LESSTHANOREQUAL = 0xa1,
160     OP_GREATERTHANOREQUAL = 0xa2,
161     OP_MIN = 0xa3,
162     OP_MAX = 0xa4,
163
164     OP_WITHIN = 0xa5,
165
166     // crypto
167     OP_RIPEMD160 = 0xa6,
168     OP_SHA1 = 0xa7,
169     OP_SHA256 = 0xa8,
170     OP_HASH160 = 0xa9,
171     OP_HASH256 = 0xaa,
172     OP_CODESEPARATOR = 0xab,
173     OP_CHECKSIG = 0xac,
174     OP_CHECKSIGVERIFY = 0xad,
175     OP_CHECKMULTISIG = 0xae,
176     OP_CHECKMULTISIGVERIFY = 0xaf,
177
178     // expansion
179     OP_NOP1 = 0xb0,
180     OP_NOP2 = 0xb1,
181     OP_NOP3 = 0xb2,
182     OP_NOP4 = 0xb3,
183     OP_NOP5 = 0xb4,
184     OP_NOP6 = 0xb5,
185     OP_NOP7 = 0xb6,
186     OP_NOP8 = 0xb7,
187     OP_NOP9 = 0xb8,
188     OP_NOP10 = 0xb9,
189
190
191
192     // template matching params
193     OP_SMALLINTEGER = 0xfa,
194     OP_PUBKEYS = 0xfb,
195     OP_PUBKEYHASH = 0xfd,
196     OP_PUBKEY = 0xfe,
197
198     OP_INVALIDOPCODE = 0xff,
199 };
200
201 const char* GetOpName(opcodetype opcode);
202
203
204
205 inline std::string ValueString(const std::vector<unsigned char>& vch)
206 {
207     if (vch.size() <= 4)
208         return strprintf("%d", CBigNum(vch).getint());
209     else
210         return HexStr(vch);
211 }
212
213 inline std::string StackString(const std::vector<std::vector<unsigned char> >& vStack)
214 {
215     std::string str;
216     BOOST_FOREACH(const std::vector<unsigned char>& vch, vStack)
217     {
218         if (!str.empty())
219             str += " ";
220         str += ValueString(vch);
221     }
222     return str;
223 }
224
225
226
227
228
229
230
231
232 /** Serialized script, used inside transaction inputs and outputs */
233 class CScript : public std::vector<unsigned char>
234 {
235 protected:
236     CScript& push_int64(int64 n)
237     {
238         if (n == -1 || (n >= 1 && n <= 16))
239         {
240             push_back(n + (OP_1 - 1));
241         }
242         else
243         {
244             CBigNum bn(n);
245             *this << bn.getvch();
246         }
247         return *this;
248     }
249
250     CScript& push_uint64(uint64 n)
251     {
252         if (n >= 1 && n <= 16)
253         {
254             push_back(n + (OP_1 - 1));
255         }
256         else
257         {
258             CBigNum bn(n);
259             *this << bn.getvch();
260         }
261         return *this;
262     }
263
264 public:
265     CScript() { }
266     CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { }
267     CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { }
268 #ifndef _MSC_VER
269     CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { }
270 #endif
271
272     CScript& operator+=(const CScript& b)
273     {
274         insert(end(), b.begin(), b.end());
275         return *this;
276     }
277
278     friend CScript operator+(const CScript& a, const CScript& b)
279     {
280         CScript ret = a;
281         ret += b;
282         return ret;
283     }
284
285
286     //explicit CScript(char b) is not portable.  Use 'signed char' or 'unsigned char'.
287     explicit CScript(signed char b)    { operator<<(b); }
288     explicit CScript(short b)          { operator<<(b); }
289     explicit CScript(int b)            { operator<<(b); }
290     explicit CScript(long b)           { operator<<(b); }
291     explicit CScript(int64 b)          { operator<<(b); }
292     explicit CScript(unsigned char b)  { operator<<(b); }
293     explicit CScript(unsigned int b)   { operator<<(b); }
294     explicit CScript(unsigned short b) { operator<<(b); }
295     explicit CScript(unsigned long b)  { operator<<(b); }
296     explicit CScript(uint64 b)         { operator<<(b); }
297
298     explicit CScript(opcodetype b)     { operator<<(b); }
299     explicit CScript(const uint256& b) { operator<<(b); }
300     explicit CScript(const CBigNum& b) { operator<<(b); }
301     explicit CScript(const std::vector<unsigned char>& b) { operator<<(b); }
302
303
304     //CScript& operator<<(char b) is not portable.  Use 'signed char' or 'unsigned char'.
305     CScript& operator<<(signed char b)    { return push_int64(b); }
306     CScript& operator<<(short b)          { return push_int64(b); }
307     CScript& operator<<(int b)            { return push_int64(b); }
308     CScript& operator<<(long b)           { return push_int64(b); }
309     CScript& operator<<(int64 b)          { return push_int64(b); }
310     CScript& operator<<(unsigned char b)  { return push_uint64(b); }
311     CScript& operator<<(unsigned int b)   { return push_uint64(b); }
312     CScript& operator<<(unsigned short b) { return push_uint64(b); }
313     CScript& operator<<(unsigned long b)  { return push_uint64(b); }
314     CScript& operator<<(uint64 b)         { return push_uint64(b); }
315
316     CScript& operator<<(opcodetype opcode)
317     {
318         if (opcode < 0 || opcode > 0xff)
319             throw std::runtime_error("CScript::operator<<() : invalid opcode");
320         insert(end(), (unsigned char)opcode);
321         return *this;
322     }
323
324     CScript& operator<<(const uint160& b)
325     {
326         insert(end(), sizeof(b));
327         insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
328         return *this;
329     }
330
331     CScript& operator<<(const uint256& b)
332     {
333         insert(end(), sizeof(b));
334         insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
335         return *this;
336     }
337
338     CScript& operator<<(const CPubKey& key)
339     {
340         std::vector<unsigned char> vchKey = key.Raw();
341         return (*this) << vchKey;
342     }
343
344     CScript& operator<<(const CBigNum& b)
345     {
346         *this << b.getvch();
347         return *this;
348     }
349
350     CScript& operator<<(const std::vector<unsigned char>& b)
351     {
352         if (b.size() < OP_PUSHDATA1)
353         {
354             insert(end(), (unsigned char)b.size());
355         }
356         else if (b.size() <= 0xff)
357         {
358             insert(end(), OP_PUSHDATA1);
359             insert(end(), (unsigned char)b.size());
360         }
361         else if (b.size() <= 0xffff)
362         {
363             insert(end(), OP_PUSHDATA2);
364             unsigned short nSize = b.size();
365             insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
366         }
367         else
368         {
369             insert(end(), OP_PUSHDATA4);
370             unsigned int nSize = b.size();
371             insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
372         }
373         insert(end(), b.begin(), b.end());
374         return *this;
375     }
376
377     CScript& operator<<(const CScript& b)
378     {
379         // I'm not sure if this should push the script or concatenate scripts.
380         // If there's ever a use for pushing a script onto a script, delete this member fn
381         assert(!"warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate");
382         return *this;
383     }
384
385
386     bool GetOp(iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>& vchRet)
387     {
388          // Wrapper so it can be called with either iterator or const_iterator
389          const_iterator pc2 = pc;
390          bool fRet = GetOp2(pc2, opcodeRet, &vchRet);
391          pc = begin() + (pc2 - begin());
392          return fRet;
393     }
394
395     bool GetOp(iterator& pc, opcodetype& opcodeRet)
396     {
397          const_iterator pc2 = pc;
398          bool fRet = GetOp2(pc2, opcodeRet, NULL);
399          pc = begin() + (pc2 - begin());
400          return fRet;
401     }
402
403     bool GetOp(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>& vchRet) const
404     {
405         return GetOp2(pc, opcodeRet, &vchRet);
406     }
407
408     bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const
409     {
410         return GetOp2(pc, opcodeRet, NULL);
411     }
412
413     bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet) const
414     {
415         opcodeRet = OP_INVALIDOPCODE;
416         if (pvchRet)
417             pvchRet->clear();
418         if (pc >= end())
419             return false;
420
421         // Read instruction
422         if (end() - pc < 1)
423             return false;
424         unsigned int opcode = *pc++;
425
426         // Immediate operand
427         if (opcode <= OP_PUSHDATA4)
428         {
429             unsigned int nSize;
430             if (opcode < OP_PUSHDATA1)
431             {
432                 nSize = opcode;
433             }
434             else if (opcode == OP_PUSHDATA1)
435             {
436                 if (end() - pc < 1)
437                     return false;
438                 nSize = *pc++;
439             }
440             else if (opcode == OP_PUSHDATA2)
441             {
442                 if (end() - pc < 2)
443                     return false;
444                 nSize = 0;
445                 memcpy(&nSize, &pc[0], 2);
446                 pc += 2;
447             }
448             else if (opcode == OP_PUSHDATA4)
449             {
450                 if (end() - pc < 4)
451                     return false;
452                 memcpy(&nSize, &pc[0], 4);
453                 pc += 4;
454             }
455             if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
456                 return false;
457             if (pvchRet)
458                 pvchRet->assign(pc, pc + nSize);
459             pc += nSize;
460         }
461
462         opcodeRet = (opcodetype)opcode;
463         return true;
464     }
465
466     // Encode/decode small integers:
467     static int DecodeOP_N(opcodetype opcode)
468     {
469         if (opcode == OP_0)
470             return 0;
471         assert(opcode >= OP_1 && opcode <= OP_16);
472         return (int)opcode - (int)(OP_1 - 1);
473     }
474     static opcodetype EncodeOP_N(int n)
475     {
476         assert(n >= 0 && n <= 16);
477         if (n == 0)
478             return OP_0;
479         return (opcodetype)(OP_1+n-1);
480     }
481
482     int FindAndDelete(const CScript& b)
483     {
484         int nFound = 0;
485         if (b.empty())
486             return nFound;
487         iterator pc = begin();
488         opcodetype opcode;
489         do
490         {
491             while (end() - pc >= (long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
492             {
493                 erase(pc, pc + b.size());
494                 ++nFound;
495             }
496         }
497         while (GetOp(pc, opcode));
498         return nFound;
499     }
500     int Find(opcodetype op) const
501     {
502         int nFound = 0;
503         opcodetype opcode;
504         for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);)
505             if (opcode == op)
506                 ++nFound;
507         return nFound;
508     }
509
510     // Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs
511     // as 20 sigops. With pay-to-script-hash, that changed:
512     // CHECKMULTISIGs serialized in scriptSigs are
513     // counted more accurately, assuming they are of the form
514     //  ... OP_N CHECKMULTISIG ...
515     unsigned int GetSigOpCount(bool fAccurate) const;
516
517     // Accurately count sigOps, including sigOps in
518     // pay-to-script-hash transactions:
519     unsigned int GetSigOpCount(const CScript& scriptSig) const;
520
521     bool IsPayToScriptHash() const;
522
523     // Called by CTransaction::IsStandard
524     bool IsPushOnly() const
525     {
526         const_iterator pc = begin();
527         while (pc < end())
528         {
529             opcodetype opcode;
530             if (!GetOp(pc, opcode))
531                 return false;
532             if (opcode > OP_16)
533                 return false;
534         }
535         return true;
536     }
537
538
539     void SetDestination(const CTxDestination& address);
540     void SetMultisig(int nRequired, const std::vector<CKey>& keys);
541
542
543     void PrintHex() const
544     {
545         printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str());
546     }
547
548     std::string ToString() const
549     {
550         std::string str;
551         opcodetype opcode;
552         std::vector<unsigned char> vch;
553         const_iterator pc = begin();
554         while (pc < end())
555         {
556             if (!str.empty())
557                 str += " ";
558             if (!GetOp(pc, opcode, vch))
559             {
560                 str += "[error]";
561                 return str;
562             }
563             if (0 <= opcode && opcode <= OP_PUSHDATA4)
564                 str += ValueString(vch);
565             else
566                 str += GetOpName(opcode);
567         }
568         return str;
569     }
570
571     void print() const
572     {
573         printf("%s\n", ToString().c_str());
574     }
575
576     CScriptID GetID() const
577     {
578         return CScriptID(Hash160(*this));
579     }
580 };
581
582
583
584
585
586 bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType);
587 bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
588 int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
589 bool IsStandard(const CScript& scriptPubKey);
590 bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
591 bool IsMine(const CKeyStore& keystore, const CTxDestination &dest);
592 bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
593 bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
594 bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
595 bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, bool fValidatePayToScriptHash, int nHashType);
596
597 #endif
This page took 0.056969 seconds and 4 git commands to generate.