diff --git a/src/RpcServer/RpcServer.SmartContract.cs b/src/RpcServer/RpcServer.SmartContract.cs index 1f19e5c65..dc61d55d3 100644 --- a/src/RpcServer/RpcServer.SmartContract.cs +++ b/src/RpcServer/RpcServer.SmartContract.cs @@ -107,57 +107,6 @@ 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 = NativeContract.ContractManagement.GetContract(snapshot, 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, true, 0); - - engine.LoadScript(new ScriptBuilder().EmitDynamicCall(scriptHash, methodName, args).ToArray()); - - 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.Wallet.cs b/src/RpcServer/RpcServer.Wallet.cs index 6ec21fb56..c9f571035 100644 --- a/src/RpcServer/RpcServer.Wallet.cs +++ b/src/RpcServer/RpcServer.Wallet.cs @@ -9,6 +9,7 @@ using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; +using Neo.VM; using Neo.Wallets; using Neo.Wallets.NEP6; using Neo.Wallets.SQLite; @@ -324,6 +325,54 @@ protected virtual JObject SendToAddress(JArray _params) return SignAndRelay(tx); } + [RpcMethod] + protected virtual JObject InvokeContractVerify(JArray _params) + { + CheckWallet(); + 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); + } + + private JObject GetVerificationResult(UInt160 scriptHash, ContractParameter[] args, Signers signers = null) + { + var snapshot = Blockchain.Singleton.GetSnapshot(); + var contract = NativeContract.ContractManagement.GetContract(snapshot, 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() + }; + ContractParametersContext context = new ContractParametersContext(tx); + wallet.Sign(context); + tx.Witnesses = context.Completed ? context.GetWitnesses() : null; + + using ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Verification, tx, snapshot.Clone()); + engine.LoadScript(new ScriptBuilder().EmitDynamicCall(scriptHash, methodName, args).ToArray(), (ushort)args.Length, 1); + + 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"; + } + return json; + } + private JObject SignAndRelay(Transaction tx) { ContractParametersContext context = new ContractParametersContext(tx);