Skip to content

Instantly share code, notes, and snippets.

@ixje
Last active January 21, 2018 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ixje/eb8e6fef5011d0232e6b44b7097da584 to your computer and use it in GitHub Desktop.
Save ixje/eb8e6fef5011d0232e6b44b7097da584 to your computer and use it in GitHub Desktop.
dry coded rpc server bodies
import binascii
from neo.Core.Blockchain import Blockchain
from neo.Wallets import Wallet
from neocore.UInt256 import UInt256
from neo.Network.NodeLeader import NodeLeader
from neo.Core.State.StorageKey import StorageKey
from neo.VM.ScriptBuilder import ScriptBuilder
from neo.Core.TX.Transaction import Transaction
from neocore.IO.BinaryReader import BinaryReader
from neo.IO.MemoryStream import MemoryStream
from neo.IO.Helper import Helper as IOHelper
from neo.Settings import settings
class RpcException(Exception):
pass
def Process(method, params):
if method == "getaccountstate":
address = params[0]
# requires making ToScriptHash static in Wallet. That'' currently not the case, it is static in C#
script_hash = Wallet.ToScriptHash(address)
account = Blockchain.Default().GetAccountState(script_hash)
return account.ToJson()
elif method == "getassetstate":
asset_id = UInt256(data=params[0])
asset = Blockchain.Default().GetAssetState(asset_id)
# return asset?.ToJson() ?? throw new RpcException(-100, "Unknown asset");
if not asset:
raise RpcException("-100 Unknown asset")
else:
return asset.ToJson()
elif method == "getbestblockhash":
return Blockchain.Default().CurrentBlockHash
elif method == "getblock":
block = Blockchain.Default().GetBlock(params[0])
if block is None:
raise RpcException("-100 Unknown block")
verbose = False
if len(params) >= 2:
if isinstance(params[1], bool):
verbose = params[1]
if not verbose:
return block.ToArray().decode('utf-8')
else:
json_data = block.ToJson()
json_data["confirmations"] = Blockchain.Default().Height - block.Index + 1
# TODO: GetNextBlockHash doesn'' exist
hash = Blockchain.Default().GetNextBlockHash(block.Hash)
if hash is not None:
json_data['nextblockhash'] = hash
return json_data
elif method == "getblockcount":
return Blockchain.Default().Height + 1
elif method == "getblockhash":
height = params[0]
if height >= 0 and height <= Blockchain.Default().Height:
return Blockchain.Default().GetBlockHash(height).decode('utf-8')
else:
raise RpcException("-100 Invalid height")
elif method == "getconnectioncount":
nl = NodeLeader.Instance()
return len(nl.Peers)
elif method == "getcontractstate":
script_hash = params[0]
contract = Blockchain.Default().GetContract(script_hash)
if contract is None:
raise RpcException("-100 Unknown contract")
else:
return contract.ToJson()
elif method == "getrawmempool":
# return new JArray(LocalNode.GetMemoryPool().Select(p => (JObject)p.Hash.ToString()));
nl = NodeLeader.Instance()
return map(lambda hash: hash.decode('utf-8'), nl.MemPool.keys())
elif method == "getrawtransaction":
hash = params[0]
verbose = False
if len(params) >= 2:
if isinstance(params[1], bool):
verbose = params[1]
height = -1
tx = NodeLeader.Instance() # TODO: implement later. There's no NodeLeader.GetTransaction() equivalent.
# Check neo-project implementation if it only fetches from the MemPool or from the db
if tx is None:
tx, height = Blockchain.Default().GetTransaction(hash)
if tx is None:
raise RpcException("-100 Unknown transaction")
if not verbose:
return tx.ToArray().decode('utf-8')
else:
json_data = tx.ToJson()
if height >= 0:
header = Blockchain.Default().GetHeaderBy(height)
json_data["blockhash"] = header.Hash.ToString()
json_data["confirmations"] = Blockchain.Default().Height - header.Index + 1
json_data["blocktime"] = header.Timestamp
elif method == "getstorage":
script_hash = params[0]
if len(params) < 2: # note this is not in the original RPC server,I assume they forgot this
raise RpcException("-100 Invalid key")
key = bytearray(params[1])
storage_key = StorageKey(script_hash, key)
item = Blockchain.Default().GetStorageItem(storage_key)
# return item.Value?.ToHexString();
# TODO: likely fix
return binascii.hexlify(item.Value)
elif method == "gettxout":
hash = params[0]
index = params[1]
# return Blockchain.Default.GetUnspent(hash, index)?.ToJson(index);
# TODO: check what does on here, as our GetUnspent is likely to return a single tx_output
# our TransactionOutput does not have an Index parameter.
tx_output = Blockchain.Default().GetUnspent(hash, index)
elif method == "invoke":
script_hash = params[0]
sb = ScriptBuilder()
# TODO: fix/implement
# script = sb.EmitAppCall(script_hash, parameters).ToArray();
# return GetInvokeResult(script);
elif method == "invokescript":
# TODO: fix/implement
script = binascii.unhexlify(params[0])
# return GetInvokeResult(script);
elif method == "sendrawtransaction":
ms = MemoryStream(binascii.unhexlify(params[0]))
reader = BinaryReader(ms)
tx = Transaction.DeserializeFrom(reader)
return NodeLeader.Instance().Relay(tx)
elif method == "submitblock":
raw_data = binascii.unhexlify(params[0])
block = IOHelper.AsSerializableWithType(raw_data, 'neo.Core.Block.Block')
return NodeLeader.Instance().Relay(block)
elif method == "validateaddress":
# TODO check neo-project Wallet.ToScriptHash body what they validate on
'''
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;
'''
pass
elif method == "getpeers":
# TODO:
pass
elif method == "getversion":
return {'port': settings.NODE_PORT,
"useragent": settings.VERSION_NAME,
"nonce": 123 # TODO: check how LocalNode.Nonce is defined. our NodeLeader doesn't have a Nonce property.
}
else:
raise RpcException("-32601 Method not found")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment