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