From e41f0947081b63ff299902f95d3a410782632549 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 15 Sep 2020 06:04:24 +0200 Subject: [PATCH] Allow querying contracts by name (#340) --- src/RpcClient/Models/RpcApplicationLog.cs | 2 +- src/RpcClient/Models/RpcNep5Balances.cs | 4 ++-- src/RpcClient/Models/RpcNep5Transfers.cs | 6 ++--- src/RpcClient/Models/RpcTransferOut.cs | 4 ++-- src/RpcClient/RpcClient.cs | 16 ++++++------- src/RpcClient/Utility.cs | 28 ++++++++++++++++++++--- 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/RpcClient/Models/RpcApplicationLog.cs b/src/RpcClient/Models/RpcApplicationLog.cs index 915a9e896..83467f817 100644 --- a/src/RpcClient/Models/RpcApplicationLog.cs +++ b/src/RpcClient/Models/RpcApplicationLog.cs @@ -67,7 +67,7 @@ public static RpcNotifyEventArgs FromJson(JObject json) { return new RpcNotifyEventArgs { - Contract = UInt160.Parse(json["contract"].AsString()), + Contract = json["contract"].ToScriptHash(), EventName = json["eventname"].AsString(), State = Utility.StackItemFromJson(json["state"]) }; diff --git a/src/RpcClient/Models/RpcNep5Balances.cs b/src/RpcClient/Models/RpcNep5Balances.cs index 0ebdc2840..4cdc1ecc7 100644 --- a/src/RpcClient/Models/RpcNep5Balances.cs +++ b/src/RpcClient/Models/RpcNep5Balances.cs @@ -25,7 +25,7 @@ public static RpcNep5Balances FromJson(JObject json) RpcNep5Balances nep5Balance = new RpcNep5Balances { Balances = ((JArray)json["balance"]).Select(p => RpcNep5Balance.FromJson(p)).ToList(), - UserScriptHash = json["address"].AsString().ToScriptHash() + UserScriptHash = json["address"].ToScriptHash() }; return nep5Balance; } @@ -52,7 +52,7 @@ public static RpcNep5Balance FromJson(JObject json) { RpcNep5Balance balance = new RpcNep5Balance { - AssetHash = UInt160.Parse(json["assethash"].AsString()), + AssetHash = json["assethash"].ToScriptHash(), Amount = BigInteger.Parse(json["amount"].AsString()), LastUpdatedBlock = (uint)json["lastupdatedblock"].AsNumber() }; diff --git a/src/RpcClient/Models/RpcNep5Transfers.cs b/src/RpcClient/Models/RpcNep5Transfers.cs index e2eb7d01e..e166d41fe 100644 --- a/src/RpcClient/Models/RpcNep5Transfers.cs +++ b/src/RpcClient/Models/RpcNep5Transfers.cs @@ -30,7 +30,7 @@ public static RpcNep5Transfers FromJson(JObject json) { Sent = ((JArray)json["sent"]).Select(p => RpcNep5Transfer.FromJson(p)).ToList(), Received = ((JArray)json["received"]).Select(p => RpcNep5Transfer.FromJson(p)).ToList(), - UserScriptHash = json["address"].AsString().ToScriptHash() + UserScriptHash = json["address"].ToScriptHash() }; return transfers; } @@ -69,8 +69,8 @@ public static RpcNep5Transfer FromJson(JObject json) { RpcNep5Transfer transfer = new RpcNep5Transfer(); transfer.TimestampMS = (ulong)json["timestamp"].AsNumber(); - transfer.AssetHash = UInt160.Parse(json["assethash"].AsString()); - transfer.UserScriptHash = json["transferaddress"].AsString().ToScriptHash(); + transfer.AssetHash = json["assethash"].ToScriptHash(); + transfer.UserScriptHash = json["transferaddress"].ToScriptHash(); transfer.Amount = BigInteger.Parse(json["amount"].AsString()); transfer.BlockIndex = (uint)json["blockindex"].AsNumber(); transfer.TransferNotifyIndex = (ushort)json["transfernotifyindex"].AsNumber(); diff --git a/src/RpcClient/Models/RpcTransferOut.cs b/src/RpcClient/Models/RpcTransferOut.cs index 6f582dfe3..6e3ce9d47 100644 --- a/src/RpcClient/Models/RpcTransferOut.cs +++ b/src/RpcClient/Models/RpcTransferOut.cs @@ -25,9 +25,9 @@ public static RpcTransferOut FromJson(JObject json) { return new RpcTransferOut { - Asset = UInt160.Parse(json["asset"].AsString()), + Asset = json["asset"].ToScriptHash(), Value = json["value"].AsString(), - ScriptHash = json["address"].AsString().ToScriptHash(), + ScriptHash = json["address"].ToScriptHash(), }; } } diff --git a/src/RpcClient/RpcClient.cs b/src/RpcClient/RpcClient.cs index f418a0c6f..c43df5683 100644 --- a/src/RpcClient/RpcClient.cs +++ b/src/RpcClient/RpcClient.cs @@ -326,7 +326,7 @@ public UInt256 SubmitBlock(byte[] block) /// public RpcInvokeResult InvokeFunction(string scriptHash, string operation, RpcStack[] stacks, params Signer[] signer) { - List parameters = new List { scriptHash, operation, stacks.Select(p => p.ToJson()).ToArray() }; + List parameters = new List { scriptHash.AsScriptHash(), operation, stacks.Select(p => p.ToJson()).ToArray() }; if (signer.Length > 0) { parameters.Add(signer.Select(p => (JObject)p.ToJson()).ToArray()); @@ -350,7 +350,7 @@ public RpcInvokeResult InvokeScript(byte[] script, params Signer[] signers) public RpcUnclaimedGas GetUnclaimedGas(string address) { - return RpcUnclaimedGas.FromJson(RpcSend("getunclaimedgas", address)); + return RpcUnclaimedGas.FromJson(RpcSend("getunclaimedgas", address.AsScriptHash())); } #endregion SmartContract @@ -408,7 +408,7 @@ public string GetNewAddress() /// new address as string public BigDecimal GetWalletBalance(string assetId) { - byte decimals = new Nep5API(this).Decimals(UInt160.Parse(assetId)); + byte decimals = new Nep5API(this).Decimals(UInt160.Parse(assetId.AsScriptHash())); BigInteger balance = BigInteger.Parse(RpcSend("getwalletbalance", assetId)["balance"].AsString()); return new BigDecimal(balance, decimals); } @@ -452,7 +452,7 @@ public bool OpenWallet(string path, string password) /// This function returns Signed Transaction JSON if successful, ContractParametersContext JSON if signing failed. public JObject SendFrom(string assetId, string fromAddress, string toAddress, string amount) { - return RpcSend("sendfrom", assetId, fromAddress, toAddress, amount); + return RpcSend("sendfrom", assetId.AsScriptHash(), fromAddress.AsScriptHash(), toAddress.AsScriptHash(), amount); } /// @@ -464,7 +464,7 @@ public JObject SendMany(string fromAddress, IEnumerable outputs) var parameters = new List(); if (!string.IsNullOrEmpty(fromAddress)) { - parameters.Add(fromAddress); + parameters.Add(fromAddress.AsScriptHash()); } parameters.Add(outputs.Select(p => p.ToJson()).ToArray()); @@ -477,7 +477,7 @@ public JObject SendMany(string fromAddress, IEnumerable outputs) /// This function returns Signed Transaction JSON if successful, ContractParametersContext JSON if signing failed. public JObject SendToAddress(string assetId, string address, string amount) { - return RpcSend("sendtoaddress", assetId, address, amount); + return RpcSend("sendtoaddress", assetId.AsScriptHash(), address.AsScriptHash(), amount); } #endregion Wallet @@ -504,7 +504,7 @@ public RpcNep5Transfers GetNep5Transfers(string address, ulong? startTimestamp = { startTimestamp ??= 0; endTimestamp ??= DateTime.UtcNow.ToTimestampMS(); - return RpcNep5Transfers.FromJson(RpcSend("getnep5transfers", address, startTimestamp, endTimestamp)); + return RpcNep5Transfers.FromJson(RpcSend("getnep5transfers", address.AsScriptHash(), startTimestamp, endTimestamp)); } /// @@ -513,7 +513,7 @@ public RpcNep5Transfers GetNep5Transfers(string address, ulong? startTimestamp = /// public RpcNep5Balances GetNep5Balances(string address) { - return RpcNep5Balances.FromJson(RpcSend("getnep5balances", address)); + return RpcNep5Balances.FromJson(RpcSend("getnep5balances", address.AsScriptHash())); } #endregion Plugins diff --git a/src/RpcClient/Utility.cs b/src/RpcClient/Utility.cs index 6bca96b12..07a65ccff 100644 --- a/src/RpcClient/Utility.cs +++ b/src/RpcClient/Utility.cs @@ -2,6 +2,7 @@ using Neo.IO.Json; using Neo.Network.P2P.Payloads; using Neo.SmartContract; +using Neo.SmartContract.Native; using Neo.VM.Types; using Neo.Wallets; using System; @@ -27,6 +28,27 @@ private static (BigInteger numerator, BigInteger denominator) Fraction(decimal d return (numerator, denominator); } + public static UInt160 ToScriptHash(this JObject value) + { + var addressOrScriptHash = value.AsString(); + + return addressOrScriptHash.Length < 40 ? + addressOrScriptHash.ToScriptHash() : UInt160.Parse(addressOrScriptHash); + } + + public static string AsScriptHash(this string addressOrScriptHash) + { + foreach (var native in NativeContract.Contracts) + { + if (addressOrScriptHash.Equals(native.Name, StringComparison.InvariantCultureIgnoreCase) || + addressOrScriptHash == native.Id.ToString()) + return native.Hash.ToString(); + } + + return addressOrScriptHash.Length < 40 ? + addressOrScriptHash : UInt160.Parse(addressOrScriptHash).ToString(); + } + /// /// Parse WIF or private key hex string to KeyPair /// @@ -114,7 +136,7 @@ public static void FromJson(this BlockBase block, JObject json) block.MerkleRoot = UInt256.Parse(json["merkleroot"].AsString()); block.Timestamp = (ulong)json["time"].AsNumber(); block.Index = (uint)json["index"].AsNumber(); - block.NextConsensus = json["nextconsensus"].AsString().ToScriptHash(); + block.NextConsensus = json["nextconsensus"].ToScriptHash(); block.Witness = ((JArray)json["witnesses"]).Select(p => WitnessFromJson(p)).FirstOrDefault(); } @@ -145,9 +167,9 @@ public static Signer SignerFromJson(JObject json) { return new Signer { - Account = UInt160.Parse(json["account"].AsString()), + Account = json["account"].ToScriptHash(), Scopes = (WitnessScope)Enum.Parse(typeof(WitnessScope), json["scopes"].AsString()), - AllowedContracts = ((JArray)json["allowedContracts"])?.Select(p => UInt160.Parse(p.AsString())).ToArray(), + AllowedContracts = ((JArray)json["allowedContracts"])?.Select(p => p.ToScriptHash()).ToArray(), AllowedGroups = ((JArray)json["allowedGroups"])?.Select(p => ECPoint.Parse(p.AsString(), ECCurve.Secp256r1)).ToArray() }; }