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