\feffusing System;
+using System.Collections.Generic;
using System.Text;
using System.Linq;
/// </summary>
public class Hash160
{
+ // 20 bytes
+ const int hashSize = 20;
+
/// <summary>
/// Array of digest bytes.
/// </summary>
- private byte[] h;
+ private byte[] hashBytes = new byte[hashSize];
/// <summary>
/// Initializes an empty instance of the Hash160 class.
/// </summary>
public Hash160 ()
{
- // Fill with 20 zero bytes
- h = Enumerable.Repeat<byte> (0, 20).ToArray ();
+ 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(List<byte> bytesList)
+ {
+ hashBytes = bytesList.Take<byte>(hashSize).ToArray<byte>();
+ }
+
+ public Hash160(byte[] bytesArray)
+ {
+ hashBytes = bytesArray;
+ }
+
public override string ToString()
{
- StringBuilder sb = new StringBuilder(h.Length * 2);
- foreach (byte b in h)
+ StringBuilder sb = new StringBuilder(hashSize * 2);
+ foreach (byte b in hashBytes)
{
sb.AppendFormat ("{0:x2}", b);
}
return sb.ToString();
}
-
}
}
\feffusing System;
using System.Text;
using System.Linq;
+using System.Collections.Generic;
+
namespace Novacoin
{
/// <summary>
/// Representation of SHA-256 hash
/// </summary>
- public class Hash256
- {
- /// <summary>
- /// Array of digest bytes.
- /// </summary>
- private byte[] h;
-
- /// <summary>
- /// Initializes an empty instance of the Hash256 class.
- /// </summary>
- public Hash256 ()
- {
- h = Enumerable.Repeat<byte>(0, 32).ToArray();
- }
-
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder(h.Length * 2);
- foreach (byte b in h)
- {
- sb.AppendFormat ("{0:x2}", b);
- }
- return sb.ToString();
- }
- }
+ public class Hash256
+ {
+ // 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(List<byte> bytesList)
+ {
+ hashBytes = bytesList.Take<byte>(hashSize).ToArray<byte>();
+ }
+
+ public Hash256(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();
+ }
+
+ }
}
-<?xml version="1.0" encoding="utf-8"?>
+\feff<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="WrappedList.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="CTxIn.cs" />
<Compile Include="CTransaction.cs" />
}
/// <summary>
- /// Get next opcode from passed enumerator and extract push arguments if there are some.
+ /// Get next opcode from passed list of bytes and extract push arguments if there are some.
/// </summary>
- /// <param name="codeBytes">Enumerator reference.</param>
+ /// <param name="codeBytes">WrappedList reference.</param>
/// <param name="opcodeRet">Opcode reference.</param>
- /// <param name="bytesRet">Bytes array reference which is used to get the push arguments.</param>
+ /// <param name="bytesRet">IEnumerable reference which is used to get the push arguments.</param>
/// <returns>Result of operation</returns>
- public static bool GetOp(ref IEnumerator<byte> codeBytes, ref opcodetype opcodeRet, ref List<byte> bytesRet)
+ public static bool GetOp(ref WrappedList<byte> codeBytes, ref opcodetype opcodeRet, ref IEnumerable<byte> bytesRet)
{
bytesRet = new List<byte>();
opcodeRet = opcodetype.OP_INVALIDOPCODE;
- // Read instruction
- if (!codeBytes.MoveNext())
+ opcodetype opcode;
+
+ try
+ {
+ // Read instruction
+ opcode = (opcodetype)codeBytes.GetItem();
+ }
+ catch (WrappedListException)
+ {
+ // No instruction found there
return false;
- opcodetype opcode = (opcodetype)codeBytes.Current;
+ }
// Immediate operand
if (opcode <= opcodetype.OP_PUSHDATA4)
{
- int nSize = 0;
- List<byte> szList = new List<byte>();
+ byte[] szBytes = null;
- if (opcode < opcodetype.OP_PUSHDATA1)
- { // False values
- szList.Add((byte)opcode);
- }
- else if (opcode == opcodetype.OP_PUSHDATA1)
- {
- // The next byte contains the number of bytes to be pushed onto the stack,
- // i.e. you have something like OP_PUSHDATA1 0x01 [0x5a]
- if (!codeBytes.MoveNext())
- return false;
- szList.Add(codeBytes.Current);
- }
- else if (opcode == opcodetype.OP_PUSHDATA2)
+ try
{
- // The next two bytes contain the number of bytes to be pushed onto the stack.
- // i.e. now your operation will seem like this: OP_PUSHDATA2 0x00 0x01 [0x5a]
- for (int i = 0; i < 2; i++)
+ if (opcode < opcodetype.OP_PUSHDATA1)
{
- if (!codeBytes.MoveNext())
- return false;
- szList.Add(codeBytes.Current);
+ // Zero values
+ szBytes = new byte[1] { (byte)opcode };
}
- }
- else if (opcode == opcodetype.OP_PUSHDATA4)
- {
- // The next four bytes contain the number of bytes to be pushed onto the stack.
- // OP_PUSHDATA4 0x00 0x00 0x00 0x01 [0x5a]
- for (int i = 0; i < 4; i++)
+ else if (opcode == opcodetype.OP_PUSHDATA1)
{
- if (!codeBytes.MoveNext())
- return false;
- szList.Add(codeBytes.Current);
+ // The next byte contains the number of bytes to be pushed onto the stack,
+ // i.e. you have something like OP_PUSHDATA1 0x01 [0x5a]
+ szBytes = new byte[1] { codeBytes.GetItem() };
+ }
+ else if (opcode == opcodetype.OP_PUSHDATA2)
+ {
+ // The next two bytes contain the number of bytes to be pushed onto the stack.
+ // i.e. now your operation will seem like this: OP_PUSHDATA2 0x00 0x01 [0x5a]
+ szBytes = codeBytes.GetItems(2);
+ }
+ else if (opcode == opcodetype.OP_PUSHDATA4)
+ {
+ // The next four bytes contain the number of bytes to be pushed onto the stack.
+ // OP_PUSHDATA4 0x00 0x00 0x00 0x01 [0x5a]
+ szBytes = codeBytes.GetItems(4);
}
}
-
- // Got all size bytes, now convert it to integer value
- byte[] SizeBytes = szList.ToArray();
- Array.Reverse(SizeBytes);
- nSize = BitConverter.ToInt32(SizeBytes, 0);
-
- // Read found number of bytes into list of OP_PUSHDATAn arguments.
- for (int i = 0; i < nSize; i++)
+ catch (WrappedListException)
{
- if (!codeBytes.MoveNext())
- return false;
+ // Unable to read operand length
+ return false;
+ }
+
+ Array.Reverse(szBytes);
+ int nSize = BitConverter.ToInt32(szBytes, 0);
- bytesRet.Add(codeBytes.Current);
+ try
+ {
+ // Read found number of bytes into list of OP_PUSHDATAn arguments.
+ bytesRet = codeBytes.GetEnumerableItems(nSize);
+ }
+ catch (WrappedListException)
+ {
+ // Unable to read data
+ return false;
}
}
--- /dev/null
+\feffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Novacoin
+{
+ public class WrappedListException : Exception
+ {
+ public WrappedListException()
+ {
+ }
+
+ public WrappedListException(string message)
+ : base(message)
+ {
+ }
+
+ public WrappedListException(string message, Exception inner)
+ : base(message, inner)
+ {
+ }
+ }
+
+ public class WrappedList<T>
+ {
+ private int Index;
+ private List<T> Elements;
+
+ public WrappedList(List<T> List, int Start)
+ {
+ Elements = List;
+ Index = Start;
+ }
+
+ public WrappedList(List<T> List)
+ {
+ Elements = List;
+ Index = 0;
+ }
+
+ public T GetItem()
+ {
+ if (Elements.Count <= Index)
+ {
+ throw new WrappedListException("No elements left.");
+ }
+
+ return Elements[Index++];
+ }
+
+ public T[] GetItems(int Count)
+ {
+ if (Elements.Count - Index < Count)
+ {
+ throw new WrappedListException("Unable to read requested amount of data.");
+ }
+
+ T[] result = Elements.Skip<T>(Index).Take<T>(Count).ToArray<T>();
+ Index += Count;
+
+ return result;
+ }
+
+ public IEnumerable<T> GetEnumerableItems(int Count)
+ {
+ if (Elements.Count - Index < Count)
+ {
+ throw new WrappedListException("Unable to read requested amount of data.");
+ }
+
+ IEnumerable<T> result = Elements.Skip<T>(Index).Take<T>(Count);
+ Index += Count;
+
+ return result;
+ }
+ }
+}