X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=Novacoin%2FCScript.cs;h=abdad9c238b64cfd219295ebe5e86e01e3f9ea15;hb=6dfa6de57c6493b76856acc9ab510ac31962c327;hp=5692fa9a4a206522aeaf9cba6e5f812d832e4308;hpb=397772c7e6df61eaf558b3502ae403b7abfd86a2;p=NovacoinLibrary.git diff --git a/Novacoin/CScript.cs b/Novacoin/CScript.cs index 5692fa9..abdad9c 100644 --- a/Novacoin/CScript.cs +++ b/Novacoin/CScript.cs @@ -20,26 +20,11 @@ using System; using System.Linq; using System.Text; using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.Numerics; namespace Novacoin { - public class CScriptException : Exception - { - public CScriptException() - { - } - - public CScriptException(string message) - : base(message) - { - } - - public CScriptException(string message, Exception inner) - : base(message, inner) - { - } - } - /// /// Representation of script code /// @@ -68,21 +53,35 @@ namespace Novacoin /// Return a new instance of ByteQueue object for current code bytes /// /// - public ByteQueue GetByteQUeue() + public InstructionQueue GetInstructionQueue() { - return new ByteQueue(codeBytes); + return new InstructionQueue(ref codeBytes); } /// - /// Adds specified operation to instruction list + /// Add serialized number to instructions list. /// - /// - public void AddInstruction(instruction opcode) + /// Number to add. + public void AddNumber(int n) { - if (opcode < instruction.OP_0 || opcode > instruction.OP_INVALIDOPCODE) + if (n == -1 || (n >= 1 && n <= 16)) { - throw new CScriptException("CScript::AddInstruction() : invalid instruction"); + codeBytes.Add((byte)ScriptCode.EncodeOP_N(n, true)); } + else + { + BigInteger bn = n; + PushData(bn.ToByteArray()); + } + } + + /// + /// Adds specified operation to instruction list + /// + /// Instruction to add. + public void AddInstruction(instruction opcode) + { + Contract.Requires(opcode >= instruction.OP_0 && opcode <= instruction.OP_INVALIDOPCODE, "Invalid instruction."); codeBytes.Add((byte)opcode); } @@ -92,11 +91,11 @@ namespace Novacoin /// New items are added in this format: /// hash_length_byte hash_bytes /// - /// Hash160 instance - public void AddHash(Hash160 hash) + /// uint160 instance + public void AddHash(uint160 hash) { - codeBytes.Add((byte)hash.hashSize); - codeBytes.AddRange(hash.hashBytes); + codeBytes.Add((byte)hash.Size); + codeBytes.AddRange((byte[])hash); } /// @@ -104,11 +103,11 @@ namespace Novacoin /// New items are added in this format: /// hash_length_byte hash_bytes /// - /// Hash256 instance - public void AddHash(Hash256 hash) + /// uint256 instance + public void AddHash(uint256 hash) { - codeBytes.Add((byte)hash.hashSize); - codeBytes.AddRange(hash.hashBytes); + codeBytes.Add((byte)hash.Size); + codeBytes.AddRange((byte[])hash); } /// @@ -132,7 +131,7 @@ namespace Novacoin } else if (nCount < 0xffff) { - // OP_PUSHDATA1 0x00 0x01 [0x5a] + // OP_PUSHDATA1 0x01 0x00 [0x5a] codeBytes.Add((byte)instruction.OP_PUSHDATA2); var szBytes = BitConverter.GetBytes((ushort)nCount); @@ -140,7 +139,7 @@ namespace Novacoin } else if (nCount < 0xffffffff) { - // OP_PUSHDATA1 0x00 0x00 0x00 0x01 [0x5a] + // OP_PUSHDATA1 0x01 0x00 0x00 0x00 [0x5a] codeBytes.Add((byte)instruction.OP_PUSHDATA4); var szBytes = BitConverter.GetBytes((uint)nCount); @@ -176,7 +175,7 @@ namespace Novacoin } var count = 0; - var bq1 = new ByteQueue(codeBytes); + var bq1 = new InstructionQueue(ref codeBytes); byte[] pushData; instruction opcode; @@ -222,7 +221,7 @@ namespace Novacoin var count = 0; var newScript = new CScript(); - var bq1 = new ByteQueue(codeBytes); + var bq1 = new InstructionQueue(ref codeBytes); while (ScriptCode.GetOp(ref bq1, out opcode, out pushData)) { @@ -258,7 +257,7 @@ namespace Novacoin { get { - var wCodeBytes = new ByteQueue(codeBytes); + var wCodeBytes = new InstructionQueue(ref codeBytes); instruction opcode; // Current instruction byte[] pushArgs; // OP_PUSHDATAn argument @@ -284,7 +283,7 @@ namespace Novacoin { get { - var wCodeBytes = new ByteQueue(codeBytes); + var wCodeBytes = new InstructionQueue(ref codeBytes); byte[] pushArgs; // OP_PUSHDATAn argument instruction opcode; // Current instruction @@ -371,14 +370,14 @@ namespace Novacoin /// /// Legacy mode flag /// Amount of sigops - public int GetSigOpCount(bool fAccurate) + public uint GetSigOpCount(bool fAccurate) { - var wCodeBytes = new ByteQueue(codeBytes); + var wCodeBytes = new InstructionQueue(ref codeBytes); instruction opcode; // Current instruction byte[] pushArgs; // OP_PUSHDATAn argument - int nCount = 0; + uint nCount = 0; var lastOpcode = instruction.OP_INVALIDOPCODE; // Scan instructions sequence @@ -392,7 +391,7 @@ namespace Novacoin { if (fAccurate && lastOpcode >= instruction.OP_1 && lastOpcode <= instruction.OP_16) { - nCount += ScriptCode.DecodeOP_N(lastOpcode); + nCount += (uint)ScriptCode.DecodeOP_N(lastOpcode); } else { @@ -410,7 +409,7 @@ namespace Novacoin /// /// pay-to-script-hash scriptPubKey /// SigOps count - public int GetSigOpCount(CScript scriptSig) + public uint GetSigOpCount(CScript scriptSig) { if (!IsPayToScriptHash) { @@ -420,13 +419,20 @@ namespace Novacoin // This is a pay-to-script-hash scriptPubKey; // get the last item that the scriptSig // pushes onto the stack: - ByteQueue wScriptSig = scriptSig.GetByteQUeue(); + InstructionQueue wScriptSig = scriptSig.GetInstructionQueue(); + uint nScriptSigSize = scriptSig.Size; instruction opcode; // Current instruction - byte[] pushArgs; // OP_PUSHDATAn argument + byte[] pushArgs = new byte[0]; // OP_PUSHDATAn argument - while (ScriptCode.GetOp(ref wScriptSig, out opcode, out pushArgs)) + + while (wScriptSig.Index < nScriptSigSize) { + if (!ScriptCode.GetOp(ref wScriptSig, out opcode, out pushArgs)) + { + return 0; + } + if (opcode > instruction.OP_16) { return 0; @@ -447,7 +453,7 @@ namespace Novacoin public void SetDestination(CPubKey pubKey) { codeBytes.Clear(); - PushData(pubKey.PublicBytes); + PushData(pubKey); AddInstruction(instruction.OP_CHECKSIG); } @@ -497,7 +503,7 @@ namespace Novacoin foreach (var key in keys) { - PushData(key.PublicBytes); + PushData(key); } AddInstruction(ScriptCode.EncodeOP_N(keys.Length)); @@ -507,14 +513,31 @@ namespace Novacoin /// /// Access to script code. /// - public byte[] Bytes + public static implicit operator byte[] (CScript script) + { + return script.codeBytes.ToArray(); + } + + /// + /// Implicit cast of byte array to CScript. + /// + /// + public static implicit operator CScript(byte[] scriptBytes) + { + return new CScript(scriptBytes); + } + + /// + /// Script size + /// + public uint Size { - get { return codeBytes.ToArray(); } + get { return (uint) codeBytes.Count; } } public CScriptID ScriptID { - get { return new CScriptID(Hash160.Compute160(codeBytes.ToArray())); } + get { return new CScriptID(CryptoUtils.ComputeHash160(codeBytes.ToArray())); } } /// @@ -524,7 +547,7 @@ namespace Novacoin public override string ToString() { var sb = new StringBuilder(); - var wCodeBytes = new ByteQueue(codeBytes); + var wCodeBytes = new InstructionQueue(ref codeBytes); instruction opcode; // Current instruction byte[] pushArgs; // OP_PUSHDATAn argument