Implement some CScript functionality
authorCryptoManiac <balthazar@yandex.ru>
Sat, 15 Aug 2015 15:13:09 +0000 (18:13 +0300)
committerCryptoManiac <balthazar@yandex.ru>
Sat, 15 Aug 2015 15:13:09 +0000 (18:13 +0300)
Novacoin/CScript.cs
Novacoin/Hash.cs [new file with mode: 0644]
Novacoin/Hash160.cs
Novacoin/Hash256.cs
Novacoin/Novacoin.csproj
Novacoin/WrappedList.cs

index 7728d4c..0b5cb2b 100644 (file)
@@ -6,15 +6,127 @@ using System.Collections.Generic;
 
 namespace Novacoin
 {
-       public class CScript : List<byte>
+    public class CScriptException : Exception
+    {
+        public CScriptException()
+        {
+        }
+
+        public CScriptException(string message)
+            : base(message)
+        {
+        }
+
+        public CScriptException(string message, Exception inner)
+            : base(message, inner)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Representation of script code
+    /// </summary>
+       public class CScript
        {
+        private List<byte> codeBytes;
+
+        /// <summary>
+        /// Initializes an empty instance of CScript
+        /// </summary>
                public CScript ()
                {
+            codeBytes = new List<byte>();
                }
 
+        /// <summary>
+        /// Initializes new instance of CScript and fills it with supplied bytes
+        /// </summary>
+        /// <param name="bytes">List of bytes</param>
+        public CScript(IList<byte> bytes)
+        {
+            codeBytes = new List<byte>(bytes);
+        }
+
+        /// <summary>
+        /// Initializes new instance of CScript and fills it with supplied bytes
+        /// </summary>
+        /// <param name="bytes">Array of bytes</param>
+        public CScript(byte[] bytes)
+        {
+            codeBytes = new List<byte>(bytes);
+        }
+
+        /// <summary>
+        /// Adds specified operation to opcode bytes list
+        /// </summary>
+        /// <param name="opcode"></param>
+        public void AddOp(opcodetype opcode)
+        {
+            if (opcode < opcodetype.OP_0 || opcode > opcodetype.OP_INVALIDOPCODE)
+            {
+                throw new CScriptException("CScript::AddOp() : invalid opcode");
+            }
+
+            codeBytes.Add((byte)opcode);
+        }
+
+        /// <summary>
+        /// Adds hash to opcode bytes list.
+        ///    New items are added in this format:
+        ///    hash_length_byte hash_bytes
+        /// </summary>
+        /// <param name="hash">Hash160 instance</param>
+        public void AddHash(Hash160 hash)
+        {
+            codeBytes.Add((byte)hash.hashSize);
+            codeBytes.AddRange(hash.hashBytes);
+        }
+
+        /// <summary>
+        /// Adds hash to opcode bytes list.
+        ///    New items are added in this format:
+        ///    hash_length_byte hash_bytes
+        /// </summary>
+        /// <param name="hash">Hash256 instance</param>
+        public void AddHash(Hash256 hash)
+        {
+            codeBytes.Add((byte)hash.hashSize);
+            codeBytes.AddRange(hash.hashBytes);
+        }
+
+        public void PushData(IList<byte> dataBytes)
+        {
+            if (dataBytes.Count < (int)opcodetype.OP_PUSHDATA1)
+            {
+                codeBytes.Add((byte)dataBytes.Count);
+            }
+            else if (dataBytes.Count < 0xff)
+            {
+                codeBytes.Add((byte)opcodetype.OP_PUSHDATA1);
+                codeBytes.Add((byte)dataBytes.Count);
+            }
+            else if (dataBytes.Count < 0xffff)
+            {
+                codeBytes.Add((byte)opcodetype.OP_PUSHDATA2);
+
+                byte[] szBytes = BitConverter.GetBytes((short)dataBytes.Count);
+                if (BitConverter.IsLittleEndian)
+                    Array.Reverse(szBytes);
+
+                codeBytes.AddRange(szBytes);
+            }
+            else if ((uint)dataBytes.Count < 0xffffffff)
+            {
+                codeBytes.Add((byte)opcodetype.OP_PUSHDATA2);
 
+                byte[] szBytes = BitConverter.GetBytes((uint)dataBytes.Count);
+                if (BitConverter.IsLittleEndian)
+                    Array.Reverse(szBytes);
 
-               
+                codeBytes.AddRange(szBytes);
+            }
+            codeBytes.AddRange(dataBytes);
+        }
 
                public override string ToString()
                {
diff --git a/Novacoin/Hash.cs b/Novacoin/Hash.cs
new file mode 100644 (file)
index 0000000..c726be6
--- /dev/null
@@ -0,0 +1,62 @@
+\feffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Novacoin
+{
+    public abstract class Hash
+    {
+        /// <summary>
+        /// Array of digest bytes.
+        /// </summary>
+        private byte[] _hashBytes = null;
+
+        /// <summary>
+        /// Hash size, must be overriden
+        /// </summary>
+        public virtual int hashSize 
+        {
+            get; 
+            private set;
+        }
+
+        public IList<byte> hashBytes
+        {
+            get { return new List<byte>(_hashBytes); }
+        }
+
+        /// <summary>
+        /// Initializes an empty instance of the Hash class.
+        /// </summary>
+        public Hash()
+        {
+            _hashBytes = Enumerable.Repeat<byte>(0, hashSize).ToArray();
+        }
+
+        /// <summary>
+        /// Initializes a new instance of Hash class with first 20 bytes from supplied list
+        /// </summary>
+        /// <param name="bytesList">List of bytes</param>
+        public Hash(IList<byte> bytesList)
+        {
+            _hashBytes = bytesList.Take<byte>(hashSize).ToArray<byte>();
+        }
+
+        public Hash(byte[] bytesArray)
+        {
+            _hashBytes = bytesArray;
+        }
+
+        public override string ToString()
+        {
+            StringBuilder sb = new StringBuilder(hashSize * 2);
+            foreach (byte b in _hashBytes)
+            {
+                sb.AppendFormat("{0:x2}", b);
+            }
+            return sb.ToString();
+        }
+    }
+}
index eb4e9e4..6aa9048 100644 (file)
@@ -8,47 +8,13 @@ namespace Novacoin
        /// <summary>
        /// Representation of pubkey/script hash.
        /// </summary>
-       public class Hash160
+       public class Hash160 : Hash
        {
         // 20 bytes
-        const int hashSize = 20;
-
-               /// <summary>
-               /// Array of digest bytes.
-               /// </summary>
-        private byte[] hashBytes = new byte[hashSize];
-
-               /// <summary>
-               /// Initializes an empty instance of the Hash160 class.
-               /// </summary>
-               public Hash160 ()
-               {
-            hashBytes = Enumerable.Repeat<byte>(0, hashSize).ToArray();
-               }
-
-        /// <summary>
-        /// Initializes a new instance of Hash160 class with first 20 bytes from supplied list
-        /// </summary>
-        /// <param name="bytesList">List of bytes</param>
-        public Hash160(IList<byte> bytesList)
+        public override int hashSize
         {
-            hashBytes = bytesList.Take<byte>(hashSize).ToArray<byte>();
+            get { return 20; }
         }
-
-        public Hash160(byte[] bytesArray)
-        {
-            hashBytes = bytesArray;
-        }
-
-               public override string ToString()
-               {
-            StringBuilder sb = new StringBuilder(hashSize * 2);
-            foreach (byte b in hashBytes)
-                       {
-                               sb.AppendFormat ("{0:x2}", b);
-                       }
-                       return sb.ToString();
-               }
        }
 }
 
index 6803ac1..7461274 100644 (file)
@@ -9,48 +9,13 @@ namespace Novacoin
        /// <summary>
        /// Representation of SHA-256 hash
        /// </summary>
-    public class Hash256
+    public class Hash256 : Hash
     {
         // 32 bytes
-        const int hashSize = 32;
-
-        /// <summary>
-        /// Array of digest bytes.
-        /// </summary>
-        private byte[] hashBytes = new byte[hashSize];
-
-        /// <summary>
-        /// Initializes an empty instance of the Hash256 class.
-        /// </summary>
-        public Hash256()
-        {
-            hashBytes = Enumerable.Repeat<byte>(0, hashSize).ToArray();
-        }
-
-        /// <summary>
-        /// Initializes a new instance of Hash256 class with first 32 bytes from supplied list
-        /// </summary>
-        /// <param name="bytesList">List of bytes</param>
-        public Hash256(IList<byte> bytesList)
-        {
-            hashBytes = bytesList.Take<byte>(hashSize).ToArray<byte>();
-        }
-
-        public Hash256(byte[] bytesArray)
-        {
-            hashBytes = bytesArray;
-        }
-
-        public override string ToString()
+        public override int hashSize
         {
-            StringBuilder sb = new StringBuilder(hashSize * 2);
-            foreach (byte b in hashBytes)
-            {
-                sb.AppendFormat("{0:x2}", b);
-            }
-            return sb.ToString();
+            get { return 32; }
         }
-
     }
 }
 
index ae41a60..a3d2f2c 100644 (file)
@@ -31,6 +31,7 @@
     <Reference Include="System" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Hash.cs" />
     <Compile Include="WrappedList.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="CTxIn.cs" />
index 11d6756..79068c3 100644 (file)
@@ -26,17 +26,17 @@ namespace Novacoin
     public class WrappedList<T>
     {
         private int Index;
-        private IList<T> Elements;
+        private List<T> Elements;
 
         public WrappedList(IList<T> List, int Start)
         {
-            Elements = List;
+            Elements = new List<T>(List);
             Index = Start;
         }
 
         public WrappedList(IList<T> List)
         {
-            Elements = List;
+            Elements = new List<T>(List);
             Index = 0;
         }