Remove if block of checking disabled opcodes
[NovacoinLibrary.git] / Novacoin / ScriptCode.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 using System.Numerics;
7
8 // using Org.BouncyCastle.Math;
9
10 namespace Novacoin
11 {
12     /// <summary>
13     /// Script opcodes
14     /// </summary>
15     public enum opcodetype
16     {
17         // push value
18         OP_0 = 0x00,
19         OP_FALSE = OP_0,
20         OP_PUSHDATA1 = 0x4c,
21         OP_PUSHDATA2 = 0x4d,
22         OP_PUSHDATA4 = 0x4e,
23         OP_1NEGATE = 0x4f,
24         OP_RESERVED = 0x50,
25         OP_1 = 0x51,
26         OP_TRUE = OP_1,
27         OP_2 = 0x52,
28         OP_3 = 0x53,
29         OP_4 = 0x54,
30         OP_5 = 0x55,
31         OP_6 = 0x56,
32         OP_7 = 0x57,
33         OP_8 = 0x58,
34         OP_9 = 0x59,
35         OP_10 = 0x5a,
36         OP_11 = 0x5b,
37         OP_12 = 0x5c,
38         OP_13 = 0x5d,
39         OP_14 = 0x5e,
40         OP_15 = 0x5f,
41         OP_16 = 0x60,
42
43         // control
44         OP_NOP = 0x61,
45         OP_VER = 0x62,
46         OP_IF = 0x63,
47         OP_NOTIF = 0x64,
48         OP_VERIF = 0x65,
49         OP_VERNOTIF = 0x66,
50         OP_ELSE = 0x67,
51         OP_ENDIF = 0x68,
52         OP_VERIFY = 0x69,
53         OP_RETURN = 0x6a,
54
55         // stack ops
56         OP_TOALTSTACK = 0x6b,
57         OP_FROMALTSTACK = 0x6c,
58         OP_2DROP = 0x6d,
59         OP_2DUP = 0x6e,
60         OP_3DUP = 0x6f,
61         OP_2OVER = 0x70,
62         OP_2ROT = 0x71,
63         OP_2SWAP = 0x72,
64         OP_IFDUP = 0x73,
65         OP_DEPTH = 0x74,
66         OP_DROP = 0x75,
67         OP_DUP = 0x76,
68         OP_NIP = 0x77,
69         OP_OVER = 0x78,
70         OP_PICK = 0x79,
71         OP_ROLL = 0x7a,
72         OP_ROT = 0x7b,
73         OP_SWAP = 0x7c,
74         OP_TUCK = 0x7d,
75
76         // splice ops
77         OP_CAT = 0x7e,
78         OP_SUBSTR = 0x7f,
79         OP_LEFT = 0x80,
80         OP_RIGHT = 0x81,
81         OP_SIZE = 0x82,
82
83         // bit logic
84         OP_INVERT = 0x83,
85         OP_AND = 0x84,
86         OP_OR = 0x85,
87         OP_XOR = 0x86,
88         OP_EQUAL = 0x87,
89         OP_EQUALVERIFY = 0x88,
90         OP_RESERVED1 = 0x89,
91         OP_RESERVED2 = 0x8a,
92
93         // numeric
94         OP_1ADD = 0x8b,
95         OP_1SUB = 0x8c,
96         OP_2MUL = 0x8d,
97         OP_2DIV = 0x8e,
98         OP_NEGATE = 0x8f,
99         OP_ABS = 0x90,
100         OP_NOT = 0x91,
101         OP_0NOTEQUAL = 0x92,
102
103         OP_ADD = 0x93,
104         OP_SUB = 0x94,
105         OP_MUL = 0x95,
106         OP_DIV = 0x96,
107         OP_MOD = 0x97,
108         OP_LSHIFT = 0x98,
109         OP_RSHIFT = 0x99,
110
111         OP_BOOLAND = 0x9a,
112         OP_BOOLOR = 0x9b,
113         OP_NUMEQUAL = 0x9c,
114         OP_NUMEQUALVERIFY = 0x9d,
115         OP_NUMNOTEQUAL = 0x9e,
116         OP_LESSTHAN = 0x9f,
117         OP_GREATERTHAN = 0xa0,
118         OP_LESSTHANOREQUAL = 0xa1,
119         OP_GREATERTHANOREQUAL = 0xa2,
120         OP_MIN = 0xa3,
121         OP_MAX = 0xa4,
122
123         OP_WITHIN = 0xa5,
124
125         // crypto
126         OP_RIPEMD160 = 0xa6,
127         OP_SHA1 = 0xa7,
128         OP_SHA256 = 0xa8,
129         OP_HASH160 = 0xa9,
130         OP_HASH256 = 0xaa,
131         OP_CODESEPARATOR = 0xab,
132         OP_CHECKSIG = 0xac,
133         OP_CHECKSIGVERIFY = 0xad,
134         OP_CHECKMULTISIG = 0xae,
135         OP_CHECKMULTISIGVERIFY = 0xaf,
136
137         // expansion
138         OP_NOP1 = 0xb0,
139         OP_NOP2 = 0xb1,
140         OP_NOP3 = 0xb2,
141         OP_NOP4 = 0xb3,
142         OP_NOP5 = 0xb4,
143         OP_NOP6 = 0xb5,
144         OP_NOP7 = 0xb6,
145         OP_NOP8 = 0xb7,
146         OP_NOP9 = 0xb8,
147         OP_NOP10 = 0xb9,
148
149         // template matching params
150         OP_SMALLDATA = 0xf9,
151         OP_SMALLINTEGER = 0xfa,
152         OP_PUBKEYS = 0xfb,
153         OP_PUBKEYHASH = 0xfd,
154         OP_PUBKEY = 0xfe,
155
156         OP_INVALIDOPCODE = 0xff,
157     };
158
159     /// <summary>
160     /// Transaction output types.
161     /// </summary>
162     public enum txnouttype
163     {
164         TX_NONSTANDARD,
165
166         // 'standard' transaction types:
167         TX_PUBKEY,
168         TX_PUBKEYHASH,
169         TX_SCRIPTHASH,
170         TX_MULTISIG,
171         TX_NULL_DATA,
172     };
173
174     /// <summary>
175     /// Signature hash types/flags
176     /// </summary>
177     public enum sigflag
178     {
179         SIGHASH_ALL = 1,
180         SIGHASH_NONE = 2,
181         SIGHASH_SINGLE = 3,
182         SIGHASH_ANYONECANPAY = 0x80,
183     };
184
185     /** Script verification flags */
186     public enum scriptflag
187     {
188         SCRIPT_VERIFY_NONE = 0,
189         SCRIPT_VERIFY_P2SH = (1 << 0), // evaluate P2SH (BIP16) subscripts
190         SCRIPT_VERIFY_STRICTENC = (1 << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys
191         SCRIPT_VERIFY_LOW_S = (1 << 2), // enforce low S values in signatures (depends on STRICTENC)
192         SCRIPT_VERIFY_NOCACHE = (1 << 3), // do not store results in signature cache (but do query it)
193         SCRIPT_VERIFY_NULLDUMMY = (1 << 4), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length
194     };
195
196     public static class ScriptCode
197     {
198         public static string GetTxnOutputType(txnouttype t)
199         {
200             switch (t)
201             {
202                 case txnouttype.TX_NONSTANDARD: return "nonstandard";
203                 case txnouttype.TX_PUBKEY: return "pubkey";
204                 case txnouttype.TX_PUBKEYHASH: return "pubkeyhash";
205                 case txnouttype.TX_SCRIPTHASH: return "scripthash";
206                 case txnouttype.TX_MULTISIG: return "multisig";
207                 case txnouttype.TX_NULL_DATA: return "nulldata";
208             }
209             return string.Empty;
210         }
211
212         /// <summary>
213         /// Get the name of supplied opcode
214         /// </summary>
215         /// <param name="opcode">Opcode</param>
216         /// <returns>Opcode name</returns>
217         public static string GetOpName(opcodetype opcode)
218         {
219             switch (opcode)
220             {
221                 // push value
222                 case opcodetype.OP_0:
223                     return "0";
224                 case opcodetype.OP_PUSHDATA1:
225                     return "OP_PUSHDATA1";
226                 case opcodetype.OP_PUSHDATA2:
227                     return "OP_PUSHDATA2";
228                 case opcodetype.OP_PUSHDATA4:
229                     return "OP_PUSHDATA4";
230                 case opcodetype.OP_1NEGATE:
231                     return "-1";
232                 case opcodetype.OP_RESERVED:
233                     return "OP_RESERVED";
234                 case opcodetype.OP_1:
235                     return "1";
236                 case opcodetype.OP_2:
237                     return "2";
238                 case opcodetype.OP_3:
239                     return "3";
240                 case opcodetype.OP_4:
241                     return "4";
242                 case opcodetype.OP_5:
243                     return "5";
244                 case opcodetype.OP_6:
245                     return "6";
246                 case opcodetype.OP_7:
247                     return "7";
248                 case opcodetype.OP_8:
249                     return "8";
250                 case opcodetype.OP_9:
251                     return "9";
252                 case opcodetype.OP_10:
253                     return "10";
254                 case opcodetype.OP_11:
255                     return "11";
256                 case opcodetype.OP_12:
257                     return "12";
258                 case opcodetype.OP_13:
259                     return "13";
260                 case opcodetype.OP_14:
261                     return "14";
262                 case opcodetype.OP_15:
263                     return "15";
264                 case opcodetype.OP_16:
265                     return "16";
266
267                 // control
268                 case opcodetype.OP_NOP:
269                     return "OP_NOP";
270                 case opcodetype.OP_VER:
271                     return "OP_VER";
272                 case opcodetype.OP_IF:
273                     return "OP_IF";
274                 case opcodetype.OP_NOTIF:
275                     return "OP_NOTIF";
276                 case opcodetype.OP_VERIF:
277                     return "OP_VERIF";
278                 case opcodetype.OP_VERNOTIF:
279                     return "OP_VERNOTIF";
280                 case opcodetype.OP_ELSE:
281                     return "OP_ELSE";
282                 case opcodetype.OP_ENDIF:
283                     return "OP_ENDIF";
284                 case opcodetype.OP_VERIFY:
285                     return "OP_VERIFY";
286                 case opcodetype.OP_RETURN:
287                     return "OP_RETURN";
288
289                 // stack ops
290                 case opcodetype.OP_TOALTSTACK:
291                     return "OP_TOALTSTACK";
292                 case opcodetype.OP_FROMALTSTACK:
293                     return "OP_FROMALTSTACK";
294                 case opcodetype.OP_2DROP:
295                     return "OP_2DROP";
296                 case opcodetype.OP_2DUP:
297                     return "OP_2DUP";
298                 case opcodetype.OP_3DUP:
299                     return "OP_3DUP";
300                 case opcodetype.OP_2OVER:
301                     return "OP_2OVER";
302                 case opcodetype.OP_2ROT:
303                     return "OP_2ROT";
304                 case opcodetype.OP_2SWAP:
305                     return "OP_2SWAP";
306                 case opcodetype.OP_IFDUP:
307                     return "OP_IFDUP";
308                 case opcodetype.OP_DEPTH:
309                     return "OP_DEPTH";
310                 case opcodetype.OP_DROP:
311                     return "OP_DROP";
312                 case opcodetype.OP_DUP:
313                     return "OP_DUP";
314                 case opcodetype.OP_NIP:
315                     return "OP_NIP";
316                 case opcodetype.OP_OVER:
317                     return "OP_OVER";
318                 case opcodetype.OP_PICK:
319                     return "OP_PICK";
320                 case opcodetype.OP_ROLL:
321                     return "OP_ROLL";
322                 case opcodetype.OP_ROT:
323                     return "OP_ROT";
324                 case opcodetype.OP_SWAP:
325                     return "OP_SWAP";
326                 case opcodetype.OP_TUCK:
327                     return "OP_TUCK";
328
329                 // splice ops
330                 case opcodetype.OP_CAT:
331                     return "OP_CAT";
332                 case opcodetype.OP_SUBSTR:
333                     return "OP_SUBSTR";
334                 case opcodetype.OP_LEFT:
335                     return "OP_LEFT";
336                 case opcodetype.OP_RIGHT:
337                     return "OP_RIGHT";
338                 case opcodetype.OP_SIZE:
339                     return "OP_SIZE";
340
341                 // bit logic
342                 case opcodetype.OP_INVERT:
343                     return "OP_INVERT";
344                 case opcodetype.OP_AND:
345                     return "OP_AND";
346                 case opcodetype.OP_OR:
347                     return "OP_OR";
348                 case opcodetype.OP_XOR:
349                     return "OP_XOR";
350                 case opcodetype.OP_EQUAL:
351                     return "OP_EQUAL";
352                 case opcodetype.OP_EQUALVERIFY:
353                     return "OP_EQUALVERIFY";
354                 case opcodetype.OP_RESERVED1:
355                     return "OP_RESERVED1";
356                 case opcodetype.OP_RESERVED2:
357                     return "OP_RESERVED2";
358
359                 // numeric
360                 case opcodetype.OP_1ADD:
361                     return "OP_1ADD";
362                 case opcodetype.OP_1SUB:
363                     return "OP_1SUB";
364                 case opcodetype.OP_2MUL:
365                     return "OP_2MUL";
366                 case opcodetype.OP_2DIV:
367                     return "OP_2DIV";
368                 case opcodetype.OP_NEGATE:
369                     return "OP_NEGATE";
370                 case opcodetype.OP_ABS:
371                     return "OP_ABS";
372                 case opcodetype.OP_NOT:
373                     return "OP_NOT";
374                 case opcodetype.OP_0NOTEQUAL:
375                     return "OP_0NOTEQUAL";
376                 case opcodetype.OP_ADD:
377                     return "OP_ADD";
378                 case opcodetype.OP_SUB:
379                     return "OP_SUB";
380                 case opcodetype.OP_MUL:
381                     return "OP_MUL";
382                 case opcodetype.OP_DIV:
383                     return "OP_DIV";
384                 case opcodetype.OP_MOD:
385                     return "OP_MOD";
386                 case opcodetype.OP_LSHIFT:
387                     return "OP_LSHIFT";
388                 case opcodetype.OP_RSHIFT:
389                     return "OP_RSHIFT";
390                 case opcodetype.OP_BOOLAND:
391                     return "OP_BOOLAND";
392                 case opcodetype.OP_BOOLOR:
393                     return "OP_BOOLOR";
394                 case opcodetype.OP_NUMEQUAL:
395                     return "OP_NUMEQUAL";
396                 case opcodetype.OP_NUMEQUALVERIFY:
397                     return "OP_NUMEQUALVERIFY";
398                 case opcodetype.OP_NUMNOTEQUAL:
399                     return "OP_NUMNOTEQUAL";
400                 case opcodetype.OP_LESSTHAN:
401                     return "OP_LESSTHAN";
402                 case opcodetype.OP_GREATERTHAN:
403                     return "OP_GREATERTHAN";
404                 case opcodetype.OP_LESSTHANOREQUAL:
405                     return "OP_LESSTHANOREQUAL";
406                 case opcodetype.OP_GREATERTHANOREQUAL:
407                     return "OP_GREATERTHANOREQUAL";
408                 case opcodetype.OP_MIN:
409                     return "OP_MIN";
410                 case opcodetype.OP_MAX:
411                     return "OP_MAX";
412                 case opcodetype.OP_WITHIN:
413                     return "OP_WITHIN";
414
415                 // crypto
416                 case opcodetype.OP_RIPEMD160:
417                     return "OP_RIPEMD160";
418                 case opcodetype.OP_SHA1:
419                     return "OP_SHA1";
420                 case opcodetype.OP_SHA256:
421                     return "OP_SHA256";
422                 case opcodetype.OP_HASH160:
423                     return "OP_HASH160";
424                 case opcodetype.OP_HASH256:
425                     return "OP_HASH256";
426                 case opcodetype.OP_CODESEPARATOR:
427                     return "OP_CODESEPARATOR";
428                 case opcodetype.OP_CHECKSIG:
429                     return "OP_CHECKSIG";
430                 case opcodetype.OP_CHECKSIGVERIFY:
431                     return "OP_CHECKSIGVERIFY";
432                 case opcodetype.OP_CHECKMULTISIG:
433                     return "OP_CHECKMULTISIG";
434                 case opcodetype.OP_CHECKMULTISIGVERIFY:
435                     return "OP_CHECKMULTISIGVERIFY";
436
437                 // expansion
438                 case opcodetype.OP_NOP1:
439                     return "OP_NOP1";
440                 case opcodetype.OP_NOP2:
441                     return "OP_NOP2";
442                 case opcodetype.OP_NOP3:
443                     return "OP_NOP3";
444                 case opcodetype.OP_NOP4:
445                     return "OP_NOP4";
446                 case opcodetype.OP_NOP5:
447                     return "OP_NOP5";
448                 case opcodetype.OP_NOP6:
449                     return "OP_NOP6";
450                 case opcodetype.OP_NOP7:
451                     return "OP_NOP7";
452                 case opcodetype.OP_NOP8:
453                     return "OP_NOP8";
454                 case opcodetype.OP_NOP9:
455                     return "OP_NOP9";
456                 case opcodetype.OP_NOP10:
457                     return "OP_NOP10";
458
459                 // template matching params
460                 case opcodetype.OP_PUBKEYHASH:
461                     return "OP_PUBKEYHASH";
462                 case opcodetype.OP_PUBKEY:
463                     return "OP_PUBKEY";
464                 case opcodetype.OP_SMALLDATA:
465                     return "OP_SMALLDATA";
466
467                 case opcodetype.OP_INVALIDOPCODE:
468                     return "OP_INVALIDOPCODE";
469                 default:
470                     return "OP_UNKNOWN";
471             }
472         }
473
474         /// <summary>
475         /// Get next opcode from passed list of bytes and extract push arguments if there are some.
476         /// </summary>
477         /// <param name="codeBytes">ByteQueue reference.</param>
478         /// <param name="opcodeRet">Found opcode.</param>
479         /// <param name="bytesRet">IEnumerable out param which is used to get the push arguments.</param>
480         /// <returns>Result of operation</returns>
481         public static bool GetOp(ref ByteQueue codeBytes, out opcodetype opcodeRet, out IEnumerable<byte> bytesRet)
482         {
483             bytesRet = new List<byte>();
484             opcodeRet = opcodetype.OP_INVALIDOPCODE;
485
486             opcodetype opcode;
487
488             try
489             {
490                 // Read instruction
491                 opcode = (opcodetype)codeBytes.Get();
492             }
493             catch (ByteQueueException)
494             {
495                 // No instruction found there
496                 return false;
497             }
498
499             // Immediate operand
500             if (opcode <= opcodetype.OP_PUSHDATA4)
501             {
502                 byte[] szBytes = new byte[4] { 0, 0, 0, 0 }; // Zero length
503
504                 try
505                 {
506                     if (opcode < opcodetype.OP_PUSHDATA1)
507                     {
508                         // Zero value opcodes (OP_0, OP_FALSE)
509                         szBytes[3] = (byte)opcode;
510                     }
511                     else if (opcode == opcodetype.OP_PUSHDATA1)
512                     {
513                         // The next byte contains the number of bytes to be pushed onto the stack, 
514                         //    i.e. you have something like OP_PUSHDATA1 0x01 [0x5a]
515                         szBytes[3] = (byte)codeBytes.Get();
516                     }
517                     else if (opcode == opcodetype.OP_PUSHDATA2)
518                     {
519                         // The next two bytes contain the number of bytes to be pushed onto the stack,
520                         //    i.e. now your operation will seem like this: OP_PUSHDATA2 0x00 0x01 [0x5a]
521                         codeBytes.Get(2).CopyTo(szBytes, 2);
522                     }
523                     else if (opcode == opcodetype.OP_PUSHDATA4)
524                     {
525                         // The next four bytes contain the number of bytes to be pushed onto the stack,
526                         //   OP_PUSHDATA4 0x00 0x00 0x00 0x01 [0x5a]
527                         szBytes = codeBytes.Get(4);
528                     }
529                 }
530                 catch (ByteQueueException)
531                 {
532                     // Unable to read operand length
533                     return false;
534                 }
535
536                 int nSize = (int)Interop.BEBytesToUInt32(szBytes);
537
538                 if (nSize > 0)
539                 {
540                     // If nSize is greater than zero then there is some data available
541                     try
542                     {
543                         // Read found number of bytes into list of OP_PUSHDATAn arguments.
544                         bytesRet = codeBytes.GetEnumerable(nSize);
545                     }
546                     catch (ByteQueueException)
547                     {
548                         // Unable to read data
549                         return false;
550                     }
551                 }
552             }
553
554             opcodeRet = opcode;
555
556             return true;
557         }
558
559         /// <summary>
560         /// Convert value bytes into readable representation.
561         /// 
562         /// If list lengh is equal or lesser than 4 bytes then bytes are interpreted as integer value. Otherwise you will get hex representation of supplied data.
563         /// </summary>
564         /// <param name="bytes">Collection of value bytes.</param>
565         /// <returns>Formatted value.</returns>
566         public static string ValueString(IEnumerable<byte> bytes)
567         {
568             StringBuilder sb = new StringBuilder();
569
570             if (bytes.Count() <= 4)
571             {
572                 byte[] valueBytes = new byte[4] { 0, 0, 0, 0 };
573                 bytes.ToArray().CopyTo(valueBytes, valueBytes.Length - bytes.Count());
574
575                 sb.Append(Interop.BEBytesToUInt32(valueBytes));
576             }
577             else
578             {
579                 return Interop.ToHex(bytes);
580             }
581
582             return sb.ToString();
583         }
584
585         /// <summary>
586         /// Convert list of stack items into human readable representation.
587         /// </summary>
588         /// <param name="stackList">List of stack items.</param>
589         /// <returns>Formatted value.</returns>
590         public static string StackString(IList<IList<byte>> stackList)
591         {
592             StringBuilder sb = new StringBuilder();
593             foreach (IList<byte> bytesList in stackList)
594             {
595                 sb.Append(ValueString(bytesList));
596             }
597
598             return sb.ToString();
599         }
600
601         /// <summary>
602         /// Decode small integer
603         /// </summary>
604         /// <param name="opcode">Small integer opcode (OP_0 - OP_16)</param>
605         /// <returns>Small integer</returns>
606         public static int DecodeOP_N(opcodetype opcode)
607         {
608             if (opcode == opcodetype.OP_0)
609                 return 0;
610
611             // Only OP_n opcodes are supported, throw exception otherwise.
612             if (opcode < opcodetype.OP_1 || opcode > opcodetype.OP_16)
613                 throw new Exception("Invalid small integer opcode.");
614             return (int)opcode - (int)(opcodetype.OP_1 - 1);
615         }
616
617         /// <summary>
618         /// Converts small integer into opcode
619         /// </summary>
620         /// <param name="n">Small integer from the range of 0 up to 16.</param>
621         /// <returns>Corresponding opcode.</returns>
622         public static opcodetype EncodeOP_N(int n)
623         {
624             // The n value must be in the range of 0 to 16.
625             if (n < 0 || n > 16)
626                 throw new Exception("Invalid small integer value.");
627             if (n == 0)
628                 return opcodetype.OP_0;
629             return (opcodetype)(opcodetype.OP_1 + n - 1);
630         }
631
632         public static int ScriptSigArgsExpected(txnouttype t, IList<IEnumerable<byte>> solutions)
633         {
634             switch (t)
635             {
636                 case txnouttype.TX_NONSTANDARD:
637                     return -1;
638                 case txnouttype.TX_NULL_DATA:
639                     return 1;
640                 case txnouttype.TX_PUBKEY:
641                     return 1;
642                 case txnouttype.TX_PUBKEYHASH:
643                     return 2;
644                 case txnouttype.TX_MULTISIG:
645                     if (solutions.Count() < 1 || solutions.First().Count() < 1)
646                         return -1;
647                     return solutions.First().First() + 1;
648                 case txnouttype.TX_SCRIPTHASH:
649                     return 1; // doesn't include args needed by the script
650             }
651             return -1;
652         }
653
654         /// <summary>
655         /// Is it a standart type of scriptPubKey?
656         /// </summary>
657         /// <param name="scriptPubKey">CScript instance</param>
658         /// <param name="whichType">utut type</param>
659         /// <returns>Checking result</returns>
660         public static bool IsStandard(CScript scriptPubKey, out txnouttype whichType)
661         {
662             IList<IEnumerable<byte>> solutions = new List<IEnumerable<byte>>();
663
664             if (!Solver(scriptPubKey, out whichType, out solutions))
665             {
666                 // No solutions found
667                 return false;
668             }
669
670             if (whichType == txnouttype.TX_MULTISIG)
671             {
672                 // Additional verification of OP_CHECKMULTISIG arguments
673                 byte m = solutions.First().First();
674                 byte n = solutions.Last().First();
675
676                 // Support up to x-of-3 multisig txns as standard
677                 if (n < 1 || n > 3)
678                 {
679                     return false;
680                 }
681                 if (m < 1 || m > n)
682                 {
683                     return false;
684                 }
685             }
686
687             return whichType != txnouttype.TX_NONSTANDARD;
688         }
689
690         /// <summary>
691         /// Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
692         /// </summary>
693         /// <param name="scriptPubKey">CScript instance</param>
694         /// <param name="typeRet">Output type</param>
695         /// <param name="solutions">Set of solutions</param>
696         /// <returns>Result</returns>
697         public static bool Solver(CScript scriptPubKey, out txnouttype typeRet, out IList<IEnumerable<byte>> solutions)
698         {
699             solutions = new List<IEnumerable<byte>>();
700
701             // There are shortcuts for pay-to-script-hash and pay-to-pubkey-hash, which are more constrained than the other types:
702
703             // It is always OP_HASH160 20 [20 byte hash] OP_EQUAL
704             if (scriptPubKey.IsPayToScriptHash)
705             {
706                 typeRet = txnouttype.TX_SCRIPTHASH;
707
708                 // Take 20 bytes with offset of 2 bytes
709                 IEnumerable<byte> hashBytes = scriptPubKey.Bytes.Skip(2).Take(20);
710                 solutions.Add(hashBytes);
711
712                 return true;
713             }
714
715             // It is always OP_DUP OP_HASH160 20 [20 byte hash] OP_EQUALVERIFY OP_CHECKSIG
716             if (scriptPubKey.IsPayToPubKeyHash)
717             {
718                 typeRet = txnouttype.TX_PUBKEYHASH;
719
720                 // Take 20 bytes with offset of 3 bytes
721                 IEnumerable<byte> hashBytes = scriptPubKey.Bytes.Skip(3).Take(20);
722                 solutions.Add(hashBytes);
723
724                 return true;
725             }
726
727             List<Tuple<txnouttype, IEnumerable<byte>>> templateTuples = new List<Tuple<txnouttype, IEnumerable<byte>>>();
728
729             // Sender provides pubkey, receiver adds signature
730             // [ECDSA public key] OP_CHECKSIG
731             templateTuples.Add(
732                 new Tuple<txnouttype, IEnumerable<byte>>(
733                     txnouttype.TX_PUBKEY,
734                     new byte[] { (byte)opcodetype.OP_PUBKEY, (byte)opcodetype.OP_CHECKSIG })
735             );
736
737             // Sender provides N pubkeys, receivers provides M signatures
738             // N [pubkey1] [pubkey2] ... [pubkeyN] M OP_CHECKMULTISIG
739             // Where N and M are small integer opcodes (OP1 ... OP_16)
740             templateTuples.Add(
741                 new Tuple<txnouttype, IEnumerable<byte>>(
742                     txnouttype.TX_MULTISIG,
743                     new byte[] { (byte)opcodetype.OP_SMALLINTEGER, (byte)opcodetype.OP_PUBKEYS, (byte)opcodetype.OP_SMALLINTEGER, (byte)opcodetype.OP_CHECKMULTISIG })
744             );
745
746             // Data-carrying output
747             // OP_RETURN [up to 80 bytes of data]
748             templateTuples.Add(
749                 new Tuple<txnouttype, IEnumerable<byte>>(
750                     txnouttype.TX_NULL_DATA,
751                     new byte[] { (byte)opcodetype.OP_RETURN, (byte)opcodetype.OP_SMALLDATA })
752             );
753
754             // Nonstandard tx output
755             typeRet = txnouttype.TX_NONSTANDARD;
756
757             foreach (Tuple<txnouttype, IEnumerable<byte>> templateTuple in templateTuples)
758             {
759                 CScript script1 = scriptPubKey;
760                 CScript script2 = new CScript(templateTuple.Item2);
761
762                 opcodetype opcode1, opcode2;
763
764                 // Compare
765                 ByteQueue wl1 = script1.GetByteQUeue();
766                 ByteQueue wl2 = script2.GetByteQUeue();
767
768                 IEnumerable<byte> args1, args2;
769
770                 byte last1 = script1.Bytes.Last();
771                 byte last2 = script2.Bytes.Last();
772
773                 while (true)
774                 {
775                     if (wl1.GetCurrent() == last1 && wl2.GetCurrent() == last2)
776                     {
777                         // Found a match
778                         typeRet = templateTuple.Item1;
779                         if (typeRet == txnouttype.TX_MULTISIG)
780                         {
781                             // Additional checks for TX_MULTISIG:
782                             byte m = solutions.First().First();
783                             byte n = solutions.Last().First();
784
785                             if (m < 1 || n < 1 || m > n || solutions.Count - 2 != n)
786                             {
787                                 return false;
788                             }
789                         }
790                         return true;
791                     }
792
793                     if (!GetOp(ref wl1, out opcode1, out args1))
794                     {
795                         break;
796                     }
797                     if (!GetOp(ref wl2, out opcode2, out args2))
798                     {
799                         break;
800                     }
801
802                     // Template matching opcodes:
803                     if (opcode2 == opcodetype.OP_PUBKEYS)
804                     {
805                         while (args1.Count() >= 33 && args1.Count() <= 120)
806                         {
807                             solutions.Add(args1);
808                             if (!GetOp(ref wl1, out opcode1, out args1))
809                             {
810                                 break;
811                             }
812                         }
813                         if (!GetOp(ref wl2, out opcode2, out args2))
814                             break;
815                         // Normal situation is to fall through
816                         // to other if/else statements
817                     }
818                     if (opcode2 == opcodetype.OP_PUBKEY)
819                     {
820                         if (args1.Count() < 33 || args1.Count() > 120)
821                         {
822                             break;
823                         }
824                         solutions.Add(args1);
825                     }
826                     else if (opcode2 == opcodetype.OP_PUBKEYHASH)
827                     {
828                         if (args1.Count() != 20) // hash160 size
829                         {
830                             break;
831                         }
832                         solutions.Add(args1);
833                     }
834                     else if (opcode2 == opcodetype.OP_SMALLINTEGER)
835                     {
836                         // Single-byte small integer pushed onto solutions
837                         if (opcode1 == opcodetype.OP_0 || (opcode1 >= opcodetype.OP_1 && opcode1 <= opcodetype.OP_16))
838                         {
839                             byte n = (byte)DecodeOP_N(opcode1);
840                             solutions.Add(new byte[] { n });
841                         }
842                         else
843                         {
844                             break;
845                         }
846                     }
847                     else if (opcode2 == opcodetype.OP_SMALLDATA)
848                     {
849                         // small pushdata, <= 80 bytes
850                         if (args1.Count() > 80)
851                         {
852                             break;
853                         }
854                     }
855                     else if (opcode1 != opcode2 || !args1.SequenceEqual(args2))
856                     {
857                         // Others must match exactly
858                         break;
859                     }
860                 }
861             }
862
863             solutions.Clear();
864             typeRet = txnouttype.TX_NONSTANDARD;
865
866             return false;
867         }
868
869         public static Hash256 SignatureHash(CScript scriptCode, CTransaction txTo, int nIn, int nHashType)
870         {
871             if (nIn >= txTo.vin.Length)
872             {
873                 StringBuilder sb = new StringBuilder();
874                 sb.AppendFormat("ERROR: SignatureHash() : nIn={0} out of range\n", nIn);
875                 throw new ArgumentOutOfRangeException("nIn", sb.ToString());
876             }
877
878             CTransaction txTmp = new CTransaction(txTo);
879
880             // In case concatenating two scripts ends up with two codeseparators,
881             // or an extra one at the end, this prevents all those possible incompatibilities.
882             scriptCode.RemovePattern(new byte[] { (byte)opcodetype.OP_CODESEPARATOR });
883
884             // Blank out other inputs' signatures
885             for (int i = 0; i < txTmp.vin.Length; i++)
886             {
887                 txTmp.vin[i].scriptSig = new CScript();
888             }
889             txTmp.vin[nIn].scriptSig = scriptCode;
890
891             // Blank out some of the outputs
892             if ((nHashType & 0x1f) == (int)sigflag.SIGHASH_NONE)
893             {
894                 // Wildcard payee
895                 txTmp.vout = new CTxOut[0];
896
897                 // Let the others update at will
898                 for (int i = 0; i < txTmp.vin.Length; i++)
899                 {
900                     if (i != nIn)
901                     {
902                         txTmp.vin[i].nSequence = 0;
903                     }
904                 }
905             }
906             else if ((nHashType & 0x1f) == (int)sigflag.SIGHASH_SINGLE)
907             {
908                 // Only lock-in the txout payee at same index as txin
909                 int nOut = nIn;
910                 if (nOut >= txTmp.vout.Length)
911                 {
912                     StringBuilder sb = new StringBuilder();
913                     sb.AppendFormat("ERROR: SignatureHash() : nOut={0} out of range\n", nOut);
914                     throw new ArgumentOutOfRangeException("nOut", sb.ToString());
915                 }
916                 Array.Resize(ref txTmp.vout, nOut + 1);
917
918                 for (int i = 0; i < nOut; i++)
919                 {
920                     txTmp.vout[i] = new CTxOut();
921                 }
922
923                 // Let the others update at will
924                 for (int i = 0; i < txTmp.vin.Length; i++)
925                 {
926                     if (i != nIn)
927                     {
928                         txTmp.vin[i].nSequence = 0;
929                     }
930                 }
931             }
932
933             // Blank out other inputs completely, not recommended for open transactions
934             if ((nHashType & (int)sigflag.SIGHASH_ANYONECANPAY) != 0)
935             {
936                 txTmp.vin[0] = txTmp.vin[nIn];
937                 Array.Resize(ref txTmp.vin, 1);
938             }
939
940             // Serialize and hash
941             List<byte> b = new List<byte>();
942             b.AddRange(txTmp.Bytes);
943             b.AddRange(BitConverter.GetBytes(nHashType));
944
945             return Hash256.Compute256(b);
946         }
947
948         public class StackMachineException : Exception
949         {
950             public StackMachineException()
951             {
952             }
953
954             public StackMachineException(string message)
955                 : base(message)
956             {
957             }
958
959             public StackMachineException(string message, Exception inner)
960                 : base(message, inner)
961             {
962             }
963         }
964
965
966         //
967         // Script is a stack machine (like Forth) that evaluates a predicate
968         // returning a bool indicating valid or not.  There are no loops.
969         //
970
971         /// <summary>
972         /// Remove last element from stack
973         /// </summary>
974         /// <param name="stack">Stack reference</param>
975         static void popstack(ref List<IEnumerable<byte>> stack)
976         {
977             int nCount = stack.Count;
978             if (nCount == 0)
979                 throw new StackMachineException("popstack() : stack empty");
980             stack.RemoveAt(nCount - 1);
981         }
982
983         /// <summary>
984         /// Get element at specified stack depth
985         /// </summary>
986         /// <param name="stack">Stack reference</param>
987         /// <param name="nDepth">Depth</param>
988         /// <returns>Byte sequence</returns>
989         static IEnumerable<byte> stacktop(ref List<IEnumerable<byte>> stack, int nDepth)
990         {
991             int nStackElement = stack.Count + nDepth;
992
993             if (nDepth >= 0)
994             {
995                 StringBuilder sb = new StringBuilder();
996                 sb.AppendFormat("stacktop() : positive depth ({0}) has no sense.", nDepth);
997
998                 throw new StackMachineException(sb.ToString());
999             }
1000
1001             if (nStackElement < 0)
1002             {
1003                 StringBuilder sb = new StringBuilder();
1004                 sb.AppendFormat("stacktop() : nDepth={0} exceeds real stack depth ({1})", nDepth, stack.Count);
1005
1006                 throw new StackMachineException(sb.ToString());
1007             }
1008
1009             return stack[nStackElement];
1010         }
1011
1012         /// <summary>
1013         /// Cast argument to boolean value
1014         /// </summary>
1015         /// <param name="value">Some byte sequence</param>
1016         /// <returns></returns>
1017         private static bool CastToBool(IEnumerable<byte> arg)
1018         {
1019             byte[] value = arg.ToArray();
1020
1021             for (var i = 0; i < value.Length; i++)
1022             {
1023                 if (value[i] != 0)
1024                 {
1025                     // Can be negative zero
1026                     if (i == value.Length - 1 && value[i] == 0x80)
1027                     {
1028                         return false;
1029                     }
1030
1031                     return true;
1032                 }
1033             }
1034
1035             return false;
1036         }
1037
1038         /// <summary>
1039         /// Cast argument to integer value
1040         /// </summary>
1041         /// <param name="value"></param>
1042         /// <returns></returns>
1043         private static BigInteger CastToBigInteger(IEnumerable<byte> value)
1044         {
1045             if (value.Count() > 4)
1046             {
1047                 throw new StackMachineException("CastToBigInteger() : overflow");
1048             }
1049
1050             return new BigInteger(value.ToArray());
1051         }
1052
1053         static bool EvalScript(ref List<IEnumerable<byte>> stack, CScript script, CTransaction txTo, int nIn, int flags, int nHashType)
1054         {
1055             ByteQueue pc = script.GetByteQUeue();
1056
1057             ByteQueue pbegincodehash = script.GetByteQUeue();
1058
1059             opcodetype opcode;
1060
1061             List<bool> vfExec = new List<bool>();
1062             List<IEnumerable<byte>> altstack = new List<IEnumerable<byte>>();
1063
1064             byte[] vchFalse = new byte[0];
1065             byte[] vchTrue = new byte[] { 0x01 };
1066
1067             if (script.Bytes.Count() > 10000)
1068             {
1069                 return false;
1070             }
1071
1072             int nOpCount = 0;
1073
1074             while (true)
1075             {
1076                 bool fExec = false;
1077                 foreach (bool fValue in vfExec)
1078                 {
1079                     if (!fValue)
1080                     {
1081                         fExec = true;
1082                         break;
1083                     }
1084                 }
1085
1086                 //
1087                 // Read instruction
1088                 //
1089                 IEnumerable<byte> pushArg;
1090                 if (!GetOp(ref pc, out opcode, out pushArg))
1091                 {
1092                     return false;
1093                 }
1094
1095                 if (pushArg.Count() > 520) // Check against MAX_SCRIPT_ELEMENT_SIZE
1096                 {
1097                     return false;
1098                 }
1099
1100                 if (opcode > opcodetype.OP_16 && ++nOpCount > 201)
1101                 {
1102                     return false;
1103                 }
1104
1105                 if (fExec && 0 <= opcode && opcode <= opcodetype.OP_PUSHDATA4)
1106                 {
1107                     // Push argument to stack
1108                     stack.Add(pushArg);
1109                 }
1110                 else if (fExec || (opcodetype.OP_IF <= opcode && opcode <= opcodetype.OP_ENDIF))
1111                     switch (opcode)
1112                     {
1113                         //
1114                         // Disabled opcodes
1115                         //
1116                         case opcodetype.OP_CAT:
1117                         case opcodetype.OP_SUBSTR:
1118                         case opcodetype.OP_LEFT:
1119                         case opcodetype.OP_RIGHT:
1120                         case opcodetype.OP_INVERT:
1121                         case opcodetype.OP_AND:
1122                         case opcodetype.OP_OR:
1123                         case opcodetype.OP_XOR:
1124                         case opcodetype.OP_2MUL:
1125                         case opcodetype.OP_2DIV:
1126                         case opcodetype.OP_MUL:
1127                         case opcodetype.OP_DIV:
1128                         case opcodetype.OP_MOD:
1129                         case opcodetype.OP_LSHIFT:
1130                         case opcodetype.OP_RSHIFT:
1131                             return false;
1132
1133                         //
1134                         // Push value
1135                         //
1136                         case opcodetype.OP_1NEGATE:
1137                         case opcodetype.OP_1:
1138                         case opcodetype.OP_2:
1139                         case opcodetype.OP_3:
1140                         case opcodetype.OP_4:
1141                         case opcodetype.OP_5:
1142                         case opcodetype.OP_6:
1143                         case opcodetype.OP_7:
1144                         case opcodetype.OP_8:
1145                         case opcodetype.OP_9:
1146                         case opcodetype.OP_10:
1147                         case opcodetype.OP_11:
1148                         case opcodetype.OP_12:
1149                         case opcodetype.OP_13:
1150                         case opcodetype.OP_14:
1151                         case opcodetype.OP_15:
1152                         case opcodetype.OP_16:
1153                             {
1154                                 // ( -- value)
1155                                 BigInteger bn = new BigInteger((int)opcode - (int)(opcodetype.OP_1 - 1));
1156                                 stack.Add(bn.ToByteArray());
1157                             }
1158                             break;
1159
1160
1161                         //
1162                         // Control
1163                         //
1164                         case opcodetype.OP_NOP:
1165                         case opcodetype.OP_NOP1:
1166                         case opcodetype.OP_NOP2:
1167                         case opcodetype.OP_NOP3:
1168                         case opcodetype.OP_NOP4:
1169                         case opcodetype.OP_NOP5:
1170                         case opcodetype.OP_NOP6:
1171                         case opcodetype.OP_NOP7:
1172                         case opcodetype.OP_NOP8:
1173                         case opcodetype.OP_NOP9:
1174                         case opcodetype.OP_NOP10:
1175                             break;
1176
1177                         case opcodetype.OP_IF:
1178                         case opcodetype.OP_NOTIF:
1179                             {
1180                                 // <expression> if [statements] [else [statements]] endif
1181                                 bool fValue = false;
1182                                 if (fExec)
1183                                 {
1184                                     if (stack.Count() < 1)
1185                                     {
1186                                         return false;
1187                                     }
1188                                     IEnumerable<byte> vch = stacktop(ref stack, -1);
1189                                     fValue = CastToBool(vch);
1190                                     if (opcode == opcodetype.OP_NOTIF)
1191                                     {
1192                                         fValue = !fValue;
1193                                     }
1194                                     popstack(ref stack);
1195                                 }
1196                                 vfExec.Add(fValue);
1197                             }
1198                             break;
1199
1200                         case opcodetype.OP_ELSE:
1201                             {
1202                                 int nExecCount = vfExec.Count();
1203                                 if (nExecCount == 0)
1204                                 {
1205                                     return false;
1206                                 }
1207                                 vfExec[nExecCount - 1] = !vfExec[nExecCount - 1];
1208                             }
1209                             break;
1210
1211                         case opcodetype.OP_ENDIF:
1212                             {
1213                                 int nExecCount = vfExec.Count();
1214                                 if (nExecCount == 0)
1215                                 {
1216                                     return false;
1217                                 }
1218                                 vfExec.RemoveAt(nExecCount - 1);
1219                             }
1220                             break;
1221
1222                         case opcodetype.OP_VERIFY:
1223                             {
1224                                 // (true -- ) or
1225                                 // (false -- false) and return
1226                                 if (stack.Count() < 1)
1227                                 {
1228                                     return false;
1229                                 }
1230
1231                                 bool fValue = CastToBool(stacktop(ref stack, -1));
1232                                 if (fValue)
1233                                 {
1234                                     popstack(ref stack);
1235                                 }
1236                                 else
1237                                 {
1238                                     return false;
1239                                 }
1240                             }
1241                             break;
1242
1243                         case opcodetype.OP_RETURN:
1244                             return false;
1245                         //
1246                         // Stack ops
1247                         //
1248                         case opcodetype.OP_TOALTSTACK:
1249                             {
1250                                 if (stack.Count() < 1)
1251                                 {
1252                                     return false;
1253                                 }
1254                                 altstack.Add(stacktop(ref stack, -1));
1255                                 popstack(ref stack);
1256                             }
1257                             break;
1258
1259                         case opcodetype.OP_FROMALTSTACK:
1260                             {
1261                                 if (altstack.Count() < 1)
1262                                 {
1263                                     return false;
1264                                 }
1265                                 stack.Add(stacktop(ref stack, -1));
1266                                 popstack(ref altstack);
1267                             }
1268                             break;
1269
1270                         case opcodetype.OP_2DROP:
1271                             {
1272                                 // (x1 x2 -- )
1273                                 if (stack.Count() < 2)
1274                                 {
1275                                     return false;
1276                                 }
1277                                 popstack(ref stack);
1278                                 popstack(ref stack);
1279                             }
1280                             break;
1281
1282                         case opcodetype.OP_2DUP:
1283                             {
1284                                 // (x1 x2 -- x1 x2 x1 x2)
1285                                 if (stack.Count() < 2)
1286                                 {
1287                                     return false;
1288                                 }
1289                                 IEnumerable<byte> vch1 = stacktop(ref stack, -2);
1290                                 IEnumerable<byte> vch2 = stacktop(ref stack, -1);
1291                                 stack.Add(vch1);
1292                                 stack.Add(vch2);
1293                             }
1294                             break;
1295
1296                         case opcodetype.OP_3DUP:
1297                             {
1298                                 // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
1299                                 if (stack.Count() < 3)
1300                                 {
1301                                     return false;
1302                                 }
1303                                 IEnumerable<byte> vch1 = stacktop(ref stack, -3);
1304                                 IEnumerable<byte> vch2 = stacktop(ref stack, -2);
1305                                 IEnumerable<byte> vch3 = stacktop(ref stack, -1);
1306                                 stack.Add(vch1);
1307                                 stack.Add(vch2);
1308                                 stack.Add(vch3);
1309                             }
1310                             break;
1311
1312                         case opcodetype.OP_2OVER:
1313                             {
1314                                 // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
1315                                 if (stack.Count() < 4)
1316                                 {
1317                                     return false;
1318                                 }
1319                                 IEnumerable<byte> vch1 = stacktop(ref stack, -4);
1320                                 IEnumerable<byte> vch2 = stacktop(ref stack, -3);
1321                                 stack.Add(vch1);
1322                                 stack.Add(vch2);
1323                             }
1324                             break;
1325
1326                         case opcodetype.OP_2ROT:
1327                             {
1328                                 int nStackDepth = stack.Count();
1329                                 // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
1330                                 if (nStackDepth < 6)
1331                                 {
1332                                     return false;
1333                                 }
1334                                 IEnumerable<byte> vch1 = stacktop(ref stack, -6);
1335                                 IEnumerable<byte> vch2 = stacktop(ref stack, -5);
1336                                 stack.RemoveRange(nStackDepth - 6, 2);
1337                                 stack.Add(vch1);
1338                                 stack.Add(vch2);
1339                             }
1340                             break;
1341
1342                         case opcodetype.OP_2SWAP:
1343                             {
1344                                 // (x1 x2 x3 x4 -- x3 x4 x1 x2)
1345                                 int nStackDepth = stack.Count();
1346                                 if (nStackDepth < 4)
1347                                 {
1348                                     return false;
1349                                 }
1350                                 stack.Swap(nStackDepth - 4, nStackDepth - 2);
1351                                 stack.Swap(nStackDepth - 3, nStackDepth - 1);
1352                             }
1353                             break;
1354
1355                         case opcodetype.OP_IFDUP:
1356                             {
1357                                 // (x - 0 | x x)
1358                                 if (stack.Count() < 1)
1359                                 {
1360                                     return false;
1361                                 }
1362
1363                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1364
1365                                 if (CastToBool(vch))
1366                                 {
1367                                     stack.Add(vch);
1368                                 }
1369                             }
1370                             break;
1371
1372                         case opcodetype.OP_DEPTH:
1373                             {
1374                                 // -- stacksize
1375                                 BigInteger bn = new BigInteger((ushort)stack.Count());
1376                                 stack.Add(bn.ToByteArray());
1377                             }
1378                             break;
1379
1380                         case opcodetype.OP_DROP:
1381                             {
1382                                 // (x -- )
1383                                 if (stack.Count() < 1)
1384                                 {
1385                                     return false;
1386                                 }
1387
1388                                 popstack(ref stack);
1389                             }
1390                             break;
1391
1392                         case opcodetype.OP_DUP:
1393                             {
1394                                 // (x -- x x)
1395                                 if (stack.Count() < 1)
1396                                 {
1397                                     return false;
1398                                 }
1399
1400                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1401                                 stack.Add(vch);
1402                             }
1403                             break;
1404
1405                         case opcodetype.OP_NIP:
1406                             {
1407                                 // (x1 x2 -- x2)
1408                                 int nStackDepth = stack.Count();
1409                                 if (nStackDepth < 2)
1410                                 {
1411                                     return false;
1412                                 }
1413
1414                                 stack.RemoveAt(nStackDepth - 2);
1415                             }
1416                             break;
1417
1418                         case opcodetype.OP_OVER:
1419                             {
1420                                 // (x1 x2 -- x1 x2 x1)
1421                                 if (stack.Count() < 2)
1422                                 {
1423                                     return false;
1424                                 }
1425
1426                                 IEnumerable<byte> vch = stacktop(ref stack, -2);
1427                                 stack.Add(vch);
1428                             }
1429                             break;
1430
1431                         case opcodetype.OP_PICK:
1432                         case opcodetype.OP_ROLL:
1433                             {
1434                                 // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
1435                                 // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
1436
1437                                 int nStackDepth = stack.Count();
1438                                 if (nStackDepth < 2)
1439                                 {
1440                                     return false;
1441                                 }
1442
1443                                 int n = (int)CastToBigInteger(stacktop(ref stack, -1));
1444                                 popstack(ref stack);
1445
1446                                 if (n < 0 || n >= stack.Count())
1447                                 {
1448                                     return false;
1449                                 }
1450
1451                                 IEnumerable<byte> vch = stacktop(ref stack, -n - 1);
1452                                 if (opcode == opcodetype.OP_ROLL)
1453                                 {
1454                                     stack.RemoveAt(nStackDepth - n - 1);
1455                                 }
1456
1457                                 stack.Add(vch);
1458                             }
1459                             break;
1460
1461                         case opcodetype.OP_ROT:
1462                             {
1463                                 // (x1 x2 x3 -- x2 x3 x1)
1464                                 //  x2 x1 x3  after first swap
1465                                 //  x2 x3 x1  after second swap
1466                                 int nStackDepth = stack.Count();
1467                                 if (nStackDepth < 3)
1468                                 {
1469                                     return false;
1470                                 }
1471                                 stack.Swap(nStackDepth - 3, nStackDepth - 2);
1472                                 stack.Swap(nStackDepth - 2, nStackDepth - 1);
1473
1474                             }
1475                             break;
1476
1477                         case opcodetype.OP_SWAP:
1478                             {
1479                                 // (x1 x2 -- x2 x1)
1480                                 int nStackDepth = stack.Count();
1481                                 if (nStackDepth < 2)
1482                                 {
1483                                     return false;
1484                                 }
1485                                 stack.Swap(nStackDepth - 2, nStackDepth - 1);
1486                             }
1487                             break;
1488
1489                         case opcodetype.OP_TUCK:
1490                             {
1491                                 // (x1 x2 -- x2 x1 x2)
1492                                 int nStackDepth = stack.Count();
1493                                 if (nStackDepth < 2)
1494                                 {
1495                                     return false;
1496                                 }
1497                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1498                                 stack.Insert(nStackDepth - 2, vch);
1499                             }
1500                             break;
1501
1502
1503                         case opcodetype.OP_SIZE:
1504                             {
1505                                 // (in -- in size)
1506                                 if (stack.Count() < 1)
1507                                 {
1508                                     return false;
1509                                 }
1510
1511                                 BigInteger bnSize = new BigInteger((ushort)stacktop(ref stack, -1).Count());
1512                                 stack.Add(bnSize.ToByteArray());
1513                             }
1514                             break;
1515
1516
1517                         //
1518                         // Bitwise logic
1519                         //
1520                         case opcodetype.OP_EQUAL:
1521                         case opcodetype.OP_EQUALVERIFY:
1522                             //case opcodetype.OP_NOTEQUAL: // use OP_NUMNOTEQUAL
1523                             {
1524                                 // (x1 x2 - bool)
1525                                 if (stack.Count() < 2)
1526                                 {
1527                                     return false;
1528                                 }
1529
1530                                 IEnumerable<byte> vch1 = stacktop(ref stack, -2);
1531                                 IEnumerable<byte> vch2 = stacktop(ref stack, -1);
1532                                 bool fEqual = (vch1 == vch2);
1533                                 // OP_NOTEQUAL is disabled because it would be too easy to say
1534                                 // something like n != 1 and have some wiseguy pass in 1 with extra
1535                                 // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
1536                                 //if (opcode == opcodetype.OP_NOTEQUAL)
1537                                 //    fEqual = !fEqual;
1538                                 popstack(ref stack);
1539                                 popstack(ref stack);
1540                                 stack.Add(fEqual ? vchTrue : vchFalse);
1541
1542                                 if (opcode == opcodetype.OP_EQUALVERIFY)
1543                                 {
1544                                     if (fEqual)
1545                                     {
1546                                         popstack(ref stack);
1547                                     }
1548                                     else
1549                                     {
1550                                         return false;
1551                                     }
1552                                 }
1553                             }
1554                             break;
1555
1556
1557                         //
1558                         // Numeric
1559                         //
1560                         case opcodetype.OP_1ADD:
1561                         case opcodetype.OP_1SUB:
1562                         case opcodetype.OP_NEGATE:
1563                         case opcodetype.OP_ABS:
1564                         case opcodetype.OP_NOT:
1565                         case opcodetype.OP_0NOTEQUAL:
1566                             {
1567                                 // (in -- out)
1568                                 if (stack.Count() < 1)
1569                                 {
1570                                     return false;
1571                                 }
1572
1573                                 BigInteger bn = CastToBigInteger(stacktop(ref stack, -1));
1574                                 switch (opcode)
1575                                 {
1576                                     case opcodetype.OP_1ADD:
1577                                         bn = bn + 1;
1578                                         break;
1579                                     case opcodetype.OP_1SUB:
1580                                         bn = bn - 1;
1581                                         break;
1582                                     case opcodetype.OP_NEGATE:
1583                                         bn = -bn;
1584                                         break;
1585                                     case opcodetype.OP_ABS:
1586                                         bn = BigInteger.Abs(bn);
1587                                         break;
1588                                     case opcodetype.OP_NOT:
1589                                         bn = bn == 0 ? 1 : 0;
1590                                         break;
1591                                     case opcodetype.OP_0NOTEQUAL:
1592                                         bn = bn != 0 ? 1 : 0;
1593                                         break;
1594
1595                                     default:
1596                                         throw new StackMachineException("invalid opcode");
1597                                         break;
1598                                 }
1599
1600                                 popstack(ref stack);
1601                                 stack.Add(bn.ToByteArray());
1602                             }
1603                             break;
1604
1605                         case opcodetype.OP_ADD:
1606                         case opcodetype.OP_SUB:
1607                         case opcodetype.OP_BOOLAND:
1608                         case opcodetype.OP_BOOLOR:
1609                         case opcodetype.OP_NUMEQUAL:
1610                         case opcodetype.OP_NUMEQUALVERIFY:
1611                         case opcodetype.OP_NUMNOTEQUAL:
1612                         case opcodetype.OP_LESSTHAN:
1613                         case opcodetype.OP_GREATERTHAN:
1614                         case opcodetype.OP_LESSTHANOREQUAL:
1615                         case opcodetype.OP_GREATERTHANOREQUAL:
1616                         case opcodetype.OP_MIN:
1617                         case opcodetype.OP_MAX:
1618                             {
1619                                 // (x1 x2 -- out)
1620                                 if (stack.Count() < 2)
1621                                 {
1622                                     return false;
1623                                 }
1624
1625                                 BigInteger bn1 = CastToBigInteger(stacktop(ref stack, -2));
1626                                 BigInteger bn2 = CastToBigInteger(stacktop(ref stack, -1));
1627                                 BigInteger bn = 0;
1628
1629                                 switch (opcode)
1630                                 {
1631                                     case opcodetype.OP_ADD:
1632                                         bn = bn1 + bn2;
1633                                         break;
1634                                     case opcodetype.OP_SUB:
1635                                         bn = bn1 - bn2;
1636                                         break;
1637                                     case opcodetype.OP_BOOLAND:
1638                                         bn = (bn1 != 0 && bn2 != 0) ? 1 : 0;
1639                                         break;
1640                                     case opcodetype.OP_BOOLOR:
1641                                         bn = (bn1 != 0 || bn2 != 0) ? 1 : 0;
1642                                         break;
1643                                     case opcodetype.OP_NUMEQUAL:
1644                                         bn = (bn1 == bn2) ? 1 : 0;
1645                                         break;
1646                                     case opcodetype.OP_NUMEQUALVERIFY:
1647                                         bn = (bn1 == bn2) ? 1 : 0;
1648                                         break;
1649                                     case opcodetype.OP_NUMNOTEQUAL:
1650                                         bn = (bn1 != bn2) ? 1 : 0;
1651                                         break;
1652                                     case opcodetype.OP_LESSTHAN:
1653                                         bn = (bn1 < bn2) ? 1 : 0;
1654                                         break;
1655                                     case opcodetype.OP_GREATERTHAN:
1656                                         bn = (bn1 > bn2) ? 1 : 0;
1657                                         break;
1658                                     case opcodetype.OP_LESSTHANOREQUAL:
1659                                         bn = (bn1 <= bn2) ? 1 : 0;
1660                                         break;
1661                                     case opcodetype.OP_GREATERTHANOREQUAL:
1662                                         bn = (bn1 >= bn2) ? 1 : 0;
1663                                         break;
1664                                     case opcodetype.OP_MIN:
1665                                         bn = (bn1 < bn2 ? bn1 : bn2);
1666                                         break;
1667                                     case opcodetype.OP_MAX:
1668                                         bn = (bn1 > bn2 ? bn1 : bn2);
1669                                         break;
1670
1671                                     default:
1672                                         throw new StackMachineException("invalid opcode");
1673                                         break;
1674                                 }
1675
1676                                 popstack(ref stack);
1677                                 popstack(ref stack);
1678                                 stack.Add(bn.ToByteArray());
1679
1680                                 if (opcode == opcodetype.OP_NUMEQUALVERIFY)
1681                                 {
1682                                     if (CastToBool(stacktop(ref stack, -1)))
1683                                     {
1684                                         popstack(ref stack);
1685                                     }
1686                                     else
1687                                     {
1688                                         return false;
1689                                     }
1690                                 }
1691                             }
1692                             break;
1693
1694                         case opcodetype.OP_WITHIN:
1695                             {
1696                                 // (x min max -- out)
1697                                 if (stack.Count() < 3)
1698                                     return false;
1699                                 BigInteger bn1 = CastToBigInteger(stacktop(ref stack, -3));
1700                                 BigInteger bn2 = CastToBigInteger(stacktop(ref stack, -2));
1701                                 BigInteger bn3 = CastToBigInteger(stacktop(ref stack, -1));
1702                                 bool fValue = (bn2 <= bn1 && bn1 < bn3);
1703                                 popstack(ref stack);
1704                                 popstack(ref stack);
1705                                 popstack(ref stack);
1706                                 stack.Add(fValue ? vchTrue : vchFalse);
1707                             }
1708                             break;
1709
1710
1711                         //
1712                         // Crypto
1713                         //
1714                         case opcodetype.OP_RIPEMD160:
1715                         case opcodetype.OP_SHA1:
1716                         case opcodetype.OP_SHA256:
1717                         case opcodetype.OP_HASH160:
1718                         case opcodetype.OP_HASH256:
1719                             {
1720                                 // (in -- hash)
1721                                 if (stack.Count() < 1)
1722                                     return false;
1723                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1724                                 IEnumerable<byte> vchHash = null;
1725                                 if (opcode == opcodetype.OP_RIPEMD160)
1726                                 {
1727                                     RIPEMD160 hash = RIPEMD160.Compute160(vch);
1728                                     vchHash = hash.hashBytes;
1729                                 }
1730                                 else if (opcode == opcodetype.OP_SHA1)
1731                                 {
1732                                     SHA1 hash = SHA1.Compute1(vch);
1733                                     vchHash = hash.hashBytes;
1734                                 }
1735                                 else if (opcode == opcodetype.OP_SHA256)
1736                                 {
1737                                     SHA256 hash = SHA256.Compute256(vch);
1738                                     vchHash = hash.hashBytes;
1739                                 }
1740                                 else if (opcode == opcodetype.OP_HASH160)
1741                                 {
1742                                     Hash160 hash = Hash160.Compute160(vch);
1743                                     vchHash = hash.hashBytes;
1744                                 }
1745                                 else if (opcode == opcodetype.OP_HASH256)
1746                                 {
1747                                     Hash256 hash = Hash256.Compute256(vch);
1748                                     vchHash = hash.hashBytes;
1749                                 }
1750                                 popstack(ref stack);
1751                                 stack.Add(vchHash);
1752                             }
1753                             break;
1754
1755                         case opcodetype.OP_CODESEPARATOR:
1756                             {
1757                                 // Hash starts after the code separator
1758                                 pbegincodehash = pc;
1759                             }
1760                             break;
1761
1762                         case opcodetype.OP_CHECKSIG:
1763                         case opcodetype.OP_CHECKSIGVERIFY:
1764                             {
1765                                 // (sig pubkey -- bool)
1766                                 if (stack.Count() < 2)
1767                                 {
1768                                     return false;
1769                                 }
1770
1771                                 IList<byte> sigBytes = stacktop(ref stack, -2).ToList();
1772                                 IList<byte> pubkeyBytes = stacktop(ref stack, -1).ToList();
1773
1774                                 // Subset of script starting at the most recent codeseparator
1775                                 CScript scriptCode = new CScript(script.Bytes.Skip(pbegincodehash.CurrentIndex));
1776
1777                                 // There's no way for a signature to sign itself
1778                                 scriptCode.RemovePattern(sigBytes);
1779
1780                                 bool fSuccess = IsCanonicalSignature(sigBytes, flags) && IsCanonicalPubKey(pubkeyBytes.ToList(), flags) && CheckSig(sigBytes, pubkeyBytes, scriptCode, txTo, nIn, nHashType, flags);
1781
1782                                 popstack(ref stack);
1783                                 popstack(ref stack);
1784                                 stack.Add(fSuccess ? vchTrue : vchFalse);
1785                                 if (opcode == opcodetype.OP_CHECKSIGVERIFY)
1786                                 {
1787                                     if (fSuccess)
1788                                     {
1789                                         popstack(ref stack);
1790                                     }
1791                                     else
1792                                     {
1793                                         return false;
1794                                     }
1795                                 }
1796                             }
1797                             break;
1798
1799                         case opcodetype.OP_CHECKMULTISIG:
1800                         case opcodetype.OP_CHECKMULTISIGVERIFY:
1801                             {
1802                                 // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
1803
1804                                 int i = 1;
1805                                 if (stack.Count() < i)
1806                                 {
1807                                     return false;
1808                                 }
1809
1810                                 int nKeysCount = (int)CastToBigInteger(stacktop(ref stack, -i));
1811                                 if (nKeysCount < 0 || nKeysCount > 20)
1812                                 {
1813                                     return false;
1814                                 }
1815                                 nOpCount += nKeysCount;
1816                                 if (nOpCount > 201)
1817                                 {
1818                                     return false;
1819                                 }
1820                                 int ikey = ++i;
1821                                 i += nKeysCount;
1822                                 if (stack.Count() < i)
1823                                 {
1824                                     return false;
1825                                 }
1826
1827                                 int nSigsCount = (int)CastToBigInteger(stacktop(ref stack, -i));
1828                                 if (nSigsCount < 0 || nSigsCount > nKeysCount)
1829                                 {
1830                                     return false;
1831                                 }
1832                                 int isig = ++i;
1833                                 i += nSigsCount;
1834                                 if (stack.Count() < i)
1835                                 {
1836                                     return false;
1837                                 }
1838
1839                                 // Subset of script starting at the most recent codeseparator
1840                                 CScript scriptCode = new CScript(script.Bytes.Skip(pbegincodehash.CurrentIndex));
1841
1842                                 // There is no way for a signature to sign itself, so we need to drop the signatures
1843                                 for (int k = 0; k < nSigsCount; k++)
1844                                 {
1845                                     IEnumerable<byte> vchSig = stacktop(ref stack, -isig - k);
1846                                     scriptCode.RemovePattern(vchSig.ToList());
1847                                 }
1848
1849                                 bool fSuccess = true;
1850                                 while (fSuccess && nSigsCount > 0)
1851                                 {
1852                                     IList<byte> sigBytes = stacktop(ref stack, -isig).ToList();
1853                                     IList<byte> pubKeyBytes = stacktop(ref stack, -ikey).ToList();
1854
1855                                     // Check signature
1856                                     bool fOk = IsCanonicalSignature(sigBytes, flags) && IsCanonicalPubKey(pubKeyBytes.ToList(), flags) && CheckSig(sigBytes, pubKeyBytes, scriptCode, txTo, nIn, nHashType, flags);
1857
1858                                     if (fOk)
1859                                     {
1860                                         isig++;
1861                                         nSigsCount--;
1862                                     }
1863                                     ikey++;
1864                                     nKeysCount--;
1865
1866                                     // If there are more signatures left than keys left,
1867                                     // then too many signatures have failed
1868                                     if (nSigsCount > nKeysCount)
1869                                     {
1870                                         fSuccess = false;
1871                                     }
1872                                 }
1873
1874                                 while (i-- > 1)
1875                                 {
1876                                     popstack(ref stack);
1877                                 }
1878
1879                                 // A bug causes CHECKMULTISIG to consume one extra argument
1880                                 // whose contents were not checked in any way.
1881                                 //
1882                                 // Unfortunately this is a potential source of mutability,
1883                                 // so optionally verify it is exactly equal to zero prior
1884                                 // to removing it from the stack.
1885                                 if (stack.Count() < 1)
1886                                 {
1887                                     return false;
1888                                 }
1889                                 if ((flags & (int)scriptflag.SCRIPT_VERIFY_NULLDUMMY) != 0 && stacktop(ref stack, -1).Count() != 0)
1890                                 {
1891                                     return false; // CHECKMULTISIG dummy argument not null
1892                                 }
1893                                 popstack(ref stack);
1894
1895                                 stack.Add(fSuccess ? vchTrue : vchFalse);
1896
1897                                 if (opcode == opcodetype.OP_CHECKMULTISIGVERIFY)
1898                                 {
1899                                     if (fSuccess)
1900                                     {
1901                                         popstack(ref stack);
1902                                     }
1903                                     else
1904                                     {
1905                                         return false;
1906                                     }
1907                                 }
1908                             }
1909                             break;
1910
1911                         default:
1912                             return false;
1913                     }
1914
1915                 // Size limits
1916                 if (stack.Count() + altstack.Count() > 1000)
1917                 {
1918                     return false;
1919                 }
1920             }
1921
1922
1923             if (vfExec.Count() == 0)
1924             {
1925                 return false;
1926             }
1927
1928             return true;
1929         }
1930
1931
1932         static bool IsCanonicalPubKey(IList<byte> pubKeyBytes, int flags)
1933         {
1934             if ((flags & (int)scriptflag.SCRIPT_VERIFY_STRICTENC) == 0)
1935                 return true;
1936
1937             if (pubKeyBytes.Count() < 33)
1938                 return false;  // Non-canonical public key: too short
1939             if (pubKeyBytes[0] == 0x04)
1940             {
1941                 if (pubKeyBytes.Count() != 65)
1942                     return false; // Non-canonical public key: invalid length for uncompressed key
1943             }
1944             else if (pubKeyBytes[0] == 0x02 || pubKeyBytes[0] == 0x03)
1945             {
1946                 if (pubKeyBytes.Count() != 33)
1947                     return false; // Non-canonical public key: invalid length for compressed key
1948             }
1949             else
1950             {
1951                 return false; // Non-canonical public key: compressed nor uncompressed
1952             }
1953             return true;
1954         }
1955
1956         static bool IsCanonicalSignature(IList<byte> sigBytes, int flags)
1957         {
1958             // STUB
1959
1960             return true;
1961         }
1962
1963
1964         static bool CheckSig(IList<byte> sigBytes, IList<byte> pubKeyBytes, CScript scriptCode, CTransaction txTo, int nIn, int nHashType, int flags)
1965         {
1966             // STUB
1967             return true;
1968         }
1969
1970 };
1971 }