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