From 6018bf40eeaf57997ce55c6cf3aee53d82383057 Mon Sep 17 00:00:00 2001 From: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Date: Fri, 11 Dec 2020 00:44:21 +0800 Subject: [PATCH 1/2] Sync to the latest neo (#422) --- src/Directory.Build.props | 2 +- src/RpcClient/ContractClient.cs | 4 +- src/RpcClient/Models/RpcContractState.cs | 3 +- src/RpcClient/RpcClient.cs | 1 + src/RpcNep17Tracker/RpcNep17Tracker.cs | 3 +- src/RpcServer/RpcServer.Blockchain.cs | 7 +++- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 41 +++++++------------ .../UT_ContractClient.cs | 3 +- 8 files changed, 28 insertions(+), 36 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index b7a7f73f8..68228f776 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/src/RpcClient/ContractClient.cs b/src/RpcClient/ContractClient.cs index a6ffb8f28..e2c5dbfdc 100644 --- a/src/RpcClient/ContractClient.cs +++ b/src/RpcClient/ContractClient.cs @@ -1,9 +1,9 @@ -using System; using System.Threading.Tasks; using Neo.Network.P2P.Payloads; using Neo.Network.RPC.Models; using Neo.SmartContract; using Neo.SmartContract.Manifest; +using Neo.SmartContract.Native; using Neo.VM; using Neo.Wallets; @@ -57,7 +57,7 @@ public async Task CreateDeployContractTxAsync(byte[] contractScript byte[] script; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitSysCall(ApplicationEngine.System_Contract_Create, contractScript, manifest.ToString()); + sb.EmitAppCall(NativeContract.Management.Hash, "deploy", contractScript, manifest.ToString()); script = sb.ToArray(); } UInt160 sender = Contract.CreateSignatureRedeemScript(key.PublicKey).ToScriptHash(); diff --git a/src/RpcClient/Models/RpcContractState.cs b/src/RpcClient/Models/RpcContractState.cs index 802710d0d..e4e0f711d 100644 --- a/src/RpcClient/Models/RpcContractState.cs +++ b/src/RpcClient/Models/RpcContractState.cs @@ -1,6 +1,6 @@ using Neo; using Neo.IO.Json; -using Neo.Ledger; +using Neo.SmartContract; using Neo.SmartContract.Manifest; using System; @@ -20,6 +20,7 @@ public static RpcContractState FromJson(JObject json) ContractState = new ContractState { Id = (int)json["id"].AsNumber(), + UpdateCounter = (ushort)json["updatecounter"].AsNumber(), Hash = UInt160.Parse(json["hash"].AsString()), Script = Convert.FromBase64String(json["script"].AsString()), Manifest = ContractManifest.FromJson(json["manifest"]) diff --git a/src/RpcClient/RpcClient.cs b/src/RpcClient/RpcClient.cs index 8c0ea27c1..ca47d82a5 100644 --- a/src/RpcClient/RpcClient.cs +++ b/src/RpcClient/RpcClient.cs @@ -201,6 +201,7 @@ public static ContractState ContractStateFromJson(JObject json) return new ContractState { Id = (int)json["id"].AsNumber(), + UpdateCounter = (ushort)json["updatecounter"].AsNumber(), Hash = UInt160.Parse(json["hash"].AsString()), Script = Convert.FromBase64String(json["script"].AsString()), Manifest = ContractManifest.FromJson(json["manifest"]) diff --git a/src/RpcNep17Tracker/RpcNep17Tracker.cs b/src/RpcNep17Tracker/RpcNep17Tracker.cs index 807e6f41e..9dcef2318 100644 --- a/src/RpcNep17Tracker/RpcNep17Tracker.cs +++ b/src/RpcNep17Tracker/RpcNep17Tracker.cs @@ -275,6 +275,7 @@ public JObject GetNep17Transfers(JArray _params) [RpcMethod] public JObject GetNep17Balances(JArray _params) { + using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString()); JObject json = new JObject(); @@ -286,7 +287,7 @@ public JObject GetNep17Balances(JArray _params) foreach (var (key, value) in dbCache.Find(prefix)) { JObject balance = new JObject(); - if (Blockchain.Singleton.View.Contracts.TryGet(key.AssetScriptHash) is null) + if (NativeContract.Management.GetContract(snapshot, key.AssetScriptHash) is null) continue; balance["assethash"] = key.AssetScriptHash.ToString(); balance["amount"] = value.Balance.ToString(); diff --git a/src/RpcServer/RpcServer.Blockchain.cs b/src/RpcServer/RpcServer.Blockchain.cs index 137d484e4..adccfbf38 100644 --- a/src/RpcServer/RpcServer.Blockchain.cs +++ b/src/RpcServer/RpcServer.Blockchain.cs @@ -6,6 +6,7 @@ using Neo.Ledger; using Neo.Network.P2P.Payloads; using Neo.Persistence; +using Neo.SmartContract; using Neo.SmartContract.Native; using System; using System.Collections.Generic; @@ -103,8 +104,9 @@ protected virtual JObject GetBlockHeader(JArray _params) [RpcMethod] protected virtual JObject GetContractState(JArray _params) { + using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); UInt160 script_hash = ToScriptHash(_params[0].AsString()); - ContractState contract = Blockchain.Singleton.View.Contracts.TryGet(script_hash); + ContractState contract = NativeContract.Management.GetContract(snapshot, script_hash); return contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract"); } @@ -166,8 +168,9 @@ protected virtual JObject GetStorage(JArray _params) { if (!int.TryParse(_params[0].AsString(), out int id)) { + using SnapshotView snapshot = Blockchain.Singleton.GetSnapshot(); UInt160 script_hash = UInt160.Parse(_params[0].AsString()); - ContractState contract = Blockchain.Singleton.View.Contracts.TryGet(script_hash); + ContractState contract = NativeContract.Management.GetContract(snapshot, script_hash); if (contract == null) return null; id = contract.Id; } diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index 42ac24a45..8f2051443 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -318,7 +318,7 @@ "Request": { "jsonrpc": "2.0", "method": "getcontractstate", - "params": [ "0x36a019d836d964c438c573f78badf79b9e7eebdd" ], + "params": [ "0xb399c051778cf37a1e4ef88509b2e054d0420a32" ], "id": 1 }, "Response": { @@ -326,9 +326,9 @@ "id": 1, "result": { "id": -2, - "updatecounter": 0, - "hash": "0x36a019d836d964c438c573f78badf79b9e7eebdd", - "script": "DANHQVNBa2d4Cw==", + "updatecounter": 2, + "hash": "0xb399c051778cf37a1e4ef88509b2e054d0420a32", + "script": "DANHQVNBGvd7Zw==", "manifest": { "name": "GAS", "groups": [], @@ -337,17 +337,12 @@ ], "abi": { "methods": [ - { - "name": "onPersist", - "parameters": [], - "offset": 0, - "returntype": "Void" - }, { "name": "totalSupply", "parameters": [], "offset": 0, - "returntype": "Integer" + "returntype": "Integer", + "safe": true }, { "name": "balanceOf", @@ -358,7 +353,8 @@ } ], "offset": 0, - "returntype": "Integer" + "returntype": "Integer", + "safe": true }, { "name": "transfer", @@ -381,25 +377,22 @@ } ], "offset": 0, - "returntype": "Boolean" - }, - { - "name": "postPersist", - "parameters": [], - "offset": 0, - "returntype": "Void" + "returntype": "Boolean", + "safe": false }, { "name": "symbol", "parameters": [], "offset": 0, - "returntype": "String" + "returntype": "String", + "safe": true }, { "name": "decimals", "parameters": [], "offset": 0, - "returntype": "Integer" + "returntype": "Integer", + "safe": true } ], "events": [ @@ -429,12 +422,6 @@ } ], "trusts": [], - "safemethods": [ - "totalSupply", - "balanceOf", - "symbol", - "decimals" - ], "extra": null } } diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs index a442fdd74..0de9a0958 100644 --- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs @@ -49,14 +49,13 @@ public async Task TestDeployContract() Methods = new ContractMethodDescriptor[0] }, Groups = new ContractGroup[0], - SafeMethods = WildcardContainer.Create(), Trusts = WildcardContainer.Create(), SupportedStandards = new string[] { "NEP-10" }, Extra = null, }; using (ScriptBuilder sb = new ScriptBuilder()) { - sb.EmitSysCall(ApplicationEngine.System_Contract_Create, new byte[1], manifest.ToString()); + sb.EmitAppCall(NativeContract.Management.Hash, "deploy", new byte[1], manifest.ToString()); script = sb.ToArray(); } From 06828a4850fd6e9cd761ffdcbfcce1d5ca2a059e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Thu, 10 Dec 2020 23:19:05 -0600 Subject: [PATCH 2/2] Add RPC InvokeContractVerify (#409) * Add RPC InvokeContractVerify * update * Update src/RpcServer/RpcServer.SmartContract.cs Co-authored-by: Shargon * Add signers * RpcException Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> --- src/RpcServer/RpcServer.SmartContract.cs | 51 ++++++++++++++++++++++++ src/RpcServer/RpcServer.csproj | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index 99dff93bf..8ed4ae144 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -107,6 +107,57 @@ private static Signers SignersFromJson(JArray _params) return ret; } + private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] args, Signers signers = null) + { + var snapshot = Blockchain.Singleton.GetSnapshot(); + var contract = snapshot.Contracts.TryGet(scriptHash); + if (contract is null) + { + throw new RpcException(-100, "Unknown contract"); + } + var methodName = "verify"; + + Transaction tx = signers == null ? null : new Transaction + { + Signers = signers.GetSigners(), + Attributes = Array.Empty(), + Witnesses = signers.Witnesses, + }; + + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.Clone()); + engine.LoadContract(contract, methodName, CallFlags.None); + + engine.LoadScript(new ScriptBuilder().EmitAppCall(scriptHash, methodName, args).ToArray(), CallFlags.AllowCall); + + JObject json = new JObject(); + json["script"] = Convert.ToBase64String(contract.Script); + json["state"] = engine.Execute(); + json["gasconsumed"] = new BigDecimal(engine.GasConsumed, NativeContract.GAS.Decimals).ToString(); + json["exception"] = GetExceptionMessage(engine.FaultException); + try + { + json["stack"] = new JArray(engine.ResultStack.Select(p => p.ToJson())); + } + catch (InvalidOperationException) + { + json["stack"] = "error: recursive reference"; + } + if (engine.State != VMState.FAULT) + { + ProcessInvokeWithWallet(json); + } + return json; + } + + [RpcMethod] + protected virtual JObject InvokeContractVerify(JArray _params) + { + UInt160 script_hash = UInt160.Parse(_params[0].AsString()); + ContractParameter[] args = _params.Count >= 2 ? ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0]; + Signers signers = _params.Count >= 3 ? SignersFromJson((JArray)_params[2]) : null; + return GetVerificationResult(script_hash, args, signers); + } + [RpcMethod] protected virtual JObject InvokeFunction(JArray _params) { diff --git a/src/RpcServer/RpcServer.csproj b/src/RpcServer/RpcServer.csproj index 9ce3d9e1c..f04dbdda5 100644 --- a/src/RpcServer/RpcServer.csproj +++ b/src/RpcServer/RpcServer.csproj @@ -1,4 +1,4 @@ - + Neo.Plugins.RpcServer