From 1b3f62853e83942f54943e5e229069fb3231e101 Mon Sep 17 00:00:00 2001 From: Shargon Date: Sat, 25 Apr 2020 16:58:12 +0200 Subject: [PATCH 1/3] NEP5 commands --- neo-cli/CLI/MainService.Contracts.cs | 81 +++++++++++++++--------- neo-cli/CLI/MainService.NEP5.cs | 94 ++++++++++++++++++++++++++++ neo-cli/CLI/MainService.cs | 2 + 3 files changed, 148 insertions(+), 29 deletions(-) create mode 100644 neo-cli/CLI/MainService.NEP5.cs diff --git a/neo-cli/CLI/MainService.Contracts.cs b/neo-cli/CLI/MainService.Contracts.cs index b7ab38503..1709d0d09 100644 --- a/neo-cli/CLI/MainService.Contracts.cs +++ b/neo-cli/CLI/MainService.Contracts.cs @@ -41,6 +41,56 @@ private void OnDeployCommand(string filePath, string manifestPath = null) SignAndSendTx(tx); } + /// + /// Process "invoke" command + /// + /// Script hash + /// Operation + /// Transaction + /// Contract parameters + private VM.Types.StackItem OnInvokeWithResult(UInt160 scriptHash, string operation, IVerifiable verificable = null, JArray contractParameters = null) + { + List parameters = new List(); + + if (contractParameters != null) + { + foreach (var contractParameter in contractParameters) + { + parameters.Add(ContractParameter.FromJson(contractParameter)); + } + } + + byte[] script; + + using (ScriptBuilder scriptBuilder = new ScriptBuilder()) + { + scriptBuilder.EmitAppCall(scriptHash, operation, parameters.ToArray()); + script = scriptBuilder.ToArray(); + Console.WriteLine($"Invoking script with: '{script.ToHexString()}'"); + } + + if (verificable is Transaction tx) + { + tx.Script = script; + } + + using (ApplicationEngine engine = ApplicationEngine.Run(script, testMode: true)) + { + Console.WriteLine($"VM State: {engine.State}"); + Console.WriteLine($"Gas Consumed: {new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals)}"); + Console.WriteLine($"Result Stack: {new JArray(engine.ResultStack.Select(p => p.ToJson()))}"); + Console.WriteLine(); + + if (engine.State.HasFlag(VMState.FAULT) || !engine.ResultStack.TryPop(out VM.Types.StackItem ret)) + { + Console.WriteLine("Engine faulted."); + return null; + } + + return ret; + } + } + /// /// Process "invoke" command /// @@ -51,10 +101,9 @@ private void OnDeployCommand(string filePath, string manifestPath = null) [ConsoleCommand("invoke", Category = "Contract Commands")] private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray contractParameters = null, UInt160[] witnessAddress = null) { - List parameters = new List(); List signCollection = new List(); - if (!NoWallet() && witnessAddress != null) + if (witnessAddress != null && !NoWallet()) { using (SnapshotView snapshot = Blockchain.Singleton.GetSnapshot()) { @@ -77,14 +126,6 @@ private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray contra } } - if (contractParameters != null) - { - foreach (var contractParameter in contractParameters) - { - parameters.Add(ContractParameter.FromJson(contractParameter)); - } - } - Transaction tx = new Transaction { Sender = UInt160.Zero, @@ -93,25 +134,7 @@ private void OnInvokeCommand(UInt160 scriptHash, string operation, JArray contra Cosigners = signCollection.ToArray() }; - using (ScriptBuilder scriptBuilder = new ScriptBuilder()) - { - scriptBuilder.EmitAppCall(scriptHash, operation, parameters.ToArray()); - tx.Script = scriptBuilder.ToArray(); - Console.WriteLine($"Invoking script with: '{tx.Script.ToHexString()}'"); - } - - using (ApplicationEngine engine = ApplicationEngine.Run(tx.Script, tx, testMode: true)) - { - Console.WriteLine($"VM State: {engine.State}"); - Console.WriteLine($"Gas Consumed: {new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals)}"); - Console.WriteLine($"Evaluation Stack: {new JArray(engine.ResultStack.Select(p => p.ToJson()))}"); - Console.WriteLine(); - if (engine.State.HasFlag(VMState.FAULT)) - { - Console.WriteLine("Engine faulted."); - return; - } - } + _ = OnInvokeWithResult(scriptHash, operation, tx, contractParameters); if (NoWallet()) return; try diff --git a/neo-cli/CLI/MainService.NEP5.cs b/neo-cli/CLI/MainService.NEP5.cs new file mode 100644 index 000000000..3987c307d --- /dev/null +++ b/neo-cli/CLI/MainService.NEP5.cs @@ -0,0 +1,94 @@ +using Neo.ConsoleService; +using Neo.IO.Json; +using Neo.Network.P2P.Payloads; +using Neo.VM; +using Neo.VM.Types; +using Neo.Wallets; +using System; +using System.Globalization; + +namespace Neo.CLI +{ + partial class MainService + { + /// + /// Process "transfer" command + /// + /// Script hash + /// To + /// Ammount + [ConsoleCommand("transfer", Category = "NEP5 Commands")] + private void OnTransferCommand(UInt160 tokenHash, UInt160 to, decimal amount) + { + var asset = new AssetDescriptor(tokenHash); + var value = BigDecimal.Parse(amount.ToString(CultureInfo.InvariantCulture), asset.Decimals); + + if (NoWallet()) return; + + Transaction tx; + try + { + tx = CurrentWallet.MakeTransaction(new[] + { + new TransferOutput + { + AssetId = tokenHash, + Value = value, + ScriptHash = to + } + }, from: null); + } + catch (InvalidOperationException) + { + Console.WriteLine("Error: insufficient balance."); + return; + } + if (!ReadUserInput("relay tx(no|yes)").IsYes()) + { + return; + } + SignAndSendTx(tx); + } + + /// + /// Process "balanceOf" command + /// + /// Script hash + /// Address + [ConsoleCommand("balanceOf", Category = "NEP5 Commands")] + private void OnBalanceOfCommand(UInt160 tokenHash, UInt160 address) + { + var arg = new JObject(); + arg["type"] = "Hash160"; + arg["value"] = address.ToString(); + + var result = OnInvokeWithResult(tokenHash, "balanceOf", null, new JArray(arg)); + + Console.WriteLine($"Result : {((PrimitiveType)result).GetBigInteger()}"); + } + + /// + /// Process "name" command + /// + /// Script hash + [ConsoleCommand("name", Category = "NEP5 Commands")] + private void OnNameCommand(UInt160 tokenHash) + { + var result = OnInvokeWithResult(tokenHash, "name", null); + + Console.WriteLine($"Result : {((PrimitiveType)result).GetString()}"); + } + + /// + /// Process "decimals" command + /// + /// Script hash + [ConsoleCommand("decimals", Category = "NEP5 Commands")] + private void OnDecimalsCommand(UInt160 tokenHash) + { + var result = OnInvokeWithResult(tokenHash, "decimals", null); + + Console.WriteLine($"Result : {((PrimitiveType)result).GetBigInteger()}"); + } + } +} diff --git a/neo-cli/CLI/MainService.cs b/neo-cli/CLI/MainService.cs index b11ab2d87..f36db811e 100644 --- a/neo-cli/CLI/MainService.cs +++ b/neo-cli/CLI/MainService.cs @@ -16,6 +16,7 @@ using Neo.Wallets.SQLite; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; @@ -114,6 +115,7 @@ public MainService() : base() RegisterCommandHander((str) => str.Select(u => ECPoint.Parse(u.Trim(), ECCurve.Secp256r1)).ToArray()); RegisterCommandHander((str) => JObject.Parse(str)); + RegisterCommandHander((str) => decimal.Parse(str, CultureInfo.InvariantCulture)); RegisterCommandHander((obj) => (JArray)obj); RegisterCommand(this); From 7451cefedc062f11d8833f1b4426c8b14aca7479 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 27 Apr 2020 09:44:32 +0200 Subject: [PATCH 2/3] Update neo-cli/CLI/MainService.Contracts.cs Co-Authored-By: ZhangHaoqiang --- neo-cli/CLI/MainService.Contracts.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo-cli/CLI/MainService.Contracts.cs b/neo-cli/CLI/MainService.Contracts.cs index 1709d0d09..7bef18fcb 100644 --- a/neo-cli/CLI/MainService.Contracts.cs +++ b/neo-cli/CLI/MainService.Contracts.cs @@ -74,7 +74,7 @@ private VM.Types.StackItem OnInvokeWithResult(UInt160 scriptHash, string operati tx.Script = script; } - using (ApplicationEngine engine = ApplicationEngine.Run(script, testMode: true)) + using (ApplicationEngine engine = ApplicationEngine.Run(script, verificable, testMode: true)) { Console.WriteLine($"VM State: {engine.State}"); Console.WriteLine($"Gas Consumed: {new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals)}"); From 9d7cb0d76176cfcc9f68d7ec427c2cf121f690b3 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 27 Apr 2020 09:46:20 +0200 Subject: [PATCH 3/3] Remove empty line --- neo-cli/CLI/MainService.Contracts.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/neo-cli/CLI/MainService.Contracts.cs b/neo-cli/CLI/MainService.Contracts.cs index 7bef18fcb..6f3b42bca 100644 --- a/neo-cli/CLI/MainService.Contracts.cs +++ b/neo-cli/CLI/MainService.Contracts.cs @@ -79,7 +79,6 @@ private VM.Types.StackItem OnInvokeWithResult(UInt160 scriptHash, string operati Console.WriteLine($"VM State: {engine.State}"); Console.WriteLine($"Gas Consumed: {new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals)}"); Console.WriteLine($"Result Stack: {new JArray(engine.ResultStack.Select(p => p.ToJson()))}"); - Console.WriteLine(); if (engine.State.HasFlag(VMState.FAULT) || !engine.ResultStack.TryPop(out VM.Types.StackItem ret)) {