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