From 5cfd34a70fadc9929ef8514b39aaa06797a18503 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Sat, 15 Aug 2015 19:17:45 +0300 Subject: [PATCH] CScript: disassembly support --- Novacoin/CScript.cs | 35 +++++++++++++++++++++++++++++++---- Novacoin/ScriptOpcode.cs | 16 ++++++++-------- Novacoin/WrappedList.cs | 7 ++++++- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/Novacoin/CScript.cs b/Novacoin/CScript.cs index 0b5cb2b..9ada832 100644 --- a/Novacoin/CScript.cs +++ b/Novacoin/CScript.cs @@ -128,14 +128,41 @@ namespace Novacoin codeBytes.AddRange(dataBytes); } + /// + /// Disassemble current script code + /// + /// Code listing public override string ToString() { - // TODO: disassembly - StringBuilder sb = new StringBuilder(); - // - + WrappedList wCodeBytes = new WrappedList(codeBytes); + + while (wCodeBytes.ItemsLeft > 0) + { + if (sb.Length != 0) + { + sb.Append(" "); + } + + opcodetype opcode; + IEnumerable pushArgs; + if (!ScriptOpcode.GetOp(ref wCodeBytes, out opcode, out pushArgs)) + { + sb.Append("[error]"); + break; + } + + if (0 <= opcode && opcode <= opcodetype.OP_PUSHDATA4) + { + sb.Append(ScriptOpcode.ValueString(pushArgs)); + } + else + { + sb.Append(ScriptOpcode.GetOpName(opcode)); + } + } + return sb.ToString(); } } diff --git a/Novacoin/ScriptOpcode.cs b/Novacoin/ScriptOpcode.cs index 0790c4c..19cde31 100644 --- a/Novacoin/ScriptOpcode.cs +++ b/Novacoin/ScriptOpcode.cs @@ -422,10 +422,10 @@ namespace Novacoin /// Get next opcode from passed list of bytes and extract push arguments if there are some. /// /// WrappedList reference. - /// Opcode reference. - /// IEnumerable reference which is used to get the push arguments. + /// Found opcode. + /// IEnumerable out param which is used to get the push arguments. /// Result of operation - public static bool GetOp(ref WrappedList codeBytes, ref opcodetype opcodeRet, ref IEnumerable bytesRet) + public static bool GetOp(ref WrappedList codeBytes, out opcodetype opcodeRet, out IEnumerable bytesRet) { bytesRet = new List(); opcodeRet = opcodetype.OP_INVALIDOPCODE; @@ -510,16 +510,16 @@ namespace Novacoin /// /// If list lengh is equal or lesser than 4 bytes then bytes are interpreted as integer value. Otherwise you will get hex representation of supplied data. /// - /// List of value bytes. + /// Collection of value bytes. /// Formatted value. - public static string ValueString(IList bytesList) + public static string ValueString(IEnumerable bytes) { StringBuilder sb = new StringBuilder(); - if (bytesList.Count <= 4) + if (bytes.Count() <= 4) { byte[] valueBytes = new byte[4] {0, 0, 0, 0}; - bytesList.ToArray().CopyTo(valueBytes, valueBytes.Length - bytesList.Count); + bytes.ToArray().CopyTo(valueBytes, valueBytes.Length - bytes.Count()); // Reverse array if we are on little-endian machine if (BitConverter.IsLittleEndian) @@ -531,7 +531,7 @@ namespace Novacoin } else { - foreach (byte b in bytesList) + foreach (byte b in bytes) { sb.AppendFormat("{0:x2}", b); } diff --git a/Novacoin/WrappedList.cs b/Novacoin/WrappedList.cs index 79068c3..e871025 100644 --- a/Novacoin/WrappedList.cs +++ b/Novacoin/WrappedList.cs @@ -28,6 +28,11 @@ namespace Novacoin private int Index; private List Elements; + public int ItemsLeft + { + get { return Elements.Count - Index; } + } + public WrappedList(IList List, int Start) { Elements = new List(List); @@ -52,7 +57,7 @@ namespace Novacoin public T[] GetItems(int Count) { - if (Elements.Count - Index < Count) + if (ItemsLeft < Count) { throw new WrappedListException("Unable to read requested amount of data."); } -- 1.7.1