From a63d82634c57fdf172ed9508d1c197e66247a92c Mon Sep 17 00:00:00 2001 From: Erik Zhang Date: Tue, 15 Aug 2017 21:32:08 +0800 Subject: [PATCH] upgrade to 2.1.0 1. Add "sendmany" rpc api 2. Add "show utxo" command 3. Save peers state to file 4. Improve the help message --- neo-cli/Network/RPC/RpcServerWithWallet.cs | 50 ++++++++++++++++++- neo-cli/Shell/MainService.cs | 56 +++++++++++++++++++++- neo-cli/neo-cli.csproj | 4 +- 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/neo-cli/Network/RPC/RpcServerWithWallet.cs b/neo-cli/Network/RPC/RpcServerWithWallet.cs index 5728f1a71..67a6cc897 100644 --- a/neo-cli/Network/RPC/RpcServerWithWallet.cs +++ b/neo-cli/Network/RPC/RpcServerWithWallet.cs @@ -37,10 +37,12 @@ protected override JObject Process(string method, JArray _params) UInt256 assetId = UInt256.Parse(_params[0].AsString()); UInt160 scriptHash = Wallet.ToScriptHash(_params[1].AsString()); Fixed8 value = Fixed8.Parse(_params[2].AsString()); - Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; - UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; if (value <= Fixed8.Zero) throw new RpcException(-32602, "Invalid params"); + Fixed8 fee = _params.Count >= 4 ? Fixed8.Parse(_params[3].AsString()) : Fixed8.Zero; + if (value < Fixed8.Zero) + throw new RpcException(-32602, "Invalid params"); + UInt160 change_address = _params.Count >= 5 ? Wallet.ToScriptHash(_params[4].AsString()) : null; ContractTransaction tx = Program.Wallet.MakeTransaction(new ContractTransaction { Outputs = new[] @@ -69,6 +71,50 @@ protected override JObject Process(string method, JArray _params) return context.ToJson(); } } + case "sendmany": + if (Program.Wallet == null) + throw new RpcException(-400, "Access denied"); + else + { + JArray to = (JArray)_params[0]; + if (to.Count == 0) + throw new RpcException(-32602, "Invalid params"); + TransactionOutput[] outputs = new TransactionOutput[to.Count]; + for (int i = 0; i < to.Count; i++) + { + outputs[i] = new TransactionOutput + { + AssetId = UInt256.Parse(to[i]["asset"].AsString()), + Value = Fixed8.Parse(to[i]["value"].AsString()), + ScriptHash = Wallet.ToScriptHash(to[i]["address"].AsString()) + }; + if (outputs[i].Value <= Fixed8.Zero) + throw new RpcException(-32602, "Invalid params"); + } + Fixed8 fee = _params.Count >= 2 ? Fixed8.Parse(_params[1].AsString()) : Fixed8.Zero; + if (fee < Fixed8.Zero) + throw new RpcException(-32602, "Invalid params"); + UInt160 change_address = _params.Count >= 3 ? Wallet.ToScriptHash(_params[2].AsString()) : null; + ContractTransaction tx = Program.Wallet.MakeTransaction(new ContractTransaction + { + Outputs = outputs + }, change_address: change_address, fee: fee); + if (tx == null) + throw new RpcException(-300, "Insufficient funds"); + SignatureContext context = new SignatureContext(tx); + Program.Wallet.Sign(context); + if (context.Completed) + { + tx.Scripts = context.GetScripts(); + Program.Wallet.SaveTransaction(tx); + LocalNode.Relay(tx); + return tx.ToJson(); + } + else + { + return context.ToJson(); + } + } case "getnewaddress": if (Program.Wallet == null) throw new RpcException(-400, "Access denied"); diff --git a/neo-cli/Shell/MainService.cs b/neo-cli/Shell/MainService.cs index 9934fd0dd..d9cad4f44 100644 --- a/neo-cli/Shell/MainService.cs +++ b/neo-cli/Shell/MainService.cs @@ -19,6 +19,8 @@ namespace Neo.Shell { internal class MainService : ConsoleServiceBase { + private const string PeerStatePath = "peers.dat"; + private RpcServerWithWallet rpc; private ConsensusWithPolicy consensus; @@ -265,10 +267,12 @@ private bool OnHelpCommand(string[] args) "Wallet Commands:\n" + "\tcreate wallet \n" + "\topen wallet \n" + + "\tupgrade wallet \n" + "\trebuild index\n" + "\tlist address\n" + "\tlist asset\n" + "\tlist key\n" + + "\tshow utxo [id|alias]\n" + "\tshow gas\n" + "\tclaim gas\n" + "\tcreate address [n=1]\n" + @@ -279,8 +283,10 @@ private bool OnHelpCommand(string[] args) "\tshow state\n" + "\tshow node\n" + "\tshow pool\n" + + "\texport blocks [path=chain.acc]\n" + "Advanced Commands:\n" + - "\tstart consensus\n"); + "\tstart consensus\n" + + "\trefresh policy\n"); return true; } @@ -604,6 +610,8 @@ private bool OnShowCommand(string[] args) return OnShowPoolCommand(args); case "state": return OnShowStateCommand(args); + case "utxo": + return OnShowUtxoCommand(args); default: return base.OnCommand(args); } @@ -634,9 +642,51 @@ private bool OnShowStateCommand(string[] args) return true; } + private bool OnShowUtxoCommand(string[] args) + { + if (Program.Wallet == null) + { + Console.WriteLine("You have to open the wallet first."); + return true; + } + IEnumerable coins = Program.Wallet.FindUnspentCoins(); + if (args.Length >= 3) + { + UInt256 assetId; + switch (args[2].ToLower()) + { + case "neo": + case "ans": + assetId = Blockchain.SystemShare.Hash; + break; + case "gas": + case "anc": + assetId = Blockchain.SystemCoin.Hash; + break; + default: + assetId = UInt256.Parse(args[2]); + break; + } + coins = coins.Where(p => p.Output.AssetId.Equals(assetId)); + } + Coin[] coins_array = coins.ToArray(); + const int MAX_SHOW = 100; + for (int i = 0; i < coins_array.Length && i < MAX_SHOW; i++) + Console.WriteLine($"{coins_array[i].Reference.PrevHash}:{coins_array[i].Reference.PrevIndex}"); + if (coins_array.Length > MAX_SHOW) + Console.WriteLine($"({coins_array.Length - MAX_SHOW} more)"); + Console.WriteLine($"total: {coins_array.Length} UTXOs"); + return true; + } + protected internal override void OnStart(string[] args) { Blockchain.RegisterBlockchain(new LevelDBBlockchain(Settings.Default.DataDirectoryPath)); + if (File.Exists(PeerStatePath)) + using (FileStream fs = new FileStream(PeerStatePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + LocalNode.LoadState(fs); + } LocalNode = new LocalNode(); Task.Run(() => { @@ -700,6 +750,10 @@ protected internal override void OnStop() if (consensus != null) consensus.Dispose(); if (rpc != null) rpc.Dispose(); LocalNode.Dispose(); + using (FileStream fs = new FileStream(PeerStatePath, FileMode.Create, FileAccess.Write, FileShare.None)) + { + LocalNode.SaveState(fs); + } Blockchain.Default.Dispose(); } diff --git a/neo-cli/neo-cli.csproj b/neo-cli/neo-cli.csproj index f78ad4798..0cc254146 100644 --- a/neo-cli/neo-cli.csproj +++ b/neo-cli/neo-cli.csproj @@ -3,7 +3,7 @@ 2016-2017 The Neo Project Neo.CLI - 2.0.2 + 2.1.0 The Neo Project netcoreapp1.0 neo-cli @@ -31,7 +31,7 @@ - +