COutPoint class, coinbase/coinstake properties
authorCryptoManiac <balthazar.ad@gmail.com>
Fri, 21 Aug 2015 12:15:34 +0000 (15:15 +0300)
committerCryptoManiac <balthazar.ad@gmail.com>
Fri, 21 Aug 2015 12:15:34 +0000 (15:15 +0300)
Novacoin/COutPoint.cs [new file with mode: 0644]
Novacoin/CScript.cs
Novacoin/CTransaction.cs
Novacoin/CTxIn.cs
Novacoin/CTxOut.cs
Novacoin/Hash.cs
Novacoin/Novacoin.csproj

diff --git a/Novacoin/COutPoint.cs b/Novacoin/COutPoint.cs
new file mode 100644 (file)
index 0000000..4c9f17a
--- /dev/null
@@ -0,0 +1,73 @@
+\feffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Novacoin
+{
+    public class COutPoint
+    {
+        /// <summary>
+        /// Hash of parent transaction.
+        /// </summary>
+        public Hash256 hash;
+
+        /// <summary>
+        /// Parent input number.
+        /// </summary>
+        public uint n;
+
+        public COutPoint()
+        {
+            hash = new Hash256();
+            n = uint.MaxValue;
+        }
+
+        public COutPoint(Hash256 hashIn, uint nIn)
+        {
+            hash = hashIn;
+            n = nIn;
+        }
+
+        public COutPoint(COutPoint o)
+        {
+            hash = new Hash256(o.hash);
+            n = o.n;
+        }
+
+        public COutPoint(IEnumerable<byte> bytes)
+        {
+            hash = new Hash256(bytes.Take(32));
+            n = BitConverter.ToUInt32(bytes.Skip(32).Take(4).ToArray(), 0);
+        }
+
+        public bool IsNull
+        {
+            get { return hash.IsZero && n == uint.MaxValue; }
+        }
+
+        public IList<byte> Bytes
+        {
+            get
+            {
+                List<byte> r = new List<byte>();
+                r.AddRange(hash.hashBytes);
+                r.AddRange(BitConverter.GetBytes(n));
+
+                return r;
+            }
+        }
+
+        public override string ToString()
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.AppendFormat("COutPoint({0}, {1})", hash.ToString(), n);
+
+            return sb.ToString();
+        }
+
+        
+    }
+
+}
index 835c53d..4223791 100644 (file)
@@ -174,7 +174,6 @@ namespace Novacoin
         /// <summary>
         /// Is it true that script doesn't contain anything except push value operations?
         /// </summary>
