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