From 131a9ca88e256fb39a8b3a3f33a1476ba7b90884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=BF=97=E5=90=8C?= Date: Mon, 7 Dec 2020 02:57:14 -0600 Subject: [PATCH] Nep17 (#412) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [RpcServer] Querying contracts by ID/name (#378) * fixed-bug-1021 * Update src/RpcServer/RpcServer.SmartContract.cs * 😂 * draft * draft * update * fixed bug with decimal of GAS consumed in invokefunction/invokescript * remove modify of invokescript * Querying contracts by ID/name, server side * update * Enable using native.name for search Enable using native.name for search * Using keyword instead of addressOrScriptHash * revert * _initialize * split * update * Update exception message in ApplicationLog * Update src/ApplicationLogs/LogReader.cs Co-authored-by: Luchuan * update * a * More fix * fix * Fixed UT * Simplify Code * Simplify Code 2 * Update RpcServer * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan * String Substitution * Modify filename and name methods * update * update * Update src/RpcClient/Models/RpcNep5TokenInfo.cs Co-authored-by: Vitor Nazário Coelho * Update src/RpcClient/Nep17API.cs Co-authored-by: Vitor Nazário Coelho * MPT in StateService from core (#410) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal (#413) * Unify GetUnclaimedGas and GetWalletUnclaimedGas with decimal * fix * Fixed UT (Neo CI01089) * Update Nep17API.cs * Update README.md Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> * update filename * Fix UT * Format * fix * update * update UT * Add Unit Tests * update Co-authored-by: Shargon Co-authored-by: Owen Zhang <38493437+superboyiii@users.noreply.github.com> Co-authored-by: superboyiii <573504781@qq.com> Co-authored-by: Vitor Nazário Coelho Co-authored-by: Luchuan Co-authored-by: ZhangTao --- README.md | 6 +- neo-modules.sln | 2 +- src/Directory.Build.props | 2 +- ...RpcNep5Balances.cs => RpcNep17Balances.cs} | 18 ++--- ...cNep5TokenInfo.cs => RpcNep17TokenInfo.cs} | 2 +- ...cNep5Transfers.cs => RpcNep17Transfers.cs} | 20 ++--- src/RpcClient/{Nep5API.cs => Nep17API.cs} | 57 ++++++------- src/RpcClient/RpcClient.cs | 20 ++--- src/RpcClient/TransactionManager.cs | 2 +- src/RpcClient/WalletAPI.cs | 34 ++++---- .../DbCache.cs | 0 .../Helper.cs | 0 .../Nep17Balance.cs} | 8 +- .../Nep17BalanceKey.cs} | 12 +-- .../Nep17Transfer.cs} | 8 +- .../Nep17TransferKey.cs} | 12 +-- .../RpcNep17Tracker.cs} | 80 +++++++++---------- .../RpcNep17Tracker.csproj} | 4 +- .../RpcNep17Tracker}/config.json | 4 +- tests/Neo.Network.RPC.Tests/RpcTestCases.json | 14 ++-- .../{UT_Nep5API.cs => UT_Nep17API.cs} | 56 ++++++------- tests/Neo.Network.RPC.Tests/UT_RpcClient.cs | 16 ++-- tests/Neo.Network.RPC.Tests/UT_RpcModels.cs | 12 +-- tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs | 16 ++++ 24 files changed, 208 insertions(+), 197 deletions(-) rename src/RpcClient/Models/{RpcNep5Balances.cs => RpcNep17Balances.cs} (75%) rename src/RpcClient/Models/{RpcNep5TokenInfo.cs => RpcNep17TokenInfo.cs} (87%) rename src/RpcClient/Models/{RpcNep5Transfers.cs => RpcNep17Transfers.cs} (81%) rename src/RpcClient/{Nep5API.cs => Nep17API.cs} (76%) rename src/{RpcNep5Tracker => RpcNep17Tracker}/DbCache.cs (100%) rename src/{RpcNep5Tracker => RpcNep17Tracker}/Helper.cs (100%) rename src/{RpcNep5Tracker/Nep5Balance.cs => RpcNep17Tracker/Nep17Balance.cs} (80%) rename src/{RpcNep5Tracker/Nep5BalanceKey.cs => RpcNep17Tracker/Nep17BalanceKey.cs} (80%) rename src/{RpcNep5Tracker/Nep5Transfer.cs => RpcNep17Tracker/Nep17Transfer.cs} (84%) rename src/{RpcNep5Tracker/Nep5TransferKey.cs => RpcNep17Tracker/Nep17TransferKey.cs} (87%) rename src/{RpcNep5Tracker/RpcNep5Tracker.cs => RpcNep17Tracker/RpcNep17Tracker.cs} (75%) rename src/{RpcNep5Tracker/RpcNep5Tracker.csproj => RpcNep17Tracker/RpcNep17Tracker.csproj} (82%) rename src/{RpcNep5Tracker/RpcNep5Tracker => RpcNep17Tracker/RpcNep17Tracker}/config.json (76%) rename tests/Neo.Network.RPC.Tests/{UT_Nep5API.cs => UT_Nep17API.cs} (67%) diff --git a/README.md b/README.md index 4712b5be2..95f0e3526 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,12 @@ You can also use `RocksDBStore` in the NEO system by modifying the default stora ### RpcServer Plugin for hosting a RpcServer on the neo-node, being able to disable specific calls. -### RpcNep5Tracker -Plugin that enables NEP5 tracking using LevelDB. +### RpcNep17Tracker +Plugin that enables NEP17 tracking using LevelDB. This module works in conjunction with RpcServer, otherwise, just local storage (on leveldb) would be created. ## C# SDK ### RpcClient The RpcClient Project is an individual SDK that is used to interact with NEO blockchain through NEO RPC methods for development using. The main functions include RPC calling, Transaction making, Contract deployment & calling, and Asset transfering. -It needs a NEO node with the `RpcServer` plugin as a provider. And the provider needs more plugins like `RpcNep5Tracker` and `ApplicationLogs` if you want to call RPC methods supplied by the plugins. +It needs a NEO node with the `RpcServer` plugin as a provider. And the provider needs more plugins like `RpcNep17Tracker` and `ApplicationLogs` if you want to call RPC methods supplied by the plugins. diff --git a/neo-modules.sln b/neo-modules.sln index 24f303eb4..18f557324 100644 --- a/neo-modules.sln +++ b/neo-modules.sln @@ -10,7 +10,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplicationLogs", "src\Appl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StatesDumper", "src\StatesDumper\StatesDumper.csproj", "{86531DB1-A231-46C4-823F-BE60972F7523}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RpcNep5Tracker", "src\RpcNep5Tracker\RpcNep5Tracker.csproj", "{BBE8AC15-12DF-4AF0-ABC1-F1557EB5DC8E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RpcNep17Tracker", "src\RpcNep17Tracker\RpcNep17Tracker.csproj", "{BBE8AC15-12DF-4AF0-ABC1-F1557EB5DC8E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LevelDBStore", "src\LevelDBStore\LevelDBStore.csproj", "{C66214CD-0B97-4EA5-B7A2-164F54346F19}" EndProject diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ab7337427..b7a7f73f8 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/Models/RpcNep5Balances.cs b/src/RpcClient/Models/RpcNep17Balances.cs similarity index 75% rename from src/RpcClient/Models/RpcNep5Balances.cs rename to src/RpcClient/Models/RpcNep17Balances.cs index 4cdc1ecc7..dfd35b939 100644 --- a/src/RpcClient/Models/RpcNep5Balances.cs +++ b/src/RpcClient/Models/RpcNep17Balances.cs @@ -6,11 +6,11 @@ namespace Neo.Network.RPC.Models { - public class RpcNep5Balances + public class RpcNep17Balances { public UInt160 UserScriptHash { get; set; } - public List Balances { get; set; } + public List Balances { get; set; } public JObject ToJson() { @@ -20,18 +20,18 @@ public JObject ToJson() return json; } - public static RpcNep5Balances FromJson(JObject json) + public static RpcNep17Balances FromJson(JObject json) { - RpcNep5Balances nep5Balance = new RpcNep5Balances + RpcNep17Balances nep17Balance = new RpcNep17Balances { - Balances = ((JArray)json["balance"]).Select(p => RpcNep5Balance.FromJson(p)).ToList(), + Balances = ((JArray)json["balance"]).Select(p => RpcNep17Balance.FromJson(p)).ToList(), UserScriptHash = json["address"].ToScriptHash() }; - return nep5Balance; + return nep17Balance; } } - public class RpcNep5Balance + public class RpcNep17Balance { public UInt160 AssetHash { get; set; } @@ -48,9 +48,9 @@ public JObject ToJson() return json; } - public static RpcNep5Balance FromJson(JObject json) + public static RpcNep17Balance FromJson(JObject json) { - RpcNep5Balance balance = new RpcNep5Balance + RpcNep17Balance balance = new RpcNep17Balance { AssetHash = json["assethash"].ToScriptHash(), Amount = BigInteger.Parse(json["amount"].AsString()), diff --git a/src/RpcClient/Models/RpcNep5TokenInfo.cs b/src/RpcClient/Models/RpcNep17TokenInfo.cs similarity index 87% rename from src/RpcClient/Models/RpcNep5TokenInfo.cs rename to src/RpcClient/Models/RpcNep17TokenInfo.cs index cb609b8a9..d28873943 100644 --- a/src/RpcClient/Models/RpcNep5TokenInfo.cs +++ b/src/RpcClient/Models/RpcNep17TokenInfo.cs @@ -2,7 +2,7 @@ namespace Neo.Network.RPC.Models { - public class RpcNep5TokenInfo + public class RpcNep17TokenInfo { public string Name { get; set; } diff --git a/src/RpcClient/Models/RpcNep5Transfers.cs b/src/RpcClient/Models/RpcNep17Transfers.cs similarity index 81% rename from src/RpcClient/Models/RpcNep5Transfers.cs rename to src/RpcClient/Models/RpcNep17Transfers.cs index d23ca7a41..bc433ede0 100644 --- a/src/RpcClient/Models/RpcNep5Transfers.cs +++ b/src/RpcClient/Models/RpcNep17Transfers.cs @@ -7,13 +7,13 @@ namespace Neo.Network.RPC.Models { - public class RpcNep5Transfers + public class RpcNep17Transfers { public UInt160 UserScriptHash { get; set; } - public List Sent { get; set; } + public List Sent { get; set; } - public List Received { get; set; } + public List Received { get; set; } public JObject ToJson() { @@ -24,19 +24,19 @@ public JObject ToJson() return json; } - public static RpcNep5Transfers FromJson(JObject json) + public static RpcNep17Transfers FromJson(JObject json) { - RpcNep5Transfers transfers = new RpcNep5Transfers + RpcNep17Transfers transfers = new RpcNep17Transfers { - Sent = ((JArray)json["sent"]).Select(p => RpcNep5Transfer.FromJson(p)).ToList(), - Received = ((JArray)json["received"]).Select(p => RpcNep5Transfer.FromJson(p)).ToList(), + Sent = ((JArray)json["sent"]).Select(p => RpcNep17Transfer.FromJson(p)).ToList(), + Received = ((JArray)json["received"]).Select(p => RpcNep17Transfer.FromJson(p)).ToList(), UserScriptHash = json["address"].ToScriptHash() }; return transfers; } } - public class RpcNep5Transfer + public class RpcNep17Transfer { public ulong TimestampMS { get; set; } @@ -65,9 +65,9 @@ public JObject ToJson() return json; } - public static RpcNep5Transfer FromJson(JObject json) + public static RpcNep17Transfer FromJson(JObject json) { - return new RpcNep5Transfer + return new RpcNep17Transfer { TimestampMS = (ulong)json["timestamp"].AsNumber(), AssetHash = json["assethash"].ToScriptHash(), diff --git a/src/RpcClient/Nep5API.cs b/src/RpcClient/Nep17API.cs similarity index 76% rename from src/RpcClient/Nep5API.cs rename to src/RpcClient/Nep17API.cs index 59cadd67e..50650ade6 100644 --- a/src/RpcClient/Nep5API.cs +++ b/src/RpcClient/Nep17API.cs @@ -13,18 +13,18 @@ namespace Neo.Network.RPC { /// - /// Call NEP5 methods with RPC API + /// Call NEP17 methods with RPC API /// - public class Nep5API : ContractClient + public class Nep17API : ContractClient { /// - /// Nep5API Constructor + /// Nep17API Constructor /// /// the RPC client to call NEO RPC methods - public Nep5API(RpcClient rpcClient) : base(rpcClient) { } + public Nep17API(RpcClient rpcClient) : base(rpcClient) { } /// - /// Get balance of NEP5 token + /// Get balance of NEP17 token /// /// contract script hash /// account script hash @@ -37,18 +37,7 @@ public async Task BalanceOfAsync(UInt160 scriptHash, UInt160 account } /// - /// Get name of NEP5 token - /// - /// contract script hash - /// - public async Task NameAsync(UInt160 scriptHash) - { - var result = await TestInvokeAsync(scriptHash, "name").ConfigureAwait(false); - return result.Stack.Single().GetString(); - } - - /// - /// Get symbol of NEP5 token + /// Get symbol of NEP17 token /// /// contract script hash /// @@ -59,7 +48,7 @@ public async Task SymbolAsync(UInt160 scriptHash) } /// - /// Get decimals of NEP5 token + /// Get decimals of NEP17 token /// /// contract script hash /// @@ -70,7 +59,7 @@ public async Task DecimalsAsync(UInt160 scriptHash) } /// - /// Get total supply of NEP5 token + /// Get total supply of NEP17 token /// /// contract script hash /// @@ -85,40 +74,43 @@ public async Task TotalSupplyAsync(UInt160 scriptHash) /// /// contract script hash /// - public async Task GetTokenInfoAsync(UInt160 scriptHash) + public async Task GetTokenInfoAsync(UInt160 scriptHash) { byte[] script = Concat( - scriptHash.MakeScript("name"), scriptHash.MakeScript("symbol"), scriptHash.MakeScript("decimals"), scriptHash.MakeScript("totalSupply")); + var contractState = await rpcClient.GetContractStateAsync(scriptHash.ToString()).ConfigureAwait(false); + var name = contractState.Manifest.Name; + var result = await rpcClient.InvokeScriptAsync(script).ConfigureAwait(false); var stack = result.Stack; - return new RpcNep5TokenInfo + return new RpcNep17TokenInfo { - Name = stack[0].GetString(), - Symbol = stack[1].GetString(), - Decimals = (byte)stack[2].GetInteger(), - TotalSupply = stack[3].GetInteger() + Name = name, + Symbol = stack[0].GetString(), + Decimals = (byte)stack[1].GetInteger(), + TotalSupply = stack[2].GetInteger() }; } /// - /// Create NEP5 token transfer transaction + /// Create NEP17 token transfer transaction /// /// contract script hash /// from KeyPair /// to account script hash /// transfer amount + /// onPayment data /// - public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount) + public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair fromKey, UInt160 to, BigInteger amount, object data = null) { var sender = Contract.CreateSignatureRedeemScript(fromKey.PublicKey).ToScriptHash(); Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; - byte[] script = scriptHash.MakeScript("transfer", sender, to, amount); + byte[] script = data is null ? scriptHash.MakeScript("transfer", sender, to, amount) : scriptHash.MakeScript("transfer", sender, to, amount, data); TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); @@ -128,7 +120,7 @@ public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair } /// - /// Create NEP5 token transfer transaction from multi-sig account + /// Create NEP17 token transfer transaction from multi-sig account /// /// contract script hash /// multi-sig min signature count @@ -136,15 +128,16 @@ public async Task CreateTransferTxAsync(UInt160 scriptHash, KeyPair /// sign keys /// to account /// transfer amount + /// onPayment data /// - public async Task CreateTransferTxAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] fromKeys, UInt160 to, BigInteger amount) + public async Task CreateTransferTxAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] fromKeys, UInt160 to, BigInteger amount, object data = null) { if (m > fromKeys.Length) throw new ArgumentException($"Need at least {m} KeyPairs for signing!"); var sender = Contract.CreateMultiSigContract(m, pubKeys).ScriptHash; Signer[] signers = new[] { new Signer { Scopes = WitnessScope.CalledByEntry, Account = sender } }; - byte[] script = scriptHash.MakeScript("transfer", sender, to, amount); + byte[] script = data is null ? scriptHash.MakeScript("transfer", sender, to, amount) : scriptHash.MakeScript("transfer", sender, to, amount, data); TransactionManagerFactory factory = new TransactionManagerFactory(rpcClient, magic); TransactionManager manager = await factory.MakeTransactionAsync(script, signers).ConfigureAwait(false); diff --git a/src/RpcClient/RpcClient.cs b/src/RpcClient/RpcClient.cs index b9c184137..8c0ea27c1 100644 --- a/src/RpcClient/RpcClient.cs +++ b/src/RpcClient/RpcClient.cs @@ -447,14 +447,14 @@ public async Task GetNewAddressAsync() /// /// Returns the balance of the corresponding asset in the wallet, based on the specified asset Id. - /// This method applies to assets that conform to NEP-5 standards. + /// This method applies to assets that conform to NEP-17 standards. /// /// new address as string public async Task GetWalletBalanceAsync(string assetId) { var result = await RpcSendAsync(GetRpcName(), assetId).ConfigureAwait(false); BigInteger balance = BigInteger.Parse(result["balance"].AsString()); - byte decimals = await new Nep5API(this).DecimalsAsync(UInt160.Parse(assetId.AsScriptHash())).ConfigureAwait(false); + byte decimals = await new Nep17API(this).DecimalsAsync(UInt160.Parse(assetId.AsScriptHash())).ConfigureAwait(false); return new BigDecimal(balance, decimals); } @@ -556,30 +556,30 @@ public async Task GetApplicationLogAsync(string txHash, Trigg } /// - /// Returns all the NEP-5 transaction information occurred in the specified address. - /// This method is provided by the plugin RpcNep5Tracker. + /// Returns all the NEP-17 transaction information occurred in the specified address. + /// This method is provided by the plugin RpcNep17Tracker. /// /// The address to query the transaction information. /// The start block Timestamp, default to seven days before UtcNow /// The end block Timestamp, default to UtcNow - public async Task GetNep5TransfersAsync(string address, ulong? startTimestamp = default, ulong? endTimestamp = default) + public async Task GetNep17TransfersAsync(string address, ulong? startTimestamp = default, ulong? endTimestamp = default) { startTimestamp ??= 0; endTimestamp ??= DateTime.UtcNow.ToTimestampMS(); var result = await RpcSendAsync(GetRpcName(), address.AsScriptHash(), startTimestamp, endTimestamp) .ConfigureAwait(false); - return RpcNep5Transfers.FromJson(result); + return RpcNep17Transfers.FromJson(result); } /// - /// Returns the balance of all NEP-5 assets in the specified address. - /// This method is provided by the plugin RpcNep5Tracker. + /// Returns the balance of all NEP-17 assets in the specified address. + /// This method is provided by the plugin RpcNep17Tracker. /// - public async Task GetNep5BalancesAsync(string address) + public async Task GetNep17BalancesAsync(string address) { var result = await RpcSendAsync(GetRpcName(), address.AsScriptHash()) .ConfigureAwait(false); - return RpcNep5Balances.FromJson(result); + return RpcNep17Balances.FromJson(result); } #endregion Plugins diff --git a/src/RpcClient/TransactionManager.cs b/src/RpcClient/TransactionManager.cs index 067fc2ff6..c301fea59 100644 --- a/src/RpcClient/TransactionManager.cs +++ b/src/RpcClient/TransactionManager.cs @@ -166,7 +166,7 @@ public async Task SignAsync() Tx.NetworkFee = await rpcClient.CalculateNetworkFeeAsync(Tx).ConfigureAwait(false); Tx.Witnesses = null; - var gasBalance = await new Nep5API(rpcClient).BalanceOfAsync(NativeContract.GAS.Hash, Tx.Sender).ConfigureAwait(false); + var gasBalance = await new Nep17API(rpcClient).BalanceOfAsync(NativeContract.GAS.Hash, Tx.Sender).ConfigureAwait(false); if (gasBalance < Tx.SystemFee + Tx.NetworkFee) throw new InvalidOperationException($"Insufficient GAS in address: {Tx.Sender.ToAddress()}"); diff --git a/src/RpcClient/WalletAPI.cs b/src/RpcClient/WalletAPI.cs index b4cef3c55..aba15cf91 100644 --- a/src/RpcClient/WalletAPI.cs +++ b/src/RpcClient/WalletAPI.cs @@ -19,7 +19,7 @@ namespace Neo.Network.RPC public class WalletAPI { private readonly RpcClient rpcClient; - private readonly Nep5API nep5API; + private readonly Nep17API nep17API; /// /// WalletAPI Constructor @@ -28,7 +28,7 @@ public class WalletAPI public WalletAPI(RpcClient rpc) { rpcClient = rpc; - nep5API = new Nep5API(rpc); + nep17API = new Nep17API(rpc); } /// @@ -52,7 +52,7 @@ public async Task GetUnclaimedGasAsync(UInt160 account) { UInt160 scriptHash = NativeContract.NEO.Hash; var blockCount = await rpcClient.GetBlockCountAsync().ConfigureAwait(false); - var result = await nep5API.TestInvokeAsync(scriptHash, "unclaimedGas", account, blockCount - 1).ConfigureAwait(false); + var result = await nep17API.TestInvokeAsync(scriptHash, "unclaimedGas", account, blockCount - 1).ConfigureAwait(false); BigInteger balance = result.Stack.Single().GetInteger(); return ((decimal)balance) / (long)NativeContract.GAS.Factor; } @@ -92,7 +92,7 @@ public Task GetTokenBalanceAsync(string tokenHash, string account) { UInt160 scriptHash = Utility.GetScriptHash(tokenHash); UInt160 accountHash = Utility.GetScriptHash(account); - return nep5API.BalanceOfAsync(scriptHash, accountHash); + return nep17API.BalanceOfAsync(scriptHash, accountHash); } /// @@ -117,49 +117,49 @@ public Task ClaimGasAsync(string key) public async Task ClaimGasAsync(KeyPair keyPair) { UInt160 toHash = Contract.CreateSignatureRedeemScript(keyPair.PublicKey).ToScriptHash(); - BigInteger balance = await nep5API.BalanceOfAsync(NativeContract.NEO.Hash, toHash).ConfigureAwait(false); - Transaction transaction = await nep5API.CreateTransferTxAsync(NativeContract.NEO.Hash, keyPair, toHash, balance).ConfigureAwait(false); + BigInteger balance = await nep17API.BalanceOfAsync(NativeContract.NEO.Hash, toHash).ConfigureAwait(false); + Transaction transaction = await nep17API.CreateTransferTxAsync(NativeContract.NEO.Hash, keyPair, toHash, balance).ConfigureAwait(false); await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } /// - /// Transfer NEP5 token balance, with common data types + /// Transfer NEP17 token balance, with common data types /// - /// nep5 token script hash, Example: scripthash ("0xb0a31817c80ad5f87b6ed390ecb3f9d312f7ceb8") + /// nep17 token script hash, Example: scripthash ("0xb0a31817c80ad5f87b6ed390ecb3f9d312f7ceb8") /// wif or private key /// Example: WIF ("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p"), PrivateKey ("450d6c2a04b5b470339a745427bae6828400cf048400837d73c415063835e005") /// address or account script hash /// token amount /// - public async Task TransferAsync(string tokenHash, string fromKey, string toAddress, decimal amount) + public async Task TransferAsync(string tokenHash, string fromKey, string toAddress, decimal amount, object data = null) { UInt160 scriptHash = Utility.GetScriptHash(tokenHash); - var decimals = await nep5API.DecimalsAsync(scriptHash).ConfigureAwait(false); + var decimals = await nep17API.DecimalsAsync(scriptHash).ConfigureAwait(false); KeyPair from = Utility.GetKeyPair(fromKey); UInt160 to = Utility.GetScriptHash(toAddress); BigInteger amountInteger = amount.ToBigInteger(decimals); - return await TransferAsync(scriptHash, from, to, amountInteger).ConfigureAwait(false); + return await TransferAsync(scriptHash, from, to, amountInteger, data).ConfigureAwait(false); } /// - /// Transfer NEP5 token from single-sig account + /// Transfer NEP17 token from single-sig account /// /// contract script hash /// from KeyPair /// to account script hash /// transfer amount /// - public async Task TransferAsync(UInt160 scriptHash, KeyPair from, UInt160 to, BigInteger amountInteger) + public async Task TransferAsync(UInt160 scriptHash, KeyPair from, UInt160 to, BigInteger amountInteger, object data = null) { - Transaction transaction = await nep5API.CreateTransferTxAsync(scriptHash, from, to, amountInteger).ConfigureAwait(false); + Transaction transaction = await nep17API.CreateTransferTxAsync(scriptHash, from, to, amountInteger, data).ConfigureAwait(false); await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } /// - /// Transfer NEP5 token from multi-sig account + /// Transfer NEP17 token from multi-sig account /// /// contract script hash /// multi-sig min signature count @@ -168,9 +168,9 @@ public async Task TransferAsync(UInt160 scriptHash, KeyPair from, U /// to account /// transfer amount /// - public async Task TransferAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] keys, UInt160 to, BigInteger amountInteger) + public async Task TransferAsync(UInt160 scriptHash, int m, ECPoint[] pubKeys, KeyPair[] keys, UInt160 to, BigInteger amountInteger, object data = null) { - Transaction transaction = await nep5API.CreateTransferTxAsync(scriptHash, m, pubKeys, keys, to, amountInteger).ConfigureAwait(false); + Transaction transaction = await nep17API.CreateTransferTxAsync(scriptHash, m, pubKeys, keys, to, amountInteger, data).ConfigureAwait(false); await rpcClient.SendRawTransactionAsync(transaction).ConfigureAwait(false); return transaction; } diff --git a/src/RpcNep5Tracker/DbCache.cs b/src/RpcNep17Tracker/DbCache.cs similarity index 100% rename from src/RpcNep5Tracker/DbCache.cs rename to src/RpcNep17Tracker/DbCache.cs diff --git a/src/RpcNep5Tracker/Helper.cs b/src/RpcNep17Tracker/Helper.cs similarity index 100% rename from src/RpcNep5Tracker/Helper.cs rename to src/RpcNep17Tracker/Helper.cs diff --git a/src/RpcNep5Tracker/Nep5Balance.cs b/src/RpcNep17Tracker/Nep17Balance.cs similarity index 80% rename from src/RpcNep5Tracker/Nep5Balance.cs rename to src/RpcNep17Tracker/Nep17Balance.cs index c848879f5..9dc5e3d67 100644 --- a/src/RpcNep5Tracker/Nep5Balance.cs +++ b/src/RpcNep17Tracker/Nep17Balance.cs @@ -4,7 +4,7 @@ namespace Neo.Plugins { - public class Nep5Balance : ICloneable, ISerializable + public class Nep17Balance : ICloneable, ISerializable { public BigInteger Balance; public uint LastUpdatedBlock; @@ -23,16 +23,16 @@ void ISerializable.Deserialize(BinaryReader reader) LastUpdatedBlock = reader.ReadUInt32(); } - Nep5Balance ICloneable.Clone() + Nep17Balance ICloneable.Clone() { - return new Nep5Balance + return new Nep17Balance { Balance = Balance, LastUpdatedBlock = LastUpdatedBlock }; } - public void FromReplica(Nep5Balance replica) + public void FromReplica(Nep17Balance replica) { Balance = replica.Balance; LastUpdatedBlock = replica.LastUpdatedBlock; diff --git a/src/RpcNep5Tracker/Nep5BalanceKey.cs b/src/RpcNep17Tracker/Nep17BalanceKey.cs similarity index 80% rename from src/RpcNep5Tracker/Nep5BalanceKey.cs rename to src/RpcNep17Tracker/Nep17BalanceKey.cs index ec1fc218d..0d5e5267a 100644 --- a/src/RpcNep5Tracker/Nep5BalanceKey.cs +++ b/src/RpcNep17Tracker/Nep17BalanceKey.cs @@ -4,18 +4,18 @@ namespace Neo.Plugins { - public class Nep5BalanceKey : IComparable, IEquatable, ISerializable + public class Nep17BalanceKey : IComparable, IEquatable, ISerializable { public readonly UInt160 UserScriptHash; public readonly UInt160 AssetScriptHash; public int Size => 20 + 20; - public Nep5BalanceKey() : this(new UInt160(), new UInt160()) + public Nep17BalanceKey() : this(new UInt160(), new UInt160()) { } - public Nep5BalanceKey(UInt160 userScriptHash, UInt160 assetScriptHash) + public Nep17BalanceKey(UInt160 userScriptHash, UInt160 assetScriptHash) { if (userScriptHash == null || assetScriptHash == null) throw new ArgumentNullException(); @@ -23,7 +23,7 @@ public Nep5BalanceKey(UInt160 userScriptHash, UInt160 assetScriptHash) AssetScriptHash = assetScriptHash; } - public int CompareTo(Nep5BalanceKey other) + public int CompareTo(Nep17BalanceKey other) { if (other is null) return 1; if (ReferenceEquals(this, other)) return 0; @@ -32,7 +32,7 @@ public int CompareTo(Nep5BalanceKey other) return AssetScriptHash.CompareTo(other.AssetScriptHash); } - public bool Equals(Nep5BalanceKey other) + public bool Equals(Nep17BalanceKey other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; @@ -41,7 +41,7 @@ public bool Equals(Nep5BalanceKey other) public override bool Equals(Object other) { - return other is Nep5BalanceKey otherKey && Equals(otherKey); + return other is Nep17BalanceKey otherKey && Equals(otherKey); } public override int GetHashCode() diff --git a/src/RpcNep5Tracker/Nep5Transfer.cs b/src/RpcNep17Tracker/Nep17Transfer.cs similarity index 84% rename from src/RpcNep5Tracker/Nep5Transfer.cs rename to src/RpcNep17Tracker/Nep17Transfer.cs index 84c71f1d7..8a2f33561 100644 --- a/src/RpcNep5Tracker/Nep5Transfer.cs +++ b/src/RpcNep17Tracker/Nep17Transfer.cs @@ -4,7 +4,7 @@ namespace Neo.Plugins { - public class Nep5Transfer : ICloneable, ISerializable + public class Nep17Transfer : ICloneable, ISerializable { public UInt160 UserScriptHash; public uint BlockIndex; @@ -29,9 +29,9 @@ void ISerializable.Deserialize(BinaryReader reader) Amount = new BigInteger(reader.ReadVarBytes(512)); } - Nep5Transfer ICloneable.Clone() + Nep17Transfer ICloneable.Clone() { - return new Nep5Transfer + return new Nep17Transfer { UserScriptHash = UserScriptHash, BlockIndex = BlockIndex, @@ -40,7 +40,7 @@ Nep5Transfer ICloneable.Clone() }; } - void ICloneable.FromReplica(Nep5Transfer replica) + void ICloneable.FromReplica(Nep17Transfer replica) { UserScriptHash = replica.UserScriptHash; BlockIndex = replica.BlockIndex; diff --git a/src/RpcNep5Tracker/Nep5TransferKey.cs b/src/RpcNep17Tracker/Nep17TransferKey.cs similarity index 87% rename from src/RpcNep5Tracker/Nep5TransferKey.cs rename to src/RpcNep17Tracker/Nep17TransferKey.cs index 69e7fc735..128a7bef1 100644 --- a/src/RpcNep5Tracker/Nep5TransferKey.cs +++ b/src/RpcNep17Tracker/Nep17TransferKey.cs @@ -4,7 +4,7 @@ namespace Neo.Plugins { - public class Nep5TransferKey : IComparable, IEquatable, ISerializable + public class Nep17TransferKey : IComparable, IEquatable, ISerializable { public readonly UInt160 UserScriptHash; public ulong TimestampMS { get; private set; } @@ -17,11 +17,11 @@ public class Nep5TransferKey : IComparable, IEquatable _balances; - private DataCache _transfersSent; - private DataCache _transfersReceived; + private DataCache _balances; + private DataCache _transfersSent; + private DataCache _transfersReceived; private WriteBatch _writeBatch; private bool _shouldTrackHistory; private bool _recordNullAddressHistory; private uint _maxResults; private Snapshot _levelDbSnapshot; - public override string Description => "Enquiries NEP-5 balances and transaction history of accounts through RPC"; + public override string Description => "Enquiries NEP-17 balances and transaction history of accounts through RPC"; - public RpcNep5Tracker() + public RpcNep17Tracker() { RpcServerPlugin.RegisterMethods(this); } @@ -44,7 +44,7 @@ protected override void Configure() { if (_db == null) { - var dbPath = GetConfiguration().GetSection("DBPath").Value ?? "Nep5BalanceData"; + var dbPath = GetConfiguration().GetSection("DBPath").Value ?? "Nep17BalanceData"; _db = DB.Open(GetFullPath(dbPath), new Options { CreateIfMissing = true }); } _shouldTrackHistory = (GetConfiguration().GetSection("TrackHistory").Value ?? true.ToString()) != false.ToString(); @@ -58,13 +58,13 @@ private void ResetBatch() _levelDbSnapshot?.Dispose(); _levelDbSnapshot = _db.GetSnapshot(); ReadOptions dbOptions = new ReadOptions { FillCache = false, Snapshot = _levelDbSnapshot }; - _balances = new DbCache(_db, dbOptions, _writeBatch, Nep5BalancePrefix); + _balances = new DbCache(_db, dbOptions, _writeBatch, Nep17BalancePrefix); if (_shouldTrackHistory) { _transfersSent = - new DbCache(_db, dbOptions, _writeBatch, Nep5TransferSentPrefix); + new DbCache(_db, dbOptions, _writeBatch, Nep17TransferSentPrefix); _transfersReceived = - new DbCache(_db, dbOptions, _writeBatch, Nep5TransferReceivedPrefix); + new DbCache(_db, dbOptions, _writeBatch, Nep17TransferReceivedPrefix); } } @@ -76,8 +76,8 @@ private void RecordTransferHistory(StoreView snapshot, UInt160 scriptHash, UInt1 if (_recordNullAddressHistory || from != UInt160.Zero) { - _transfersSent.Add(new Nep5TransferKey(from, header.Timestamp, scriptHash, transferIndex), - new Nep5Transfer + _transfersSent.Add(new Nep17TransferKey(from, header.Timestamp, scriptHash, transferIndex), + new Nep17Transfer { Amount = amount, UserScriptHash = to, @@ -88,8 +88,8 @@ private void RecordTransferHistory(StoreView snapshot, UInt160 scriptHash, UInt1 if (_recordNullAddressHistory || to != UInt160.Zero) { - _transfersReceived.Add(new Nep5TransferKey(to, header.Timestamp, scriptHash, transferIndex), - new Nep5Transfer + _transfersReceived.Add(new Nep17TransferKey(to, header.Timestamp, scriptHash, transferIndex), + new Nep17Transfer { Amount = amount, UserScriptHash = from, @@ -102,7 +102,7 @@ private void RecordTransferHistory(StoreView snapshot, UInt160 scriptHash, UInt1 private void HandleNotification(StoreView snapshot, IVerifiable scriptContainer, UInt160 scriptHash, string eventName, VM.Types.Array stateItems, - Dictionary nep5BalancesChanged, ref ushort transferIndex) + Dictionary nep17BalancesChanged, ref ushort transferIndex) { if (stateItems.Count == 0) return; if (eventName != "Transfer") return; @@ -129,15 +129,15 @@ private void HandleNotification(StoreView snapshot, IVerifiable scriptContainer, if (fromBytes != null) { from = new UInt160(fromBytes); - var fromKey = new Nep5BalanceKey(from, scriptHash); - if (!nep5BalancesChanged.ContainsKey(fromKey)) nep5BalancesChanged.Add(fromKey, new Nep5Balance()); + var fromKey = new Nep17BalanceKey(from, scriptHash); + if (!nep17BalancesChanged.ContainsKey(fromKey)) nep17BalancesChanged.Add(fromKey, new Nep17Balance()); } if (toBytes != null) { to = new UInt160(toBytes); - var toKey = new Nep5BalanceKey(to, scriptHash); - if (!nep5BalancesChanged.ContainsKey(toKey)) nep5BalancesChanged.Add(toKey, new Nep5Balance()); + var toKey = new Nep17BalanceKey(to, scriptHash); + if (!nep17BalancesChanged.ContainsKey(toKey)) nep17BalancesChanged.Add(toKey, new Nep17Balance()); } if (scriptContainer is Transaction transaction) { @@ -149,7 +149,7 @@ public void OnPersist(StoreView snapshot, IReadOnlyList nep5BalancesChanged = new Dictionary(); + Dictionary nep17BalancesChanged = new Dictionary(); ushort transferIndex = 0; foreach (Blockchain.ApplicationExecuted appExecuted in applicationExecutedList) @@ -161,18 +161,18 @@ public void OnPersist(StoreView snapshot, IReadOnlyList nep5BalancePair.Value); - if (itemToChange != nep5BalancePair.Value) - itemToChange.FromReplica(nep5BalancePair.Value); + var itemToChange = _balances.GetAndChange(nep17BalancePair.Key, () => nep17BalancePair.Value); + if (itemToChange != nep17BalancePair.Value) + itemToChange.FromReplica(nep17BalancePair.Value); } } @@ -223,7 +223,7 @@ private void AddTransfers(byte dbPrefix, UInt160 userScriptHash, ulong startTime Array.Reverse(endTimeBytes); } - var transferPairs = _db.FindRange( + var transferPairs = _db.FindRange( prefix.Concat(startTimeBytes).ToArray(), prefix.Concat(endTimeBytes).ToArray()); @@ -250,7 +250,7 @@ private UInt160 GetScriptHashFromParam(string addressOrScriptHash) } [RpcMethod] - public JObject GetNep5Transfers(JArray _params) + public JObject GetNep17Transfers(JArray _params) { if (!_shouldTrackHistory) throw new RpcException(-32601, "Method not found"); UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString()); @@ -267,13 +267,13 @@ public JObject GetNep5Transfers(JArray _params) JArray transfersReceived = new JArray(); json["received"] = transfersReceived; json["address"] = userScriptHash.ToAddress(); - AddTransfers(Nep5TransferSentPrefix, userScriptHash, startTime, endTime, transfersSent); - AddTransfers(Nep5TransferReceivedPrefix, userScriptHash, startTime, endTime, transfersReceived); + AddTransfers(Nep17TransferSentPrefix, userScriptHash, startTime, endTime, transfersSent); + AddTransfers(Nep17TransferReceivedPrefix, userScriptHash, startTime, endTime, transfersReceived); return json; } [RpcMethod] - public JObject GetNep5Balances(JArray _params) + public JObject GetNep17Balances(JArray _params) { UInt160 userScriptHash = GetScriptHashFromParam(_params[0].AsString()); @@ -281,7 +281,7 @@ public JObject GetNep5Balances(JArray _params) JArray balances = new JArray(); json["balance"] = balances; json["address"] = userScriptHash.ToAddress(); - var dbCache = new DbCache(_db, null, null, Nep5BalancePrefix); + var dbCache = new DbCache(_db, null, null, Nep17BalancePrefix); byte[] prefix = userScriptHash.ToArray(); foreach (var (key, value) in dbCache.Find(prefix)) { diff --git a/src/RpcNep5Tracker/RpcNep5Tracker.csproj b/src/RpcNep17Tracker/RpcNep17Tracker.csproj similarity index 82% rename from src/RpcNep5Tracker/RpcNep5Tracker.csproj rename to src/RpcNep17Tracker/RpcNep17Tracker.csproj index 403f4a12a..bb3b93e44 100644 --- a/src/RpcNep5Tracker/RpcNep5Tracker.csproj +++ b/src/RpcNep17Tracker/RpcNep17Tracker.csproj @@ -1,10 +1,10 @@ - Neo.Plugins.RpcNep5Tracker + Neo.Plugins.RpcNep17Tracker Neo.Plugins - + PreserveNewest PreserveNewest diff --git a/src/RpcNep5Tracker/RpcNep5Tracker/config.json b/src/RpcNep17Tracker/RpcNep17Tracker/config.json similarity index 76% rename from src/RpcNep5Tracker/RpcNep5Tracker/config.json rename to src/RpcNep17Tracker/RpcNep17Tracker/config.json index 13e79b805..af5e20247 100644 --- a/src/RpcNep5Tracker/RpcNep5Tracker/config.json +++ b/src/RpcNep17Tracker/RpcNep17Tracker/config.json @@ -1,6 +1,6 @@ -{ +{ "PluginConfiguration": { - "DBPath": "Nep5BalanceData", + "DBPath": "Nep17BalanceData", "TrackHistory" : true, "RecordNullAddressHistory": false, "MaxResults" : 1000 diff --git a/tests/Neo.Network.RPC.Tests/RpcTestCases.json b/tests/Neo.Network.RPC.Tests/RpcTestCases.json index eae9639f9..42ac24a45 100644 --- a/tests/Neo.Network.RPC.Tests/RpcTestCases.json +++ b/tests/Neo.Network.RPC.Tests/RpcTestCases.json @@ -850,7 +850,7 @@ ] }, { - "name": "RpcNep5Tracker", + "name": "RpcNep17Tracker", "version": "3.0.0.0", "interfaces": [ "IPersistencePlugin" @@ -1340,10 +1340,10 @@ } }, { - "Name": "getnep5transfersasync", + "Name": "getnep17transfersasync", "Request": { "jsonrpc": "2.0", - "method": "getnep5transfers", + "method": "getnep17transfers", "params": [ "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ", 0, 1868595301000 ], "id": 1 }, @@ -1387,10 +1387,10 @@ } }, { - "Name": "getnep5transfersasync_with_null_transferaddress", + "Name": "getnep17transfersasync_with_null_transferaddress", "Request": { "jsonrpc": "2.0", - "method": "getnep5transfers", + "method": "getnep17transfers", "params": [ "Ncb7jVsYWBt1q5T5k3ZTP8bn5eK4DuanLd", 0, 1868595301000 ], "id": 1 }, @@ -1434,10 +1434,10 @@ } }, { - "Name": "getnep5balancesasync", + "Name": "getnep17balancesasync", "Request": { "jsonrpc": "2.0", - "method": "getnep5balances", + "method": "getnep17balances", "params": [ "NVVwFw6XyhtRCFQ8SpUTMdPyYt4Vd9A1XQ" ], "id": 1 }, diff --git a/tests/Neo.Network.RPC.Tests/UT_Nep5API.cs b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs similarity index 67% rename from tests/Neo.Network.RPC.Tests/UT_Nep5API.cs rename to tests/Neo.Network.RPC.Tests/UT_Nep17API.cs index 12f0142c9..b35a2bfc9 100644 --- a/tests/Neo.Network.RPC.Tests/UT_Nep5API.cs +++ b/tests/Neo.Network.RPC.Tests/UT_Nep17API.cs @@ -1,5 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; +using Neo.IO.Json; using Neo.SmartContract; using Neo.SmartContract.Native; using Neo.VM; @@ -11,12 +12,12 @@ namespace Neo.Network.RPC.Tests { [TestClass] - public class UT_Nep5API + public class UT_Nep17API { Mock rpcClientMock; KeyPair keyPair1; UInt160 sender; - Nep5API nep5API; + Nep17API nep17API; [TestInitialize] public void TestSetup() @@ -24,7 +25,7 @@ public void TestSetup() keyPair1 = new KeyPair(Wallet.GetPrivateKeyFromWIF("KyXwTh1hB76RRMquSvnxZrJzQx7h9nQP2PCRL38v6VDb5ip3nf1p")); sender = Contract.CreateSignatureRedeemScript(keyPair1.PublicKey).ToScriptHash(); rpcClientMock = UT_TransactionManager.MockRpcClient(sender, new byte[0]); - nep5API = new Nep5API(rpcClientMock.Object); + nep17API = new Nep17API(rpcClientMock.Object); } [TestMethod] @@ -33,27 +34,17 @@ public async Task TestBalanceOf() byte[] testScript = NativeContract.GAS.Hash.MakeScript("balanceOf", UInt160.Zero); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(10000) }); - var balance = await nep5API.BalanceOfAsync(NativeContract.GAS.Hash, UInt160.Zero); + var balance = await nep17API.BalanceOfAsync(NativeContract.GAS.Hash, UInt160.Zero); Assert.AreEqual(10000, (int)balance); } - [TestMethod] - public async Task TestGetName() - { - byte[] testScript = NativeContract.GAS.Hash.MakeScript("name"); - UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Name }); - - var result = await nep5API.NameAsync(NativeContract.GAS.Hash); - Assert.AreEqual(NativeContract.GAS.Name, result); - } - [TestMethod] public async Task TestGetSymbol() { byte[] testScript = NativeContract.GAS.Hash.MakeScript("symbol"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Symbol }); - var result = await nep5API.SymbolAsync(NativeContract.GAS.Hash); + var result = await nep17API.SymbolAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Symbol, result); } @@ -63,7 +54,7 @@ public async Task TestGetDecimals() byte[] testScript = NativeContract.GAS.Hash.MakeScript("decimals"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) }); - var result = await nep5API.DecimalsAsync(NativeContract.GAS.Hash); + var result = await nep17API.DecimalsAsync(NativeContract.GAS.Hash); Assert.AreEqual(NativeContract.GAS.Decimals, result); } @@ -73,7 +64,7 @@ public async Task TestGetTotalSupply() byte[] testScript = NativeContract.GAS.Hash.MakeScript("totalSupply"); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); - var result = await nep5API.TotalSupplyAsync(NativeContract.GAS.Hash); + var result = await nep17API.TotalSupplyAsync(NativeContract.GAS.Hash); Assert.AreEqual(1_00000000, (int)result); } @@ -81,22 +72,28 @@ public async Task TestGetTotalSupply() public async Task TestGetTokenInfo() { UInt160 scriptHash = NativeContract.GAS.Hash; - byte[] testScript = scriptHash.MakeScript("name") - .Concat(scriptHash.MakeScript("symbol")) + byte[] testScript = scriptHash.MakeScript("symbol") .Concat(scriptHash.MakeScript("decimals")) .Concat(scriptHash.MakeScript("totalSupply")) - .ToArray(); ; + .ToArray(); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, - new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Name }, new ContractParameter { Type = ContractParameterType.String, Value = NativeContract.GAS.Symbol }, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(NativeContract.GAS.Decimals) }, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_00000000) }); - var result = await nep5API.GetTokenInfoAsync(NativeContract.GAS.Hash); - Assert.AreEqual(NativeContract.GAS.Name, result.Name); - Assert.AreEqual(NativeContract.GAS.Symbol, result.Symbol); - Assert.AreEqual(8, (int)result.Decimals); - Assert.AreEqual(1_00000000, (int)result.TotalSupply); + var tests = TestUtils.RpcTestCases.Where(p => p.Name == "getcontractstateasync"); + foreach (var test in tests) + { + rpcClientMock.Setup(p => p.RpcSendAsync("getcontractstate", It.Is(u => true))) + .ReturnsAsync(test.Response.Result) + .Verifiable(); + + var result = await nep17API.GetTokenInfoAsync(NativeContract.GAS.Hash); + Assert.AreEqual(NativeContract.GAS.Symbol, result.Symbol); + Assert.AreEqual(8, (int)result.Decimals); + Assert.AreEqual(1_00000000, (int)result.TotalSupply); + Assert.AreEqual("GAS", result.Name); + } } [TestMethod] @@ -105,7 +102,12 @@ public async Task TestTransfer() byte[] testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000)); UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter()); - var result = await nep5API.CreateTransferTxAsync(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); + var result = await nep17API.CreateTransferTxAsync(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000)); + + testScript = NativeContract.GAS.Hash.MakeScript("transfer", sender, UInt160.Zero, new BigInteger(1_00000000), string.Empty); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter()); + + result = await nep17API.CreateTransferTxAsync(NativeContract.GAS.Hash, keyPair1, UInt160.Zero, new BigInteger(1_00000000), string.Empty); Assert.IsNotNull(result); } } diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs index b558ef201..69ba8caaf 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcClient.cs @@ -431,21 +431,21 @@ public async Task GetApplicationLogTest_TriggerType() } [TestMethod()] - public async Task GetNep5TransfersTest() + public async Task GetNep17TransfersTest() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep5TransfersAsync).ToLower()); - var result = await rpc.GetNep5TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep17TransfersAsync).ToLower()); + var result = await rpc.GetNep17TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); - test = TestUtils.RpcTestCases.Find(p => p.Name == (nameof(rpc.GetNep5TransfersAsync).ToLower() + "_with_null_transferaddress")); - result = await rpc.GetNep5TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); + test = TestUtils.RpcTestCases.Find(p => p.Name == (nameof(rpc.GetNep17TransfersAsync).ToLower() + "_with_null_transferaddress")); + result = await rpc.GetNep17TransfersAsync(test.Request.Params[0].AsString(), (ulong)test.Request.Params[1].AsNumber(), (ulong)test.Request.Params[2].AsNumber()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } [TestMethod()] - public async Task GetNep5BalancesTest() + public async Task GetNep17BalancesTest() { - var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep5BalancesAsync).ToLower()); - var result = await rpc.GetNep5BalancesAsync(test.Request.Params[0].AsString()); + var test = TestUtils.RpcTestCases.Find(p => p.Name == nameof(rpc.GetNep17BalancesAsync).ToLower()); + var result = await rpc.GetNep17BalancesAsync(test.Request.Params[0].AsString()); Assert.AreEqual(test.Response.Result.ToString(), result.ToJson().ToString()); } diff --git a/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs b/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs index 04613dbc1..18b55c603 100644 --- a/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs +++ b/tests/Neo.Network.RPC.Tests/UT_RpcModels.cs @@ -57,18 +57,18 @@ public void TestRpcInvokeResult() } [TestMethod()] - public void TestRpcNep5Balances() + public void TestRpcNep17Balances() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep5BalancesAsync).ToLower()).Response.Result; - var item = RpcNep5Balances.FromJson(json); + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep17BalancesAsync).ToLower()).Response.Result; + var item = RpcNep17Balances.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } [TestMethod()] - public void TestRpcNep5Transfers() + public void TestRpcNep17Transfers() { - JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep5TransfersAsync).ToLower()).Response.Result; - var item = RpcNep5Transfers.FromJson(json); + JObject json = TestUtils.RpcTestCases.Find(p => p.Name == nameof(RpcClient.GetNep17TransfersAsync).ToLower()).Response.Result; + var item = RpcNep17Transfers.FromJson(json); Assert.AreEqual(json.ToString(), item.ToJson().ToString()); } diff --git a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs index ebfbcb51b..721b53fef 100644 --- a/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs +++ b/tests/Neo.Network.RPC.Tests/UT_WalletAPI.cs @@ -127,6 +127,22 @@ public async Task TestTransferfromMultiSigAccount() var tranaction = await walletAPI.TransferAsync(NativeContract.GAS.Hash, 1, new[] { keyPair1.PublicKey }, new[] { keyPair1 }, UInt160.Zero, NativeContract.GAS.Factor * 100); Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); + + try + { + tranaction = await walletAPI.TransferAsync(NativeContract.GAS.Hash, 2, new[] { keyPair1.PublicKey }, new[] { keyPair1 }, UInt160.Zero, NativeContract.GAS.Factor * 100); + Assert.Fail(); + } + catch (System.Exception e) + { + Assert.AreEqual(e.Message, $"Need at least 2 KeyPairs for signing!"); + } + + testScript = NativeContract.GAS.Hash.MakeScript("transfer", multiSender, UInt160.Zero, NativeContract.GAS.Factor * 100, string.Empty); + UT_TransactionManager.MockInvokeScript(rpcClientMock, testScript, new ContractParameter { Type = ContractParameterType.Integer, Value = new BigInteger(1_10000000) }); + + tranaction = await walletAPI.TransferAsync(NativeContract.GAS.Hash, 1, new[] { keyPair1.PublicKey }, new[] { keyPair1 }, UInt160.Zero, NativeContract.GAS.Factor * 100, string.Empty); + Assert.AreEqual(testScript.ToHexString(), tranaction.Script.ToHexString()); } [TestMethod]