From 292f8ed7702a2bf98be5f404d8f9d99db6ea27e4 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Sat, 15 Aug 2015 20:43:45 +0300 Subject: [PATCH] Fix PushData and add RemovePattern function --- Novacoin/CScript.cs | 57 +++++++++++++++++++++++++++++++++++++++++++-- Novacoin/ScriptOpcode.cs | 20 +++++++++------ 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/Novacoin/CScript.cs b/Novacoin/CScript.cs index a6f16a2..47ad01c 100644 --- a/Novacoin/CScript.cs +++ b/Novacoin/CScript.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Text; using System.Collections; @@ -94,41 +95,91 @@ namespace Novacoin codeBytes.AddRange(hash.hashBytes); } + /// + /// Create new OP_PUSHDATAn operator and add it to opcode bytes list + /// + /// List of data bytes public void PushData(IList dataBytes) { if (dataBytes.Count < (int)opcodetype.OP_PUSHDATA1) { + // OP_0 and OP_FALSE codeBytes.Add((byte)dataBytes.Count); } else if (dataBytes.Count < 0xff) { + // OP_PUSHDATA1 0x01 [0x5a] codeBytes.Add((byte)opcodetype.OP_PUSHDATA1); codeBytes.Add((byte)dataBytes.Count); } else if (dataBytes.Count < 0xffff) { + // OP_PUSHDATA1 0x00 0x01 [0x5a] 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); + // OP_PUSHDATA1 0x00 0x00 0x00 0x01 [0x5a] + codeBytes.Add((byte)opcodetype.OP_PUSHDATA4); byte[] szBytes = BitConverter.GetBytes((uint)dataBytes.Count); if (BitConverter.IsLittleEndian) + { Array.Reverse(szBytes); - + } codeBytes.AddRange(szBytes); } + + // Add data bytes codeBytes.AddRange(dataBytes); } /// + /// Scan code bytes for pattern + /// + /// Pattern sequence + /// Matches enumerator + private IEnumerable FindPattern(IList pattern) + { + for (int i = 0; i < codeBytes.Count; i++) + { + if (codeBytes.Skip(i).Take(pattern.Count).SequenceEqual(pattern)) + { + yield return i; + } + } + } + + /// + /// Scan code bytes for pattern and remove it + /// + /// Pattern sequence + /// Matches number + public int RemovePattern(IList pattern) + { + List resultBytes = new List(codeBytes); + int count = 0; + int patternLen = pattern.Count; + + foreach (int i in FindPattern(pattern)) + { + resultBytes.RemoveRange(i - count * patternLen, patternLen); + count++; + } + + codeBytes = resultBytes; + + return count; + } + + /// /// Disassemble current script code /// /// Code listing diff --git a/Novacoin/ScriptOpcode.cs b/Novacoin/ScriptOpcode.cs index 19cde31..b967b5a 100644 --- a/Novacoin/ScriptOpcode.cs +++ b/Novacoin/ScriptOpcode.cs @@ -488,15 +488,19 @@ namespace Novacoin int nSize = BitConverter.ToInt32(szBytes, 0); - try + if (nSize > 0) { - // Read found number of bytes into list of OP_PUSHDATAn arguments. - bytesRet = codeBytes.GetEnumerableItems(nSize); - } - catch (WrappedListException) - { - // Unable to read data - return false; + // If nSize is greater than zero then there is some data available + try + { + // Read found number of bytes into list of OP_PUSHDATAn arguments. + bytesRet = codeBytes.GetEnumerableItems(nSize); + } + catch (WrappedListException) + { + // Unable to read data + return false; + } } } -- 1.7.1