EvaluateScript and IsCanonicalPubKey implementation, IsCanonicalSignature/CheckSig...
[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})", 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", nDepth);
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                         return false;
1028
1029                     return true;
1030                 }
1031             }
1032
1033             return false;
1034         }
1035
1036         /// <summary>
1037         /// Cast argument to integer value
1038         /// </summary>
1039         /// <param name="value"></param>
1040         /// <returns></returns>
1041         private static BigInteger CastToBigInteger(IEnumerable<byte> value)
1042         {
1043             if (value.Count() > 4)
1044             {
1045                 throw new StackMachineException("CastToBigInteger() : overflow");
1046             }
1047
1048             return new BigInteger(value.ToArray());
1049         }
1050
1051         static bool EvalScript(ref List<IEnumerable<byte>> stack, CScript script, CTransaction txTo, int nIn, int flags, int nHashType)
1052         {
1053             ByteQueue pc = script.GetByteQUeue();
1054
1055             ByteQueue pbegincodehash = script.GetByteQUeue();
1056
1057             opcodetype opcode;
1058             IEnumerable<byte> vchPushValue;
1059
1060             List<bool> vfExec = new List<bool>();
1061             List<IEnumerable<byte>> altstack = new List<IEnumerable<byte>>();
1062
1063             byte[] vchFalse = new byte[0];
1064             byte[] vchTrue = new byte[] { 0x01 };
1065
1066             if (script.Bytes.Count() > 10000)
1067             {
1068                 return false;
1069             }
1070
1071             int nOpCount = 0;
1072
1073             while (true)
1074             {
1075                 bool fExec = false;
1076                 foreach (bool fValue in vfExec)
1077                 {
1078                     if (!fValue)
1079                     {
1080                         fExec = true;
1081                         break;
1082                     }
1083                 }
1084
1085                 //
1086                 // Read instruction
1087                 //
1088                 if (!GetOp(ref pc, out opcode, out vchPushValue))
1089                     return false;
1090                 if (vchPushValue.Count() > 520) // Check against MAX_SCRIPT_ELEMENT_SIZE
1091                     return false;
1092                 if (opcode > opcodetype.OP_16 && ++nOpCount > 201)
1093                     return false;
1094
1095                 if (opcode == opcodetype.OP_CAT ||
1096                     opcode == opcodetype.OP_SUBSTR ||
1097                     opcode == opcodetype.OP_LEFT ||
1098                     opcode == opcodetype.OP_RIGHT ||
1099                     opcode == opcodetype.OP_INVERT ||
1100                     opcode == opcodetype.OP_AND ||
1101                     opcode == opcodetype.OP_OR ||
1102                     opcode == opcodetype.OP_XOR ||
1103                     opcode == opcodetype.OP_2MUL ||
1104                     opcode == opcodetype.OP_2DIV ||
1105                     opcode == opcodetype.OP_MUL ||
1106                     opcode == opcodetype.OP_DIV ||
1107                     opcode == opcodetype.OP_MOD ||
1108                     opcode == opcodetype.OP_LSHIFT ||
1109                     opcode == opcodetype.OP_RSHIFT)
1110                     return false; // Disabled opcodes.
1111
1112                 if (fExec && 0 <= opcode && opcode <= opcodetype.OP_PUSHDATA4)
1113                 {
1114                     stack.Add(vchPushValue);
1115                 }
1116                 else if (fExec || (opcodetype.OP_IF <= opcode && opcode <= opcodetype.OP_ENDIF))
1117                     switch (opcode)
1118                     {
1119                         //
1120                         // Push value
1121                         //
1122                         case opcodetype.OP_1NEGATE:
1123                         case opcodetype.OP_1:
1124                         case opcodetype.OP_2:
1125                         case opcodetype.OP_3:
1126                         case opcodetype.OP_4:
1127                         case opcodetype.OP_5:
1128                         case opcodetype.OP_6:
1129                         case opcodetype.OP_7:
1130                         case opcodetype.OP_8:
1131                         case opcodetype.OP_9:
1132                         case opcodetype.OP_10:
1133                         case opcodetype.OP_11:
1134                         case opcodetype.OP_12:
1135                         case opcodetype.OP_13:
1136                         case opcodetype.OP_14:
1137                         case opcodetype.OP_15:
1138                         case opcodetype.OP_16:
1139                             {
1140                                 // ( -- value)
1141                                 BigInteger bn = new BigInteger((int)opcode - (int)(opcodetype.OP_1 - 1));
1142                                 stack.Add(bn.ToByteArray());
1143                             }
1144                             break;
1145
1146
1147                         //
1148                         // Control
1149                         //
1150                         case opcodetype.OP_NOP:
1151                         case opcodetype.OP_NOP1:
1152                         case opcodetype.OP_NOP2:
1153                         case opcodetype.OP_NOP3:
1154                         case opcodetype.OP_NOP4:
1155                         case opcodetype.OP_NOP5:
1156                         case opcodetype.OP_NOP6:
1157                         case opcodetype.OP_NOP7:
1158                         case opcodetype.OP_NOP8:
1159                         case opcodetype.OP_NOP9:
1160                         case opcodetype.OP_NOP10:
1161                             break;
1162
1163                         case opcodetype.OP_IF:
1164                         case opcodetype.OP_NOTIF:
1165                             {
1166                                 // <expression> if [statements] [else [statements]] endif
1167                                 bool fValue = false;
1168                                 if (fExec)
1169                                 {
1170                                     if (stack.Count() < 1)
1171                                     {
1172                                         return false;
1173                                     }
1174                                     IEnumerable<byte> vch = stacktop(ref stack, -1);
1175                                     fValue = CastToBool(vch);
1176                                     if (opcode == opcodetype.OP_NOTIF)
1177                                     {
1178                                         fValue = !fValue;
1179                                     }
1180                                     popstack(ref stack);
1181                                 }
1182                                 vfExec.Add(fValue);
1183                             }
1184                             break;
1185
1186                         case opcodetype.OP_ELSE:
1187                             {
1188                                 int nExecCount = vfExec.Count();
1189                                 if (nExecCount == 0)
1190                                 {
1191                                     return false;
1192                                 }
1193                                 vfExec[nExecCount - 1] = !vfExec[nExecCount - 1];
1194                             }
1195                             break;
1196
1197                         case opcodetype.OP_ENDIF:
1198                             {
1199                                 int nExecCount = vfExec.Count();
1200                                 if (nExecCount == 0)
1201                                 {
1202                                     return false;
1203                                 }
1204                                 vfExec.RemoveAt(nExecCount - 1);
1205                             }
1206                             break;
1207
1208                         case opcodetype.OP_VERIFY:
1209                             {
1210                                 // (true -- ) or
1211                                 // (false -- false) and return
1212                                 if (stack.Count() < 1)
1213                                 {
1214                                     return false;
1215                                 }
1216
1217                                 bool fValue = CastToBool(stacktop(ref stack, -1));
1218                                 if (fValue)
1219                                 {
1220                                     popstack(ref stack);
1221                                 }
1222                                 else
1223                                 {
1224                                     return false;
1225                                 }
1226                             }
1227                             break;
1228
1229                         case opcodetype.OP_RETURN:
1230                             return false;
1231                         //
1232                         // Stack ops
1233                         //
1234                         case opcodetype.OP_TOALTSTACK:
1235                             {
1236                                 if (stack.Count() < 1)
1237                                 {
1238                                     return false;
1239                                 }
1240                                 altstack.Add(stacktop(ref stack, -1));
1241                                 popstack(ref stack);
1242                             }
1243                             break;
1244
1245                         case opcodetype.OP_FROMALTSTACK:
1246                             {
1247                                 if (altstack.Count() < 1)
1248                                 {
1249                                     return false;
1250                                 }
1251                                 stack.Add(stacktop(ref stack, -1));
1252                                 popstack(ref altstack);
1253                             }
1254                             break;
1255
1256                         case opcodetype.OP_2DROP:
1257                             {
1258                                 // (x1 x2 -- )
1259                                 if (stack.Count() < 2)
1260                                 {
1261                                     return false;
1262                                 }
1263                                 popstack(ref stack);
1264                                 popstack(ref stack);
1265                             }
1266                             break;
1267
1268                         case opcodetype.OP_2DUP:
1269                             {
1270                                 // (x1 x2 -- x1 x2 x1 x2)
1271                                 if (stack.Count() < 2)
1272                                 {
1273                                     return false;
1274                                 }
1275                                 IEnumerable<byte> vch1 = stacktop(ref stack, -2);
1276                                 IEnumerable<byte> vch2 = stacktop(ref stack, -1);
1277                                 stack.Add(vch1);
1278                                 stack.Add(vch2);
1279                             }
1280                             break;
1281
1282                         case opcodetype.OP_3DUP:
1283                             {
1284                                 // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
1285                                 if (stack.Count() < 3)
1286                                 {
1287                                     return false;
1288                                 }
1289                                 IEnumerable<byte> vch1 = stacktop(ref stack, -3);
1290                                 IEnumerable<byte> vch2 = stacktop(ref stack, -2);
1291                                 IEnumerable<byte> vch3 = stacktop(ref stack, -1);
1292                                 stack.Add(vch1);
1293                                 stack.Add(vch2);
1294                                 stack.Add(vch3);
1295                             }
1296                             break;
1297
1298                         case opcodetype.OP_2OVER:
1299                             {
1300                                 // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
1301                                 if (stack.Count() < 4)
1302                                 {
1303                                     return false;
1304                                 }
1305                                 IEnumerable<byte> vch1 = stacktop(ref stack, -4);
1306                                 IEnumerable<byte> vch2 = stacktop(ref stack, -3);
1307                                 stack.Add(vch1);
1308                                 stack.Add(vch2);
1309                             }
1310                             break;
1311
1312                         case opcodetype.OP_2ROT:
1313                             {
1314                                 int nStackDepth = stack.Count();
1315                                 // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
1316                                 if (nStackDepth < 6)
1317                                 {
1318                                     return false;
1319                                 }
1320                                 IEnumerable<byte> vch1 = stacktop(ref stack, -6);
1321                                 IEnumerable<byte> vch2 = stacktop(ref stack, -5);
1322                                 stack.RemoveRange(nStackDepth - 6, 2);
1323                                 stack.Add(vch1);
1324                                 stack.Add(vch2);
1325                             }
1326                             break;
1327
1328                         case opcodetype.OP_2SWAP:
1329                             {
1330                                 // (x1 x2 x3 x4 -- x3 x4 x1 x2)
1331                                 int nStackDepth = stack.Count();
1332                                 if (nStackDepth < 4)
1333                                 {
1334                                     return false;
1335                                 }
1336                                 stack.Swap(nStackDepth - 4, nStackDepth - 2);
1337                                 stack.Swap(nStackDepth - 3, nStackDepth - 1);
1338                             }
1339                             break;
1340
1341                         case opcodetype.OP_IFDUP:
1342                             {
1343                                 // (x - 0 | x x)
1344                                 if (stack.Count() < 1)
1345                                 {
1346                                     return false;
1347                                 }
1348
1349                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1350
1351                                 if (CastToBool(vch))
1352                                 {
1353                                     stack.Add(vch);
1354                                 }
1355                             }
1356                             break;
1357
1358                         case opcodetype.OP_DEPTH:
1359                             {
1360                                 // -- stacksize
1361                                 BigInteger bn = new BigInteger((ushort)stack.Count());
1362                                 stack.Add(bn.ToByteArray());
1363                             }
1364                             break;
1365
1366                         case opcodetype.OP_DROP:
1367                             {
1368                                 // (x -- )
1369                                 if (stack.Count() < 1)
1370                                 {
1371                                     return false;
1372                                 }
1373
1374                                 popstack(ref stack);
1375                             }
1376                             break;
1377
1378                         case opcodetype.OP_DUP:
1379                             {
1380                                 // (x -- x x)
1381                                 if (stack.Count() < 1)
1382                                 {
1383                                     return false;
1384                                 }
1385
1386                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1387                                 stack.Add(vch);
1388                             }
1389                             break;
1390
1391                         case opcodetype.OP_NIP:
1392                             {
1393                                 // (x1 x2 -- x2)
1394                                 int nStackDepth = stack.Count();
1395                                 if (nStackDepth < 2)
1396                                 {
1397                                     return false;
1398                                 }
1399
1400                                 stack.RemoveAt(nStackDepth - 2);
1401                             }
1402                             break;
1403
1404                         case opcodetype.OP_OVER:
1405                             {
1406                                 // (x1 x2 -- x1 x2 x1)
1407                                 if (stack.Count() < 2)
1408                                 {
1409                                     return false;
1410                                 }
1411
1412                                 IEnumerable<byte> vch = stacktop(ref stack, -2);
1413                                 stack.Add(vch);
1414                             }
1415                             break;
1416
1417                         case opcodetype.OP_PICK:
1418                         case opcodetype.OP_ROLL:
1419                             {
1420                                 // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
1421                                 // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
1422
1423                                 int nStackDepth = stack.Count();
1424                                 if (nStackDepth < 2)
1425                                 {
1426                                     return false;
1427                                 }
1428
1429                                 int n = (int)CastToBigInteger(stacktop(ref stack, -1));
1430                                 popstack(ref stack);
1431
1432                                 if (n < 0 || n >= stack.Count())
1433                                 {
1434                                     return false;
1435                                 }
1436
1437                                 IEnumerable<byte> vch = stacktop(ref stack, -n - 1);
1438                                 if (opcode == opcodetype.OP_ROLL)
1439                                 {
1440                                     stack.RemoveAt(nStackDepth - n - 1);
1441                                 }
1442
1443                                 stack.Add(vch);
1444                             }
1445                             break;
1446
1447                         case opcodetype.OP_ROT:
1448                             {
1449                                 // (x1 x2 x3 -- x2 x3 x1)
1450                                 //  x2 x1 x3  after first swap
1451                                 //  x2 x3 x1  after second swap
1452                                 int nStackDepth = stack.Count();
1453                                 if (nStackDepth < 3)
1454                                 {
1455                                     return false;
1456                                 }
1457                                 stack.Swap(nStackDepth - 3, nStackDepth - 2);
1458                                 stack.Swap(nStackDepth - 2, nStackDepth - 1);
1459
1460                             }
1461                             break;
1462
1463                         case opcodetype.OP_SWAP:
1464                             {
1465                                 // (x1 x2 -- x2 x1)
1466                                 int nStackDepth = stack.Count();
1467                                 if (nStackDepth < 2)
1468                                 {
1469                                     return false;
1470                                 }
1471                                 stack.Swap(nStackDepth - 2, nStackDepth - 1);
1472                             }
1473                             break;
1474
1475                         case opcodetype.OP_TUCK:
1476                             {
1477                                 // (x1 x2 -- x2 x1 x2)
1478                                 int nStackDepth = stack.Count();
1479                                 if (nStackDepth < 2)
1480                                 {
1481                                     return false;
1482                                 }
1483                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1484                                 stack.Insert(nStackDepth - 2, vch);
1485                             }
1486                             break;
1487
1488
1489                         case opcodetype.OP_SIZE:
1490                             {
1491                                 // (in -- in size)
1492                                 if (stack.Count() < 1)
1493                                 {
1494                                     return false;
1495                                 }
1496
1497                                 BigInteger bnSize = new BigInteger((ushort)stacktop(ref stack, -1).Count());
1498                                 stack.Add(bnSize.ToByteArray());
1499                             }
1500                             break;
1501
1502
1503                         //
1504                         // Bitwise logic
1505                         //
1506                         case opcodetype.OP_EQUAL:
1507                         case opcodetype.OP_EQUALVERIFY:
1508                             //case opcodetype.OP_NOTEQUAL: // use OP_NUMNOTEQUAL
1509                             {
1510                                 // (x1 x2 - bool)
1511                                 if (stack.Count() < 2)
1512                                 {
1513                                     return false;
1514                                 }
1515
1516                                 IEnumerable<byte> vch1 = stacktop(ref stack, -2);
1517                                 IEnumerable<byte> vch2 = stacktop(ref stack, -1);
1518                                 bool fEqual = (vch1 == vch2);
1519                                 // OP_NOTEQUAL is disabled because it would be too easy to say
1520                                 // something like n != 1 and have some wiseguy pass in 1 with extra
1521                                 // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
1522                                 //if (opcode == opcodetype.OP_NOTEQUAL)
1523                                 //    fEqual = !fEqual;
1524                                 popstack(ref stack);
1525                                 popstack(ref stack);
1526                                 stack.Add(fEqual ? vchTrue : vchFalse);
1527
1528                                 if (opcode == opcodetype.OP_EQUALVERIFY)
1529                                 {
1530                                     if (fEqual)
1531                                     {
1532                                         popstack(ref stack);
1533                                     }
1534                                     else
1535                                     {
1536                                         return false;
1537                                     }
1538                                 }
1539                             }
1540                             break;
1541
1542
1543                         //
1544                         // Numeric
1545                         //
1546                         case opcodetype.OP_1ADD:
1547                         case opcodetype.OP_1SUB:
1548                         case opcodetype.OP_NEGATE:
1549                         case opcodetype.OP_ABS:
1550                         case opcodetype.OP_NOT:
1551                         case opcodetype.OP_0NOTEQUAL:
1552                             {
1553                                 // (in -- out)
1554                                 if (stack.Count() < 1)
1555                                 {
1556                                     return false;
1557                                 }
1558
1559                                 BigInteger bn = CastToBigInteger(stacktop(ref stack, -1));
1560                                 switch (opcode)
1561                                 {
1562                                     case opcodetype.OP_1ADD:
1563                                         bn = bn + 1;
1564                                         break;
1565                                     case opcodetype.OP_1SUB:
1566                                         bn = bn - 1;
1567                                         break;
1568                                     case opcodetype.OP_NEGATE:
1569                                         bn = -bn;
1570                                         break;
1571                                     case opcodetype.OP_ABS:
1572                                         bn = BigInteger.Abs(bn);
1573                                         break;
1574                                     case opcodetype.OP_NOT:
1575                                         bn = bn == 0 ? 1 : 0;
1576                                         break;
1577                                     case opcodetype.OP_0NOTEQUAL:
1578                                         bn = bn != 0 ? 1 : 0;
1579                                         break;
1580
1581                                     default:
1582                                         throw new StackMachineException("invalid opcode");
1583                                         break;
1584                                 }
1585
1586                                 popstack(ref stack);
1587                                 stack.Add(bn.ToByteArray());
1588                             }
1589                             break;
1590
1591                         case opcodetype.OP_ADD:
1592                         case opcodetype.OP_SUB:
1593                         case opcodetype.OP_BOOLAND:
1594                         case opcodetype.OP_BOOLOR:
1595                         case opcodetype.OP_NUMEQUAL:
1596                         case opcodetype.OP_NUMEQUALVERIFY:
1597                         case opcodetype.OP_NUMNOTEQUAL:
1598                         case opcodetype.OP_LESSTHAN:
1599                         case opcodetype.OP_GREATERTHAN:
1600                         case opcodetype.OP_LESSTHANOREQUAL:
1601                         case opcodetype.OP_GREATERTHANOREQUAL:
1602                         case opcodetype.OP_MIN:
1603                         case opcodetype.OP_MAX:
1604                             {
1605                                 // (x1 x2 -- out)
1606                                 if (stack.Count() < 2)
1607                                 {
1608                                     return false;
1609                                 }
1610
1611                                 BigInteger bn1 = CastToBigInteger(stacktop(ref stack, -2));
1612                                 BigInteger bn2 = CastToBigInteger(stacktop(ref stack, -1));
1613                                 BigInteger bn = 0;
1614
1615                                 switch (opcode)
1616                                 {
1617                                     case opcodetype.OP_ADD:
1618                                         bn = bn1 + bn2;
1619                                         break;
1620                                     case opcodetype.OP_SUB:
1621                                         bn = bn1 - bn2;
1622                                         break;
1623                                     case opcodetype.OP_BOOLAND:
1624                                         bn = (bn1 != 0 && bn2 != 0) ? 1 : 0;
1625                                         break;
1626                                     case opcodetype.OP_BOOLOR:
1627                                         bn = (bn1 != 0 || bn2 != 0) ? 1 : 0;
1628                                         break;
1629                                     case opcodetype.OP_NUMEQUAL:
1630                                         bn = (bn1 == bn2) ? 1 : 0;
1631                                         break;
1632                                     case opcodetype.OP_NUMEQUALVERIFY:
1633                                         bn = (bn1 == bn2) ? 1 : 0;
1634                                         break;
1635                                     case opcodetype.OP_NUMNOTEQUAL:
1636                                         bn = (bn1 != bn2) ? 1 : 0;
1637                                         break;
1638                                     case opcodetype.OP_LESSTHAN:
1639                                         bn = (bn1 < bn2) ? 1 : 0;
1640                                         break;
1641                                     case opcodetype.OP_GREATERTHAN:
1642                                         bn = (bn1 > bn2) ? 1 : 0;
1643                                         break;
1644                                     case opcodetype.OP_LESSTHANOREQUAL:
1645                                         bn = (bn1 <= bn2) ? 1 : 0;
1646                                         break;
1647                                     case opcodetype.OP_GREATERTHANOREQUAL:
1648                                         bn = (bn1 >= bn2) ? 1 : 0;
1649                                         break;
1650                                     case opcodetype.OP_MIN:
1651                                         bn = (bn1 < bn2 ? bn1 : bn2);
1652                                         break;
1653                                     case opcodetype.OP_MAX:
1654                                         bn = (bn1 > bn2 ? bn1 : bn2);
1655                                         break;
1656
1657                                     default:
1658                                         throw new StackMachineException("invalid opcode");
1659                                         break;
1660                                 }
1661
1662                                 popstack(ref stack);
1663                                 popstack(ref stack);
1664                                 stack.Add(bn.ToByteArray());
1665
1666                                 if (opcode == opcodetype.OP_NUMEQUALVERIFY)
1667                                 {
1668                                     if (CastToBool(stacktop(ref stack, -1)))
1669                                     {
1670                                         popstack(ref stack);
1671                                     }
1672                                     else
1673                                     {
1674                                         return false;
1675                                     }
1676                                 }
1677                             }
1678                             break;
1679
1680                         case opcodetype.OP_WITHIN:
1681                             {
1682                                 // (x min max -- out)
1683                                 if (stack.Count() < 3)
1684                                     return false;
1685                                 BigInteger bn1 = CastToBigInteger(stacktop(ref stack, -3));
1686                                 BigInteger bn2 = CastToBigInteger(stacktop(ref stack, -2));
1687                                 BigInteger bn3 = CastToBigInteger(stacktop(ref stack, -1));
1688                                 bool fValue = (bn2 <= bn1 && bn1 < bn3);
1689                                 popstack(ref stack);
1690                                 popstack(ref stack);
1691                                 popstack(ref stack);
1692                                 stack.Add(fValue ? vchTrue : vchFalse);
1693                             }
1694                             break;
1695
1696
1697                         //
1698                         // Crypto
1699                         //
1700                         case opcodetype.OP_RIPEMD160:
1701                         case opcodetype.OP_SHA1:
1702                         case opcodetype.OP_SHA256:
1703                         case opcodetype.OP_HASH160:
1704                         case opcodetype.OP_HASH256:
1705                             {
1706                                 // (in -- hash)
1707                                 if (stack.Count() < 1)
1708                                     return false;
1709                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1710                                 IEnumerable<byte> vchHash = null;
1711                                 if (opcode == opcodetype.OP_RIPEMD160)
1712                                 {
1713                                     RIPEMD160 hash = RIPEMD160.Compute160(vch);
1714                                     vchHash = hash.hashBytes;
1715                                 }
1716                                 else if (opcode == opcodetype.OP_SHA1)
1717                                 {
1718                                     SHA1 hash = SHA1.Compute1(vch);
1719                                     vchHash = hash.hashBytes;
1720                                 }
1721                                 else if (opcode == opcodetype.OP_SHA256)
1722                                 {
1723                                     SHA256 hash = SHA256.Compute256(vch);
1724                                     vchHash = hash.hashBytes;
1725                                 }
1726                                 else if (opcode == opcodetype.OP_HASH160)
1727                                 {
1728                                     Hash160 hash = Hash160.Compute160(vch);
1729                                     vchHash = hash.hashBytes;
1730                                 }
1731                                 else if (opcode == opcodetype.OP_HASH256)
1732                                 {
1733                                     Hash256 hash = Hash256.Compute256(vch);
1734                                     vchHash = hash.hashBytes;
1735                                 }
1736                                 popstack(ref stack);
1737                                 stack.Add(vchHash);
1738                             }
1739                             break;
1740
1741                         case opcodetype.OP_CODESEPARATOR:
1742                             {
1743                                 // Hash starts after the code separator
1744                                 pbegincodehash = pc;
1745                             }
1746                             break;
1747
1748                         case opcodetype.OP_CHECKSIG:
1749                         case opcodetype.OP_CHECKSIGVERIFY:
1750                             {
1751                                 // (sig pubkey -- bool)
1752                                 if (stack.Count() < 2)
1753                                 {
1754                                     return false;
1755                                 }
1756
1757                                 IList<byte> sigBytes = stacktop(ref stack, -2).ToList();
1758                                 IList<byte> pubkeyBytes = stacktop(ref stack, -1).ToList();
1759
1760                                 // Subset of script starting at the most recent codeseparator
1761                                 CScript scriptCode = new CScript(script.Bytes.Skip(pbegincodehash.CurrentIndex));
1762
1763                                 // There's no way for a signature to sign itself
1764                                 scriptCode.RemovePattern(sigBytes);
1765
1766                                 bool fSuccess = IsCanonicalSignature(sigBytes, flags) && IsCanonicalPubKey(pubkeyBytes.ToList(), flags) && CheckSig(sigBytes, pubkeyBytes, scriptCode, txTo, nIn, nHashType, flags);
1767
1768                                 popstack(ref stack);
1769                                 popstack(ref stack);
1770                                 stack.Add(fSuccess ? vchTrue : vchFalse);
1771                                 if (opcode == opcodetype.OP_CHECKSIGVERIFY)
1772                                 {
1773                                     if (fSuccess)
1774                                     {
1775                                         popstack(ref stack);
1776                                     }
1777                                     else
1778                                     {
1779                                         return false;
1780                                     }
1781                                 }
1782                             }
1783                             break;
1784
1785                         case opcodetype.OP_CHECKMULTISIG:
1786                         case opcodetype.OP_CHECKMULTISIGVERIFY:
1787                             {
1788                                 // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
1789
1790                                 int i = 1;
1791                                 if (stack.Count() < i)
1792                                 {
1793                                     return false;
1794                                 }
1795
1796                                 int nKeysCount = (int)CastToBigInteger(stacktop(ref stack, -i));
1797                                 if (nKeysCount < 0 || nKeysCount > 20)
1798                                 {
1799                                     return false;
1800                                 }
1801                                 nOpCount += nKeysCount;
1802                                 if (nOpCount > 201)
1803                                 {
1804                                     return false;
1805                                 }
1806                                 int ikey = ++i;
1807                                 i += nKeysCount;
1808                                 if (stack.Count() < i)
1809                                 {
1810                                     return false;
1811                                 }
1812
1813                                 int nSigsCount = (int)CastToBigInteger(stacktop(ref stack, -i));
1814                                 if (nSigsCount < 0 || nSigsCount > nKeysCount)
1815                                 {
1816                                     return false;
1817                                 }
1818                                 int isig = ++i;
1819                                 i += nSigsCount;
1820                                 if (stack.Count() < i)
1821                                 {
1822                                     return false;
1823                                 }
1824
1825                                 // Subset of script starting at the most recent codeseparator
1826                                 CScript scriptCode = new CScript(script.Bytes.Skip(pbegincodehash.CurrentIndex));
1827
1828                                 // There is no way for a signature to sign itself, so we need to drop the signatures
1829                                 for (int k = 0; k < nSigsCount; k++)
1830                                 {
1831                                     IEnumerable<byte> vchSig = stacktop(ref stack, -isig - k);
1832                                     scriptCode.RemovePattern(vchSig.ToList());
1833                                 }
1834
1835                                 bool fSuccess = true;
1836                                 while (fSuccess && nSigsCount > 0)
1837                                 {
1838                                     IList<byte> sigBytes = stacktop(ref stack, -isig).ToList();
1839                                     IList<byte> pubKeyBytes = stacktop(ref stack, -ikey).ToList();
1840
1841                                     // Check signature
1842                                     bool fOk = IsCanonicalSignature(sigBytes, flags) && IsCanonicalPubKey(pubKeyBytes.ToList(), flags) && CheckSig(sigBytes, pubKeyBytes, scriptCode, txTo, nIn, nHashType, flags);
1843
1844                                     if (fOk)
1845                                     {
1846                                         isig++;
1847                                         nSigsCount--;
1848                                     }
1849                                     ikey++;
1850                                     nKeysCount--;
1851
1852                                     // If there are more signatures left than keys left,
1853                                     // then too many signatures have failed
1854                                     if (nSigsCount > nKeysCount)
1855                                     {
1856                                         fSuccess = false;
1857                                     }
1858                                 }
1859
1860                                 while (i-- > 1)
1861                                 {
1862                                     popstack(ref stack);
1863                                 }
1864
1865                                 // A bug causes CHECKMULTISIG to consume one extra argument
1866                                 // whose contents were not checked in any way.
1867                                 //
1868                                 // Unfortunately this is a potential source of mutability,
1869                                 // so optionally verify it is exactly equal to zero prior
1870                                 // to removing it from the stack.
1871                                 if (stack.Count() < 1)
1872                                 {
1873                                     return false;
1874                                 }
1875                                 if ((flags & (int)scriptflag.SCRIPT_VERIFY_NULLDUMMY) != 0 && stacktop(ref stack, -1).Count() != 0)
1876                                 {
1877                                     return false; // CHECKMULTISIG dummy argument not null
1878                                 }
1879                                 popstack(ref stack);
1880
1881                                 stack.Add(fSuccess ? vchTrue : vchFalse);
1882
1883                                 if (opcode == opcodetype.OP_CHECKMULTISIGVERIFY)
1884                                 {
1885                                     if (fSuccess)
1886                                     {
1887                                         popstack(ref stack);
1888                                     }
1889                                     else
1890                                     {
1891                                         return false;
1892                                     }
1893                                 }
1894                             }
1895                             break;
1896
1897                         default:
1898                             return false;
1899                     }
1900
1901                 // Size limits
1902                 if (stack.Count() + altstack.Count() > 1000)
1903                 {
1904                     return false;
1905                 }
1906             }
1907
1908
1909             if (vfExec.Count() == 0)
1910             {
1911                 return false;
1912             }
1913
1914             return true;
1915         }
1916
1917
1918         static bool IsCanonicalPubKey(IList<byte> pubKeyBytes, int flags)
1919         {
1920             if ((flags & (int)scriptflag.SCRIPT_VERIFY_STRICTENC) == 0)
1921                 return true;
1922
1923             if (pubKeyBytes.Count() < 33)
1924                 return false;  // Non-canonical public key: too short
1925             if (pubKeyBytes[0] == 0x04)
1926             {
1927                 if (pubKeyBytes.Count() != 65)
1928                     return false; // Non-canonical public key: invalid length for uncompressed key
1929             }
1930             else if (pubKeyBytes[0] == 0x02 || pubKeyBytes[0] == 0x03)
1931             {
1932                 if (pubKeyBytes.Count() != 33)
1933                     return false; // Non-canonical public key: invalid length for compressed key
1934             }
1935             else
1936             {
1937                 return false; // Non-canonical public key: compressed nor uncompressed
1938             }
1939             return true;
1940         }
1941
1942         static bool IsCanonicalSignature(IList<byte> sigBytes, int flags)
1943         {
1944             // STUB
1945
1946             return true;
1947         }
1948
1949
1950         static bool CheckSig(IList<byte> sigBytes, IList<byte> pubKeyBytes, CScript scriptCode, CTransaction txTo, int nIn, int nHashType, int flags)
1951         {
1952             // STUB
1953             return true;
1954         }
1955
1956 };
1957 }