]>
Commit | Line | Data |
---|---|---|
0a61b0df | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
db0e8ccd | 2 | // Copyright (c) 2009-2013 The Bitcoin developers |
0a61b0df | 3 | // Distributed under the MIT/X11 software license, see the accompanying |
3a25a2b9 | 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
51ed9ec9 | 5 | |
223b6f1b WL |
6 | #ifndef H_BITCOIN_SCRIPT |
7 | #define H_BITCOIN_SCRIPT | |
8 | ||
51ed9ec9 BD |
9 | #include "bignum.h" |
10 | #include "key.h" | |
11 | #include "util.h" | |
12 | ||
13 | #include <stdexcept> | |
14 | #include <stdint.h> | |
223b6f1b WL |
15 | #include <string> |
16 | #include <vector> | |
0a61b0df | 17 | |
437173f4 | 18 | #include <boost/foreach.hpp> |
10254401 PW |
19 | #include <boost/variant.hpp> |
20 | ||
450cbb09 | 21 | class CCoins; |
51ed9ec9 | 22 | class CKeyStore; |
0a61b0df | 23 | class CTransaction; |
24 | ||
192cc910 MC |
25 | static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes |
26 | ||
6b8de05d | 27 | /** Signature hash types/flags */ |
0a61b0df | 28 | enum |
29 | { | |
30 | SIGHASH_ALL = 1, | |
31 | SIGHASH_NONE = 2, | |
32 | SIGHASH_SINGLE = 3, | |
33 | SIGHASH_ANYONECANPAY = 0x80, | |
34 | }; | |
35 | ||
99d0d0f3 PW |
36 | /** Script verification flags */ |
37 | enum | |
38 | { | |
39 | SCRIPT_VERIFY_NONE = 0, | |
a81cd968 PW |
40 | SCRIPT_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts |
41 | SCRIPT_VERIFY_STRICTENC = (1U << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys | |
42 | SCRIPT_VERIFY_EVEN_S = (1U << 2), // enforce even S values in signatures (depends on STRICTENC) | |
43 | SCRIPT_VERIFY_NOCACHE = (1U << 3), // do not store results in signature cache (but do query it) | |
99d0d0f3 | 44 | }; |
0a61b0df | 45 | |
2a45a494 | 46 | enum txnouttype |
e679ec96 GA |
47 | { |
48 | TX_NONSTANDARD, | |
49 | // 'standard' transaction types: | |
50 | TX_PUBKEY, | |
51 | TX_PUBKEYHASH, | |
52 | TX_SCRIPTHASH, | |
53 | TX_MULTISIG, | |
a7934247 | 54 | TX_NULL_DATA, |
e679ec96 GA |
55 | }; |
56 | ||
10254401 PW |
57 | class CNoDestination { |
58 | public: | |
59 | friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; } | |
60 | friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } | |
61 | }; | |
62 | ||
63 | /** A txout script template with a specific destination. It is either: | |
64 | * * CNoDestination: no destination set | |
65 | * * CKeyID: TX_PUBKEYHASH destination | |
66 | * * CScriptID: TX_SCRIPTHASH destination | |
67 | * A CTxDestination is the internal data type encoded in a CBitcoinAddress | |
68 | */ | |
69 | typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination; | |
70 | ||
2a45a494 | 71 | const char* GetTxnOutputType(txnouttype t); |
0a61b0df | 72 | |
6b8de05d | 73 | /** Script opcodes */ |
0a61b0df | 74 | enum opcodetype |
75 | { | |
76 | // push value | |
7be8b2ff WL |
77 | OP_0 = 0x00, |
78 | OP_FALSE = OP_0, | |
79 | OP_PUSHDATA1 = 0x4c, | |
80 | OP_PUSHDATA2 = 0x4d, | |
81 | OP_PUSHDATA4 = 0x4e, | |
82 | OP_1NEGATE = 0x4f, | |
83 | OP_RESERVED = 0x50, | |
84 | OP_1 = 0x51, | |
0a61b0df | 85 | OP_TRUE=OP_1, |
7be8b2ff WL |
86 | OP_2 = 0x52, |
87 | OP_3 = 0x53, | |
88 | OP_4 = 0x54, | |
89 | OP_5 = 0x55, | |
90 | OP_6 = 0x56, | |
91 | OP_7 = 0x57, | |
92 | OP_8 = 0x58, | |
93 | OP_9 = 0x59, | |
94 | OP_10 = 0x5a, | |
95 | OP_11 = 0x5b, | |
96 | OP_12 = 0x5c, | |
97 | OP_13 = 0x5d, | |
98 | OP_14 = 0x5e, | |
99 | OP_15 = 0x5f, | |
100 | OP_16 = 0x60, | |
0a61b0df | 101 | |
102 | // control | |
7be8b2ff WL |
103 | OP_NOP = 0x61, |
104 | OP_VER = 0x62, | |
105 | OP_IF = 0x63, | |
106 | OP_NOTIF = 0x64, | |
107 | OP_VERIF = 0x65, | |
108 | OP_VERNOTIF = 0x66, | |
109 | OP_ELSE = 0x67, | |
110 | OP_ENDIF = 0x68, | |
111 | OP_VERIFY = 0x69, | |
112 | OP_RETURN = 0x6a, | |
0a61b0df | 113 | |
114 | // stack ops | |
7be8b2ff WL |
115 | OP_TOALTSTACK = 0x6b, |
116 | OP_FROMALTSTACK = 0x6c, | |
117 | OP_2DROP = 0x6d, | |
118 | OP_2DUP = 0x6e, | |
119 | OP_3DUP = 0x6f, | |
120 | OP_2OVER = 0x70, | |
121 | OP_2ROT = 0x71, | |
122 | OP_2SWAP = 0x72, | |
123 | OP_IFDUP = 0x73, | |
124 | OP_DEPTH = 0x74, | |
125 | OP_DROP = 0x75, | |
126 | OP_DUP = 0x76, | |
127 | OP_NIP = 0x77, | |
128 | OP_OVER = 0x78, | |
129 | OP_PICK = 0x79, | |
130 | OP_ROLL = 0x7a, | |
131 | OP_ROT = 0x7b, | |
132 | OP_SWAP = 0x7c, | |
133 | OP_TUCK = 0x7d, | |
0a61b0df | 134 | |
135 | // splice ops | |
7be8b2ff WL |
136 | OP_CAT = 0x7e, |
137 | OP_SUBSTR = 0x7f, | |
138 | OP_LEFT = 0x80, | |
139 | OP_RIGHT = 0x81, | |
140 | OP_SIZE = 0x82, | |
0a61b0df | 141 | |
142 | // bit logic | |
7be8b2ff WL |
143 | OP_INVERT = 0x83, |
144 | OP_AND = 0x84, | |
145 | OP_OR = 0x85, | |
146 | OP_XOR = 0x86, | |
147 | OP_EQUAL = 0x87, | |
148 | OP_EQUALVERIFY = 0x88, | |
149 | OP_RESERVED1 = 0x89, | |
150 | OP_RESERVED2 = 0x8a, | |
0a61b0df | 151 | |
152 | // numeric | |
7be8b2ff WL |
153 | OP_1ADD = 0x8b, |
154 | OP_1SUB = 0x8c, | |
155 | OP_2MUL = 0x8d, | |
156 | OP_2DIV = 0x8e, | |
157 | OP_NEGATE = 0x8f, | |
158 | OP_ABS = 0x90, | |
159 | OP_NOT = 0x91, | |
160 | OP_0NOTEQUAL = 0x92, | |
161 | ||
162 | OP_ADD = 0x93, | |
163 | OP_SUB = 0x94, | |
164 | OP_MUL = 0x95, | |
165 | OP_DIV = 0x96, | |
166 | OP_MOD = 0x97, | |
167 | OP_LSHIFT = 0x98, | |
168 | OP_RSHIFT = 0x99, | |
169 | ||
170 | OP_BOOLAND = 0x9a, | |
171 | OP_BOOLOR = 0x9b, | |
172 | OP_NUMEQUAL = 0x9c, | |
173 | OP_NUMEQUALVERIFY = 0x9d, | |
174 | OP_NUMNOTEQUAL = 0x9e, | |
175 | OP_LESSTHAN = 0x9f, | |
176 | OP_GREATERTHAN = 0xa0, | |
177 | OP_LESSTHANOREQUAL = 0xa1, | |
178 | OP_GREATERTHANOREQUAL = 0xa2, | |
179 | OP_MIN = 0xa3, | |
180 | OP_MAX = 0xa4, | |
181 | ||
182 | OP_WITHIN = 0xa5, | |
0a61b0df | 183 | |
184 | // crypto | |
7be8b2ff WL |
185 | OP_RIPEMD160 = 0xa6, |
186 | OP_SHA1 = 0xa7, | |
187 | OP_SHA256 = 0xa8, | |
188 | OP_HASH160 = 0xa9, | |
189 | OP_HASH256 = 0xaa, | |
190 | OP_CODESEPARATOR = 0xab, | |
191 | OP_CHECKSIG = 0xac, | |
192 | OP_CHECKSIGVERIFY = 0xad, | |
193 | OP_CHECKMULTISIG = 0xae, | |
194 | OP_CHECKMULTISIGVERIFY = 0xaf, | |
0a61b0df | 195 | |
196 | // expansion | |
7be8b2ff WL |
197 | OP_NOP1 = 0xb0, |
198 | OP_NOP2 = 0xb1, | |
199 | OP_NOP3 = 0xb2, | |
200 | OP_NOP4 = 0xb3, | |
201 | OP_NOP5 = 0xb4, | |
202 | OP_NOP6 = 0xb5, | |
203 | OP_NOP7 = 0xb6, | |
204 | OP_NOP8 = 0xb7, | |
205 | OP_NOP9 = 0xb8, | |
206 | OP_NOP10 = 0xb9, | |
0a61b0df | 207 | |
208 | ||
209 | ||
0a61b0df | 210 | // template matching params |
a7934247 | 211 | OP_SMALLDATA = 0xf9, |
e679ec96 GA |
212 | OP_SMALLINTEGER = 0xfa, |
213 | OP_PUBKEYS = 0xfb, | |
f1e1fb4b | 214 | OP_PUBKEYHASH = 0xfd, |
215 | OP_PUBKEY = 0xfe, | |
0a61b0df | 216 | |
f1e1fb4b | 217 | OP_INVALIDOPCODE = 0xff, |
0a61b0df | 218 | }; |
219 | ||
e679ec96 | 220 | const char* GetOpName(opcodetype opcode); |
0a61b0df | 221 | |
222 | ||
223 | ||
223b6f1b | 224 | inline std::string ValueString(const std::vector<unsigned char>& vch) |
0a61b0df | 225 | { |
226 | if (vch.size() <= 4) | |
227 | return strprintf("%d", CBigNum(vch).getint()); | |
228 | else | |
f1e1fb4b | 229 | return HexStr(vch); |
0a61b0df | 230 | } |
231 | ||
223b6f1b | 232 | inline std::string StackString(const std::vector<std::vector<unsigned char> >& vStack) |
0a61b0df | 233 | { |
223b6f1b WL |
234 | std::string str; |
235 | BOOST_FOREACH(const std::vector<unsigned char>& vch, vStack) | |
0a61b0df | 236 | { |
237 | if (!str.empty()) | |
238 | str += " "; | |
239 | str += ValueString(vch); | |
240 | } | |
241 | return str; | |
242 | } | |
243 | ||
244 | ||
245 | ||
246 | ||
247 | ||
248 | ||
249 | ||
250 | ||
6b8de05d | 251 | /** Serialized script, used inside transaction inputs and outputs */ |
223b6f1b | 252 | class CScript : public std::vector<unsigned char> |
0a61b0df | 253 | { |
254 | protected: | |
51ed9ec9 | 255 | CScript& push_int64(int64_t n) |
0a61b0df | 256 | { |
257 | if (n == -1 || (n >= 1 && n <= 16)) | |
258 | { | |
259 | push_back(n + (OP_1 - 1)); | |
260 | } | |
261 | else | |
262 | { | |
263 | CBigNum bn(n); | |
264 | *this << bn.getvch(); | |
265 | } | |
f1e1fb4b | 266 | return *this; |
0a61b0df | 267 | } |
268 | ||
51ed9ec9 | 269 | CScript& push_uint64(uint64_t n) |
0a61b0df | 270 | { |
f1e1fb4b | 271 | if (n >= 1 && n <= 16) |
0a61b0df | 272 | { |
273 | push_back(n + (OP_1 - 1)); | |
274 | } | |
275 | else | |
276 | { | |
277 | CBigNum bn(n); | |
278 | *this << bn.getvch(); | |
279 | } | |
f1e1fb4b | 280 | return *this; |
0a61b0df | 281 | } |
282 | ||
283 | public: | |
284 | CScript() { } | |
223b6f1b WL |
285 | CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { } |
286 | CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { } | |
0a61b0df | 287 | #ifndef _MSC_VER |
223b6f1b | 288 | CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { } |
0a61b0df | 289 | #endif |
290 | ||
291 | CScript& operator+=(const CScript& b) | |
292 | { | |
293 | insert(end(), b.begin(), b.end()); | |
294 | return *this; | |
295 | } | |
296 | ||
297 | friend CScript operator+(const CScript& a, const CScript& b) | |
298 | { | |
299 | CScript ret = a; | |
300 | ret += b; | |
f1e1fb4b | 301 | return ret; |
0a61b0df | 302 | } |
303 | ||
304 | ||
8c8e8c2e | 305 | //explicit CScript(char b) is not portable. Use 'signed char' or 'unsigned char'. |
51ed9ec9 BD |
306 | explicit CScript(signed char b) { operator<<(b); } |
307 | explicit CScript(short b) { operator<<(b); } | |
308 | explicit CScript(int b) { operator<<(b); } | |
309 | explicit CScript(long b) { operator<<(b); } | |
310 | explicit CScript(long long b) { operator<<(b); } | |
311 | explicit CScript(unsigned char b) { operator<<(b); } | |
312 | explicit CScript(unsigned int b) { operator<<(b); } | |
313 | explicit CScript(unsigned short b) { operator<<(b); } | |
314 | explicit CScript(unsigned long b) { operator<<(b); } | |
315 | explicit CScript(unsigned long long b) { operator<<(b); } | |
0a61b0df | 316 | |
317 | explicit CScript(opcodetype b) { operator<<(b); } | |
318 | explicit CScript(const uint256& b) { operator<<(b); } | |
319 | explicit CScript(const CBigNum& b) { operator<<(b); } | |
223b6f1b | 320 | explicit CScript(const std::vector<unsigned char>& b) { operator<<(b); } |
0a61b0df | 321 | |
322 | ||
8c8e8c2e | 323 | //CScript& operator<<(char b) is not portable. Use 'signed char' or 'unsigned char'. |
51ed9ec9 BD |
324 | CScript& operator<<(signed char b) { return push_int64(b); } |
325 | CScript& operator<<(short b) { return push_int64(b); } | |
326 | CScript& operator<<(int b) { return push_int64(b); } | |
327 | CScript& operator<<(long b) { return push_int64(b); } | |
328 | CScript& operator<<(long long b) { return push_int64(b); } | |
329 | CScript& operator<<(unsigned char b) { return push_uint64(b); } | |
330 | CScript& operator<<(unsigned int b) { return push_uint64(b); } | |
331 | CScript& operator<<(unsigned short b) { return push_uint64(b); } | |
332 | CScript& operator<<(unsigned long b) { return push_uint64(b); } | |
333 | CScript& operator<<(unsigned long long b) { return push_uint64(b); } | |
0a61b0df | 334 | |
335 | CScript& operator<<(opcodetype opcode) | |
336 | { | |
f1e1fb4b | 337 | if (opcode < 0 || opcode > 0xff) |
223b6f1b | 338 | throw std::runtime_error("CScript::operator<<() : invalid opcode"); |
f1e1fb4b | 339 | insert(end(), (unsigned char)opcode); |
340 | return *this; | |
0a61b0df | 341 | } |
342 | ||
343 | CScript& operator<<(const uint160& b) | |
344 | { | |
345 | insert(end(), sizeof(b)); | |
346 | insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); | |
f1e1fb4b | 347 | return *this; |
0a61b0df | 348 | } |
349 | ||
350 | CScript& operator<<(const uint256& b) | |
351 | { | |
352 | insert(end(), sizeof(b)); | |
353 | insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); | |
f1e1fb4b | 354 | return *this; |
0a61b0df | 355 | } |
356 | ||
fd61d6f5 PW |
357 | CScript& operator<<(const CPubKey& key) |
358 | { | |
5d891489 PW |
359 | assert(key.size() < OP_PUSHDATA1); |
360 | insert(end(), (unsigned char)key.size()); | |
361 | insert(end(), key.begin(), key.end()); | |
362 | return *this; | |
fd61d6f5 PW |
363 | } |
364 | ||
0a61b0df | 365 | CScript& operator<<(const CBigNum& b) |
366 | { | |
367 | *this << b.getvch(); | |
f1e1fb4b | 368 | return *this; |
0a61b0df | 369 | } |
370 | ||
223b6f1b | 371 | CScript& operator<<(const std::vector<unsigned char>& b) |
0a61b0df | 372 | { |
373 | if (b.size() < OP_PUSHDATA1) | |
374 | { | |
375 | insert(end(), (unsigned char)b.size()); | |
376 | } | |
377 | else if (b.size() <= 0xff) | |
378 | { | |
379 | insert(end(), OP_PUSHDATA1); | |
380 | insert(end(), (unsigned char)b.size()); | |
381 | } | |
f1e1fb4b | 382 | else if (b.size() <= 0xffff) |
0a61b0df | 383 | { |
384 | insert(end(), OP_PUSHDATA2); | |
385 | unsigned short nSize = b.size(); | |
386 | insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); | |
387 | } | |
f1e1fb4b | 388 | else |
389 | { | |
390 | insert(end(), OP_PUSHDATA4); | |
391 | unsigned int nSize = b.size(); | |
392 | insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); | |
393 | } | |
0a61b0df | 394 | insert(end(), b.begin(), b.end()); |
f1e1fb4b | 395 | return *this; |
0a61b0df | 396 | } |
397 | ||
398 | CScript& operator<<(const CScript& b) | |
399 | { | |
400 | // I'm not sure if this should push the script or concatenate scripts. | |
401 | // If there's ever a use for pushing a script onto a script, delete this member fn | |
e6bc9c35 | 402 | assert(!"Warning: Pushing a CScript onto a CScript with << is probably not intended, use + to concatenate!"); |
f1e1fb4b | 403 | return *this; |
0a61b0df | 404 | } |
405 | ||
406 | ||
223b6f1b | 407 | bool GetOp(iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>& vchRet) |
0a61b0df | 408 | { |
409 | // Wrapper so it can be called with either iterator or const_iterator | |
410 | const_iterator pc2 = pc; | |
f1e1fb4b | 411 | bool fRet = GetOp2(pc2, opcodeRet, &vchRet); |
412 | pc = begin() + (pc2 - begin()); | |
413 | return fRet; | |
414 | } | |
415 | ||
416 | bool GetOp(iterator& pc, opcodetype& opcodeRet) | |
417 | { | |
418 | const_iterator pc2 = pc; | |
419 | bool fRet = GetOp2(pc2, opcodeRet, NULL); | |
0a61b0df | 420 | pc = begin() + (pc2 - begin()); |
421 | return fRet; | |
422 | } | |
423 | ||
223b6f1b | 424 | bool GetOp(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>& vchRet) const |
f1e1fb4b | 425 | { |
426 | return GetOp2(pc, opcodeRet, &vchRet); | |
427 | } | |
428 | ||
429 | bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const | |
430 | { | |
431 | return GetOp2(pc, opcodeRet, NULL); | |
432 | } | |
433 | ||
223b6f1b | 434 | bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet) const |
0a61b0df | 435 | { |
436 | opcodeRet = OP_INVALIDOPCODE; | |
f1e1fb4b | 437 | if (pvchRet) |
438 | pvchRet->clear(); | |
0a61b0df | 439 | if (pc >= end()) |
440 | return false; | |
441 | ||
442 | // Read instruction | |
f1e1fb4b | 443 | if (end() - pc < 1) |
444 | return false; | |
0a61b0df | 445 | unsigned int opcode = *pc++; |
0a61b0df | 446 | |
447 | // Immediate operand | |
448 | if (opcode <= OP_PUSHDATA4) | |
449 | { | |
5f048816 | 450 | unsigned int nSize = 0; |
f1e1fb4b | 451 | if (opcode < OP_PUSHDATA1) |
452 | { | |
453 | nSize = opcode; | |
454 | } | |
455 | else if (opcode == OP_PUSHDATA1) | |
0a61b0df | 456 | { |
f1e1fb4b | 457 | if (end() - pc < 1) |
0a61b0df | 458 | return false; |
459 | nSize = *pc++; | |
460 | } | |
461 | else if (opcode == OP_PUSHDATA2) | |
462 | { | |
f1e1fb4b | 463 | if (end() - pc < 2) |
0a61b0df | 464 | return false; |
465 | nSize = 0; | |
466 | memcpy(&nSize, &pc[0], 2); | |
467 | pc += 2; | |
468 | } | |
469 | else if (opcode == OP_PUSHDATA4) | |
470 | { | |
f1e1fb4b | 471 | if (end() - pc < 4) |
0a61b0df | 472 | return false; |
473 | memcpy(&nSize, &pc[0], 4); | |
474 | pc += 4; | |
475 | } | |
467b7939 | 476 | if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize) |
0a61b0df | 477 | return false; |
f1e1fb4b | 478 | if (pvchRet) |
479 | pvchRet->assign(pc, pc + nSize); | |
0a61b0df | 480 | pc += nSize; |
481 | } | |
482 | ||
483 | opcodeRet = (opcodetype)opcode; | |
484 | return true; | |
485 | } | |
486 | ||
e679ec96 | 487 | // Encode/decode small integers: |
bf798734 GA |
488 | static int DecodeOP_N(opcodetype opcode) |
489 | { | |
490 | if (opcode == OP_0) | |
491 | return 0; | |
492 | assert(opcode >= OP_1 && opcode <= OP_16); | |
493 | return (int)opcode - (int)(OP_1 - 1); | |
494 | } | |
e679ec96 GA |
495 | static opcodetype EncodeOP_N(int n) |
496 | { | |
497 | assert(n >= 0 && n <= 16); | |
498 | if (n == 0) | |
499 | return OP_0; | |
500 | return (opcodetype)(OP_1+n-1); | |
501 | } | |
0a61b0df | 502 | |
e679ec96 | 503 | int FindAndDelete(const CScript& b) |
0a61b0df | 504 | { |
e679ec96 | 505 | int nFound = 0; |
f1e1fb4b | 506 | if (b.empty()) |
e679ec96 | 507 | return nFound; |
0a61b0df | 508 | iterator pc = begin(); |
509 | opcodetype opcode; | |
0a61b0df | 510 | do |
511 | { | |
1d8c7a95 | 512 | while (end() - pc >= (long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) |
e679ec96 | 513 | { |
0a61b0df | 514 | erase(pc, pc + b.size()); |
e679ec96 GA |
515 | ++nFound; |
516 | } | |
0a61b0df | 517 | } |
f1e1fb4b | 518 | while (GetOp(pc, opcode)); |
e679ec96 GA |
519 | return nFound; |
520 | } | |
521 | int Find(opcodetype op) const | |
522 | { | |
523 | int nFound = 0; | |
524 | opcodetype opcode; | |
525 | for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);) | |
526 | if (opcode == op) | |
527 | ++nFound; | |
528 | return nFound; | |
f1e1fb4b | 529 | } |
530 | ||
922e8e29 GA |
531 | // Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs |
532 | // as 20 sigops. With pay-to-script-hash, that changed: | |
533 | // CHECKMULTISIGs serialized in scriptSigs are | |
534 | // counted more accurately, assuming they are of the form | |
535 | // ... OP_N CHECKMULTISIG ... | |
7bd9c3a3 | 536 | unsigned int GetSigOpCount(bool fAccurate) const; |
922e8e29 GA |
537 | |
538 | // Accurately count sigOps, including sigOps in | |
539 | // pay-to-script-hash transactions: | |
7bd9c3a3 | 540 | unsigned int GetSigOpCount(const CScript& scriptSig) const; |
922e8e29 GA |
541 | |
542 | bool IsPayToScriptHash() const; | |
0a61b0df | 543 | |
05df3fc6 | 544 | // Called by IsStandardTx |
a206a239 | 545 | bool IsPushOnly() const |
546 | { | |
547 | const_iterator pc = begin(); | |
548 | while (pc < end()) | |
549 | { | |
550 | opcodetype opcode; | |
551 | if (!GetOp(pc, opcode)) | |
552 | return false; | |
214d45b6 PT |
553 | // Note that IsPushOnly() *does* consider OP_RESERVED to be a |
554 | // push-type opcode, however execution of OP_RESERVED fails, so | |
555 | // it's not relevant to P2SH as the scriptSig would fail prior to | |
556 | // the P2SH special validation code being executed. | |
a206a239 | 557 | if (opcode > OP_16) |
558 | return false; | |
559 | } | |
560 | return true; | |
561 | } | |
562 | ||
ec84e81e PW |
563 | // Returns whether the script is guaranteed to fail at execution, |
564 | // regardless of the initial stack. This allows outputs to be pruned | |
565 | // instantly when entering the UTXO set. | |
566 | bool IsUnspendable() const | |
567 | { | |
568 | return (size() > 0 && *begin() == OP_RETURN); | |
569 | } | |
a206a239 | 570 | |
10254401 | 571 | void SetDestination(const CTxDestination& address); |
dfa23b94 | 572 | void SetMultisig(int nRequired, const std::vector<CPubKey>& keys); |
0a61b0df | 573 | |
574 | ||
575 | void PrintHex() const | |
576 | { | |
881a85a2 | 577 | LogPrintf("CScript(%s)\n", HexStr(begin(), end(), true).c_str()); |
0a61b0df | 578 | } |
579 | ||
223b6f1b | 580 | std::string ToString() const |
0a61b0df | 581 | { |
223b6f1b | 582 | std::string str; |
0a61b0df | 583 | opcodetype opcode; |
223b6f1b | 584 | std::vector<unsigned char> vch; |
f1e1fb4b | 585 | const_iterator pc = begin(); |
586 | while (pc < end()) | |
0a61b0df | 587 | { |
588 | if (!str.empty()) | |
589 | str += " "; | |
f1e1fb4b | 590 | if (!GetOp(pc, opcode, vch)) |
591 | { | |
592 | str += "[error]"; | |
593 | return str; | |
594 | } | |
595 | if (0 <= opcode && opcode <= OP_PUSHDATA4) | |
0a61b0df | 596 | str += ValueString(vch); |
597 | else | |
598 | str += GetOpName(opcode); | |
599 | } | |
600 | return str; | |
601 | } | |
602 | ||
603 | void print() const | |
604 | { | |
881a85a2 | 605 | LogPrintf("%s\n", ToString().c_str()); |
0a61b0df | 606 | } |
10254401 PW |
607 | |
608 | CScriptID GetID() const | |
609 | { | |
610 | return CScriptID(Hash160(*this)); | |
611 | } | |
0a61b0df | 612 | }; |
613 | ||
69fc8047 PW |
614 | /** Compact serializer for scripts. |
615 | * | |
616 | * It detects common cases and encodes them much more efficiently. | |
617 | * 3 special cases are defined: | |
618 | * * Pay to pubkey hash (encoded as 21 bytes) | |
619 | * * Pay to script hash (encoded as 21 bytes) | |
620 | * * Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes) | |
621 | * | |
622 | * Other scripts up to 121 bytes require 1 byte + script length. Above | |
623 | * that, scripts up to 16505 bytes require 2 bytes + script length. | |
624 | */ | |
625 | class CScriptCompressor | |
626 | { | |
627 | private: | |
628 | // make this static for now (there are only 6 special scripts defined) | |
629 | // this can potentially be extended together with a new nVersion for | |
630 | // transactions, in which case this value becomes dependent on nVersion | |
631 | // and nHeight of the enclosing transaction. | |
632 | static const unsigned int nSpecialScripts = 6; | |
633 | ||
634 | CScript &script; | |
635 | protected: | |
636 | // These check for scripts for which a special case with a shorter encoding is defined. | |
637 | // They are implemented separately from the CScript test, as these test for exact byte | |
638 | // sequence correspondences, and are more strict. For example, IsToPubKey also verifies | |
639 | // whether the public key is valid (as invalid ones cannot be represented in compressed | |
640 | // form). | |
641 | bool IsToKeyID(CKeyID &hash) const; | |
642 | bool IsToScriptID(CScriptID &hash) const; | |
dfa23b94 | 643 | bool IsToPubKey(CPubKey &pubkey) const; |
69fc8047 PW |
644 | |
645 | bool Compress(std::vector<unsigned char> &out) const; | |
646 | unsigned int GetSpecialSize(unsigned int nSize) const; | |
647 | bool Decompress(unsigned int nSize, const std::vector<unsigned char> &out); | |
648 | public: | |
649 | CScriptCompressor(CScript &scriptIn) : script(scriptIn) { } | |
650 | ||
651 | unsigned int GetSerializeSize(int nType, int nVersion) const { | |
652 | std::vector<unsigned char> compr; | |
653 | if (Compress(compr)) | |
654 | return compr.size(); | |
655 | unsigned int nSize = script.size() + nSpecialScripts; | |
656 | return script.size() + VARINT(nSize).GetSerializeSize(nType, nVersion); | |
657 | } | |
0a61b0df | 658 | |
69fc8047 PW |
659 | template<typename Stream> |
660 | void Serialize(Stream &s, int nType, int nVersion) const { | |
661 | std::vector<unsigned char> compr; | |
662 | if (Compress(compr)) { | |
663 | s << CFlatData(&compr[0], &compr[compr.size()]); | |
664 | return; | |
665 | } | |
666 | unsigned int nSize = script.size() + nSpecialScripts; | |
667 | s << VARINT(nSize); | |
668 | s << CFlatData(&script[0], &script[script.size()]); | |
669 | } | |
670 | ||
671 | template<typename Stream> | |
672 | void Unserialize(Stream &s, int nType, int nVersion) { | |
5f048816 | 673 | unsigned int nSize = 0; |
69fc8047 PW |
674 | s >> VARINT(nSize); |
675 | if (nSize < nSpecialScripts) { | |
676 | std::vector<unsigned char> vch(GetSpecialSize(nSize), 0x00); | |
677 | s >> REF(CFlatData(&vch[0], &vch[vch.size()])); | |
678 | Decompress(nSize, vch); | |
679 | return; | |
680 | } | |
681 | nSize -= nSpecialScripts; | |
682 | script.resize(nSize); | |
683 | s >> REF(CFlatData(&script[0], &script[script.size()])); | |
684 | } | |
685 | }; | |
0a61b0df | 686 | |
a81cd968 PW |
687 | bool IsCanonicalPubKey(const std::vector<unsigned char> &vchPubKey, unsigned int flags); |
688 | bool IsCanonicalSignature(const std::vector<unsigned char> &vchSig, unsigned int flags); | |
0a61b0df | 689 | |
99d0d0f3 | 690 | bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); |
2a45a494 | 691 | bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet); |
39f0d968 | 692 | int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions); |
a7934247 | 693 | bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); |
64c7ee7e | 694 | bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); |
10254401 | 695 | bool IsMine(const CKeyStore& keystore, const CTxDestination &dest); |
acc775c5 | 696 | void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector<CKeyID> &vKeys); |
10254401 PW |
697 | bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); |
698 | bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet); | |
34420d65 | 699 | bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); |
d11a58a2 | 700 | bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); |
f1136200 | 701 | bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType); |
223b6f1b | 702 | |
a2709fad GA |
703 | // Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, |
704 | // combine them intelligently and return the result. | |
705 | CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); | |
706 | ||
223b6f1b | 707 | #endif |