Turn ByteQueue into MemoryStream wrapper, use MemoryStream for serialization of COutP...
[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 using System.IO;
23
24 namespace Novacoin
25 {
26     [Serializable]
27     public class TxInConstructorException : Exception
28     {
29         public TxInConstructorException()
30         {
31         }
32
33         public TxInConstructorException(string message)
34                 : base(message)
35         {
36         }
37
38         public TxInConstructorException(string message, Exception inner)
39                 : base(message, inner)
40         {
41         }
42     }
43
44     /// <summary>
45     /// Transaction input.
46     /// </summary>
47     public class CTxIn
48         {
49         /// <summary>
50         /// Previous input data
51         /// </summary>
52         public COutPoint prevout;
53
54                 /// <summary>
55                 /// First half of script, signatures for the scriptPubKey
56                 /// </summary>
57         public CScript scriptSig;
58
59                 /// <summary>
60                 /// Transaction variant number, irrelevant if nLockTime isn't specified. Its value is 0xffffffff by default.
61                 /// </summary>
62         public uint nSequence = uint.MaxValue;
63
64         /// <summary>
65         /// Initialize new CTxIn instance as copy of another one.
66         /// </summary>
67         /// <param name="i">CTxIn instance.</param>
68         public CTxIn(CTxIn i)
69         {
70             prevout = new COutPoint(i.prevout);
71             scriptSig = i.scriptSig;
72             nSequence = i.nSequence;
73         }
74
75         /// <summary>
76         /// Initialize an empty instance of CTxIn class
77         /// </summary>
78         public CTxIn()
79         {
80             prevout = new COutPoint();
81             scriptSig = new CScript();
82         }
83
84         /// <summary>
85         /// Read vin list from byte sequence.
86         /// </summary>
87         /// <param name="wBytes">Reference to byte sequence</param>
88         /// <returns>Inputs array</returns>
89         public static CTxIn[] ReadTxInList(ref ByteQueue wBytes)
90         {
91             try
92             {
93                 // Get amount
94                 int nInputs = (int)wBytes.GetVarInt();
95                 var vin = new CTxIn[nInputs];
96
97                 for (int nIndex = 0; nIndex < nInputs; nIndex++)
98                 {
99                     // Fill inputs array
100                     vin[nIndex] = new CTxIn();
101                     vin[nIndex].prevout = new COutPoint(wBytes.Get(36));
102                     vin[nIndex].scriptSig = new CScript(wBytes.Get((int)wBytes.GetVarInt()));
103                     vin[nIndex].nSequence = BitConverter.ToUInt32(wBytes.Get(4), 0);
104                 }
105
106                 // Return inputs array
107                 return vin;
108             }
109             catch (Exception e)
110             {
111                 throw new TxInConstructorException("Desirealization failed.", e);
112             }
113         }
114
115         /// <summary>
116         /// Serialized size
117         /// </summary>
118         public int Size
119         {
120             get {
121                 int nSize = 40; // COutPoint, nSequence
122                 nSize += VarInt.GetEncodedSize(scriptSig.Size);
123                 nSize += scriptSig.Size;
124
125                 return nSize;
126             }
127         }
128
129         /// <summary>
130         /// Get raw bytes representation of our input.
131         /// </summary>
132         /// <returns>Byte sequence.</returns>
133         public static implicit operator byte[] (CTxIn input)
134         {
135             var stream = new MemoryStream();
136             var writer = new BinaryWriter(stream);
137
138             writer.Write(input.prevout); // prevout
139             writer.Write(VarInt.EncodeVarInt(input.scriptSig.Size)); // scriptSig length
140             writer.Write(input.scriptSig); // scriptSig
141             writer.Write(input.nSequence); // nSequence
142
143             var inputBytes = stream.ToArray();
144             writer.Close();
145             return inputBytes;
146         }
147
148         public bool IsFinal
149         {
150             get { return (nSequence == uint.MaxValue); }
151         }
152         public override string ToString ()
153                 {
154                         StringBuilder sb = new StringBuilder ();
155
156             sb.AppendFormat("CTxIn(");
157             sb.Append(prevout.ToString());
158
159             if(prevout.IsNull)
160             {
161                 sb.AppendFormat(", coinbase={0}", Interop.ToHex((byte[])scriptSig));
162             }
163             else
164             {
165                 sb.AppendFormat(", scriptsig={0}", scriptSig.ToString());
166             }
167
168             if (nSequence != uint.MaxValue)
169             {
170                 sb.AppendFormat(", nSequence={0}", nSequence);
171             }
172
173             sb.Append(")");
174
175
176             return sb.ToString ();
177                 }
178
179         }
180 }