diff --git a/src/RpcClient/Models/RpcInvokeResult.cs b/src/RpcClient/Models/RpcInvokeResult.cs
index eeae4518c..67fb81e9a 100644
--- a/src/RpcClient/Models/RpcInvokeResult.cs
+++ b/src/RpcClient/Models/RpcInvokeResult.cs
@@ -1,5 +1,6 @@
using Neo.IO.Json;
-using Neo.SmartContract;
+using Neo.VM;
+using Neo.VM.Types;
using System;
using System.Linq;
@@ -13,7 +14,7 @@ public class RpcInvokeResult
public string GasConsumed { get; set; }
- public ContractParameter[] Stack { get; set; }
+ public StackItem[] Stack { get; set; }
public string Tx { get; set; }
@@ -44,7 +45,7 @@ public static RpcInvokeResult FromJson(JObject json)
invokeScriptResult.GasConsumed = json["gasconsumed"].AsString();
try
{
- invokeScriptResult.Stack = ((JArray)json["stack"]).Select(p => ContractParameter.FromJson(p)).ToArray();
+ invokeScriptResult.Stack = ((JArray)json["stack"]).Select(p => Utility.StackItemFromJson(p)).ToArray();
}
catch { }
invokeScriptResult.Tx = json["tx"]?.AsString();
diff --git a/src/RpcClient/Nep5API.cs b/src/RpcClient/Nep5API.cs
index fc1616126..c700d5c68 100644
--- a/src/RpcClient/Nep5API.cs
+++ b/src/RpcClient/Nep5API.cs
@@ -30,7 +30,7 @@ public Nep5API(RpcClient rpcClient) : base(rpcClient) { }
///
public BigInteger BalanceOf(UInt160 scriptHash, UInt160 account)
{
- BigInteger balance = TestInvoke(scriptHash, "balanceOf", account).Stack.Single().ToStackItem().GetInteger();
+ BigInteger balance = TestInvoke(scriptHash, "balanceOf", account).Stack.Single().GetInteger();
return balance;
}
@@ -41,7 +41,7 @@ public BigInteger BalanceOf(UInt160 scriptHash, UInt160 account)
///
public string Name(UInt160 scriptHash)
{
- return TestInvoke(scriptHash, "name").Stack.Single().ToStackItem().GetString();
+ return TestInvoke(scriptHash, "name").Stack.Single().GetString();
}
///
@@ -51,7 +51,7 @@ public string Name(UInt160 scriptHash)
///
public string Symbol(UInt160 scriptHash)
{
- return TestInvoke(scriptHash, "symbol").Stack.Single().ToStackItem().GetString();
+ return TestInvoke(scriptHash, "symbol").Stack.Single().GetString();
}
///
@@ -61,7 +61,7 @@ public string Symbol(UInt160 scriptHash)
///
public byte Decimals(UInt160 scriptHash)
{
- return (byte)TestInvoke(scriptHash, "decimals").Stack.Single().ToStackItem().GetInteger();
+ return (byte)TestInvoke(scriptHash, "decimals").Stack.Single().GetInteger();
}
///
@@ -71,7 +71,7 @@ public byte Decimals(UInt160 scriptHash)
///
public BigInteger TotalSupply(UInt160 scriptHash)
{
- return TestInvoke(scriptHash, "totalSupply").Stack.Single().ToStackItem().GetInteger();
+ return TestInvoke(scriptHash, "totalSupply").Stack.Single().GetInteger();
}
///
@@ -90,10 +90,10 @@ public RpcNep5TokenInfo GetTokenInfo(UInt160 scriptHash)
return new RpcNep5TokenInfo
{
- Name = result[0].ToStackItem().GetString(),
- Symbol = result[1].ToStackItem().GetString(),
- Decimals = (byte)result[2].ToStackItem().GetInteger(),
- TotalSupply = result[3].ToStackItem().GetInteger()
+ Name = result[0].GetString(),
+ Symbol = result[1].GetString(),
+ Decimals = (byte)result[2].GetInteger(),
+ TotalSupply = result[3].GetInteger()
};
}
diff --git a/src/RpcClient/PolicyAPI.cs b/src/RpcClient/PolicyAPI.cs
index de078a8e3..073b105b3 100644
--- a/src/RpcClient/PolicyAPI.cs
+++ b/src/RpcClient/PolicyAPI.cs
@@ -23,7 +23,7 @@ public PolicyAPI(RpcClient rpcClient) : base(rpcClient) { }
///
public uint GetMaxTransactionsPerBlock()
{
- return (uint)TestInvoke(scriptHash, "getMaxTransactionsPerBlock").Stack.Single().ToStackItem().GetInteger();
+ return (uint)TestInvoke(scriptHash, "getMaxTransactionsPerBlock").Stack.Single().GetInteger();
}
///
@@ -32,7 +32,7 @@ public uint GetMaxTransactionsPerBlock()
///
public uint GetMaxBlockSize()
{
- return (uint)TestInvoke(scriptHash, "getMaxBlockSize").Stack.Single().ToStackItem().GetInteger();
+ return (uint)TestInvoke(scriptHash, "getMaxBlockSize").Stack.Single().GetInteger();
}
///
@@ -41,7 +41,7 @@ public uint GetMaxBlockSize()
///
public long GetFeePerByte()
{
- return (long)TestInvoke(scriptHash, "getFeePerByte").Stack.Single().ToStackItem().GetInteger();
+ return (long)TestInvoke(scriptHash, "getFeePerByte").Stack.Single().GetInteger();
}
///
@@ -50,7 +50,7 @@ public long GetFeePerByte()
///
public UInt160[] GetBlockedAccounts()
{
- var result = (VM.Types.Array)TestInvoke(scriptHash, "getBlockedAccounts").Stack.Single().ToStackItem();
+ var result = (VM.Types.Array)TestInvoke(scriptHash, "getBlockedAccounts").Stack.Single();
return result.Select(p => new UInt160(p.GetSpan().ToArray())).ToArray();
}
}
diff --git a/src/RpcClient/Utility.cs b/src/RpcClient/Utility.cs
index cff72fd78..6bca96b12 100644
--- a/src/RpcClient/Utility.cs
+++ b/src/RpcClient/Utility.cs
@@ -2,11 +2,15 @@
using Neo.IO.Json;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract;
+using Neo.VM.Types;
using Neo.Wallets;
using System;
using System.Globalization;
using System.Linq;
using System.Numerics;
+using Array = Neo.VM.Types.Array;
+using Boolean = Neo.VM.Types.Boolean;
+using Buffer = Neo.VM.Types.Buffer;
namespace Neo.Network.RPC
{
@@ -173,5 +177,44 @@ public static Witness WitnessFromJson(JObject json)
witness.VerificationScript = Convert.FromBase64String(json["verification"].AsString());
return witness;
}
+
+ public static StackItem StackItemFromJson(JObject json)
+ {
+ StackItemType type = json["type"].TryGetEnum();
+ switch (type)
+ {
+ case StackItemType.Boolean:
+ return new Boolean(json["value"].AsBoolean());
+ case StackItemType.Buffer:
+ return new Buffer(Convert.FromBase64String(json["value"].AsString()));
+ case StackItemType.ByteString:
+ return new ByteString(Convert.FromBase64String(json["value"].AsString()));
+ case StackItemType.Integer:
+ return new Integer(new BigInteger(json["value"].AsNumber()));
+ case StackItemType.Array:
+ Array array = new Array();
+ foreach (var item in (JArray)json["value"])
+ array.Add(StackItemFromJson(item));
+ return array;
+ case StackItemType.Struct:
+ Struct @struct = new Struct();
+ foreach (var item in (JArray)json["value"])
+ @struct.Add(StackItemFromJson(item));
+ return @struct;
+ case StackItemType.Map:
+ Map map = new Map();
+ foreach (var item in (JArray)json["value"])
+ {
+ PrimitiveType key = (PrimitiveType)StackItemFromJson(item["key"]);
+ map[key] = StackItemFromJson(item["value"]);
+ }
+ return map;
+ case StackItemType.Pointer:
+ return new Pointer(null, (int)json["value"].AsNumber());
+ case StackItemType.InteropInterface:
+ return new InteropInterface(new object()); // See https://github.com/neo-project/neo/blob/master/src/neo/VM/Helper.cs#L194
+ }
+ return null;
+ }
}
}
diff --git a/src/RpcClient/WalletAPI.cs b/src/RpcClient/WalletAPI.cs
index 3d9edaa83..014aba6ec 100644
--- a/src/RpcClient/WalletAPI.cs
+++ b/src/RpcClient/WalletAPI.cs
@@ -52,7 +52,7 @@ public decimal GetUnclaimedGas(UInt160 account)
{
UInt160 scriptHash = NativeContract.NEO.Hash;
BigInteger balance = nep5API.TestInvoke(scriptHash, "unclaimedGas", account, rpcClient.GetBlockCount() - 1)
- .Stack.Single().ToStackItem().GetInteger();
+ .Stack.Single().GetInteger();
return ((decimal)balance) / (long)NativeContract.GAS.Factor;
}
diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json
index d364a71d3..33ee866d1 100644
--- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json
+++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json
@@ -758,20 +758,62 @@
"gasconsumed": "5061560",
"stack": [
{
- "type": "ByteArray",
- "value": "R0FT"
- },
- {
- "type": "ByteArray",
- "value": "Z2Fz"
- },
- {
- "type": "Integer",
- "value": "8"
- },
- {
- "type": "Integer",
- "value": "3001101329992600"
+ "type": "Array",
+ "value": [
+ {
+ "type": "ByteString",
+ "value": "dGVzdA=="
+ },
+ {
+ "type": "InteropInterface"
+ },
+ {
+ "type": "Integer",
+ "value": "1"
+ },
+ {
+ "type": "Buffer",
+ "value": "CAwiNQw="
+ },
+ {
+ "type": "Array",
+ "value": [
+ {
+ "type": "ByteString",
+ "value": "YmI="
+ },
+ {
+ "type": "ByteString",
+ "value": "Y2Mw"
+ }
+ ]
+ },
+ {
+ "type": "Map",
+ "value": [
+ {
+ "key": {
+ "type": "Integer",
+ "value": "2"
+ },
+ "value": {
+ "type": "Integer",
+ "value": "12"
+ }
+ },
+ {
+ "key": {
+ "type": "Integer",
+ "value": "0"
+ },
+ "value": {
+ "type": "Integer",
+ "value": "24"
+ }
+ }
+ ]
+ }
+ ]
}
],
"tx": "00769d16556925aa554712439a9c613ba114efa3fac23ddbca00e1f505000000009e021400000000005620200000009910c30c046e616d650c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c0673796d626f6c0c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c08646563696d616c730c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5210c30c0b746f74616c537570706c790c143b7d3711c6f0ccf9b1dca903d1bfa1d896f1238c41627d5b5201420c40c848d0fcbf5e6a820508242ea8b7ccbeed3caefeed5db570537279c2154f7cfd8b0d8f477f37f4e6ca912935b732684d57c455dff7aa525ad4ab000931f22208290c2103aa052fbcb8e5b33a4eefd662536f8684641f04109f1d5e69cdda6f084890286a0b410a906ad4"
diff --git a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs
index 0e84afa3d..dfdbf9990 100644
--- a/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs
+++ b/tests/Neo.Network.RPC.Tests/UT_ContractClient.cs
@@ -32,7 +32,7 @@ public void TestInvoke()
ContractClient contractClient = new ContractClient(rpcClientMock.Object);
var result = contractClient.TestInvoke(NativeContract.GAS.Hash, "balanceOf", UInt160.Zero);
- Assert.AreEqual(30000000000000L, (long)result.Stack[0].ToStackItem().GetInteger());
+ Assert.AreEqual(30000000000000L, (long)result.Stack[0].GetInteger());
}
[TestMethod]
diff --git a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs
index 1f4da3250..b1546a9c7 100644
--- a/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs
+++ b/tests/Neo.Network.RPC.Tests/UT_TransactionManager.cs
@@ -95,7 +95,7 @@ public static void MockInvokeScript(Mock mockClient, byte[] script, p
{
var result = new RpcInvokeResult()
{
- Stack = parameters,
+ Stack = parameters.Select(p => p.ToStackItem()).ToArray(),
GasConsumed = "100",
Script = script.ToHexString(),
State = VMState.HALT