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