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