From 397772c7e6df61eaf558b3502ae403b7abfd86a2 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Mon, 24 Aug 2015 20:28:52 +0300 Subject: [PATCH] CScript: implement new AddRawData method, allow RemoveInstruction to process the PUSH operators. + remove all these big-endian conversions, we're not on big-endian platform. --- Novacoin/CScript.cs | 40 ++++++++++++++++++------- Novacoin/Interop.cs | 76 ------------------------------------------------ Novacoin/ScriptCode.cs | 17 +++++------ 3 files changed, 37 insertions(+), 96 deletions(-) diff --git a/Novacoin/CScript.cs b/Novacoin/CScript.cs index f5ea036..5692fa9 100644 --- a/Novacoin/CScript.cs +++ b/Novacoin/CScript.cs @@ -135,7 +135,7 @@ namespace Novacoin // OP_PUSHDATA1 0x00 0x01 [0x5a] codeBytes.Add((byte)instruction.OP_PUSHDATA2); - var szBytes = Interop.BEBytes((ushort)nCount); + var szBytes = BitConverter.GetBytes((ushort)nCount); codeBytes.AddRange(szBytes); } else if (nCount < 0xffffffff) @@ -143,7 +143,7 @@ namespace Novacoin // OP_PUSHDATA1 0x00 0x00 0x00 0x01 [0x5a] codeBytes.Add((byte)instruction.OP_PUSHDATA4); - var szBytes = Interop.BEBytes((uint)nCount); + var szBytes = BitConverter.GetBytes((uint)nCount); codeBytes.AddRange(szBytes); } @@ -152,13 +152,24 @@ namespace Novacoin } /// + /// Just insert data array without including any prefixes. Please make sure that you know what you're doing, + /// it is recommended to use AddInstruction, AddHash or PushData instead. + /// + /// Data bytes + public void AddRawData(byte[] dataBytes) + { + // Add data bytes + codeBytes.AddRange(dataBytes); + } + + /// /// Scan pushed data bytes for pattern and, in case of exact match, remove it. /// /// Pattern sequence /// Matches count public int RemovePattern(byte[] pattern) { - // There is no sense to continue if pattern is longer than script itself + // There is no sense to continue if pattern is empty or longer than script itself if (pattern.Length == 0 || pattern.Length > codeBytes.Count) { return 0; @@ -167,7 +178,6 @@ namespace Novacoin var count = 0; var bq1 = new ByteQueue(codeBytes); - byte[] pushData; instruction opcode; @@ -191,7 +201,11 @@ namespace Novacoin } } - codeBytes = newScript.codeBytes; + if (count > 0) + { + // Replace current script if any matches were found + codeBytes = newScript.codeBytes; + } return count; } @@ -203,23 +217,23 @@ namespace Novacoin /// Matches count public int RemoveInstruction(instruction op) { - var count = 0; - var bq1 = new ByteQueue(codeBytes); - - byte[] pushData; instruction opcode; + var count = 0; var newScript = new CScript(); + var bq1 = new ByteQueue(codeBytes); while (ScriptCode.GetOp(ref bq1, out opcode, out pushData)) { - if (pushData.Length != 0) + if (pushData.Length != 0 && op != opcode) { + // If instruction didn't match then push its data again newScript.PushData(pushData); } else if (Enum.IsDefined(typeof(instruction), op) && op != opcode) { + // Instruction didn't match newScript.AddInstruction(opcode); } else @@ -228,7 +242,11 @@ namespace Novacoin } } - codeBytes = newScript.codeBytes; + if (count > 0) + { + // Replace current script if any matches were found + codeBytes = newScript.codeBytes; + } return count; } diff --git a/Novacoin/Interop.cs b/Novacoin/Interop.cs index 545e361..e3e4e6d 100644 --- a/Novacoin/Interop.cs +++ b/Novacoin/Interop.cs @@ -68,82 +68,6 @@ namespace Novacoin return result; } - public static byte[] BEBytes(ushort n) - { - var resultBytes = BitConverter.GetBytes(n); - - Array.Reverse(resultBytes); - - return resultBytes; - } - - public static byte[] BEBytes(uint n) - { - var resultBytes = BitConverter.GetBytes(n); - - Array.Reverse(resultBytes); - - return resultBytes; - } - - public static byte[] BEBytes(ulong n) - { - var resultBytes = BitConverter.GetBytes(n); - - Array.Reverse(resultBytes); - - return resultBytes; - } - - - public static ushort BEBytesToUInt16(byte[] bytes) - { - if (bytes.Length < sizeof(ushort)) - { - Array.Resize(ref bytes, sizeof(ushort)); - } - if (bytes.Length != sizeof(ushort)) - { - throw new InteropException("Array size doesn't match the ushort data type."); - } - - Array.Reverse(bytes); - - return BitConverter.ToUInt16(bytes, 0); - } - - public static uint BEBytesToUInt32(byte[] bytes) - { - if (bytes.Length < sizeof(uint)) - { - Array.Resize(ref bytes, sizeof(uint)); - } - else if (bytes.Length != sizeof(uint)) - { - throw new InteropException("Array size doesn't match the uint data type."); - } - - Array.Reverse(bytes); - - return BitConverter.ToUInt32(bytes, 0); - } - - public static ulong BEBytesToUInt64(byte[] bytes) - { - if (bytes.Length < sizeof(ulong)) - { - Array.Resize(ref bytes, sizeof(ulong)); - } - else if (bytes.Length != sizeof(ulong)) - { - throw new InteropException("Array size doesn't match the ulong data type."); - } - - Array.Reverse(bytes); - - return BitConverter.ToUInt64(bytes, 0); - } - public static byte[] HexToArray(string hex) { int nChars = hex.Length; diff --git a/Novacoin/ScriptCode.cs b/Novacoin/ScriptCode.cs index 19850c9..e1964b3 100644 --- a/Novacoin/ScriptCode.cs +++ b/Novacoin/ScriptCode.cs @@ -268,31 +268,32 @@ namespace Novacoin if (opcode <= instruction.OP_PUSHDATA4) { var szBytes = new byte[4] { 0, 0, 0, 0 }; // Zero length + int nSize = 0; try { if (opcode < instruction.OP_PUSHDATA1) { // Zero value instructions (OP_0, OP_FALSE) - szBytes[3] = (byte)opcode; + nSize = (int) opcode; } else if (opcode == instruction.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] - szBytes[3] = codeBytes.Get(); + nSize = codeBytes.Get(); } else if (opcode == instruction.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] - codeBytes.Get(2).CopyTo(szBytes, 2); + // i.e. now your operation will seem like this: OP_PUSHDATA2 0x01 0x00 [0x5a] + nSize = BitConverter.ToInt16(codeBytes.Get(2), 0); } else if (opcode == instruction.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.Get(4); + // OP_PUSHDATA4 0x01 0x00 0x00 0x00 [0x5a] + nSize = BitConverter.ToInt32(codeBytes.Get(4), 0); } } catch (ByteQueueException) @@ -301,8 +302,6 @@ namespace Novacoin return false; } - int nSize = (int)Interop.BEBytesToUInt32(szBytes); - if (nSize > 0) { // If nSize is greater than zero then there is some data available @@ -337,7 +336,7 @@ namespace Novacoin if (bytes.Length <= 4) { - sb.Append(Interop.BEBytesToUInt32(bytes)); + sb.Append(new BigInteger(bytes)); } else { -- 1.7.1