Exemplo n.º 1
0
        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":
            {
                Block block;
                if (_params[0] is JNumber)
                {
                    uint index = (uint)_params[0].AsNumber();
                    block = Blockchain.Default.GetBlock(index);
                }
                else
                {
                    UInt256 hash = UInt256.Parse(_params[0].AsString());
                    block = Blockchain.Default.GetBlock(hash);
                }
                if (block == null)
                {
                    throw new RpcException(-100, "Unknown block");
                }
                bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false);
                if (verbose)
                {
                    JObject json = block.ToJson();
                    json["confirmations"] = Blockchain.Default.Height - block.Index + 1;
                    UInt256 hash = Blockchain.Default.GetNextBlockHash(block.Hash);
                    if (hash != null)
                    {
                        json["nextblockhash"] = hash.ToString();
                    }
                    return(json);
                }
                else
                {
                    return(block.ToArray().ToHexString());
                }
            }

            case "getblockcount":
                return(Blockchain.Default.Height + 1);

            case "getblockhash":
            {
                uint height = (uint)_params[0].AsNumber();
                if (height >= 0 && height <= Blockchain.Default.Height)
                {
                    return(Blockchain.Default.GetBlockHash(height).ToString());
                }
                else
                {
                    throw new RpcException(-100, "Invalid Height");
                }
            }

            case "getblocksysfee":
            {
                uint height = (uint)_params[0].AsNumber();
                if (height >= 0 && height <= Blockchain.Default.Height)
                {
                    return(Blockchain.Default.GetSysFeeAmount(height).ToString());
                }
                else
                {
                    throw new RpcException(-100, "Invalid Height");
                }
            }

            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":
            {
                UInt256     hash    = UInt256.Parse(_params[0].AsString());
                bool        verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false);
                int         height  = -1;
                Transaction tx      = LocalNode.GetTransaction(hash);
                if (tx == null)
                {
                    tx = Blockchain.Default.GetTransaction(hash, out height);
                }
                if (tx == null)
                {
                    throw new RpcException(-100, "Unknown transaction");
                }
                if (verbose)
                {
                    JObject json = tx.ToJson();
                    if (height >= 0)
                    {
                        Header header = Blockchain.Default.GetHeader((uint)height);
                        json["blockhash"]     = header.Hash.ToString();
                        json["confirmations"] = Blockchain.Default.Height - header.Index + 1;
                        json["blocktime"]     = header.Timestamp;
                    }
                    return(json);
                }
                else
                {
                    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());
                ushort  index = (ushort)_params[1].AsNumber();
                return(Blockchain.Default.GetUnspent(hash, index)?.ToJson(index));
            }

            case "invoke":
            {
                UInt160             script_hash = UInt160.Parse(_params[0].AsString());
                ContractParameter[] parameters  = ((JArray)_params[1]).Select(p => ContractParameter.FromJson(p)).ToArray();
                byte[] script;
                using (ScriptBuilder sb = new ScriptBuilder())
                {
                    script = sb.EmitAppCall(script_hash, parameters).ToArray();
                }
                return(GetInvokeResult(script));
            }

            case "invokefunction":
            {
                UInt160             script_hash = UInt160.Parse(_params[0].AsString());
                string              operation   = _params[1].AsString();
                ContractParameter[] args        = _params.Count >= 3 ? ((JArray)_params[2]).Select(p => ContractParameter.FromJson(p)).ToArray() : new ContractParameter[0];
                byte[]              script;
                using (ScriptBuilder sb = new ScriptBuilder())
                {
                    script = sb.EmitAppCall(script_hash, operation, args).ToArray();
                }
                return(GetInvokeResult(script));
            }

            case "invokescript":
            {
                byte[] script = _params[0].AsString().HexToBytes();
                return(GetInvokeResult(script));
            }

            case "sendrawtransaction":
            {
                Transaction tx = Transaction.DeserializeFrom(_params[0].AsString().HexToBytes());
                return(LocalNode.Relay(tx));
            }

            case "submitblock":
            {
                Block block = _params[0].AsString().HexToBytes().AsSerializable <Block>();
                return(LocalNode.Relay(block));
            }

            case "validateaddress":
            {
                JObject json = new JObject();
                UInt160 scriptHash;
                try
                {
                    scriptHash = Wallet.ToScriptHash(_params[0].AsString());
                }
                catch
                {
                    scriptHash = null;
                }
                json["address"] = _params[0];
                json["isvalid"] = scriptHash != null;
                return(json);
            }

            case "getpeers":
            {
                JObject json = new JObject();

                {
                    JArray unconnectedPeers = new JArray();
                    foreach (IPEndPoint peer in LocalNode.GetUnconnectedPeers())
                    {
                        JObject peerJson = new JObject();
                        peerJson["address"] = peer.Address.ToString();
                        peerJson["port"]    = peer.Port;
                        unconnectedPeers.Add(peerJson);
                    }
                    json["unconnected"] = unconnectedPeers;
                }

                {
                    JArray badPeers = new JArray();
                    foreach (IPEndPoint peer in LocalNode.GetBadPeers())
                    {
                        JObject peerJson = new JObject();
                        peerJson["address"] = peer.Address.ToString();
                        peerJson["port"]    = peer.Port;
                        badPeers.Add(peerJson);
                    }
                    json["bad"] = badPeers;
                }

                {
                    JArray connectedPeers = new JArray();
                    foreach (RemoteNode node in LocalNode.GetRemoteNodes())
                    {
                        JObject peerJson = new JObject();
                        peerJson["address"] = node.RemoteEndpoint.Address.ToString();
                        peerJson["port"]    = node.ListenerEndpoint?.Port ?? 0;
                        connectedPeers.Add(peerJson);
                    }
                    json["connected"] = connectedPeers;
                }

                return(json);
            }

            case "getversion":
            {
                JObject json = new JObject();
                json["port"]      = LocalNode.Port;
                json["nonce"]     = LocalNode.Nonce;
                json["useragent"] = LocalNode.UserAgent;
                return(json);
            }

            default:
                throw new RpcException(-32601, "Method not found");
            }
        }