From 9968fc63785f48758c8633a0bee7786a2fb1e771 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Sat, 15 Aug 2015 18:13:09 +0300 Subject: [PATCH] Implement some CScript functionality --- Novacoin/CScript.cs | 116 +++++++++++++++++++++++++++++++++++++++++++++- Novacoin/Hash.cs | 62 ++++++++++++++++++++++++ Novacoin/Hash160.cs | 40 +--------------- Novacoin/Hash256.cs | 41 +--------------- Novacoin/Novacoin.csproj | 1 + Novacoin/WrappedList.cs | 6 +- 6 files changed, 186 insertions(+), 80 deletions(-) create mode 100644 Novacoin/Hash.cs diff --git a/Novacoin/CScript.cs b/Novacoin/CScript.cs index 7728d4c..0b5cb2b 100644 --- a/Novacoin/CScript.cs +++ b/Novacoin/CScript.cs @@ -6,15 +6,127 @@ using System.Collections.Generic; namespace Novacoin { - public class CScript : List + public class CScriptException : Exception + { + public CScriptException() + { + } + + public CScriptException(string message) + : base(message) + { + } + + public CScriptException(string message, Exception inner) + : base(message, inner) + { + } + } + + /// + /// Representation of script code + /// + public class CScript { + private List codeBytes; + + /// + /// Initializes an empty instance of CScript + /// public CScript () { + codeBytes = new List(); } + /// + /// Initializes new instance of CScript and fills it with supplied bytes + /// + /// List of bytes + public CScript(IList bytes) + { + codeBytes = new List(bytes); + } + + /// + /// Initializes new instance of CScript and fills it with supplied bytes + /// + /// Array of bytes + public CScript(byte[] bytes) + { + codeBytes = new List(bytes); + } + + /// + /// Adds specified operation to opcode bytes list + /// + /// + 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); + } + + /// + /// Adds hash to opcode bytes list. + /// New items are added in this format: + /// hash_length_byte hash_bytes + /// + /// Hash160 instance + public void AddHash(Hash160 hash) + { + codeBytes.Add((byte)hash.hashSize); + codeBytes.AddRange(hash.hashBytes); + } + + /// + /// Adds hash to opcode bytes list. + /// New items are added in this format: + /// hash_length_byte hash_bytes + /// + /// Hash256 instance + public void AddHash(Hash256 hash) + { + codeBytes.Add((byte)hash.hashSize); + codeBytes.AddRange(hash.hashBytes); + } + + public void PushData(IList 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 index 0000000..c726be6 --- /dev/null +++ b/Novacoin/Hash.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Novacoin +{ + public abstract class Hash + { + /// + /// Array of digest bytes. + /// + private byte[] _hashBytes = null; + + /// + /// Hash size, must be overriden + /// + public virtual int hashSize + { + get; + private set; + } + + public IList hashBytes + { + get { return new List(_hashBytes); } + } + + /// + /// Initializes an empty instance of the Hash class. + /// + public Hash() + { + _hashBytes = Enumerable.Repeat(0, hashSize).ToArray(); + } + + /// + /// Initializes a new instance of Hash class with first 20 bytes from supplied list + /// + /// List of bytes + public Hash(IList bytesList) + { + _hashBytes = bytesList.Take(hashSize).ToArray(); + } + + 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(); + } + } +} diff --git a/Novacoin/Hash160.cs b/Novacoin/Hash160.cs index eb4e9e4..6aa9048 100644 --- a/Novacoin/Hash160.cs +++ b/Novacoin/Hash160.cs @@ -8,47 +8,13 @@ namespace Novacoin /// /// Representation of pubkey/script hash. /// - public class Hash160 + public class Hash160 : Hash { // 20 bytes - const int hashSize = 20; - - /// - /// Array of digest bytes. - /// - private byte[] hashBytes = new byte[hashSize]; - - /// - /// Initializes an empty instance of the Hash160 class. - /// - public Hash160 () - { - hashBytes = Enumerable.Repeat(0, hashSize).ToArray(); - } - - /// - /// Initializes a new instance of Hash160 class with first 20 bytes from supplied list - /// - /// List of bytes - public Hash160(IList bytesList) + public override int hashSize { - hashBytes = bytesList.Take(hashSize).ToArray(); + 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(); - } } } diff --git a/Novacoin/Hash256.cs b/Novacoin/Hash256.cs index 6803ac1..7461274 100644 --- a/Novacoin/Hash256.cs +++ b/Novacoin/Hash256.cs @@ -9,48 +9,13 @@ namespace Novacoin /// /// Representation of SHA-256 hash /// - public class Hash256 + public class Hash256 : Hash { // 32 bytes - const int hashSize = 32; - - /// - /// Array of digest bytes. - /// - private byte[] hashBytes = new byte[hashSize]; - - /// - /// Initializes an empty instance of the Hash256 class. - /// - public Hash256() - { - hashBytes = Enumerable.Repeat(0, hashSize).ToArray(); - } - - /// - /// Initializes a new instance of Hash256 class with first 32 bytes from supplied list - /// - /// List of bytes - public Hash256(IList bytesList) - { - hashBytes = bytesList.Take(hashSize).ToArray(); - } - - 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; } } - } } diff --git a/Novacoin/Novacoin.csproj b/Novacoin/Novacoin.csproj index ae41a60..a3d2f2c 100644 --- a/Novacoin/Novacoin.csproj +++ b/Novacoin/Novacoin.csproj @@ -31,6 +31,7 @@ + diff --git a/Novacoin/WrappedList.cs b/Novacoin/WrappedList.cs index 11d6756..79068c3 100644 --- a/Novacoin/WrappedList.cs +++ b/Novacoin/WrappedList.cs @@ -26,17 +26,17 @@ namespace Novacoin public class WrappedList { private int Index; - private IList Elements; + private List Elements; public WrappedList(IList List, int Start) { - Elements = List; + Elements = new List(List); Index = Start; } public WrappedList(IList List) { - Elements = List; + Elements = new List(List); Index = 0; } -- 1.7.1