Merge pull request #7 from step21/master

ipc support
pull/12/head
Bernhard Mueller 7 years ago committed by GitHub
commit e824333583
  1. 33
      myth
  2. 9
      mythril/ether/contractstorage.py
  3. 17
      mythril/ether/util.py
  4. 0
      mythril/ipc/__init__.py
  5. 697
      mythril/ipc/client.py
  6. 8
      mythril/ipc/constants.py
  7. 18
      mythril/ipc/exceptions.py
  8. 38
      mythril/ipc/utils.py
  9. 1
      requirements.txt
  10. 1
      tests/ipc_test.py

33
myth

@ -9,6 +9,7 @@ from mythril.disassembler.disassembly import Disassembly
from mythril.disassembler.callgraph import generate_callgraph
from mythril.ether.contractstorage import get_persistent_storage
from mythril.rpc.client import EthJsonRpc
from mythril.ipc.client import EthIpc
from ethereum import utils
import binascii
import sys
@ -36,6 +37,7 @@ parser.add_argument('-c', '--code', help='hex-encoded bytecode string ("60606040
parser.add_argument('-a', '--address', help='contract address')
parser.add_argument('-o', '--outfile')
parser.add_argument('-g', '--graph', help='when disassembling, also generate a callgraph', metavar='OUTPUT_FILE')
parser.add_argument('--ipc', help='use ipc interface', action='store_true')
parser.add_argument('--data', help='message call input data for tracing')
parser.add_argument('--search', help='search the contract database')
parser.add_argument('--xrefs', help='get xrefs from contract in database', metavar='CONTRACT_HASH')
@ -59,14 +61,21 @@ if (args.disassemble):
if (args.code):
encoded_bytecode = args.code
elif (args.address):
if args.ipc:
try:
eth = EthIpc()
try:
eth = EthJsonRpc(args.rpchost, args.rpcport)
encoded_bytecode = eth.eth_getCode(args.address)
except Exception as e:
exitWithError("Exception loading bytecode via IPC: " + str(e))
encoded_bytecode = eth.eth_getCode(args.address)
try:
eth = EthJsonRpc(args.rpchost, args.rpcport)
encoded_bytecode = eth.eth_getCode(args.address)
except Exception as e:
exitWithError("Exception loading bytecode via RPC: " + str(e))
except Exception as e:
exitWithError("Exception loading bytecode via RPC: " + str(e))
else:
exitWithError("Disassembler: Provide the input bytecode via -c BYTECODE or --id ID")
@ -94,10 +103,13 @@ elif (args.trace):
encoded_bytecode = args.code
elif (args.address):
if args.ipc:
eth = EthIpc()
encoded_bytecode = eth.eth_getCode(args.address)
eth = EthJsonRpc(args.rpchost, args.rpcport)
encoded_bytecode = eth.eth_getCode(args.address)
else:
eth = EthJsonRpc(args.rpchost, args.rpcport)
encoded_bytecode = eth.eth_getCode(args.address)
else:
exitWithError("Disassembler: Provide the input bytecode via -c BYTECODE or --id ID")
@ -135,7 +147,10 @@ elif (args.xrefs):
exitWithError("Contract not found in the database.")
elif (args.init_db):
contract_storage.initialize(args.rpchost, args.rpcport, args.sync_all)
if args.ipc:
contract_storage.initialize(args.rpchost, args.rpcport, args.sync_all, args.ipc)
else:
contract_storage.initialize(args.rpchost, args.rpcport, args.sync_all, args.ipc)
elif (args.hash):
print("0x" + utils.sha3(args.hash)[:4].hex())

@ -1,4 +1,5 @@
from mythril.rpc.client import EthJsonRpc
from mythril.ipc.client import EthIpc
from mythril.ether.ethcontract import ETHContract, InstanceList
import hashlib
import os
@ -46,9 +47,11 @@ class ContractStorage(persistent.Persistent):
return self.contracts[contract_hash]
def initialize(self, rpchost, rpcport, sync_all):
eth = EthJsonRpc(rpchost, rpcport)
def initialize(self, rpchost, rpcport, sync_all, ipc):
if ipc:
eth = EthIpc()
else:
eth = EthJsonRpc(rpchost, rpcport)
if self.last_block:
blockNum = self.last_block

@ -1,4 +1,5 @@
from mythril.rpc.client import EthJsonRpc
from mythril.ipc.client import EthIpc
from ethereum.abi import encode_abi, encode_int
from ethereum.utils import zpad
from ethereum.abi import method_id
@ -16,20 +17,22 @@ def safe_decode(hex_encoded_string):
# return codecs.decode(hex_encoded_string, 'hex_codec')
def bytecode_from_blockchain(creation_tx_hash, rpc_host='127.0.0.1', rpc_port=8545):
def bytecode_from_blockchain(creation_tx_hash, ipc, rpc_host='127.0.0.1', rpc_port=8545):
"""Load bytecode from a local node via
creation_tx_hash = ID of transaction that created the contract.
"""
if ipc:
pass
else:
eth = EthJsonRpc(rpc_host, rpc_port)
eth = EthJsonRpc(rpc_host, rpc_port)
trace = eth.traceTransaction(creation_tx_hash)
trace = eth.traceTransaction(creation_tx_hash)
if trace['returnValue']:
if trace['returnValue']:
return trace['returnValue']
return trace['returnValue']
raise RuntimeError("Transaction trace didn't return any bytecode")
raise RuntimeError("Transaction trace didn't return any bytecode")
def encode_calldata(func_name, arg_types, args):

@ -0,0 +1,697 @@
import json
import warnings
from ethereum import utils
from ethereum.abi import encode_abi, decode_abi
from web3 import Web3, IPCProvider
#HTTPProvider,
from .constants import BLOCK_TAGS, BLOCK_TAG_LATEST
from .utils import hex_to_dec, clean_hex, validate_block
from .exceptions import (ConnectionError, BadStatusCodeError,
BadJsonError, BadResponseError)
IPC_PATH = None
'''
This code is adapted from: https://github.com/ConsenSys/ethjsonrpc
'''
class EthIpc(object):
'''
Ethereum IPC client class using web3.py
'''
web3 = Web3(IPCProvider())
DEFAULT_GAS_PER_TX = 90000
DEFAULT_GAS_PRICE = 50 * 10**9 # 50 gwei
def __init__(self, ipc_path=IPC_PATH):
#not used so far
self.ipc_path = ipc_path
def _encode_function(self, signature, param_values):
prefix = utils.big_endian_to_int(utils.sha3(signature)[:4])
if signature.find('(') == -1:
raise RuntimeError('Invalid function signature. Missing "(" and/or ")"...')
if signature.find(')') - signature.find('(') == 1:
return utils.encode_int(prefix)
types = signature[signature.find('(') + 1: signature.find(')')].split(',')
encoded_params = encode_abi(types, param_values)
return utils.zpad(utils.encode_int(prefix), 4) + encoded_params
################################################################################
# high-level methods
################################################################################
def transfer(self, from_, to, amount):
'''
Send wei from one address to another
'''
return self.eth_sendTransaction(from_address=from_, to_address=to, value=amount)
def create_contract(self, from_, code, gas, sig=None, args=None):
'''
Create a contract on the blockchain from compiled EVM code. Returns the
transaction hash.
'''
from_ = from_ or self.eth_coinbase()
if sig is not None and args is not None:
types = sig[sig.find('(') + 1: sig.find(')')].split(',')
encoded_params = encode_abi(types, args)
code += encoded_params.hex()
return self.eth_sendTransaction(from_address=from_, gas=gas, data=code)
def get_contract_address(self, tx):
'''
Get the address for a contract from the transaction that created it
'''
receipt = self.eth_getTransactionReceipt(tx)
return receipt['contractAddress']
def call(self, address, sig, args, result_types):
'''
Call a contract function on the RPC server, without sending a
transaction (useful for reading data)
'''
data = self._encode_function(sig, args)
data_hex = data.encode('hex')
response = self.eth_call(to_address=address, data=data_hex)
return decode_abi(result_types, response[2:].decode('hex'))
def call_with_transaction(self, from_, address, sig, args, gas=None, gas_price=None, value=None):
'''
Call a contract function by sending a transaction (useful for storing
data)
'''
gas = gas or self.DEFAULT_GAS_PER_TX
gas_price = gas_price or self.DEFAULT_GAS_PRICE
data = self._encode_function(sig, args)
data_hex = data.encode('hex')
return self.eth_sendTransaction(from_address=from_, to_address=address, data=data_hex, gas=gas,
gas_price=gas_price, value=value)
################################################################################
# JSON-RPC methods
################################################################################
def web3_clientVersion(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#web3_clientversion
http://web3py.readthedocs.io/en/latest/web3.version.html#web3.version.Version.node
'''
return self.web3.version.node
def web3_sha3(self, data):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#web3_sha3
http://web3py.readthedocs.io/en/latest/overview.html#Web3.sha3
Encoding probably not necessary
'''
data = str(data).encode('hex')
return self.web3.sha3(data)
def net_version(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#net_version
http://web3py.readthedocs.io/en/latest/web3.version.html#web3.version.Version.network
'''
return self.web3.version.network
def net_listening(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#net_listening
ONLY indirectly available
TESTED
'''
return self.web3net.listening()
def net_peerCount(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#net_peercount
ONLY indirectly available
TESTED
'''
return self.web3.net.peerCount()
def eth_protocolVersion(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_protocolversion
http://web3py.readthedocs.io/en/latest/web3.version.html?highlight=net#web3.version.Version.ethereum
'''
return self.web3.version.ethereum
def eth_syncing(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_syncing
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=syncing#web3.eth.Eth.syncing
'''
return self.web3.eth.syncing
def eth_coinbase(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_coinbase
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=syncing#web3.eth.Eth.coinbase
'''
return self.web3.eth.coinbase
def eth_mining(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_mining
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=syncing#web3.eth.Eth.mining
'''
return self.web3.Eth.mining
def eth_hashrate(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_hashrate
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=syncing#web3.eth.Eth.hashrate
'''
return hex_to_dec(web3.eth.hashrate)
def eth_gasPrice(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gasprice
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.gasPrice
'''
return hex_to_dec(web3.eth.gasPrice)
def eth_accounts(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_accounts
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.accounts
'''
return self.web3.eth.accounts
def eth_blockNumber(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_blocknumber
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.blockNumber
'''
return hex_to_dec(self.web3.eth.blockNumber)
def eth_getBalance(self, address=None, block=BLOCK_TAG_LATEST):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getbalance
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getBalance
'''
address = address or self.eth_coinbase()
block = validate_block(block)
return self.web3.eth.getBalance(address, block_identifier=block)
def eth_getStorageAt(self, address=None, position=0, block=BLOCK_TAG_LATEST):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getstorageat
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getStorageAt
'''
block = validate_block(block)
return self.web3.eth.getStorageAt(address, position, block_identifier=block)
def eth_getTransactionCount(self, address, block=BLOCK_TAG_LATEST):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactioncount
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getTransactionCount
'''
block = validate_block(block)
return self.web3.eth.getTransactionCount(address, block_identifier=block)
def eth_getBlockTransactionCountByHash(self, block_hash):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblocktransactioncountbyhash
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getBlockTransactionCount
'''
return self.web3.eth.getBlockTransactionCount(block_hash)
def eth_getBlockTransactionCountByNumber(self, block=BLOCK_TAG_LATEST):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblocktransactioncountbynumber
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getBlockTransactionCount
'''
block = validate_block(block)
return self.web3.eth.getBlockTransactionCount(block)
def eth_getUncleCountByBlockHash(self, block_hash):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getunclecountbyblockhash
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getUncle
'''
return self.web3.eth.getUncleCount(block_hash)
def eth_getUncleCountByBlockNumber(self, block=BLOCK_TAG_LATEST):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getunclecountbyblocknumber
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getUncle
'''
block = validate_block(block)
return self.web3.eth.getUncleCount(block)
def eth_getCode(self, address, default_block=BLOCK_TAG_LATEST):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getcode
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getCode
NEEDS TESTING
'''
if isinstance(default_block, str):
if default_block not in BLOCK_TAGS:
raise ValueError
return self.web3.eth.getCode(address, block_identifier=default_block)
def eth_sign(self, address, data):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.sign
either data= hexstr= or text= probably not needed now but if used should be differentiated
NEEDS TESTING
'''
return self.web3.eth.sign(address, data)
def eth_sendTransaction(self, to_address=None, from_address=None, gas=None, gas_price=None, value=None, data=None,
nonce=None):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=syncing#web3.eth.Eth.sendTransaction
NEEDS TESTING
'''
params = {}
params['from'] = from_address or self.eth_coinbase()
if to_address is not None:
params['to'] = to_address
if gas is not None:
params['gas'] = hex(gas)
if gas_price is not None:
params['gasPrice'] = clean_hex(gas_price)
if value is not None:
params['value'] = clean_hex(value)
if data is not None:
params['data'] = data
if nonce is not None:
params['nonce'] = hex(nonce)
return self.web3.eth.sendTransaction(params)
def eth_sendRawTransaction(self, data):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendrawtransaction
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=syncing#web3.eth.Eth.sendRawTransaction
NEEDS TESTING
'''
return self.web3.eth.sendRawTransaction(data)
def eth_call(self, to_address, from_address=None, gas=None, gas_price=None, value=None, data=None,
default_block=BLOCK_TAG_LATEST):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_call
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=syncing#web3.eth.Eth.call
NEEDS TESTING
'''
if isinstance(default_block, str):
if default_block not in BLOCK_TAGS:
raise ValueError
obj = {}
obj['to'] = to_address
if from_address is not None:
obj['from'] = from_address
if gas is not None:
obj['gas'] = hex(gas)
if gas_price is not None:
obj['gasPrice'] = clean_hex(gas_price)
if value is not None:
obj['value'] = value
if data is not None:
obj['data'] = data
return self.web3.eth.call(obj, block_identifier=default_block)
def eth_estimateGas(self, to_address=None, from_address=None, gas=None, gas_price=None, value=None, data=None,
default_block=BLOCK_TAG_LATEST):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_estimategas
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.estimateGas
NEEDS TESTING
'''
if isinstance(default_block, str):
if default_block not in BLOCK_TAGS:
raise ValueError
obj = {}
if to_address is not None:
obj['to'] = to_address
if from_address is not None:
obj['from'] = from_address
if gas is not None:
obj['gas'] = hex(gas)
if gas_price is not None:
obj['gasPrice'] = clean_hex(gas_price)
if value is not None:
obj['value'] = value
if data is not None:
obj['data'] = data
return self.web3.eth.estimateGas(obj)
def eth_getBlockByHash(self, block_hash, tx_objects=True):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbyhash
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getBlock
TESTED
'''
return self.web3.eth.getBlock(block_identifier=block_hash, full_transactions=tx_objects)
def eth_getBlockByNumber(self, block=BLOCK_TAG_LATEST, tx_objects=True):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbynumber
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getBlock
TESTED
'''
block = validate_block(block)
return self.web3.eth.getBlock(block_identifier=block, full_transactions=tx_objects)
def eth_getTransactionByHash(self, tx_hash):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyhash
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getTransaction
TESTED
'''
return self.web3.eth.getTransactionByHash(tx_hash)
def eth_getTransactionByBlockHashAndIndex(self, block_hash, index=0):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyblockhashandindex
http://web3py.readthedocs.io/en/latest/web3.eth.html#web3.eth.Eth.getTransactionFromBlock
TESTED
'''
return self.web3.eth.getTransactionFromBlock(block_identifier=block_hash, transaction_index=index)
def eth_getTransactionByBlockNumberAndIndex(self, block=BLOCK_TAG_LATEST, index=0):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyblocknumberandindex
http://web3py.readthedocs.io/en/latest/web3.eth.html#web3.eth.Eth.getTransactionFromBlock
TESTED
'''
block = validate_block(block)
return self.web3.eth.getTransactionFromBlock(block_identifier=block, transaction_index=index)
def eth_getTransactionReceipt(self, tx_hash):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionreceipt
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=gasprice#web3.eth.Eth.getTransactionReceipt
TESTED
'''
return self.web3.eth.getTransactionReceipt(tx_hash)
def eth_getUncleByBlockHashAndIndex(self, block_hash, index=0):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getunclebyblockhashandindex
NOT IMPLEMENTED
TESTED
'''
return "Not implemented"
def eth_getUncleByBlockNumberAndIndex(self, block=BLOCK_TAG_LATEST, index=0):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getunclebyblocknumberandindex
NOT IMPLEMENTED
TESTED
'''
block = validate_block(block)
return "Not implemented"
def eth_getCompilers(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getcompilers
Does not seem to be implemented
TESTED
'''
return "Not implemented"
def eth_compileSolidity(self, code):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compilesolidity
Implemented?
TESTED
'''
return self.web3.eth.compileSolidity(code)
def eth_compileLLL(self, code):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compilelll
Implemented?
N/A
'''
return self.web3.eth.compileLLL(code)
def eth_compileSerpent(self, code):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compileserpent
Implemented?
N/A
'''
return self.web3.eth.compileSerpent(code)
def eth_newFilter(self, from_block=BLOCK_TAG_LATEST, to_block=BLOCK_TAG_LATEST, address=None, topics=None):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter
http://web3py.readthedocs.io/en/latest/web3.eth.html#web3.eth.Eth.filter
NEEDS TESTING
'''
filter_params = {
'fromBlock': from_block,
'toBlock': to_block,
'address': address,
'topics': topics,
}
return self.web3.eth.newFilter(filter_params)
def eth_newBlockFilter(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newblockfilter
http://web3py.readthedocs.io/en/latest/web3.eth.html#web3.eth.Eth.filter
TESTED
'''
return self.web3.eth.newFilter('latest')
def eth_newPendingTransactionFilter(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newpendingtransactionfilter
http://web3py.readthedocs.io/en/latest/web3.eth.html#web3.eth.Eth.filter
TESTED
'''
return self.web3.eth.newFilter('pending')
def eth_uninstallFilter(self, filter_id):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_uninstallfilter
http://web3py.readthedocs.io/en/latest/web3.eth.html#web3.eth.Eth.uninstallFilter
NEEDS TESTING
'''
return self.web3.eth.uninstallFilter(filter_id)
def eth_getFilterChanges(self, filter_id):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterchanges
http://web3py.readthedocs.io/en/latest/web3.eth.html#web3.eth.Eth.getFilterChanges
NEEDS TESTING
'''
return self.web3.eth.getFilterChanges(filter_id)
def eth_getFilterLogs(self, filter_id):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterlogs
http://web3py.readthedocs.io/en/latest/web3.eth.html#web3.eth.Eth.getFilterLogs
NEEDS TESTING
'''
return self.web3.eth.getFilterLogs(filter_id)
def eth_getLogs(self, filter_object):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs
http://web3py.readthedocs.io/en/latest/filters.html?highlight=getLogs#web3.utils.filters.LogFilter.get
NEEDS TESTING
'''
return self.filter_object.get()
def eth_getWork(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getwork
http://web3py.readthedocs.io/en/latest/releases.html?highlight=getWork#id15
TESTED
'''
return self.web3.eth.getWork()
def eth_submitWork(self, nonce, header, mix_digest):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_submitwork
Not sure if implemented
NEEDS TESTING
'''
return self.web3.eth.submitWork(nonce, header, mix_digest)
def eth_submitHashrate(self, hash_rate, client_id):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_submithashrate
Not sure if implemented
TESTED
'''
return self.web3.eth.submitHashrate(hash_rate, client_id)
def db_putString(self, db_name, key, value):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#db_putstring
Not implemented I think
TESTED
'''
warnings.warn('deprecated', DeprecationWarning)
return self.web3.db.putString(db_name, key, value)
def db_getString(self, db_name, key):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#db_getstring
Not implemented I think
TESTED
'''
warnings.warn('deprecated', DeprecationWarning)
return self.web3.db.getString(db_name, key)
def db_putHex(self, db_name, key, value):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#db_puthex
TESTED
'''
if not value.startswith('0x'):
value = '0x{}'.format(value)
warnings.warn('deprecated', DeprecationWarning)
return self.web3.db.putHex(db_name, key, value)
def db_getHex(self, db_name, key):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#db_gethex
TESTED
'''
warnings.warn('deprecated', DeprecationWarning)
return self.web3.db.getHex(db_name, key)
def shh_version(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_version
http://web3py.readthedocs.io/en/latest/web3.shh.html#web3.shh.Shh.version
N/A
'''
return self.web3.shh.version()
def shh_post(self, topics, payload, priority, ttl, from_=None, to=None):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_post
NEEDS TESTING
'''
whisper_object = {
'from': from_,
'to': to,
'topics': topics,
'payload': payload,
'priority': hex(priority),
'ttl': hex(ttl),
}
return self._call('shh_post', [whisper_object])
def shh_newIdentity(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_newidentity
N/A
'''
return self._call('shh_newIdentity')
def shh_hasIdentity(self, address):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_hasidentity
NEEDS TESTING
'''
return self._call('shh_hasIdentity', [address])
def shh_newGroup(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_newgroup
N/A
'''
return self._call('shh_newGroup')
def shh_addToGroup(self):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_addtogroup
NEEDS TESTING
'''
return self._call('shh_addToGroup')
def shh_newFilter(self, to, topics):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_newfilter
NEEDS TESTING
'''
_filter = {
'to': to,
'topics': topics,
}
return self._call('shh_newFilter', [_filter])
def shh_uninstallFilter(self, filter_id):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_uninstallfilter
NEEDS TESTING
'''
return self._call('shh_uninstallFilter', [filter_id])
def shh_getFilterChanges(self, filter_id):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_getfilterchanges
http://web3py.readthedocs.io/en/latest/web3.eth.html?highlight=syncing#web3.eth.Eth.getFilterChanges
NEEDS TESTING
'''
filt = self.web3.eth.filter()
return self._call('shh_getFilterChanges', [filter_id])
def shh_getMessages(self, filter_id):
'''
https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_getmessages
NEEDS TESTING
'''
return self._call('shh_getMessages', [filter_id])
def getBlockRlp(self, number=0):
return self._call('debug_getBlockRlp', [number])
def traceTransaction(self, txHash):
return self._call('debug_traceTransaction', [txHash])

@ -0,0 +1,8 @@
BLOCK_TAG_EARLIEST = 'earliest'
BLOCK_TAG_LATEST = 'latest'
BLOCK_TAG_PENDING = 'pending'
BLOCK_TAGS = (
BLOCK_TAG_EARLIEST,
BLOCK_TAG_LATEST,
BLOCK_TAG_PENDING,
)

@ -0,0 +1,18 @@
class EthIpcError(Exception):
pass
class ConnectionError(EthIpcError):
pass
class BadStatusCodeError(EthIpcError):
pass
class BadJsonError(EthIpcError):
pass
class BadResponseError(EthIpcError):
pass

@ -0,0 +1,38 @@
from .constants import BLOCK_TAGS
def hex_to_dec(x):
'''
Convert hex to decimal
'''
return int(x, 16)
def clean_hex(d):
'''
Convert decimal to hex and remove the "L" suffix that is appended to large
numbers
'''
return hex(d).rstrip('L')
def validate_block(block):
if isinstance(block, str):
if block not in BLOCK_TAGS:
raise ValueError('invalid block tag')
if isinstance(block, int):
block = hex(block)
return block
def wei_to_ether(wei):
'''
Convert wei to ether
'''
return 1.0 * wei / 10**18
def ether_to_wei(ether):
'''
Convert ether to wei
'''
return ether * 10**18

@ -1,3 +1,4 @@
ethereum>=2.0.4
ZODB>=5.3.0
graphviz>=0.8
web3

@ -0,0 +1 @@
import unittest
Loading…
Cancel
Save