From 593adbdb6f7f792903d567bf7fa66589ab943762 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Thu, 6 Aug 2015 16:31:21 +0300 Subject: [PATCH] GetOpcode implementation It seems we need to derive from List and rewrite all dependent parts of code. --- Novacoin/CScript.cs | 88 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 86 insertions(+), 2 deletions(-) diff --git a/Novacoin/CScript.cs b/Novacoin/CScript.cs index 70cf412..b79f2ff 100644 --- a/Novacoin/CScript.cs +++ b/Novacoin/CScript.cs @@ -1,10 +1,13 @@ using System; using System.Text; +using System.Collections; +using System.Collections.Generic; + namespace Novacoin { /** Script opcodes */ - enum opcodetype + public enum opcodetype { // push value OP_0 = 0x00, @@ -138,7 +141,6 @@ namespace Novacoin OP_NOP9 = 0xb8, OP_NOP10 = 0xb9, - // template matching params OP_SMALLDATA = 0xf9, OP_SMALLINTEGER = 0xfa, @@ -413,6 +415,88 @@ namespace Novacoin } } + public bool GetOp(ref IEnumerator codeBytes, ref opcodetype opcodeRet, ref byte[] bytesRet) + { + opcodeRet = opcodetype.OP_INVALIDOPCODE; + + // Initialize local byte list + List bytesRetIn = new List (); + + // Read instruction + if (!codeBytes.MoveNext()) + return false; + opcodetype opcode = (opcodetype)codeBytes.Current; + + // Immediate operand + if (opcode <= opcodetype.OP_PUSHDATA4) + { + int nSize = 0; + if (opcode < opcodetype.OP_PUSHDATA1) { // False values + nSize = (int)opcode; + } else if (opcode == opcodetype.OP_PUSHDATA1) { // One byte size prefix + if (!codeBytes.MoveNext ()) + return false; + nSize = codeBytes.Current; + } else if (opcode == opcodetype.OP_PUSHDATA2) { // Two bytes size prefix + byte[] SizeBytes = {0,0}; + + for (int i = 0; i < 2; i++) { // TODO: implement some intelligent solution instead + if (!codeBytes.MoveNext ()) + return false; + + SizeBytes [i] = codeBytes.Current; + } + + Array.Reverse (SizeBytes); + BitConverter.ToUInt32(SizeBytes, 0); + } else if (opcode == opcodetype.OP_PUSHDATA4) { // Four bytes size prefix + byte[] SizeBytes = {0,0,0,0}; + + for (int i = 0; i < 4; i++) { + if (!codeBytes.MoveNext ()) + return false; + + SizeBytes [i] = codeBytes.Current; + } + + Array.Reverse (SizeBytes); + nSize = BitConverter.ToInt32 (SizeBytes, 0); + } + + for (int i = 0; i < nSize; i++) { + if (!codeBytes.MoveNext ()) + return false; + + bytesRetIn.Add (codeBytes.Current); + } + + // Return OP_PUSHDATA arguments + bytesRet = bytesRetIn.ToArray (); + } + + opcodeRet = opcode; + + return true; + } + + // Encode/decode small integers: + static int DecodeOP_N(opcodetype opcode) + { + if (opcode == opcodetype.OP_0) + return 0; + if(! (opcode >= opcodetype.OP_1 && opcode <= opcodetype.OP_16)) + throw new Exception ("! (opcode >= opcodetype.OP_1 && opcode <= opcodetype.OP_16)"); + return (int)opcode - (int)(opcodetype.OP_1 - 1); + } + static opcodetype EncodeOP_N(int n) + { + if (!(n >= 0 && n <= 16)) + throw new Exception ("! (n >= 0 && n <= 16)"); + if (n == 0) + return opcodetype.OP_0; + return (opcodetype)(opcodetype.OP_1+n-1); + } + public override string ToString() { // TODO: disassembly -- 1.7.1