-        /// <returns>Checking result</returns>
         public bool IsPushonly
         {
             get
@@ -201,7 +200,6 @@ namespace Novacoin
         /// <summary>
         /// Is it true that script doesn't contain non-canonical push operations?
         /// </summary>
-        /// <returns>Checking result</returns>
         public bool HasOnlyCanonicalPushes
         {
             get
@@ -245,7 +243,6 @@ namespace Novacoin
         /// <summary>
         /// Quick test for pay-to-script-hash CScripts
         /// </summary>
-        /// <returns>Checking result</returns>
         public bool IsPayToScriptHash
         {
             get
@@ -262,7 +259,6 @@ namespace Novacoin
         /// <summary>
         /// Quick test for pay-to-pubkeyhash CScripts
         /// </summary>
-        /// <returns>Checking result</returns>
         public bool IsPayToPubKeyHash
         {
             get
@@ -279,6 +275,14 @@ namespace Novacoin
         }
 
         /// <summary>
+        /// Quick test for Null destination
+        /// </summary>
+        public bool IsNull
+        {
+            get { return codeBytes.Count == 0; }
+        }
+
+        /// <summary>
         /// Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs
         /// as 20 sigops. With pay-to-script-hash, that changed:
         /// CHECKMULTISIGs serialized in scriptSigs are
index 8fba084..1c58089 100644 (file)
@@ -4,35 +4,35 @@ using System.Collections.Generic;
 
 namespace Novacoin
 {
-       /// <summary>
-       /// Represents the transaction. Any transaction must provide one input and one output at least.
-       /// </summary>
-       public class CTransaction
-       {
-               /// <summary>
-               /// Version of transaction schema.
-               /// </summary>
-               public uint nVersion = 1;
-
-               /// <summary>
-               /// Transaction timestamp.
-               /// </summary>
-               public uint nTime = 0;
-
-               /// <summary>
-               /// Array of transaction inputs
-               /// </summary>
-               public CTxIn[] vin;
-
-               /// <summary>
-               /// Array of transaction outputs
-               /// </summary>
-               public CTxOut[] vout;
-
-               /// <summary>
-               /// Block height or timestamp when transaction is final
-               /// </summary>
-               public uint nLockTime = 0;
+    /// <summary>
+    /// Represents the transaction. Any transaction must provide one input and one output at least.
+    /// </summary>
+    public class CTransaction
+    {
+        /// <summary>
+        /// Version of transaction schema.
+        /// </summary>
+        public uint nVersion = 1;
+
+        /// <summary>
+        /// Transaction timestamp.
+        /// </summary>
+        public uint nTime = 0;
+
+        /// <summary>
+        /// Array of transaction inputs
+        /// </summary>
+        public CTxIn[] vin;
+
+        /// <summary>
+        /// Array of transaction outputs
+        /// </summary>
+        public CTxOut[] vout;
+
+        /// <summary>
+        /// Block height or timestamp when transaction is final
+        /// </summary>
+        public uint nLockTime = 0;
 
         /// <summary>
         /// Initialize an empty instance
@@ -77,12 +77,12 @@ namespace Novacoin
         /// Parse byte sequence and initialize new instance of CTransaction
         /// </summary>
         /// <param name="txBytes">Byte sequence</param>
-               public CTransaction (IList<byte> txBytes)
-               {
+               public CTransaction(IList<byte> txBytes)
+        {
             WrappedList<byte> wBytes = new WrappedList<byte>(txBytes);
 
-            nVersion = BitConverter.ToUInt32(wBytes.GetItems(4),0);
-            nTime = BitConverter.ToUInt32(wBytes.GetItems(4),0);
+            nVersion = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
+            nTime = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
 
             int nInputs = (int)VarInt.ReadVarInt(ref wBytes);
             vin = new CTxIn[nInputs];
@@ -92,8 +92,7 @@ namespace Novacoin
                 // Fill inputs array
                 vin[nCurrentInput] = new CTxIn();
 
-                vin[nCurrentInput].txID = new Hash256(wBytes.GetItems(32));
-                vin[nCurrentInput].n = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
+                vin[nCurrentInput].prevout = new COutPoint(wBytes.GetItems(36));
 
                 int nScriptSigLen = (int)VarInt.ReadVarInt(ref wBytes);
                 vin[nCurrentInput].scriptSig = new CScript(wBytes.GetItems(nScriptSigLen));
@@ -107,14 +106,14 @@ namespace Novacoin
             {
                 // Fill outputs array
                 vout[nCurrentOutput] = new CTxOut();
-                vout[nCurrentOutput].nValue = BitConverter.ToUInt64(wBytes.GetItems(8), 0);
+                vout[nCurrentOutput].nValue = BitConverter.ToInt64(wBytes.GetItems(8), 0);
 
                 int nScriptPKLen = (int)VarInt.ReadVarInt(ref wBytes);
                 vout[nCurrentOutput].scriptPubKey = new CScript(wBytes.GetItems(nScriptPKLen));
             }
 
             nLockTime = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
-               }
+        }
 
         /// <summary>
         /// Read transactions array which is encoded in the block body.
@@ -124,9 +123,9 @@ namespace Novacoin
         public static CTransaction[] ReadTransactionsList(ref WrappedList<byte> wTxBytes)
         {
             CTransaction[] tx;
-            
+
             // Read amount of transactions
-            int nTransactions = (int) VarInt.ReadVarInt(ref wTxBytes);
+            int nTransactions = (int)VarInt.ReadVarInt(ref wTxBytes);
             tx = new CTransaction[nTransactions];
 
             for (int nTx = 0; nTx < nTransactions; nTx++)
@@ -149,6 +148,20 @@ namespace Novacoin
             return tx;
         }
 
+        public bool IsCoinBase
+        {
+            get { return (vin.Length == 1 && vin[0].prevout.IsNull && vout.Length >= 1); }
+        }
+
+        public bool IsCoinStake
+        {
+            get
+            {
+                return (vin.Length > 0 && (!vin[0].prevout.IsNull) && vout.Length >= 2 && vout[0].IsEmpty);
+            }
+        }
+
+
         public IList<byte> Bytes
         {
             get
index 9983c65..671a0a1 100644 (file)
@@ -9,15 +9,10 @@ namespace Novacoin
        /// </summary>
        public class CTxIn
        {
-               /// <summary>
-               /// Hash of parent transaction.
-               /// </summary>
-               public Hash256 txID;
-
-               /// <summary>
-               /// Parent input number.
-               /// </summary>
-        public uint n = 0;
+        /// <summary>
+        /// Previous input data
+        /// </summary>
+        public COutPoint prevout;
 
                /// <summary>
                /// First half of script, signatures for the scriptPubKey
@@ -35,8 +30,7 @@ namespace Novacoin
         /// <param name="i">CTxIn instance.</param>
         public CTxIn(CTxIn i)
         {
-            txID = i.txID;
-            n = i.n;
+            prevout = new COutPoint(i.prevout);
             scriptSig = i.scriptSig;
             nSequence = i.nSequence;
         }
@@ -46,7 +40,7 @@ namespace Novacoin
         /// </summary>
         public CTxIn()
         {
-            txID = new Hash256();
+            prevout = new COutPoint();
             scriptSig = new CScript();
         }
 
@@ -67,9 +61,7 @@ namespace Novacoin
             {
                 // Fill inputs array
                 vin[nIndex] = new CTxIn();
-
-                vin[nIndex].txID = new Hash256(wBytes.GetItems(32));
-                vin[nIndex].n = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
+                vin[nIndex].prevout = new COutPoint(wBytes.GetItems(36));
                 vin[nIndex].scriptSig = new CScript(wBytes.GetItems((int)VarInt.ReadVarInt(ref wBytes)));
                 vin[nIndex].nSequence = BitConverter.ToUInt32(wBytes.GetItems(4), 0);
             }
@@ -88,8 +80,7 @@ namespace Novacoin
             {
                 List<byte> inputBytes = new List<byte>();
 
-                inputBytes.AddRange(txID.hashBytes); // Input transaction id
-                inputBytes.AddRange(BitConverter.GetBytes(n)); // Output number
+                inputBytes.AddRange(prevout.Bytes); // prevout
 
                 List<byte> s = new List<byte>(scriptSig.Bytes);
 
@@ -101,15 +92,15 @@ namespace Novacoin
             }
         }
 
-        public bool IsCoinBase
+        public bool IsFinal
         {
-            get { return txID.IsZero; }
+            get { return (nSequence == uint.MaxValue); }
         }
-
-               public override string ToString ()
+        public override string ToString ()
                {
                        StringBuilder sb = new StringBuilder ();
 
+            /*
             if (IsCoinBase)
             {
                 sb.AppendFormat("CTxIn(txId={0}, coinbase={2}, nSequence={3})", txID.ToString(), n, Interop.ToHex(scriptSig.Bytes), nSequence);
@@ -118,8 +109,30 @@ namespace Novacoin
             {
                 sb.AppendFormat("CTxIn(txId={0}, n={1}, scriptSig={2}, nSequence={3})", txID.ToString(), n, scriptSig.ToString(), nSequence);
             }
+            */
+
+
+            sb.AppendFormat("CTxIn(");
+            sb.Append(prevout.ToString());
+
+            if(prevout.IsNull)
+            {
+                sb.AppendFormat(", coinbase={0}", Interop.ToHex(scriptSig.Bytes));
+            }
+            else
+            {
+                sb.AppendFormat(", scriptsig={0}", scriptSig.ToString());
+            }
+
+            if (nSequence != uint.MaxValue)
+            {
+                sb.AppendFormat(", nSequence={0}", nSequence);
+            }
+
+            sb.Append(")");
+
 
-                       return sb.ToString ();
+            return sb.ToString ();
                }
 
        }
index 920fcd5..3e3d4c1 100644 (file)
@@ -12,7 +12,7 @@ namespace Novacoin
                /// <summary>
                /// Input value.
                /// </summary>
-        public ulong nValue;
+        public long nValue = -1;
 
                /// <summary>
                /// Second half of script which contains spending instructions.
@@ -81,6 +81,28 @@ namespace Novacoin
             }
         }
 
+        public void SetNull()
+        {
+            nValue = -1;
+            scriptPubKey.SetNullDestination();
+        }
+
+        public void SetEmpty()
+        {
+            nValue = 0;
+            scriptPubKey.SetNullDestination();
+        }
+
+        public bool IsNull
+        {
+            get { return (nValue == -1); }
+        }
+
+        public bool IsEmpty
+        {
+           get { return nValue == 0 && scriptPubKey.IsNull; }
+        }
+
                public override string ToString ()
                {
                        StringBuilder sb = new StringBuilder ();
index 8cf0b55..fbff17f 100644 (file)
@@ -53,6 +53,7 @@ namespace Novacoin
 
         public Hash(Hash h)
         {
+            _hashBytes = new byte[h.hashSize];
             h._hashBytes.CopyTo(_hashBytes, 0);
         }
 
index 6f13cc7..0c94140 100644 (file)
@@ -42,6 +42,7 @@
     <Compile Include="CKeyID.cs" />
     <Compile Include="CKeyPair.cs" />
     <Compile Include="CNovacoinAddress.cs" />
+    <Compile Include="COutPoint.cs" />
     <Compile Include="CPubKey.cs" />
     <Compile Include="CryptoUtils.cs" />
     <Compile Include="CScriptID.cs" />