From 245b7d7f52e423f8a56f39c75f129242b18b2f24 Mon Sep 17 00:00:00 2001 From: ProDog Date: Thu, 2 Jul 2020 14:43:51 +0800 Subject: [PATCH 1/6] fix add signature in invokefunction and invokescript --- src/RpcServer/RpcServer.SmartContract.cs | 21 +++++++++++++-------- src/RpcServer/RpcServer.Wallet.cs | 9 ++++++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index bffb524c2..2d4005104 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -20,13 +20,13 @@ partial class RpcServer { private class CheckWitnessHashes : IVerifiable { - private readonly UInt160[] _scriptHashesForVerifying; + private readonly Cosigner[] _cosigners; public Witness[] Witnesses { get; set; } public int Size { get; } - public CheckWitnessHashes(UInt160[] scriptHashesForVerifying) + public CheckWitnessHashes(Cosigner[] cosigners) { - _scriptHashesForVerifying = scriptHashesForVerifying; + _cosigners = cosigners; } public void Serialize(BinaryWriter writer) @@ -46,7 +46,12 @@ public void DeserializeUnsigned(BinaryReader reader) public UInt160[] GetScriptHashesForVerifying(StoreView snapshot) { - return _scriptHashesForVerifying; + return _cosigners.Select(p => p.Account).ToArray(); + } + + public Cosigner[] GetCosigners() + { + return _cosigners; } public void SerializeUnsigned(BinaryWriter writer) @@ -55,7 +60,7 @@ public void SerializeUnsigned(BinaryWriter writer) } } - private JObject GetInvokeResult(byte[] script, IVerifiable checkWitnessHashes = null) + private JObject GetInvokeResult(byte[] script, CheckWitnessHashes checkWitnessHashes = null) { using ApplicationEngine engine = ApplicationEngine.Run(script, checkWitnessHashes, extraGAS: settings.MaxGasInvoke); JObject json = new JObject(); @@ -70,7 +75,7 @@ private JObject GetInvokeResult(byte[] script, IVerifiable checkWitnessHashes = { json["stack"] = "error: recursive reference"; } - ProcessInvokeWithWallet(json); + ProcessInvokeWithWallet(json, checkWitnessHashes); return json; } @@ -80,7 +85,7 @@ private JObject InvokeFunction(JArray _params) UInt160 script_hash = UInt160.Parse(_params[0].AsString()); string operation = _params[1].AsString(); ContractParameter[] args = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; - CheckWitnessHashes checkWitnessHashes = _params.Count >= 4 ? new CheckWitnessHashes(((JArray)_params[3]).Select(u => UInt160.Parse(u.AsString())).ToArray()) : null; + CheckWitnessHashes checkWitnessHashes = _params.Count >= 4 ? new CheckWitnessHashes(((JArray)_params[3]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString()) }).ToArray()) : null; byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { @@ -93,7 +98,7 @@ private JObject InvokeFunction(JArray _params) private JObject InvokeScript(JArray _params) { byte[] script = _params[0].AsString().HexToBytes(); - CheckWitnessHashes checkWitnessHashes = _params.Count >= 2 ? new CheckWitnessHashes(((JArray)_params[1]).Select(u => UInt160.Parse(u.AsString())).ToArray()) : null; + CheckWitnessHashes checkWitnessHashes = _params.Count >= 2 ? new CheckWitnessHashes(((JArray)_params[1]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString(), true) }).ToArray()) : null; return GetInvokeResult(script, checkWitnessHashes); } diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index b0b0f4f74..39c008b48 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -138,11 +138,14 @@ private JObject OpenWallet(JArray _params) return true; } - private void ProcessInvokeWithWallet(JObject result) + private void ProcessInvokeWithWallet(JObject result, CheckWitnessHashes checkWitnessHashes = null) { - if (wallet != null) + if (wallet != null && checkWitnessHashes != null) { - Transaction tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes()); + UInt160[] accounts = wallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).ToArray(); + Cosigner[] cosigners = checkWitnessHashes.GetCosigners().Where(p => accounts.Contains(p.Account)).ToArray(); + + Transaction tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, cosigners); ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) From f97c70d0c91b6bb11235d388f0036ea5e4f34f74 Mon Sep 17 00:00:00 2001 From: HaoqiangZhang Date: Thu, 2 Jul 2020 14:54:40 +0800 Subject: [PATCH 2/6] Update RpcServer.SmartContract.cs --- src/RpcServer/RpcServer.SmartContract.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index 2d4005104..26d4eea2a 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -98,7 +98,7 @@ private JObject InvokeFunction(JArray _params) private JObject InvokeScript(JArray _params) { byte[] script = _params[0].AsString().HexToBytes(); - CheckWitnessHashes checkWitnessHashes = _params.Count >= 2 ? new CheckWitnessHashes(((JArray)_params[1]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString(), true) }).ToArray()) : null; + CheckWitnessHashes checkWitnessHashes = _params.Count >= 2 ? new CheckWitnessHashes(((JArray)_params[1]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString()) }).ToArray()) : null; return GetInvokeResult(script, checkWitnessHashes); } From 1965e353dd31a911d0617e89439c3711c52205e8 Mon Sep 17 00:00:00 2001 From: ProDog Date: Fri, 3 Jul 2020 15:32:42 +0800 Subject: [PATCH 3/6] rename --- src/RpcServer/RpcServer.SmartContract.cs | 18 +++++++++--------- src/RpcServer/RpcServer.Wallet.cs | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index 26d4eea2a..0129c9683 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -18,13 +18,13 @@ namespace Neo.Plugins { partial class RpcServer { - private class CheckWitnessHashes : IVerifiable + private class Cosigners : IVerifiable { private readonly Cosigner[] _cosigners; public Witness[] Witnesses { get; set; } public int Size { get; } - public CheckWitnessHashes(Cosigner[] cosigners) + public Cosigners(Cosigner[] cosigners) { _cosigners = cosigners; } @@ -60,9 +60,9 @@ public void SerializeUnsigned(BinaryWriter writer) } } - private JObject GetInvokeResult(byte[] script, CheckWitnessHashes checkWitnessHashes = null) + private JObject GetInvokeResult(byte[] script, Cosigners cosigners = null) { - using ApplicationEngine engine = ApplicationEngine.Run(script, checkWitnessHashes, extraGAS: settings.MaxGasInvoke); + using ApplicationEngine engine = ApplicationEngine.Run(script, cosigners, extraGAS: settings.MaxGasInvoke); JObject json = new JObject(); json["script"] = script.ToHexString(); json["state"] = engine.State; @@ -75,7 +75,7 @@ private JObject GetInvokeResult(byte[] script, CheckWitnessHashes checkWitnessHa { json["stack"] = "error: recursive reference"; } - ProcessInvokeWithWallet(json, checkWitnessHashes); + ProcessInvokeWithWallet(json, cosigners); return json; } @@ -85,21 +85,21 @@ private JObject InvokeFunction(JArray _params) UInt160 script_hash = UInt160.Parse(_params[0].AsString()); string operation = _params[1].AsString(); ContractParameter[] args = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; - CheckWitnessHashes checkWitnessHashes = _params.Count >= 4 ? new CheckWitnessHashes(((JArray)_params[3]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString()) }).ToArray()) : null; + Cosigners cosigners = _params.Count >= 4 ? new Cosigners(((JArray)_params[3]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString()) }).ToArray()) : null; byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { script = sb.EmitAppCall(script_hash, operation, args).ToArray(); } - return GetInvokeResult(script, checkWitnessHashes); + return GetInvokeResult(script, cosigners); } [RpcMethod] private JObject InvokeScript(JArray _params) { byte[] script = _params[0].AsString().HexToBytes(); - CheckWitnessHashes checkWitnessHashes = _params.Count >= 2 ? new CheckWitnessHashes(((JArray)_params[1]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString()) }).ToArray()) : null; - return GetInvokeResult(script, checkWitnessHashes); + Cosigners cosigners = _params.Count >= 2 ? new Cosigners(((JArray)_params[1]).Select(u => new Cosigner() { Account = UInt160.Parse(u["account"].AsString()), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), u["scopes"].AsString()) }).ToArray()) : null; + return GetInvokeResult(script, cosigners); } [RpcMethod] diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 39c008b48..13a9d73db 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -138,14 +138,14 @@ private JObject OpenWallet(JArray _params) return true; } - private void ProcessInvokeWithWallet(JObject result, CheckWitnessHashes checkWitnessHashes = null) + private void ProcessInvokeWithWallet(JObject result, Cosigners cosigners = null) { - if (wallet != null && checkWitnessHashes != null) + if (wallet != null && cosigners != null) { UInt160[] accounts = wallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).ToArray(); - Cosigner[] cosigners = checkWitnessHashes.GetCosigners().Where(p => accounts.Contains(p.Account)).ToArray(); + Cosigner[] witnessCosigners= cosigners.GetCosigners().Where(p => accounts.Contains(p.Account)).ToArray(); - Transaction tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, cosigners); + Transaction tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, witnessCosigners); ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); if (context.Completed) From e4584924a708cdc5affa784a6fe8ccae3b00813f Mon Sep 17 00:00:00 2001 From: ProDog Date: Fri, 3 Jul 2020 15:36:36 +0800 Subject: [PATCH 4/6] fix format --- src/RpcServer/RpcServer.Wallet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 13a9d73db..6020a897a 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -143,7 +143,7 @@ private void ProcessInvokeWithWallet(JObject result, Cosigners cosigners = null) if (wallet != null && cosigners != null) { UInt160[] accounts = wallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).ToArray(); - Cosigner[] witnessCosigners= cosigners.GetCosigners().Where(p => accounts.Contains(p.Account)).ToArray(); + Cosigner[] witnessCosigners = cosigners.GetCosigners().Where(p => accounts.Contains(p.Account)).ToArray(); Transaction tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, witnessCosigners); ContractParametersContext context = new ContractParametersContext(tx); From de6ac6c3e02bc2f1e53130fdf1023c6e933568e1 Mon Sep 17 00:00:00 2001 From: ProDog Date: Fri, 3 Jul 2020 16:57:26 +0800 Subject: [PATCH 5/6] add exception if wallet or cosigners is null --- src/RpcServer/RpcServer.Wallet.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 6020a897a..1c04778e5 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -144,7 +144,8 @@ private void ProcessInvokeWithWallet(JObject result, Cosigners cosigners = null) { UInt160[] accounts = wallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).ToArray(); Cosigner[] witnessCosigners = cosigners.GetCosigners().Where(p => accounts.Contains(p.Account)).ToArray(); - + if (witnessCosigners.Count() == 0) + throw new RpcException(-32603, "Didn't open wallet or cosigners incorrect"); Transaction tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, witnessCosigners); ContractParametersContext context = new ContractParametersContext(tx); wallet.Sign(context); From 02d5fc877158a32a6c3bbf6a3e8adb0c525e1165 Mon Sep 17 00:00:00 2001 From: ProDog Date: Sat, 4 Jul 2020 18:21:11 +0800 Subject: [PATCH 6/6] Set the default tx to null --- src/RpcServer/RpcServer.Wallet.cs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/RpcServer/RpcServer.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 1c04778e5..398ce2de3 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -140,21 +140,23 @@ private JObject OpenWallet(JArray _params) private void ProcessInvokeWithWallet(JObject result, Cosigners cosigners = null) { + Transaction tx = null; if (wallet != null && cosigners != null) { UInt160[] accounts = wallet.GetAccounts().Where(p => !p.Lock && !p.WatchOnly).Select(p => p.ScriptHash).ToArray(); Cosigner[] witnessCosigners = cosigners.GetCosigners().Where(p => accounts.Contains(p.Account)).ToArray(); - if (witnessCosigners.Count() == 0) - throw new RpcException(-32603, "Didn't open wallet or cosigners incorrect"); - Transaction tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, witnessCosigners); - ContractParametersContext context = new ContractParametersContext(tx); - wallet.Sign(context); - if (context.Completed) - tx.Witnesses = context.GetWitnesses(); - else - tx = null; - result["tx"] = tx?.ToArray().ToHexString(); + if (witnessCosigners.Count() > 0) + { + tx = wallet.MakeTransaction(result["script"].AsString().HexToBytes(), null, witnessCosigners); + ContractParametersContext context = new ContractParametersContext(tx); + wallet.Sign(context); + if (context.Completed) + tx.Witnesses = context.GetWitnesses(); + else + tx = null; + } } + result["tx"] = tx?.ToArray().ToHexString(); } [RpcMethod]