Few new structures to be used in the near future.
[NovacoinLibrary.git] / Novacoin / CTxOut.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         /// <summary>
27         /// Transaction output.
28         /// </summary>
29         public class CTxOut
30         {
31                 /// <summary>
32                 /// Input value.
33                 /// </summary>
34         public ulong nValue = ulong.MaxValue;
35
36                 /// <summary>
37                 /// Second half of script which contains spending instructions.
38                 /// </summary>
39         public CScript scriptPubKey;
40
41         /// <summary>
42         /// Initialize new outpoint using provided value and script.
43         /// </summary>
44         /// <param name="nValue">Input value</param>
45         /// <param name="scriptPubKey">Spending instructions.</param>
46         public CTxOut(ulong nValue, CScript scriptPubKey)
47         {
48             this.nValue = nValue;
49             this.scriptPubKey = scriptPubKey;
50         }
51
52         /// <summary>
53         /// Initialize new CTxOut instance as a copy of another instance.
54         /// </summary>
55         /// <param name="o">CTxOut instance.</param>
56         public CTxOut(CTxOut o)
57         {
58             nValue = o.nValue;
59             scriptPubKey = o.scriptPubKey;
60         }
61
62         /// <summary>
63         /// Initialize an empty instance of CTxOut class
64         /// </summary>
65         public CTxOut()
66         {
67             SetEmpty();
68         }
69
70         /// <summary>
71         /// Read vout list from byte sequence.
72         /// </summary>
73         /// <param name="wBytes">Reference to binary reader</param>
74         /// <returns>Outputs array</returns>
75         internal static CTxOut[] ReadTxOutList(ref BinaryReader reader)
76         {
77             int nOutputs = (int)VarInt.ReadVarInt(ref reader);
78             var vout =new CTxOut[nOutputs];
79
80             for (int nIndex = 0; nIndex < nOutputs; nIndex++)
81             {
82                 // Fill outputs array
83                 vout[nIndex] = new CTxOut();
84                 vout[nIndex].nValue = reader.ReadUInt64();
85
86                 int nScriptPKLen = (int)VarInt.ReadVarInt(ref reader);
87                 vout[nIndex].scriptPubKey = new CScript(reader.ReadBytes(nScriptPKLen));
88             }
89
90             return vout;
91         }
92
93         /// <summary>
94         /// Deserialize outputs array.
95         /// </summary>
96         /// <param name="outBytes">Byte array</param>
97         /// <returns>Outputs array</returns>
98         public static CTxOut[] DeserializeOutputsArray(byte[] outBytes)
99         {
100             var stream = new MemoryStream(outBytes);
101             var reader = new BinaryReader(stream);
102
103             CTxOut[] result = ReadTxOutList(ref reader);
104
105             reader.Close();
106
107             return result;
108         }
109
110         /// <summary>
111         /// Create serialized representation of outputs array.
112         /// </summary>
113         /// <param name="vout">Outputs array</param>
114         /// <returns>Byte array</returns>
115         public static byte[] SerializeOutputsArray(CTxOut[] vout)
116         {
117             var stream = new MemoryStream();
118             var writer = new BinaryWriter(stream);
119
120             writer.Write(VarInt.EncodeVarInt(vout.Length));
121
122             foreach (var o in vout)
123             {
124                 writer.Write(o);
125             }
126
127             var resultBytes = stream.ToArray();
128
129             writer.Close();
130
131             return resultBytes;
132         }
133
134
135         /// <summary>
136         /// Get raw bytes representation of our output.
137         /// </summary>
138         /// <returns>Byte sequence.</returns>
139         public static implicit operator byte[] (CTxOut output)
140         {
141             var stream = new MemoryStream();
142             var writer = new BinaryWriter(stream);
143
144             writer.Write(output.nValue); // txout value
145             writer.Write(VarInt.EncodeVarInt(output.scriptPubKey.Size)); // scriptPubKey length
146             writer.Write(output.scriptPubKey);  // scriptPubKey
147
148             var resultBytes = stream.ToArray();
149
150             writer.Close();
151
152             return resultBytes;
153         }
154
155         /// <summary>
156         /// Null prevouts have -1 value
157         /// </summary>
158         public void SetNull()
159         {
160             nValue = ulong.MaxValue;
161             scriptPubKey = new CScript();
162         }
163
164         /// <summary>
165         /// Empty outputs have zero value and empty scriptPubKey
166         /// </summary>
167         public void SetEmpty()
168         {
169             nValue = 0;
170             scriptPubKey = new CScript();
171         }
172
173         public bool IsNull
174         {
175             get { return (nValue == ulong.MaxValue); }
176         }
177
178         public bool IsEmpty
179         {
180            get { return nValue == 0 && scriptPubKey.IsNull; }
181         }
182
183         /// <summary>
184         /// Serialized size
185         /// </summary>
186         public int Size
187         {
188             get
189             {
190                 var nScriptSize = scriptPubKey.Size;
191                 return 8 + VarInt.GetEncodedSize(nScriptSize) + nScriptSize;
192             }
193         }
194
195         public override string ToString ()
196                 {
197                         var sb = new StringBuilder ();
198                         sb.AppendFormat ("CTxOut(nValue={0}, scriptPubKey={1})", nValue, scriptPubKey.ToString());
199
200                         return sb.ToString ();
201                 }
202         }
203 }
204