Turn ByteQueue into MemoryStream wrapper, use MemoryStream for serialization of COutP...
[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 byte sequence</param>
63         /// <returns>Outputs array</returns>
64         public static CTxOut[] ReadTxOutList(ref ByteQueue wBytes)
65         {
66             int nOutputs = (int)wBytes.GetVarInt();
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 = BitConverter.ToUInt64(wBytes.Get(8), 0);
74
75                 int nScriptPKLen = (int)wBytes.GetVarInt();
76                 vout[nIndex].scriptPubKey = new CScript(wBytes.Get(nScriptPKLen));
77             }
78
79             return vout;
80         }
81
82         /// <summary>
83         /// Get raw bytes representation of our output.
84         /// </summary>
85         /// <returns>Byte sequence.</returns>
86         public static implicit operator byte[] (CTxOut output)
87         {
88             var stream = new MemoryStream();
89             var writer = new BinaryWriter(stream);
90
91             writer.Write(output.nValue); // txout value
92             writer.Write(VarInt.EncodeVarInt(output.scriptPubKey.Size)); // scriptPubKey length
93             writer.Write(output.scriptPubKey);  // scriptPubKey
94
95             var resultBytes = stream.ToArray();
96
97             writer.Close();
98
99             return resultBytes;
100         }
101
102         /// <summary>
103         /// Null prevouts have -1 value
104         /// </summary>
105         public void SetNull()
106         {
107             nValue = ulong.MaxValue;
108             scriptPubKey = new CScript();
109         }
110
111         /// <summary>
112         /// Empty outputs have zero value and empty scriptPubKey
113         /// </summary>
114         public void SetEmpty()
115         {
116             nValue = 0;
117             scriptPubKey = new CScript();
118         }
119
120         public bool IsNull
121         {
122             get { return (nValue == ulong.MaxValue); }
123         }
124
125         public bool IsEmpty
126         {
127            get { return nValue == 0 && scriptPubKey.IsNull; }
128         }
129
130         /// <summary>
131         /// Serialized size
132         /// </summary>
133         public int Size
134         {
135             get
136             {
137                 var nScriptSize = scriptPubKey.Size;
138                 return 8 + VarInt.GetEncodedSize(nScriptSize) + nScriptSize;
139             }
140         }
141
142         public override string ToString ()
143                 {
144                         var sb = new StringBuilder ();
145                         sb.AppendFormat ("CTxOut(nValue={0}, scriptPubKey={1})", nValue, scriptPubKey.ToString());
146
147                         return sb.ToString ();
148                 }
149         }
150 }
151