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