CheckSig implementation
[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 instruction
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(instruction opcode)
218         {
219             switch (opcode)
220             {
221                 // push value
222                 case instruction.OP_0:
223                     return "OP_0";
224                 case instruction.OP_PUSHDATA1:
225                     return "OP_PUSHDATA1";
226                 case instruction.OP_PUSHDATA2:
227                     return "OP_PUSHDATA2";
228                 case instruction.OP_PUSHDATA4:
229                     return "OP_PUSHDATA4";
230                 case instruction.OP_1NEGATE:
231                     return "OP_1NEGATE";
232                 case instruction.OP_RESERVED:
233                     return "OP_RESERVED";
234                 case instruction.OP_1:
235                     return "OP_1";
236                 case instruction.OP_2:
237                     return "OP_2";
238                 case instruction.OP_3:
239                     return "OP_3";
240                 case instruction.OP_4:
241                     return "OP_4";
242                 case instruction.OP_5:
243                     return "OP_5";
244                 case instruction.OP_6:
245                     return "OP_6";
246                 case instruction.OP_7:
247                     return "OP_7";
248                 case instruction.OP_8:
249                     return "OP_8";
250                 case instruction.OP_9:
251                     return "OP_9";
252                 case instruction.OP_10:
253                     return "OP_10";
254                 case instruction.OP_11:
255                     return "OP_11";
256                 case instruction.OP_12:
257                     return "OP_12";
258                 case instruction.OP_13:
259                     return "OP_13";
260                 case instruction.OP_14:
261                     return "OP_14";
262                 case instruction.OP_15:
263                     return "OP_15";
264                 case instruction.OP_16:
265                     return "OP_16";
266
267                 // control
268                 case instruction.OP_NOP:
269                     return "OP_NOP";
270                 case instruction.OP_VER:
271                     return "OP_VER";
272                 case instruction.OP_IF:
273                     return "OP_IF";
274                 case instruction.OP_NOTIF:
275                     return "OP_NOTIF";
276                 case instruction.OP_VERIF:
277                     return "OP_VERIF";
278                 case instruction.OP_VERNOTIF:
279                     return "OP_VERNOTIF";
280                 case instruction.OP_ELSE:
281                     return "OP_ELSE";
282                 case instruction.OP_ENDIF:
283                     return "OP_ENDIF";
284                 case instruction.OP_VERIFY:
285                     return "OP_VERIFY";
286                 case instruction.OP_RETURN:
287                     return "OP_RETURN";
288
289                 // stack ops
290                 case instruction.OP_TOALTSTACK:
291                     return "OP_TOALTSTACK";
292                 case instruction.OP_FROMALTSTACK:
293                     return "OP_FROMALTSTACK";
294                 case instruction.OP_2DROP:
295                     return "OP_2DROP";
296                 case instruction.OP_2DUP:
297                     return "OP_2DUP";
298                 case instruction.OP_3DUP:
299                     return "OP_3DUP";
300                 case instruction.OP_2OVER:
301                     return "OP_2OVER";
302                 case instruction.OP_2ROT:
303                     return "OP_2ROT";
304                 case instruction.OP_2SWAP:
305                     return "OP_2SWAP";
306                 case instruction.OP_IFDUP:
307                     return "OP_IFDUP";
308                 case instruction.OP_DEPTH:
309                     return "OP_DEPTH";
310                 case instruction.OP_DROP:
311                     return "OP_DROP";
312                 case instruction.OP_DUP:
313                     return "OP_DUP";
314                 case instruction.OP_NIP:
315                     return "OP_NIP";
316                 case instruction.OP_OVER:
317                     return "OP_OVER";
318                 case instruction.OP_PICK:
319                     return "OP_PICK";
320                 case instruction.OP_ROLL:
321                     return "OP_ROLL";
322                 case instruction.OP_ROT:
323                     return "OP_ROT";
324                 case instruction.OP_SWAP:
325                     return "OP_SWAP";
326                 case instruction.OP_TUCK:
327                     return "OP_TUCK";
328
329                 // splice ops
330                 case instruction.OP_CAT:
331                     return "OP_CAT";
332                 case instruction.OP_SUBSTR:
333                     return "OP_SUBSTR";
334                 case instruction.OP_LEFT:
335                     return "OP_LEFT";
336                 case instruction.OP_RIGHT:
337                     return "OP_RIGHT";
338                 case instruction.OP_SIZE:
339                     return "OP_SIZE";
340
341                 // bit logic
342                 case instruction.OP_INVERT:
343                     return "OP_INVERT";
344                 case instruction.OP_AND:
345                     return "OP_AND";
346                 case instruction.OP_OR:
347                     return "OP_OR";
348                 case instruction.OP_XOR:
349                     return "OP_XOR";
350                 case instruction.OP_EQUAL:
351                     return "OP_EQUAL";
352                 case instruction.OP_EQUALVERIFY:
353                     return "OP_EQUALVERIFY";
354                 case instruction.OP_RESERVED1:
355                     return "OP_RESERVED1";
356                 case instruction.OP_RESERVED2:
357                     return "OP_RESERVED2";
358
359                 // numeric
360                 case instruction.OP_1ADD:
361                     return "OP_1ADD";
362                 case instruction.OP_1SUB:
363                     return "OP_1SUB";
364                 case instruction.OP_2MUL:
365                     return "OP_2MUL";
366                 case instruction.OP_2DIV:
367                     return "OP_2DIV";
368                 case instruction.OP_NEGATE:
369                     return "OP_NEGATE";
370                 case instruction.OP_ABS:
371                     return "OP_ABS";
372                 case instruction.OP_NOT:
373                     return "OP_NOT";
374                 case instruction.OP_0NOTEQUAL:
375                     return "OP_0NOTEQUAL";
376                 case instruction.OP_ADD:
377                     return "OP_ADD";
378                 case instruction.OP_SUB:
379                     return "OP_SUB";
380                 case instruction.OP_MUL:
381                     return "OP_MUL";
382                 case instruction.OP_DIV:
383                     return "OP_DIV";
384                 case instruction.OP_MOD:
385                     return "OP_MOD";
386                 case instruction.OP_LSHIFT:
387                     return "OP_LSHIFT";
388                 case instruction.OP_RSHIFT:
389                     return "OP_RSHIFT";
390                 case instruction.OP_BOOLAND:
391                     return "OP_BOOLAND";
392                 case instruction.OP_BOOLOR:
393                     return "OP_BOOLOR";
394                 case instruction.OP_NUMEQUAL:
395                     return "OP_NUMEQUAL";
396                 case instruction.OP_NUMEQUALVERIFY:
397                     return "OP_NUMEQUALVERIFY";
398                 case instruction.OP_NUMNOTEQUAL:
399                     return "OP_NUMNOTEQUAL";
400                 case instruction.OP_LESSTHAN:
401                     return "OP_LESSTHAN";
402                 case instruction.OP_GREATERTHAN:
403                     return "OP_GREATERTHAN";
404                 case instruction.OP_LESSTHANOREQUAL:
405                     return "OP_LESSTHANOREQUAL";
406                 case instruction.OP_GREATERTHANOREQUAL:
407                     return "OP_GREATERTHANOREQUAL";
408                 case instruction.OP_MIN:
409                     return "OP_MIN";
410                 case instruction.OP_MAX:
411                     return "OP_MAX";
412                 case instruction.OP_WITHIN:
413                     return "OP_WITHIN";
414
415                 // crypto
416                 case instruction.OP_RIPEMD160:
417                     return "OP_RIPEMD160";
418                 case instruction.OP_SHA1:
419                     return "OP_SHA1";
420                 case instruction.OP_SHA256:
421                     return "OP_SHA256";
422                 case instruction.OP_HASH160:
423                     return "OP_HASH160";
424                 case instruction.OP_HASH256:
425                     return "OP_HASH256";
426                 case instruction.OP_CODESEPARATOR:
427                     return "OP_CODESEPARATOR";
428                 case instruction.OP_CHECKSIG:
429                     return "OP_CHECKSIG";
430                 case instruction.OP_CHECKSIGVERIFY:
431                     return "OP_CHECKSIGVERIFY";
432                 case instruction.OP_CHECKMULTISIG:
433                     return "OP_CHECKMULTISIG";
434                 case instruction.OP_CHECKMULTISIGVERIFY:
435                     return "OP_CHECKMULTISIGVERIFY";
436
437                 // expansion
438                 case instruction.OP_NOP1:
439                     return "OP_NOP1";
440                 case instruction.OP_NOP2:
441                     return "OP_NOP2";
442                 case instruction.OP_NOP3:
443                     return "OP_NOP3";
444                 case instruction.OP_NOP4:
445                     return "OP_NOP4";
446                 case instruction.OP_NOP5:
447                     return "OP_NOP5";
448                 case instruction.OP_NOP6:
449                     return "OP_NOP6";
450                 case instruction.OP_NOP7:
451                     return "OP_NOP7";
452                 case instruction.OP_NOP8:
453                     return "OP_NOP8";
454                 case instruction.OP_NOP9:
455                     return "OP_NOP9";
456                 case instruction.OP_NOP10:
457                     return "OP_NOP10";
458
459                 // template matching params
460                 case instruction.OP_PUBKEYHASH:
461                     return "OP_PUBKEYHASH";
462                 case instruction.OP_PUBKEY:
463                     return "OP_PUBKEY";
464                 case instruction.OP_SMALLDATA:
465                     return "OP_SMALLDATA";
466
467                 case instruction.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 instruction opcodeRet, out IEnumerable<byte> bytesRet)
482         {
483             bytesRet = new List<byte>();
484             opcodeRet = instruction.OP_INVALIDOPCODE;
485
486             instruction opcode;
487
488             try
489             {
490                 // Read instruction
491                 opcode = (instruction)codeBytes.Get();
492             }
493             catch (ByteQueueException)
494             {
495                 // No instruction found there
496                 return false;
497             }
498
499             // Immediate operand
500             if (opcode <= instruction.OP_PUSHDATA4)
501             {
502                 byte[] szBytes = new byte[4] { 0, 0, 0, 0 }; // Zero length
503
504                 try
505                 {
506                     if (opcode < instruction.OP_PUSHDATA1)
507                     {
508                         // Zero value opcodes (OP_0, OP_FALSE)
509                         szBytes[3] = (byte)opcode;
510                     }
511                     else if (opcode == instruction.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 == instruction.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 == instruction.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 instruction to integer value
603         /// </summary>
604         /// <param name="opcode">Small integer opcode (OP_1_NEGATE and OP_0 - OP_16)</param>
605         /// <returns>Small integer</returns>
606         public static int DecodeOP_N(instruction opcode, bool AllowNegate = false)
607         {
608             if (AllowNegate && opcode == instruction.OP_1NEGATE)
609             {
610                 return -1;
611             }
612
613             if (opcode == instruction.OP_0)
614             {
615                 return 0;
616             }
617
618             // Only OP_n opcodes are supported, throw exception otherwise.
619             if (opcode < instruction.OP_1 || opcode > instruction.OP_16)
620             {
621                 throw new Exception("Invalid integer instruction.");
622             }
623
624             return (int)opcode - (int)(instruction.OP_1 - 1);
625         }
626
627         /// <summary>
628         /// Converts integer into instruction
629         /// </summary>
630         /// <param name="n">Small integer from the range of -1 up to 16.</param>
631         /// <returns>Corresponding opcode.</returns>
632         public static instruction EncodeOP_N(int n, bool allowNegate = false)
633         {
634             if (allowNegate && n == -1)
635             {
636                 return instruction.OP_1NEGATE;
637             }
638
639             if (n == 0)
640             {
641                 return instruction.OP_0;
642             }
643
644             // The n value must be in the range of 0 to 16.
645             if (n < 0 || n > 16)
646                 throw new Exception("Invalid integer value.");
647             return (instruction.OP_1 + n - 1);
648         }
649
650         public static int ScriptSigArgsExpected(txnouttype t, IList<IEnumerable<byte>> solutions)
651         {
652             switch (t)
653             {
654                 case txnouttype.TX_NONSTANDARD:
655                     return -1;
656                 case txnouttype.TX_NULL_DATA:
657                     return 1;
658                 case txnouttype.TX_PUBKEY:
659                     return 1;
660                 case txnouttype.TX_PUBKEYHASH:
661                     return 2;
662                 case txnouttype.TX_MULTISIG:
663                     if (solutions.Count() < 1 || solutions.First().Count() < 1)
664                         return -1;
665                     return solutions.First().First() + 1;
666                 case txnouttype.TX_SCRIPTHASH:
667                     return 1; // doesn't include args needed by the script
668             }
669             return -1;
670         }
671
672         /// <summary>
673         /// Is it a standart type of scriptPubKey?
674         /// </summary>
675         /// <param name="scriptPubKey">CScript instance</param>
676         /// <param name="whichType">utut type</param>
677         /// <returns>Checking result</returns>
678         public static bool IsStandard(CScript scriptPubKey, out txnouttype whichType)
679         {
680             IList<IEnumerable<byte>> solutions = new List<IEnumerable<byte>>();
681
682             if (!Solver(scriptPubKey, out whichType, out solutions))
683             {
684                 // No solutions found
685                 return false;
686             }
687
688             if (whichType == txnouttype.TX_MULTISIG)
689             {
690                 // Additional verification of OP_CHECKMULTISIG arguments
691                 byte m = solutions.First().First();
692                 byte n = solutions.Last().First();
693
694                 // Support up to x-of-3 multisig txns as standard
695                 if (n < 1 || n > 3)
696                 {
697                     return false;
698                 }
699                 if (m < 1 || m > n)
700                 {
701                     return false;
702                 }
703             }
704
705             return whichType != txnouttype.TX_NONSTANDARD;
706         }
707
708         /// <summary>
709         /// Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
710         /// </summary>
711         /// <param name="scriptPubKey">CScript instance</param>
712         /// <param name="typeRet">Output type</param>
713         /// <param name="solutions">Set of solutions</param>
714         /// <returns>Result</returns>
715         public static bool Solver(CScript scriptPubKey, out txnouttype typeRet, out IList<IEnumerable<byte>> solutions)
716         {
717             solutions = new List<IEnumerable<byte>>();
718
719             // There are shortcuts for pay-to-script-hash and pay-to-pubkey-hash, which are more constrained than the other types.
720
721             // It is always OP_HASH160 20 [20 byte hash] OP_EQUAL
722             if (scriptPubKey.IsPayToScriptHash)
723             {
724                 typeRet = txnouttype.TX_SCRIPTHASH;
725
726                 // Take 20 bytes with offset of 2 bytes
727                 IEnumerable<byte> hashBytes = scriptPubKey.Bytes.Skip(2).Take(20);
728                 solutions.Add(hashBytes);
729
730                 return true;
731             }
732
733             // It is always OP_DUP OP_HASH160 20 [20 byte hash] OP_EQUALVERIFY OP_CHECKSIG
734             if (scriptPubKey.IsPayToPubKeyHash)
735             {
736                 typeRet = txnouttype.TX_PUBKEYHASH;
737
738                 // Take 20 bytes with offset of 3 bytes
739                 IEnumerable<byte> hashBytes = scriptPubKey.Bytes.Skip(3).Take(20);
740                 solutions.Add(hashBytes);
741
742                 return true;
743             }
744
745             List<Tuple<txnouttype, IEnumerable<byte>>> templateTuples = new List<Tuple<txnouttype, IEnumerable<byte>>>();
746
747             // Sender provides pubkey, receiver adds signature
748             // [ECDSA public key] OP_CHECKSIG
749             templateTuples.Add(
750                 new Tuple<txnouttype, IEnumerable<byte>>(
751                     txnouttype.TX_PUBKEY,
752                     new byte[] {
753                         (byte)instruction.OP_PUBKEY,
754                         (byte)instruction.OP_CHECKSIG
755                     })
756             );
757
758             // Sender provides N pubkeys, receivers provides M signatures
759             // N [pubkey1] [pubkey2] ... [pubkeyN] M OP_CHECKMULTISIG
760             // Where N and M are small integer opcodes (OP1 ... OP_16)
761             templateTuples.Add(
762                 new Tuple<txnouttype, IEnumerable<byte>>(
763                     txnouttype.TX_MULTISIG,
764                     new byte[] {
765                         (byte)instruction.OP_SMALLINTEGER,
766                         (byte)instruction.OP_PUBKEYS,
767                         (byte)instruction.OP_SMALLINTEGER,
768                         (byte)instruction.OP_CHECKMULTISIG
769                     })
770             );
771
772             // Data-carrying output
773             // OP_RETURN [up to 80 bytes of data]
774             templateTuples.Add(
775                 new Tuple<txnouttype, IEnumerable<byte>>(
776                     txnouttype.TX_NULL_DATA,
777                     new byte[] {
778                         (byte)instruction.OP_RETURN,
779                         (byte)instruction.OP_SMALLDATA
780                     })
781             );
782
783             // Nonstandard tx output
784             typeRet = txnouttype.TX_NONSTANDARD;
785
786             foreach (Tuple<txnouttype, IEnumerable<byte>> templateTuple in templateTuples)
787             {
788                 CScript script1 = scriptPubKey;
789                 CScript script2 = new CScript(templateTuple.Item2);
790
791                 instruction opcode1, opcode2;
792
793                 // Compare
794                 ByteQueue bq1 = script1.GetByteQUeue();
795                 ByteQueue bq2 = script2.GetByteQUeue();
796
797                 IEnumerable<byte> args1, args2;
798
799                 byte last1 = script1.Bytes.Last();
800                 byte last2 = script2.Bytes.Last();
801
802                 while (true)
803                 {
804                     if (bq1.GetCurrent() == last1 && bq2.GetCurrent() == last2)
805                     {
806                         // Found a match
807                         typeRet = templateTuple.Item1;
808                         if (typeRet == txnouttype.TX_MULTISIG)
809                         {
810                             // Additional checks for TX_MULTISIG:
811                             byte m = solutions.First().First();
812                             byte n = solutions.Last().First();
813
814                             if (m < 1 || n < 1 || m > n || solutions.Count - 2 != n)
815                             {
816                                 return false;
817                             }
818                         }
819                         return true;
820                     }
821
822                     if (!GetOp(ref bq1, out opcode1, out args1))
823                     {
824                         break;
825                     }
826                     if (!GetOp(ref bq2, out opcode2, out args2))
827                     {
828                         break;
829                     }
830
831                     // Template matching opcodes:
832                     if (opcode2 == instruction.OP_PUBKEYS)
833                     {
834                         while (args1.Count() >= 33 && args1.Count() <= 120)
835                         {
836                             solutions.Add(args1);
837                             if (!GetOp(ref bq1, out opcode1, out args1))
838                             {
839                                 break;
840                             }
841                         }
842                         if (!GetOp(ref bq2, out opcode2, out args2))
843                             break;
844                         // Normal situation is to fall through
845                         // to other if/else statements
846                     }
847                     if (opcode2 == instruction.OP_PUBKEY)
848                     {
849                         if (args1.Count() < 33 || args1.Count() > 120)
850                         {
851                             break;
852                         }
853                         solutions.Add(args1);
854                     }
855                     else if (opcode2 == instruction.OP_PUBKEYHASH)
856                     {
857                         if (args1.Count() != 20) // hash160 size
858                         {
859                             break;
860                         }
861                         solutions.Add(args1);
862                     }
863                     else if (opcode2 == instruction.OP_SMALLINTEGER)
864                     {
865                         // Single-byte small integer pushed onto solutions
866                         if (opcode1 == instruction.OP_0 || (opcode1 >= instruction.OP_1 && opcode1 <= instruction.OP_16))
867                         {
868                             byte n = (byte)DecodeOP_N(opcode1);
869                             solutions.Add(new byte[] { n });
870                         }
871                         else
872                         {
873                             break;
874                         }
875                     }
876                     else if (opcode2 == instruction.OP_SMALLDATA)
877                     {
878                         // small pushdata, <= 80 bytes
879                         if (args1.Count() > 80)
880                         {
881                             break;
882                         }
883                     }
884                     else if (opcode1 != opcode2 || !args1.SequenceEqual(args2))
885                     {
886                         // Others must match exactly
887                         break;
888                     }
889                 }
890             }
891
892             solutions.Clear();
893             typeRet = txnouttype.TX_NONSTANDARD;
894
895             return false;
896         }
897
898         public static Hash256 SignatureHash(CScript scriptCode, CTransaction txTo, int nIn, int nHashType)
899         {
900             if (nIn >= txTo.vin.Length)
901             {
902                 StringBuilder sb = new StringBuilder();
903                 sb.AppendFormat("ERROR: SignatureHash() : nIn={0} out of range\n", nIn);
904                 throw new ArgumentOutOfRangeException("nIn", sb.ToString());
905             }
906
907             CTransaction txTmp = new CTransaction(txTo);
908
909             // In case concatenating two scripts ends up with two codeseparators,
910             // or an extra one at the end, this prevents all those possible incompatibilities.
911             scriptCode.RemovePattern(new byte[] { (byte)instruction.OP_CODESEPARATOR });
912
913             // Blank out other inputs' signatures
914             for (int i = 0; i < txTmp.vin.Length; i++)
915             {
916                 txTmp.vin[i].scriptSig = new CScript();
917             }
918             txTmp.vin[nIn].scriptSig = scriptCode;
919
920             // Blank out some of the outputs
921             if ((nHashType & 0x1f) == (int)sigflag.SIGHASH_NONE)
922             {
923                 // Wildcard payee
924                 txTmp.vout = new CTxOut[0];
925
926                 // Let the others update at will
927                 for (int i = 0; i < txTmp.vin.Length; i++)
928                 {
929                     if (i != nIn)
930                     {
931                         txTmp.vin[i].nSequence = 0;
932                     }
933                 }
934             }
935             else if ((nHashType & 0x1f) == (int)sigflag.SIGHASH_SINGLE)
936             {
937                 // Only lock-in the txout payee at same index as txin
938                 int nOut = nIn;
939                 if (nOut >= txTmp.vout.Length)
940                 {
941                     StringBuilder sb = new StringBuilder();
942                     sb.AppendFormat("ERROR: SignatureHash() : nOut={0} out of range\n", nOut);
943                     throw new ArgumentOutOfRangeException("nOut", sb.ToString());
944                 }
945                 Array.Resize(ref txTmp.vout, nOut + 1);
946
947                 for (int i = 0; i < nOut; i++)
948                 {
949                     txTmp.vout[i] = new CTxOut();
950                 }
951
952                 // Let the others update at will
953                 for (int i = 0; i < txTmp.vin.Length; i++)
954                 {
955                     if (i != nIn)
956                     {
957                         txTmp.vin[i].nSequence = 0;
958                     }
959                 }
960             }
961
962             // Blank out other inputs completely, not recommended for open transactions
963             if ((nHashType & (int)sigflag.SIGHASH_ANYONECANPAY) != 0)
964             {
965                 txTmp.vin[0] = txTmp.vin[nIn];
966                 Array.Resize(ref txTmp.vin, 1);
967             }
968
969             // Serialize and hash
970             List<byte> b = new List<byte>();
971             b.AddRange(txTmp.Bytes);
972             b.AddRange(BitConverter.GetBytes(nHashType));
973
974             return Hash256.Compute256(b);
975         }
976
977         public class StackMachineException : Exception
978         {
979             public StackMachineException()
980             {
981             }
982
983             public StackMachineException(string message)
984                 : base(message)
985             {
986             }
987
988             public StackMachineException(string message, Exception inner)
989                 : base(message, inner)
990             {
991             }
992         }
993
994
995         //
996         // Script is a stack machine (like Forth) that evaluates a predicate
997         // returning a bool indicating valid or not.  There are no loops.
998         //
999
1000         /// <summary>
1001         /// Remove last element from stack
1002         /// </summary>
1003         /// <param name="stack">Stack reference</param>
1004         static void popstack(ref List<IEnumerable<byte>> stack)
1005         {
1006             int nCount = stack.Count;
1007             if (nCount == 0)
1008                 throw new StackMachineException("popstack() : stack empty");
1009             stack.RemoveAt(nCount - 1);
1010         }
1011
1012         /// <summary>
1013         /// Get element at specified stack depth
1014         /// </summary>
1015         /// <param name="stack">Stack reference</param>
1016         /// <param name="nDepth">Depth</param>
1017         /// <returns>Byte sequence</returns>
1018         static IEnumerable<byte> stacktop(ref List<IEnumerable<byte>> stack, int nDepth)
1019         {
1020             int nStackElement = stack.Count + nDepth;
1021
1022             if (nDepth >= 0)
1023             {
1024                 StringBuilder sb = new StringBuilder();
1025                 sb.AppendFormat("stacktop() : positive depth ({0}) has no sense.", nDepth);
1026
1027                 throw new StackMachineException(sb.ToString());
1028             }
1029
1030             if (nStackElement < 0)
1031             {
1032                 StringBuilder sb = new StringBuilder();
1033                 sb.AppendFormat("stacktop() : nDepth={0} exceeds real stack depth ({1})", nDepth, stack.Count);
1034
1035                 throw new StackMachineException(sb.ToString());
1036             }
1037
1038             return stack[nStackElement];
1039         }
1040
1041         /// <summary>
1042         /// Cast argument to boolean value
1043         /// </summary>
1044         /// <param name="value">Some byte sequence</param>
1045         /// <returns></returns>
1046         private static bool CastToBool(IEnumerable<byte> arg)
1047         {
1048             byte[] value = arg.ToArray();
1049
1050             for (var i = 0; i < value.Length; i++)
1051             {
1052                 if (value[i] != 0)
1053                 {
1054                     // Can be negative zero
1055                     if (i == value.Length - 1 && value[i] == 0x80)
1056                     {
1057                         return false;
1058                     }
1059
1060                     return true;
1061                 }
1062             }
1063
1064             return false;
1065         }
1066
1067         /// <summary>
1068         /// Cast argument to integer value
1069         /// </summary>
1070         /// <param name="value"></param>
1071         /// <returns></returns>
1072         private static BigInteger CastToBigInteger(IEnumerable<byte> value)
1073         {
1074             if (value.Count() > 4)
1075             {
1076                 throw new StackMachineException("CastToBigInteger() : overflow");
1077             }
1078
1079             return new BigInteger(value.ToArray());
1080         }
1081
1082         static bool EvalScript(ref List<IEnumerable<byte>> stack, CScript script, CTransaction txTo, int nIn, int flags, int nHashType)
1083         {
1084             instruction opcode;
1085
1086             ByteQueue CodeQueue = script.GetByteQUeue();
1087
1088             List<bool> vfExec = new List<bool>();
1089             List<IEnumerable<byte>> altStack = new List<IEnumerable<byte>>();
1090
1091             byte[] falseBytes = new byte[0];
1092             byte[] trueBytes = new byte[] { 0x01 };
1093
1094             if (script.Bytes.Count() > 10000)
1095             {
1096                 return false; // Size limit failed
1097             }
1098
1099             int nOpCount = 0;
1100             int nCodeHashBegin = 0;
1101
1102             IEnumerable<byte> pushArg;
1103
1104             while (GetOp(ref CodeQueue, out opcode, out pushArg)) // Read instructions
1105             {
1106                 bool fExec = vfExec.IndexOf(false) != -1;
1107
1108                 if (pushArg.Count() > 520)
1109                 {
1110                     return false; // Script element size limit failed
1111                 }
1112
1113                 if (opcode > instruction.OP_16 && ++nOpCount > 201)
1114                 {
1115                     return false;
1116                 }
1117
1118                 if (fExec && 0 <= opcode && opcode <= instruction.OP_PUSHDATA4)
1119                 {
1120                     stack.Add(pushArg); // Push argument to stack
1121                 }
1122                 else if (fExec || (instruction.OP_IF <= opcode && opcode <= instruction.OP_ENDIF))
1123                     switch (opcode)
1124                     {
1125                         //
1126                         // Disabled opcodes
1127                         //
1128                         case instruction.OP_CAT:
1129                         case instruction.OP_SUBSTR:
1130                         case instruction.OP_LEFT:
1131                         case instruction.OP_RIGHT:
1132                         case instruction.OP_INVERT:
1133                         case instruction.OP_AND:
1134                         case instruction.OP_OR:
1135                         case instruction.OP_XOR:
1136                         case instruction.OP_2MUL:
1137                         case instruction.OP_2DIV:
1138                         case instruction.OP_MUL:
1139                         case instruction.OP_DIV:
1140                         case instruction.OP_MOD:
1141                         case instruction.OP_LSHIFT:
1142                         case instruction.OP_RSHIFT:
1143                             return false;
1144
1145                         //
1146                         // Push integer instructions
1147                         //
1148                         case instruction.OP_1NEGATE:
1149                         case instruction.OP_1:
1150                         case instruction.OP_2:
1151                         case instruction.OP_3:
1152                         case instruction.OP_4:
1153                         case instruction.OP_5:
1154                         case instruction.OP_6:
1155                         case instruction.OP_7:
1156                         case instruction.OP_8:
1157                         case instruction.OP_9:
1158                         case instruction.OP_10:
1159                         case instruction.OP_11:
1160                         case instruction.OP_12:
1161                         case instruction.OP_13:
1162                         case instruction.OP_14:
1163                         case instruction.OP_15:
1164                         case instruction.OP_16:
1165                             {
1166                                 // ( -- value)
1167                                 BigInteger bn = DecodeOP_N(opcode);
1168                                 stack.Add(bn.ToByteArray());
1169                             }
1170                             break;
1171
1172                         //
1173                         // Extension
1174                         //
1175                         case instruction.OP_NOP:
1176                         case instruction.OP_NOP1:
1177                         case instruction.OP_NOP2:
1178                         case instruction.OP_NOP3:
1179                         case instruction.OP_NOP4:
1180                         case instruction.OP_NOP5:
1181                         case instruction.OP_NOP6:
1182                         case instruction.OP_NOP7:
1183                         case instruction.OP_NOP8:
1184                         case instruction.OP_NOP9:
1185                         case instruction.OP_NOP10:
1186                             {
1187                                 // Just do nothing
1188                                 break;
1189                             }
1190
1191                         //
1192                         // Control
1193                         //
1194                         case instruction.OP_IF:
1195                         case instruction.OP_NOTIF:
1196                             {
1197                                 // <expression> if [statements] [else [statements]] endif
1198                                 bool fValue = false;
1199                                 if (fExec)
1200                                 {
1201                                     if (stack.Count() < 1)
1202                                     {
1203                                         return false;
1204                                     }
1205                                     IEnumerable<byte> vch = stacktop(ref stack, -1);
1206                                     fValue = CastToBool(vch);
1207                                     if (opcode == instruction.OP_NOTIF)
1208                                     {
1209                                         fValue = !fValue;
1210                                     }
1211                                     popstack(ref stack);
1212                                 }
1213                                 vfExec.Add(fValue);
1214                             }
1215                             break;
1216
1217                         case instruction.OP_ELSE:
1218                             {
1219                                 int nExecCount = vfExec.Count();
1220                                 if (nExecCount == 0)
1221                                 {
1222                                     return false;
1223                                 }
1224                                 vfExec[nExecCount - 1] = !vfExec[nExecCount - 1];
1225                             }
1226                             break;
1227
1228                         case instruction.OP_ENDIF:
1229                             {
1230                                 int nExecCount = vfExec.Count();
1231                                 if (nExecCount == 0)
1232                                 {
1233                                     return false;
1234                                 }
1235                                 vfExec.RemoveAt(nExecCount - 1);
1236                             }
1237                             break;
1238
1239                         case instruction.OP_VERIFY:
1240                             {
1241                                 // (true -- ) or
1242                                 // (false -- false) and return
1243                                 if (stack.Count() < 1)
1244                                 {
1245                                     return false;
1246                                 }
1247
1248                                 bool fValue = CastToBool(stacktop(ref stack, -1));
1249                                 if (fValue)
1250                                 {
1251                                     popstack(ref stack);
1252                                 }
1253                                 else
1254                                 {
1255                                     return false;
1256                                 }
1257                             }
1258                             break;
1259
1260                         case instruction.OP_RETURN:
1261                             {
1262                                 return false;
1263                             }
1264
1265                         //
1266                         // Stack ops
1267                         //
1268                         case instruction.OP_TOALTSTACK:
1269                             {
1270                                 if (stack.Count() < 1)
1271                                 {
1272                                     return false;
1273                                 }
1274                                 altStack.Add(stacktop(ref stack, -1));
1275                                 popstack(ref stack);
1276                             }
1277                             break;
1278
1279                         case instruction.OP_FROMALTSTACK:
1280                             {
1281                                 if (altStack.Count() < 1)
1282                                 {
1283                                     return false;
1284                                 }
1285                                 stack.Add(stacktop(ref stack, -1));
1286                                 popstack(ref altStack);
1287                             }
1288                             break;
1289
1290                         case instruction.OP_2DROP:
1291                             {
1292                                 // (x1 x2 -- )
1293                                 if (stack.Count() < 2)
1294                                 {
1295                                     return false;
1296                                 }
1297                                 popstack(ref stack);
1298                                 popstack(ref stack);
1299                             }
1300                             break;
1301
1302                         case instruction.OP_2DUP:
1303                             {
1304                                 // (x1 x2 -- x1 x2 x1 x2)
1305                                 if (stack.Count() < 2)
1306                                 {
1307                                     return false;
1308                                 }
1309                                 IEnumerable<byte> vch1 = stacktop(ref stack, -2);
1310                                 IEnumerable<byte> vch2 = stacktop(ref stack, -1);
1311                                 stack.Add(vch1);
1312                                 stack.Add(vch2);
1313                             }
1314                             break;
1315
1316                         case instruction.OP_3DUP:
1317                             {
1318                                 // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
1319                                 if (stack.Count() < 3)
1320                                 {
1321                                     return false;
1322                                 }
1323                                 IEnumerable<byte> vch1 = stacktop(ref stack, -3);
1324                                 IEnumerable<byte> vch2 = stacktop(ref stack, -2);
1325                                 IEnumerable<byte> vch3 = stacktop(ref stack, -1);
1326                                 stack.Add(vch1);
1327                                 stack.Add(vch2);
1328                                 stack.Add(vch3);
1329                             }
1330                             break;
1331
1332                         case instruction.OP_2OVER:
1333                             {
1334                                 // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
1335                                 if (stack.Count() < 4)
1336                                 {
1337                                     return false;
1338                                 }
1339                                 IEnumerable<byte> vch1 = stacktop(ref stack, -4);
1340                                 IEnumerable<byte> vch2 = stacktop(ref stack, -3);
1341                                 stack.Add(vch1);
1342                                 stack.Add(vch2);
1343                             }
1344                             break;
1345
1346                         case instruction.OP_2ROT:
1347                             {
1348                                 int nStackDepth = stack.Count();
1349                                 // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
1350                                 if (nStackDepth < 6)
1351                                 {
1352                                     return false;
1353                                 }
1354                                 IEnumerable<byte> vch1 = stacktop(ref stack, -6);
1355                                 IEnumerable<byte> vch2 = stacktop(ref stack, -5);
1356                                 stack.RemoveRange(nStackDepth - 6, 2);
1357                                 stack.Add(vch1);
1358                                 stack.Add(vch2);
1359                             }
1360                             break;
1361
1362                         case instruction.OP_2SWAP:
1363                             {
1364                                 // (x1 x2 x3 x4 -- x3 x4 x1 x2)
1365                                 int nStackDepth = stack.Count();
1366                                 if (nStackDepth < 4)
1367                                 {
1368                                     return false;
1369                                 }
1370                                 stack.Swap(nStackDepth - 4, nStackDepth - 2);
1371                                 stack.Swap(nStackDepth - 3, nStackDepth - 1);
1372                             }
1373                             break;
1374
1375                         case instruction.OP_IFDUP:
1376                             {
1377                                 // (x - 0 | x x)
1378                                 if (stack.Count() < 1)
1379                                 {
1380                                     return false;
1381                                 }
1382
1383                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1384
1385                                 if (CastToBool(vch))
1386                                 {
1387                                     stack.Add(vch);
1388                                 }
1389                             }
1390                             break;
1391
1392                         case instruction.OP_DEPTH:
1393                             {
1394                                 // -- stacksize
1395                                 BigInteger bn = new BigInteger((ushort)stack.Count());
1396                                 stack.Add(bn.ToByteArray());
1397                             }
1398                             break;
1399
1400                         case instruction.OP_DROP:
1401                             {
1402                                 // (x -- )
1403                                 if (stack.Count() < 1)
1404                                 {
1405                                     return false;
1406                                 }
1407
1408                                 popstack(ref stack);
1409                             }
1410                             break;
1411
1412                         case instruction.OP_DUP:
1413                             {
1414                                 // (x -- x x)
1415                                 if (stack.Count() < 1)
1416                                 {
1417                                     return false;
1418                                 }
1419
1420                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1421                                 stack.Add(vch);
1422                             }
1423                             break;
1424
1425                         case instruction.OP_NIP:
1426                             {
1427                                 // (x1 x2 -- x2)
1428                                 int nStackDepth = stack.Count();
1429                                 if (nStackDepth < 2)
1430                                 {
1431                                     return false;
1432                                 }
1433
1434                                 stack.RemoveAt(nStackDepth - 2);
1435                             }
1436                             break;
1437
1438                         case instruction.OP_OVER:
1439                             {
1440                                 // (x1 x2 -- x1 x2 x1)
1441                                 if (stack.Count() < 2)
1442                                 {
1443                                     return false;
1444                                 }
1445
1446                                 IEnumerable<byte> vch = stacktop(ref stack, -2);
1447                                 stack.Add(vch);
1448                             }
1449                             break;
1450
1451                         case instruction.OP_PICK:
1452                         case instruction.OP_ROLL:
1453                             {
1454                                 // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
1455                                 // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
1456
1457                                 int nStackDepth = stack.Count();
1458                                 if (nStackDepth < 2)
1459                                 {
1460                                     return false;
1461                                 }
1462
1463                                 int n = (int)CastToBigInteger(stacktop(ref stack, -1));
1464                                 popstack(ref stack);
1465
1466                                 if (n < 0 || n >= stack.Count())
1467                                 {
1468                                     return false;
1469                                 }
1470
1471                                 IEnumerable<byte> vch = stacktop(ref stack, -n - 1);
1472                                 if (opcode == instruction.OP_ROLL)
1473                                 {
1474                                     stack.RemoveAt(nStackDepth - n - 1);
1475                                 }
1476
1477                                 stack.Add(vch);
1478                             }
1479                             break;
1480
1481                         case instruction.OP_ROT:
1482                             {
1483                                 // (x1 x2 x3 -- x2 x3 x1)
1484                                 //  x2 x1 x3  after first swap
1485                                 //  x2 x3 x1  after second swap
1486                                 int nStackDepth = stack.Count();
1487                                 if (nStackDepth < 3)
1488                                 {
1489                                     return false;
1490                                 }
1491                                 stack.Swap(nStackDepth - 3, nStackDepth - 2);
1492                                 stack.Swap(nStackDepth - 2, nStackDepth - 1);
1493
1494                             }
1495                             break;
1496
1497                         case instruction.OP_SWAP:
1498                             {
1499                                 // (x1 x2 -- x2 x1)
1500                                 int nStackDepth = stack.Count();
1501                                 if (nStackDepth < 2)
1502                                 {
1503                                     return false;
1504                                 }
1505                                 stack.Swap(nStackDepth - 2, nStackDepth - 1);
1506                             }
1507                             break;
1508
1509                         case instruction.OP_TUCK:
1510                             {
1511                                 // (x1 x2 -- x2 x1 x2)
1512                                 int nStackDepth = stack.Count();
1513                                 if (nStackDepth < 2)
1514                                 {
1515                                     return false;
1516                                 }
1517                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1518                                 stack.Insert(nStackDepth - 2, vch);
1519                             }
1520                             break;
1521
1522
1523                         case instruction.OP_SIZE:
1524                             {
1525                                 // (in -- in size)
1526                                 if (stack.Count() < 1)
1527                                 {
1528                                     return false;
1529                                 }
1530
1531                                 BigInteger bnSize = new BigInteger((ushort)stacktop(ref stack, -1).Count());
1532                                 stack.Add(bnSize.ToByteArray());
1533                             }
1534                             break;
1535
1536
1537                         //
1538                         // Bitwise logic
1539                         //
1540                         case instruction.OP_EQUAL:
1541                         case instruction.OP_EQUALVERIFY:
1542                             //case instruction.OP_NOTEQUAL: // use OP_NUMNOTEQUAL
1543                             {
1544                                 // (x1 x2 - bool)
1545                                 if (stack.Count() < 2)
1546                                 {
1547                                     return false;
1548                                 }
1549
1550                                 IEnumerable<byte> vch1 = stacktop(ref stack, -2);
1551                                 IEnumerable<byte> vch2 = stacktop(ref stack, -1);
1552                                 bool fEqual = (vch1 == vch2);
1553                                 // OP_NOTEQUAL is disabled because it would be too easy to say
1554                                 // something like n != 1 and have some wiseguy pass in 1 with extra
1555                                 // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
1556                                 //if (opcode == instruction.OP_NOTEQUAL)
1557                                 //    fEqual = !fEqual;
1558                                 popstack(ref stack);
1559                                 popstack(ref stack);
1560                                 stack.Add(fEqual ? trueBytes : falseBytes);
1561
1562                                 if (opcode == instruction.OP_EQUALVERIFY)
1563                                 {
1564                                     if (fEqual)
1565                                     {
1566                                         popstack(ref stack);
1567                                     }
1568                                     else
1569                                     {
1570                                         return false;
1571                                     }
1572                                 }
1573                             }
1574                             break;
1575
1576
1577                         //
1578                         // Numeric
1579                         //
1580                         case instruction.OP_1ADD:
1581                         case instruction.OP_1SUB:
1582                         case instruction.OP_NEGATE:
1583                         case instruction.OP_ABS:
1584                         case instruction.OP_NOT:
1585                         case instruction.OP_0NOTEQUAL:
1586                             {
1587                                 // (in -- out)
1588                                 if (stack.Count() < 1)
1589                                 {
1590                                     return false;
1591                                 }
1592
1593                                 BigInteger bn = CastToBigInteger(stacktop(ref stack, -1));
1594                                 switch (opcode)
1595                                 {
1596                                     case instruction.OP_1ADD:
1597                                         bn = bn + 1;
1598                                         break;
1599                                     case instruction.OP_1SUB:
1600                                         bn = bn - 1;
1601                                         break;
1602                                     case instruction.OP_NEGATE:
1603                                         bn = -bn;
1604                                         break;
1605                                     case instruction.OP_ABS:
1606                                         bn = BigInteger.Abs(bn);
1607                                         break;
1608                                     case instruction.OP_NOT:
1609                                         bn = bn == 0 ? 1 : 0;
1610                                         break;
1611                                     case instruction.OP_0NOTEQUAL:
1612                                         bn = bn != 0 ? 1 : 0;
1613                                         break;
1614
1615                                     default:
1616                                         throw new StackMachineException("invalid instruction");
1617                                 }
1618
1619                                 popstack(ref stack);
1620                                 stack.Add(bn.ToByteArray());
1621                             }
1622                             break;
1623
1624                         case instruction.OP_ADD:
1625                         case instruction.OP_SUB:
1626                         case instruction.OP_BOOLAND:
1627                         case instruction.OP_BOOLOR:
1628                         case instruction.OP_NUMEQUAL:
1629                         case instruction.OP_NUMEQUALVERIFY:
1630                         case instruction.OP_NUMNOTEQUAL:
1631                         case instruction.OP_LESSTHAN:
1632                         case instruction.OP_GREATERTHAN:
1633                         case instruction.OP_LESSTHANOREQUAL:
1634                         case instruction.OP_GREATERTHANOREQUAL:
1635                         case instruction.OP_MIN:
1636                         case instruction.OP_MAX:
1637                             {
1638                                 // (x1 x2 -- out)
1639                                 if (stack.Count() < 2)
1640                                 {
1641                                     return false;
1642                                 }
1643
1644                                 BigInteger bn1 = CastToBigInteger(stacktop(ref stack, -2));
1645                                 BigInteger bn2 = CastToBigInteger(stacktop(ref stack, -1));
1646                                 BigInteger bn = 0;
1647
1648                                 switch (opcode)
1649                                 {
1650                                     case instruction.OP_ADD:
1651                                         bn = bn1 + bn2;
1652                                         break;
1653                                     case instruction.OP_SUB:
1654                                         bn = bn1 - bn2;
1655                                         break;
1656                                     case instruction.OP_BOOLAND:
1657                                         bn = (bn1 != 0 && bn2 != 0) ? 1 : 0;
1658                                         break;
1659                                     case instruction.OP_BOOLOR:
1660                                         bn = (bn1 != 0 || bn2 != 0) ? 1 : 0;
1661                                         break;
1662                                     case instruction.OP_NUMEQUAL:
1663                                         bn = (bn1 == bn2) ? 1 : 0;
1664                                         break;
1665                                     case instruction.OP_NUMEQUALVERIFY:
1666                                         bn = (bn1 == bn2) ? 1 : 0;
1667                                         break;
1668                                     case instruction.OP_NUMNOTEQUAL:
1669                                         bn = (bn1 != bn2) ? 1 : 0;
1670                                         break;
1671                                     case instruction.OP_LESSTHAN:
1672                                         bn = (bn1 < bn2) ? 1 : 0;
1673                                         break;
1674                                     case instruction.OP_GREATERTHAN:
1675                                         bn = (bn1 > bn2) ? 1 : 0;
1676                                         break;
1677                                     case instruction.OP_LESSTHANOREQUAL:
1678                                         bn = (bn1 <= bn2) ? 1 : 0;
1679                                         break;
1680                                     case instruction.OP_GREATERTHANOREQUAL:
1681                                         bn = (bn1 >= bn2) ? 1 : 0;
1682                                         break;
1683                                     case instruction.OP_MIN:
1684                                         bn = (bn1 < bn2 ? bn1 : bn2);
1685                                         break;
1686                                     case instruction.OP_MAX:
1687                                         bn = (bn1 > bn2 ? bn1 : bn2);
1688                                         break;
1689
1690                                     default:
1691                                         throw new StackMachineException("invalid instruction");
1692                                 }
1693
1694                                 popstack(ref stack);
1695                                 popstack(ref stack);
1696                                 stack.Add(bn.ToByteArray());
1697
1698                                 if (opcode == instruction.OP_NUMEQUALVERIFY)
1699                                 {
1700                                     if (CastToBool(stacktop(ref stack, -1)))
1701                                     {
1702                                         popstack(ref stack);
1703                                     }
1704                                     else
1705                                     {
1706                                         return false;
1707                                     }
1708                                 }
1709                             }
1710                             break;
1711
1712                         case instruction.OP_WITHIN:
1713                             {
1714                                 // (x min max -- out)
1715                                 if (stack.Count() < 3)
1716                                     return false;
1717                                 BigInteger bn1 = CastToBigInteger(stacktop(ref stack, -3));
1718                                 BigInteger bn2 = CastToBigInteger(stacktop(ref stack, -2));
1719                                 BigInteger bn3 = CastToBigInteger(stacktop(ref stack, -1));
1720                                 bool fValue = (bn2 <= bn1 && bn1 < bn3);
1721                                 popstack(ref stack);
1722                                 popstack(ref stack);
1723                                 popstack(ref stack);
1724                                 stack.Add(fValue ? trueBytes : falseBytes);
1725                             }
1726                             break;
1727
1728
1729                         //
1730                         // Crypto
1731                         //
1732                         case instruction.OP_RIPEMD160:
1733                         case instruction.OP_SHA1:
1734                         case instruction.OP_SHA256:
1735                         case instruction.OP_HASH160:
1736                         case instruction.OP_HASH256:
1737                             {
1738                                 // (in -- hash)
1739                                 if (stack.Count() < 1)
1740                                     return false;
1741                                 IEnumerable<byte> vch = stacktop(ref stack, -1);
1742                                 IEnumerable<byte> vchHash = null;
1743                                 if (opcode == instruction.OP_RIPEMD160)
1744                                 {
1745                                     RIPEMD160 hash = RIPEMD160.Compute160(vch);
1746                                     vchHash = hash.hashBytes;
1747                                 }
1748                                 else if (opcode == instruction.OP_SHA1)
1749                                 {
1750                                     SHA1 hash = SHA1.Compute1(vch);
1751                                     vchHash = hash.hashBytes;
1752                                 }
1753                                 else if (opcode == instruction.OP_SHA256)
1754                                 {
1755                                     SHA256 hash = SHA256.Compute256(vch);
1756                                     vchHash = hash.hashBytes;
1757                                 }
1758                                 else if (opcode == instruction.OP_HASH160)
1759                                 {
1760                                     Hash160 hash = Hash160.Compute160(vch);
1761                                     vchHash = hash.hashBytes;
1762                                 }
1763                                 else if (opcode == instruction.OP_HASH256)
1764                                 {
1765                                     Hash256 hash = Hash256.Compute256(vch);
1766                                     vchHash = hash.hashBytes;
1767                                 }
1768                                 popstack(ref stack);
1769                                 stack.Add(vchHash);
1770                             }
1771                             break;
1772
1773                         case instruction.OP_CODESEPARATOR:
1774                             {
1775                                 // Hash starts after the code separator
1776                                 nCodeHashBegin = CodeQueue.CurrentIndex;
1777                             }
1778                             break;
1779
1780                         case instruction.OP_CHECKSIG:
1781                         case instruction.OP_CHECKSIGVERIFY:
1782                             {
1783                                 // (sig pubkey -- bool)
1784                                 if (stack.Count() < 2)
1785                                 {
1786                                     return false;
1787                                 }
1788
1789                                 IList<byte> sigBytes = stacktop(ref stack, -2).ToList();
1790                                 IList<byte> pubkeyBytes = stacktop(ref stack, -1).ToList();
1791
1792                                 // Subset of script starting at the most recent codeseparator
1793                                 CScript scriptCode = new CScript(script.Bytes.Skip(nCodeHashBegin));
1794
1795                                 // There's no way for a signature to sign itself
1796                                 scriptCode.RemovePattern(sigBytes);
1797
1798                                 bool fSuccess = IsCanonicalSignature(sigBytes, flags) && IsCanonicalPubKey(pubkeyBytes.ToList(), flags) && CheckSig(sigBytes, pubkeyBytes, scriptCode, txTo, nIn, nHashType, flags);
1799
1800                                 popstack(ref stack);
1801                                 popstack(ref stack);
1802                                 stack.Add(fSuccess ? trueBytes : falseBytes);
1803                                 if (opcode == instruction.OP_CHECKSIGVERIFY)
1804                                 {
1805                                     if (fSuccess)
1806                                     {
1807                                         popstack(ref stack);
1808                                     }
1809                                     else
1810                                     {
1811                                         return false;
1812                                     }
1813                                 }
1814                             }
1815                             break;
1816
1817                         case instruction.OP_CHECKMULTISIG:
1818                         case instruction.OP_CHECKMULTISIGVERIFY:
1819                             {
1820                                 // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
1821
1822                                 int i = 1;
1823                                 if (stack.Count() < i)
1824                                 {
1825                                     return false;
1826                                 }
1827
1828                                 int nKeysCount = (int)CastToBigInteger(stacktop(ref stack, -i));
1829                                 if (nKeysCount < 0 || nKeysCount > 20)
1830                                 {
1831                                     return false;
1832                                 }
1833                                 nOpCount += nKeysCount;
1834                                 if (nOpCount > 201)
1835                                 {
1836                                     return false;
1837                                 }
1838                                 int ikey = ++i;
1839                                 i += nKeysCount;
1840                                 if (stack.Count() < i)
1841                                 {
1842                                     return false;
1843                                 }
1844
1845                                 int nSigsCount = (int)CastToBigInteger(stacktop(ref stack, -i));
1846                                 if (nSigsCount < 0 || nSigsCount > nKeysCount)
1847                                 {
1848                                     return false;
1849                                 }
1850                                 int isig = ++i;
1851                                 i += nSigsCount;
1852                                 if (stack.Count() < i)
1853                                 {
1854                                     return false;
1855                                 }
1856
1857                                 // Subset of script starting at the most recent codeseparator
1858                                 CScript scriptCode = new CScript(script.Bytes.Skip(nCodeHashBegin));
1859
1860                                 // There is no way for a signature to sign itself, so we need to drop the signatures
1861                                 for (int k = 0; k < nSigsCount; k++)
1862                                 {
1863                                     IEnumerable<byte> vchSig = stacktop(ref stack, -isig - k);
1864                                     scriptCode.RemovePattern(vchSig.ToList());
1865                                 }
1866
1867                                 bool fSuccess = true;
1868                                 while (fSuccess && nSigsCount > 0)
1869                                 {
1870                                     IList<byte> sigBytes = stacktop(ref stack, -isig).ToList();
1871                                     IList<byte> pubKeyBytes = stacktop(ref stack, -ikey).ToList();
1872
1873                                     // Check signature
1874                                     bool fOk = IsCanonicalSignature(sigBytes, flags) && IsCanonicalPubKey(pubKeyBytes.ToList(), flags) && CheckSig(sigBytes, pubKeyBytes, scriptCode, txTo, nIn, nHashType, flags);
1875
1876                                     if (fOk)
1877                                     {
1878                                         isig++;
1879                                         nSigsCount--;
1880                                     }
1881                                     ikey++;
1882                                     nKeysCount--;
1883
1884                                     // If there are more signatures left than keys left,
1885                                     // then too many signatures have failed
1886                                     if (nSigsCount > nKeysCount)
1887                                     {
1888                                         fSuccess = false;
1889                                     }
1890                                 }
1891
1892                                 while (i-- > 1)
1893                                 {
1894                                     popstack(ref stack);
1895                                 }
1896
1897                                 // A bug causes CHECKMULTISIG to consume one extra argument
1898                                 // whose contents were not checked in any way.
1899                                 //
1900                                 // Unfortunately this is a potential source of mutability,
1901                                 // so optionally verify it is exactly equal to zero prior
1902                                 // to removing it from the stack.
1903                                 if (stack.Count() < 1)
1904                                 {
1905                                     return false;
1906                                 }
1907                                 if ((flags & (int)scriptflag.SCRIPT_VERIFY_NULLDUMMY) != 0 && stacktop(ref stack, -1).Count() != 0)
1908                                 {
1909                                     return false; // CHECKMULTISIG dummy argument not null
1910                                 }
1911                                 popstack(ref stack);
1912
1913                                 stack.Add(fSuccess ? trueBytes : falseBytes);
1914
1915                                 if (opcode == instruction.OP_CHECKMULTISIGVERIFY)
1916                                 {
1917                                     if (fSuccess)
1918                                     {
1919                                         popstack(ref stack);
1920                                     }
1921                                     else
1922                                     {
1923                                         return false;
1924                                     }
1925                                 }
1926                             }
1927                             break;
1928
1929                         default:
1930                             return false;
1931                     }
1932
1933                 // Size limits
1934                 if (stack.Count() + altStack.Count() > 1000)
1935                 {
1936                     return false;
1937                 }
1938             }
1939
1940
1941             if (vfExec.Count() == 0)
1942             {
1943                 return false;
1944             }
1945
1946             return true;
1947         }
1948
1949
1950         static bool IsCanonicalPubKey(IList<byte> pubKeyBytes, int flags)
1951         {
1952             if ((flags & (int)scriptflag.SCRIPT_VERIFY_STRICTENC) == 0)
1953                 return true;
1954
1955             if (pubKeyBytes.Count() < 33)
1956                 return false;  // Non-canonical public key: too short
1957             if (pubKeyBytes[0] == 0x04)
1958             {
1959                 if (pubKeyBytes.Count() != 65)
1960                     return false; // Non-canonical public key: invalid length for uncompressed key
1961             }
1962             else if (pubKeyBytes[0] == 0x02 || pubKeyBytes[0] == 0x03)
1963             {
1964                 if (pubKeyBytes.Count() != 33)
1965                     return false; // Non-canonical public key: invalid length for compressed key
1966             }
1967             else
1968             {
1969                 return false; // Non-canonical public key: compressed nor uncompressed
1970             }
1971             return true;
1972         }
1973
1974         static bool IsCanonicalSignature(IList<byte> sigBytes, int flags)
1975         {
1976             // STUB
1977
1978             return true;
1979         }
1980
1981         static bool CheckSig(IList<byte> vchSig, IList<byte> vchPubKey, CScript scriptCode, CTransaction txTo, int nIn, int nHashType, int flags)
1982         {
1983             CPubKey pubkey;
1984
1985             try
1986             {
1987                 // Trying to initialize the public key instance
1988
1989                 pubkey = new CPubKey(vchPubKey);
1990             }
1991             catch (Exception)
1992             {
1993                 // Exception occurred while initializing the public key
1994
1995                 return false; 
1996             }
1997
1998             if (!pubkey.IsValid)
1999             {
2000                 return false;
2001             }
2002
2003             if (vchSig.Count == 0)
2004             {
2005                 return false;
2006             }
2007
2008             // Hash type is one byte tacked on to the end of the signature
2009             if (nHashType == 0)
2010             {
2011                 nHashType = vchSig.Last();
2012             }
2013             else if (nHashType != vchSig.Last())
2014             {
2015                 return false;
2016             }
2017
2018             // Remove hash type
2019             vchSig.RemoveAt(vchSig.Count - 1);
2020
2021             Hash256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType);
2022
2023             if (!pubkey.VerifySignature(sighash, vchSig))
2024             {
2025                 return false;
2026             }
2027
2028             return true;
2029         }
2030     };
2031 }