af8539feac791b19f035c45b20ceaf5230675f03
[NovacoinLibrary.git] / Novacoin / CTxIn.cs
1 \feff/**
2  *  Novacoin classes library
3  *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
4
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Affero General Public License as
7  *  published by the Free Software Foundation, either version 3 of the
8  *  License, or (at your option) any later version.
9
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Affero General Public License for more details.
14
15  *  You should have received a copy of the GNU Affero General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 using System;
20 using System.Text;
21 using System.Collections.Generic;
22
23 namespace Novacoin
24 {
25     [Serializable]
26     public class TxInConstructorException : Exception
27     {
28         public TxInConstructorException()
29         {
30         }
31
32         public TxInConstructorException(string message)
33                 : base(message)
34         {
35         }
36
37         public TxInConstructorException(string message, Exception inner)
38                 : base(message, inner)
39         {
40         }
41     }
42
43     /// <summary>
44     /// Transaction input.
45     /// </summary>
46     public class CTxIn
47         {
48         /// <summary>
49         /// Previous input data
50         /// </summary>
51         public COutPoint prevout;
52
53                 /// <summary>
54                 /// First half of script, signatures for the scriptPubKey
55                 /// </summary>
56         public CScript scriptSig;
57
58                 /// <summary>
59                 /// Transaction variant number, irrelevant if nLockTime isn't specified. Its value is 0xffffffff by default.
60                 /// </summary>
61         public uint nSequence = uint.MaxValue;
62
63         /// <summary>
64         /// Initialize new CTxIn instance as copy of another one.
65         /// </summary>
66         /// <param name="i">CTxIn instance.</param>
67         public CTxIn(CTxIn i)
68         {
69             prevout = new COutPoint(i.prevout);
70             scriptSig = i.scriptSig;
71             nSequence = i.nSequence;
72         }
73
74         /// <summary>
75         /// Initialize an empty instance of CTxIn class
76         /// </summary>
77         public CTxIn()
78         {
79             prevout = new COutPoint();
80             scriptSig = new CScript();
81         }
82
83         /// <summary>
84         /// Read vin list from byte sequence.
85         /// </summary>
86         /// <param name="wBytes">Reference to byte sequence</param>
87         /// <returns>Inputs array</returns>
88         public static CTxIn[] ReadTxInList(ref ByteQueue wBytes)
89         {
90             try
91             {
92                 // Get amount
93                 int nInputs = (int)wBytes.GetVarInt();
94                 var vin = new CTxIn[nInputs];
95
96                 for (int nIndex = 0; nIndex < nInputs; nIndex++)
97                 {
98                     // Fill inputs array
99                     vin[nIndex] = new CTxIn();
100                     vin[nIndex].prevout = new COutPoint(wBytes.Get(36));
101                     vin[nIndex].scriptSig = new CScript(wBytes.Get((int)wBytes.GetVarInt()));
102                     vin[nIndex].nSequence = BitConverter.ToUInt32(wBytes.Get(4), 0);
103                 }
104
105                 // Return inputs array
106                 return vin;
107             }
108             catch (Exception e)
109             {
110                 throw new TxInConstructorException("Desirealization failed.", e);
111             }
112         }
113
114         /// <summary>
115         /// Serialized size
116         /// </summary>
117         public int Size
118         {
119             get {
120                 int nSize = 40; // COutPoint, nSequence
121                 nSize += VarInt.GetEncodedSize(scriptSig.Size);
122                 nSize += scriptSig.Size;
123
124                 return nSize;
125             }
126         }
127
128         /// <summary>
129         /// Get raw bytes representation of our input.
130         /// </summary>
131         /// <returns>Byte sequence.</returns>
132         public static implicit operator byte[] (CTxIn input)
133         {
134             var inputBytes = new List<byte>();
135
136             inputBytes.AddRange((byte[])input.prevout); // prevout
137
138             var s = (byte[])input.scriptSig;
139             inputBytes.AddRange(VarInt.EncodeVarInt(s.Length)); // scriptSig length
140             inputBytes.AddRange(s); // scriptSig
141             inputBytes.AddRange(BitConverter.GetBytes(input.nSequence)); // Sequence
142
143             return inputBytes.ToArray();
144         }
145         
146         public bool IsFinal
147         {
148             get { return (nSequence == uint.MaxValue); }
149         }
150         public override string ToString ()
151                 {
152                         StringBuilder sb = new StringBuilder ();
153
154             sb.AppendFormat("CTxIn(");
155             sb.Append(prevout.ToString());
156
157             if(prevout.IsNull)
158             {
159                 sb.AppendFormat(", coinbase={0}", Interop.ToHex((byte[])scriptSig));
160             }
161             else
162             {
163                 sb.AppendFormat(", scriptsig={0}", scriptSig.ToString());
164             }
165
166             if (nSequence != uint.MaxValue)
167             {
168                 sb.AppendFormat(", nSequence={0}", nSequence);
169             }
170
171             sb.Append(")");
172
173
174             return sb.ToString ();
175                 }
176
177         }
178 }