diff --git a/neo/Core/AccountState.cs b/neo/Core/AccountState.cs index 3745a03c1b..03c7e44a1b 100644 --- a/neo/Core/AccountState.cs +++ b/neo/Core/AccountState.cs @@ -1,5 +1,6 @@ using Neo.Cryptography.ECC; using Neo.IO; +using Neo.IO.Json; using Neo.VM; using System.Collections.Generic; using System.IO; @@ -17,6 +18,16 @@ public class AccountState : StateBase, ICloneable public override int Size => base.Size + ScriptHash.Size + sizeof(bool) + Votes.GetVarSize() + IO.Helper.GetVarSize(Balances.Count) + Balances.Count * (32 + 8); + public AccountState() { } + + public AccountState(UInt160 hash) + { + this.ScriptHash = hash; + this.IsFrozen = false; + this.Votes = new ECPoint[0]; + this.Balances = new Dictionary(); + } + AccountState ICloneable.Clone() { return new AccountState @@ -68,5 +79,21 @@ public override void Serialize(BinaryWriter writer) writer.Write(pair.Value); } } + + public override JObject ToJson() + { + JObject json = base.ToJson(); + json["script_hash"] = ScriptHash.ToString(); + json["frozen"] = IsFrozen; + json["votes"] = new JArray(Votes.Select(p => (JObject)p.ToString())); + json["balances"] = new JArray(Balances.Select(p => + { + JObject balance = new JObject(); + balance["asset"] = p.Key.ToString(); + balance["value"] = p.Value.ToString(); + return balance; + })); + return json; + } } } diff --git a/neo/Core/AssetState.cs b/neo/Core/AssetState.cs index 61ab672043..ba650c9ab8 100644 --- a/neo/Core/AssetState.cs +++ b/neo/Core/AssetState.cs @@ -2,6 +2,7 @@ using Neo.IO; using Neo.IO.Json; using Neo.VM; +using Neo.Wallets; using System; using System.Collections.Generic; using System.Globalization; @@ -144,6 +145,30 @@ public override void Serialize(BinaryWriter writer) writer.Write(IsFrozen); } + public override JObject ToJson() + { + JObject json = base.ToJson(); + json["id"] = AssetId.ToString(); + json["type"] = AssetType; + try + { + json["name"] = Name == "" ? null : JObject.Parse(Name); + } + catch (FormatException) + { + json["name"] = Name; + } + json["amount"] = Amount.ToString(); + json["available"] = Available.ToString(); + json["precision"] = Precision; + json["owner"] = Owner.ToString(); + json["admin"] = Wallet.ToAddress(Admin); + json["issuer"] = Wallet.ToAddress(Issuer); + json["expiration"] = Expiration; + json["frozen"] = IsFrozen; + return json; + } + public override string ToString() { return GetName(); diff --git a/neo/Core/ContractState.cs b/neo/Core/ContractState.cs index e24d1066e6..9d6e8ca649 100644 --- a/neo/Core/ContractState.cs +++ b/neo/Core/ContractState.cs @@ -1,4 +1,5 @@ using Neo.IO; +using Neo.IO.Json; using System.IO; namespace Neo.Core @@ -65,5 +66,18 @@ public override void Serialize(BinaryWriter writer) writer.WriteVarString(Email); writer.WriteVarString(Description); } + + public override JObject ToJson() + { + JObject json = base.ToJson(); + json["code"] = Code.ToJson(); + json["storage"] = HasStorage; + json["name"] = Name; + json["code_version"] = CodeVersion; + json["author"] = Author; + json["email"] = Email; + json["description"] = Description; + return json; + } } } diff --git a/neo/Core/FunctionCode.cs b/neo/Core/FunctionCode.cs index d8ad16dc7d..bd3017dbce 100644 --- a/neo/Core/FunctionCode.cs +++ b/neo/Core/FunctionCode.cs @@ -1,4 +1,5 @@ using Neo.IO; +using Neo.IO.Json; using System.IO; using System.Linq; @@ -38,5 +39,15 @@ void ISerializable.Serialize(BinaryWriter writer) writer.WriteVarBytes(ParameterList.Cast().ToArray()); writer.Write((byte)ReturnType); } + + public JObject ToJson() + { + JObject json = new JObject(); + json["hash"] = ScriptHash.ToString(); + json["script"] = Script.ToHexString(); + json["parameters"] = new JArray(ParameterList.Select(p => (JObject)p)); + json["returntype"] = ReturnType; + return json; + } } } diff --git a/neo/Core/PublishTransaction.cs b/neo/Core/PublishTransaction.cs index eaceb808b3..893308b547 100644 --- a/neo/Core/PublishTransaction.cs +++ b/neo/Core/PublishTransaction.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; namespace Neo.Core { @@ -55,10 +54,7 @@ public override JObject ToJson() { JObject json = base.ToJson(); json["contract"] = new JObject(); - json["contract"]["hash"] = Code.ScriptHash.ToString(); - json["contract"]["script"] = Code.Script.ToHexString(); - json["contract"]["parameters"] = new JArray(Code.ParameterList.Select(p => (JObject)p)); - json["contract"]["returntype"] = Code.ReturnType; + json["contract"]["code"] = Code.ToJson(); json["contract"]["needstorage"] = NeedStorage; json["contract"]["name"] = Name; json["contract"]["version"] = CodeVersion; diff --git a/neo/Core/StateBase.cs b/neo/Core/StateBase.cs index f50ae73df2..ca1bf5b3f0 100644 --- a/neo/Core/StateBase.cs +++ b/neo/Core/StateBase.cs @@ -1,4 +1,5 @@ using Neo.IO; +using Neo.IO.Json; using Neo.VM; using System; using System.IO; @@ -20,5 +21,12 @@ public virtual void Serialize(BinaryWriter writer) { writer.Write(StateVersion); } + + public virtual JObject ToJson() + { + JObject json = new JObject(); + json["version"] = StateVersion; + return json; + } } } diff --git a/neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs b/neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs index bce40726b3..62a1c2357b 100644 --- a/neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs +++ b/neo/Implementations/Blockchains/LevelDB/LevelDBBlockchain.cs @@ -459,13 +459,7 @@ private void Persist(Block block) }); foreach (TransactionOutput output in tx.Outputs) { - AccountState account = accounts.GetAndChange(output.ScriptHash, () => new AccountState - { - ScriptHash = output.ScriptHash, - IsFrozen = false, - Votes = new ECPoint[0], - Balances = new Dictionary() - }); + AccountState account = accounts.GetAndChange(output.ScriptHash, () => new AccountState(output.ScriptHash)); if (account.Balances.ContainsKey(output.AssetId)) account.Balances[output.AssetId] += output.Value; else diff --git a/neo/Network/RPC/RpcServer.cs b/neo/Network/RPC/RpcServer.cs index 5a60337a30..63b95af609 100644 --- a/neo/Network/RPC/RpcServer.cs +++ b/neo/Network/RPC/RpcServer.cs @@ -1,10 +1,10 @@ -using Neo.Core; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Neo.Core; using Neo.IO; using Neo.IO.Json; using Neo.Wallets; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using System; using System.IO; using System.Linq; @@ -55,6 +55,18 @@ protected virtual JObject Process(string method, JArray _params) { switch (method) { + case "getaccountstate": + { + UInt160 script_hash = Wallet.ToScriptHash(_params[0].AsString()); + AccountState account = Blockchain.Default.GetAccountState(script_hash) ?? new AccountState(script_hash); + return account.ToJson(); + } + case "getassetstate": + { + UInt256 asset_id = UInt256.Parse(_params[0].AsString()); + AssetState asset = Blockchain.Default.GetAssetState(asset_id); + return asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset"); + } case "getbestblockhash": return Blockchain.Default.CurrentBlockHash.ToString(); case "getblock": @@ -96,6 +108,12 @@ protected virtual JObject Process(string method, JArray _params) } case "getconnectioncount": return LocalNode.RemoteNodeCount; + case "getcontractstate": + { + UInt160 script_hash = UInt160.Parse(_params[0].AsString()); + ContractState contract = Blockchain.Default.GetContract(script_hash); + return contract?.ToJson() ?? throw new RpcException(-100, "Unknown contract"); + } case "getrawmempool": return new JArray(LocalNode.GetMemoryPool().Select(p => (JObject)p.Hash.ToString())); case "getrawtransaction": @@ -107,7 +125,7 @@ protected virtual JObject Process(string method, JArray _params) if (tx == null) tx = Blockchain.Default.GetTransaction(hash, out height); if (tx == null) - throw new RpcException(-101, "Unknown transaction"); + throw new RpcException(-100, "Unknown transaction"); if (verbose) { JObject json = tx.ToJson(); @@ -125,6 +143,17 @@ protected virtual JObject Process(string method, JArray _params) return tx.ToArray().ToHexString(); } } + case "getstorage": + { + UInt160 script_hash = UInt160.Parse(_params[0].AsString()); + byte[] key = _params[1].AsString().HexToBytes(); + StorageItem item = Blockchain.Default.GetStorageItem(new StorageKey + { + ScriptHash = script_hash, + Key = key + }) ?? new StorageItem(); + return item.Value?.ToHexString(); + } case "gettxout": { UInt256 hash = UInt256.Parse(_params[0].AsString());