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