def assert_call(self, contract, name, params, return_value): contract_address = self.replace_address(contract) return_value = self.replace_address(return_value) contract_abi = self.contract_abis[contract] translator = ContractTranslator(contract_abi) data = "0x" + translator.encode( name, [self.replace_address(p) for p in params]).encode("hex") logging.info('Try to assert return value of {} in contract {}.'.format( name, contract)) response = self.json_rpc.eth_call(from_address=self.user_address, to_address=contract_address, data=data) bc_return_val = response["result"] result_decoded = translator.decode(name, bc_return_val[2:].decode("hex")) result_decoded = result_decoded if len( result_decoded) > 1 else result_decoded[0] if isinstance(return_value, int) or isinstance(return_value, long): assert result_decoded == return_value else: assert result_decoded.lower() == self.strip_0x( return_value.lower()) logging.info( 'Assertion successful for return value of {} in contract {}.'. format(name, contract))
def call(self, _from, to, value, name, params, label, assertion, abi): reference = to to = self.replace_references(to) if not name: name = abi['name'] abi = self.abis[to] if to in self.abis else [abi] translator = ContractTranslator(abi) data = encode(translator.encode(name, self.replace_references(params)), 'hex') response = self.json_rpc.eth_call( self.add_0x(to), from_address=self.add_0x(_from if _from else self._from), value=value, data=self.add_0x(data), gas=self.gas, gas_price=self.gas_price) result = translator.decode( name, decode(self.strip_0x(response['result']), 'hex')) result = result if len(result) > 1 else result[0] if label: self.references[label] = result if assertion: expected_result = self.replace_references(assertion) if isinstance(expected_result, int) or isinstance( expected_result, long): assert result == expected_result else: assert result.lower() == self.strip_0x(expected_result.lower()) self.log('Assertion of {} at {} successful'.format( name, self.format_reference(reference))) else: self.log('Call to {} calling function {} successful'.format( self.format_reference(reference), name))
def do_transaction(json_rpc, coinbase, contract, name, params, gas, gas_price, private_key): contract_address = addresses[ contract] if contract in addresses else contract contract_abi = abis[contract] translator = ContractTranslator(contract_abi) data = translator.encode(name, [ addresses[param] if param in addresses else param for param in params ]).encode("hex") print 'Try to send {} transaction to contract {}.'.format(name, contract) if private_key: address = privtoaddr(private_key.decode('hex')) nonce = int( json_rpc.eth_getTransactionCount('0x' + address.encode('hex')) ["result"][2:], 16) tx = Transaction(nonce, gas_price, gas, contract_address, 0, data.decode('hex')) tx.sign(private_key.decode('hex')) raw_tx = rlp.encode(tx).encode('hex') transaction_hash = json_rpc.eth_sendRawTransaction("0x" + raw_tx)["result"] else: transaction_hash = json_rpc.eth_sendTransaction( coinbase, to_address=contract_address, data=data, gas=gas, gas_price=gas_price)["result"] wait_for_transaction_receipt(json_rpc, transaction_hash) print 'Transaction {} for contract {} completed.'.format(name, contract)
def do_assertion(json_rpc, contract, name, params, return_value): contract_address = addresses[ contract] if contract in addresses else contract return_value = addresses[ return_value] if return_value in addresses else return_value contract_abi = abis[contract] translator = ContractTranslator(contract_abi) data = translator.encode(name, [ addresses[param] if param in addresses else param for param in params ]).encode("hex") print 'Try to assert return value of {} in contract {}.'.format( name, contract) bc_return_val = json_rpc.eth_call(to_address=contract_address, data=data)["result"] result_decoded = translator.decode(name, bc_return_val[2:].decode("hex")) result_decoded = result_decoded if len( result_decoded) > 1 else result_decoded[0] assert result_decoded == return_value[2:]
def send_transaction(self, _from, to, value, name, params, abi): reference = to to = self.replace_references(to) data = '' if name or abi: if not name: name = abi['name'] abi = self.abis[to] if to in self.abis else [abi] translator = ContractTranslator(abi) data = encode( translator.encode(name, self.replace_references(params)), "hex") self.log('Transaction to {}{} sent'.format( self.format_reference(reference), ' calling {} function'.format(name) if name else '')) tx_response = None if self.private_key: raw_tx = self.get_raw_transaction(to=to, value=value, data=data) while tx_response is None or 'error' in tx_response: if tx_response and 'error' in tx_response: self.log('Transaction failed with error {}'.format( tx_response['error']['message'])) time.sleep(5) tx_response = self.json_rpc.eth_sendRawTransaction(raw_tx) else: while tx_response is None or 'error' in tx_response: if tx_response and 'error' in tx_response: self.log('Transaction failed with error {}'.format( tx_response['error']['message'])) time.sleep(5) tx_response = self.json_rpc.eth_sendTransaction( self.add_0x(_from if _from else self._from), to_address=self.add_0x(to), value=value, data=self.add_0x(data), gas=self.gas, gas_price=self.gas_price) transaction_hash = tx_response['result'] transaction_receipt = self.wait_for_transaction_receipt( self.add_0x(transaction_hash)) self.log('Transaction to {}{} successful'.format( self.format_reference(reference), ' calling {} function'.format(name) if name else '')) self.log_transaction_receipt(transaction_receipt)
def assert_call(self, contract, name, params, return_value): contract_address = self.replace_address(contract) return_value = self.replace_address(return_value) contract_abi = self.contract_abis[contract] translator = ContractTranslator(contract_abi) data = translator.encode(name, [self.replace_address(p) for p in params]).encode("hex") logging.info('Try to assert return value of {} in contract {}.'.format( name, contract)) bc_return_val = self.json_rpc.eth_call(to_address=contract_address, data=data)["result"] result_decoded = translator.decode(name, bc_return_val[2:].decode("hex")) result_decoded = result_decoded if len( result_decoded) > 1 else result_decoded[0] assert result_decoded == return_value logging.info( 'Assertion successful for return value of {} in contract {}.'. format(name, contract))
def setup(host, port, contract, gas, gas_price, private_key): gas = int(gas) gas_price = int(gas_price) json_rpc = EthJsonRpc(host, port) coinbase = json_rpc.eth_coinbase()["result"] if private_key: print "Your address for your private key: {}".format( privtoaddr(private_key.decode('hex')).encode('hex')) else: print "Your coinbase: {}".format(coinbase) contract_abi = json.loads( '[{"inputs": [], "constant": true, "type": "function", "name": "startDate", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "CROWDFUNDING_PERIOD", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "emergencyCall", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [{"type": "address", "name": "singularDTVFundAddress"}, {"type": "address", "name": "singularDTVTokenAddress"}], "constant": false, "type": "function", "name": "setup", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "withdrawFunding", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "fundBalance", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "singularDTVFund", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "baseValue", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "TOKEN_TARGET", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "singularDTVToken", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "owner", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [{"type": "uint256", "name": "valueInWei"}], "constant": false, "type": "function", "name": "changeBaseValue", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [{"type": "address", "name": ""}], "constant": true, "type": "function", "name": "investments", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "fund", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "stage", "outputs": [{"type": "uint8", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "updateStage", "outputs": [{"type": "uint8", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "valuePerShare", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "TOKEN_LOCKING_PERIOD", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "campaignEndedSuccessfully", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "workshopWaited2Years", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "CAP", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "withdrawForWorkshop", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "type": "constructor"}]' ) translator = ContractTranslator(contract_abi) data = translator.encode("emergencyCall", ()).encode("hex") bc_return_val = json_rpc.eth_call(to_address=contract, data=data)["result"] result_decoded = translator.decode("emergencyCall", bc_return_val[2:].decode("hex"))[0] if result_decoded: if private_key: address = privtoaddr(private_key.decode('hex')) nonce = int( json_rpc.eth_getTransactionCount('0x' + address.encode('hex')) ["result"][2:], 16) tx = Transaction(nonce, gas_price, gas, contract, 0, data.decode('hex')) tx.sign(private_key.decode('hex')) raw_tx = rlp.encode(tx).encode('hex') transaction_hash = json_rpc.eth_sendRawTransaction( "0x" + raw_tx)["result"] else: transaction_hash = json_rpc.eth_sendTransaction( coinbase, to_address=contract, data=data, gas=gas, gas_price=gas_price)["result"] wait_for_transaction_receipt(json_rpc, transaction_hash) print 'Transaction {} for contract {} completed.'.format( "emergencyCall", contract)
def send_transaction(self, contract, name, params): contract_address = self.replace_address(contract) contract_abi = self.contract_abis[contract] translator = ContractTranslator(contract_abi) data = translator.encode(name, [self.replace_address(p) for p in params]).encode("hex") logging.info('Try to send {} transaction to contract {}.'.format( name, contract)) if self.private_key: raw_tx = self.get_raw_transaction(data, contract_address) tx_response = self.json_rpc.eth_sendRawTransaction("0x" + raw_tx) while 'error' in tx_response: logging.info('Transaction failed with error {}. Retry!'.format( tx_response['error'])) time.sleep(5) tx_response = self.json_rpc.eth_sendRawTransaction("0x" + raw_tx) else: tx_response = self.json_rpc.eth_sendTransaction( self.user_address, to_address=contract_address, data=data, gas=self.gas, gas_price=self.gas_price) while 'error' in tx_response: logging.info('Transaction failed with error {}. Retry!'.format( tx_response['error'])) time.sleep(5) tx_response = self.json_rpc.eth_sendTransaction( self.user_address, to_address=contract_address, data=data, gas=self.gas, gas_price=self.gas_price) transaction_hash = tx_response['result'] self.wait_for_transaction_receipt(transaction_hash) logging.info('Transaction {} for contract {} completed.'.format( name, contract))
class EthJsonRpc: def __init__(self, host, port, contract_code=None, contract_address=None): self.host = host self.port = port self.contract_code = None self.signature = None self.translation = None self.contract_address = contract_address self.update_code(contract_code) def update_code(self, contract_code): if contract_code: self.contract_code = contract_code self.signature = serpent.mk_full_signature(contract_code) self.translation = ContractTranslator(self.signature) def _call(self, method, params=None, _id=0): if params is None: params = [] data = json.dumps({ 'jsonrpc': '2.0', 'method': method, 'params': params, 'id': _id }) response = requests.post("http://{}:{}".format(self.host, self.port), data=data).json() return response def create_contract(self, contract_code, value=0, from_address=None, gas=0, gas_price=0): self.update_code(contract_code) byte_code = serpent.compile(contract_code) self.contract_address = self.eth_sendTransaction( data=byte_code, value=value, from_address=from_address, gas=gas, gas_price=gas_price) return self.contract_address def eth_sendTransaction(self, to_address=None, function_name=None, data=None, value=0, from_address=None, gas=0, gas_price=0, code=None): """ Creates new message call transaction or a contract creation, if the data field contains code. """ if code: self.update_code(code) else: self.update_code(self.eth_getCode(to_address)) if function_name: if data is None: data = [] data = self.translation.encode(function_name, data) params = { 'from': from_address, 'to': to_address, 'gas': hex(gas) if gas else None, 'gasPrice': hex(gas_price) if gas_price else None, 'value': hex(value) if value else None, 'data': '0x{}'.format(data.encode('hex')) if data else None } return self._call('eth_sendTransaction', [params]) def eth_call(self, to_address, function_name, data=None, code=None, default_block="latest"): """ Executes a new message call immediately without creating a transaction on the block chain. """ if code: self.update_code(code) else: self.update_code(self.eth_getCode(to_address)) if data is None: data = [] data = self.translation.encode(function_name, data) params = [{ 'to': to_address, 'data': '0x{}'.format(data.encode('hex')) }, default_block] response = self._call('eth_call', params) if function_name: response = self.translation.decode(function_name, response[2:].decode('hex')) return response def web3_clientVersion(self): """ Returns the current client version. """ return self._call('web3_clientVersion') def web3_sha3(self, data): """ Returns SHA3 of the given data. """ data = str(data).encode('hex') return self._call('web3_sha3', [data]) def net_version(self): """ Returns the current network protocol version. """ return self._call('net_version') def net_listening(self): """ Returns true if client is actively listening for network connections. """ return self._call('net_listening') def net_peerCount(self): """ Returns number of peers currenly connected to the client. """ return self._call('net_peerCount') def eth_version(self): """ Returns the current ethereum protocol version. """ return self._call('eth_version') def eth_coinbase(self): """ Returns the client coinbase address. """ return self._call('eth_coinbase') def eth_mining(self): """ Returns true if client is actively mining new blocks. """ return self._call('eth_mining') def eth_gasPrice(self): """ Returns the current price per gas in wei. """ return self._call('eth_gasPrice') def eth_accounts(self): """ Returns a list of addresses owned by client. """ return self._call('eth_accounts') def eth_blockNumber(self): """ Returns the number of most recent block. """ return self._call('eth_blockNumber') def eth_getBalance(self, address, default_block="latest"): """ Returns the balance of the account of given address. """ return self._call('eth_getBalance', [address, default_block]) def eth_getStorageAt(self, address, position, default_block="latest"): """ Returns the value from a storage position at a given address. """ return self._call('eth_getStorageAt', [address, hex(position), default_block]) def eth_getTransactionCount(self, address, default_block="latest"): """ Returns the number of transactions send from a address. """ return self._call('eth_getTransactionCount', [address, default_block]) def eth_getBlockTransactionCountByHash(self, block_hash): """ Returns the number of transactions in a block from a block matching the given block hash. """ return self._call('eth_getTransactionCount', [block_hash]) def eth_getBlockTransactionCountByNumber(self, block_number): """ Returns the number of transactions in a block from a block matching the given block number. """ return self._call('eth_getBlockTransactionCountByNumber', [hex(block_number)]) def eth_getUncleCountByblockHash(self, block_hash): """ Returns the number of uncles in a block from a block matching the given block hash. """ return self._call('eth_getUncleCountByblockHash', [block_hash]) def eth_getUncleCountByblockNumber(self, block_number): """ Returns the number of uncles in a block from a block matching the given block number. """ return self._call('eth_getUncleCountByblockNumber', [hex(block_number)]) def eth_getCode(self, address, default_block="latest"): """ Returns code at a given address. """ return self._call('eth_getCode', [address, default_block]) def eth_getBlockByHash(self, block_hash, transaction_objects=True): """ Returns information about a block by hash. """ return self._call('eth_getBlockByHash', [block_hash, transaction_objects]) def eth_flush(self): """ """ return self._call('eth_flush') def eth_getBlockByNumber(self, block_number, transaction_objects=True): """ Returns information about a block by hash. """ return self._call('eth_getBlockByNumber', [block_number, transaction_objects]) def eth_getTransactionByHash(self, transaction_hash): """ Returns the information about a transaction requested by transaction hash. """ return self._call('eth_getTransactionByHash', [transaction_hash]) def eth_getTransactionByblockHashAndIndex(self, block_hash, index): """ Returns information about a transaction by block hash and transaction index position. """ return self._call('eth_getTransactionByblock_hashAndIndex', [block_hash, hex(index)]) def eth_getTransactionByblockNumberAndIndex(self, block_number, index): """ Returns information about a transaction by block number and transaction index position. """ return self._call('eth_getTransactionByblock_numberAndIndex', [block_number, hex(index)]) def eth_getUncleByblockHashAndIndex(self, block_hash, index, transaction_objects=True): """ Returns information about a uncle of a block by hash and uncle index position. """ return self._call( 'eth_getUncleByblock_hashAndIndex', [block_hash, hex(index), transaction_objects]) def eth_getUncleByblockNumberAndIndex(self, block_number, index, transaction_objects=True): """ Returns information about a uncle of a block by number and uncle index position. """ return self._call( 'eth_getUncleByblock_numberAndIndex', [block_number, hex(index), transaction_objects]) def eth_getCompilers(self): """ Returns a list of available compilers in the client. """ return self._call('eth_getCompilers') def eth_compileSolidity(self, code): """ Returns compiled solidity code. """ return self._call('eth_compileSolidity', [code]) def eth_compileLLL(self, code): """ Returns compiled LLL code. """ return self._call('eth_compileLLL', [code]) def eth_compileSerpent(self, code): """ Returns compiled serpent code. """ return self._call('eth_compileSerpent', [code]) def eth_newFilter(self, from_block="latest", to_block="latest", address=None, topics=None): """ Creates a filter object, based on filter options, to notify when the state changes (logs). To check if the state has changed, call eth_getFilterChanges. """ _filter = { 'fromBlock': from_block, 'toBlock': to_block, 'address': address, 'topics': topics } return self._call('eth_newFilter', [_filter]) def eth_newBlockFilter(self, default_block="latest"): """ Creates a filter object, based on an option string, to notify when state changes (logs). To check if the state has changed, call eth_getFilterChanges. """ return self._call('eth_newBlockFilter', [default_block]) def eth_uninstallFilter(self, filter_id): """ Uninstalls a filter with given id. Should always be called when watch is no longer needed. Additonally Filters timeout when they aren't requested with eth_getFilterChanges for a period of time. """ return self._call('eth_uninstallFilter', [hex(filter_id)]) def eth_getFilterChanges(self, filter_id): """ Polling method for a filter, which returns an array of logs which occurred since last poll. """ return self._call('eth_getFilterChanges', [hex(filter_id)]) def eth_getFilterLogs(self, filter_id): """ Returns an array of all logs matching filter with given id. """ return self._call('eth_getFilterLogs', [hex(filter_id)]) def eth_getLogs(self, filter_object): """ Returns an array of all logs matching a given filter object. """ return self._call('eth_getLogs', [filter_object]) def eth_getWork(self): """ Returns the hash of the current block, the seedHash, and the difficulty to be met. """ return self._call('eth_getWork') def eth_submitWork(self, nonce, header, mix_digest): """ Used for submitting a proof-of-work solution. """ return self._call('eth_submitWork', [nonce, header, mix_digest]) def db_putString(self, database_name, key_name, string): """ Stores a string in the local database. """ return self._call('db_putString', [database_name, key_name, string]) def db_getString(self, database_name, key_name): """ Stores a string in the local database. """ return self._call('db_getString', [database_name, key_name]) def db_putHex(self, database_name, key_name, string): """ Stores binary data in the local database. """ return self._call('db_putHex', [database_name, key_name, string.encode('hex')]) def db_getHex(self, database_name, key_name): """ Returns binary data from the local database. """ return self._call('db_getString', [database_name, key_name]).decode('hex') def shh_version(self): """ Returns the current whisper protocol version. """ return self._call('shh_version') def shh_post(self, topics, payload, priority, ttl, _from=None, to=None): """ Sends a whisper message. """ whisper_object = { 'from': _from, 'to': to, 'topics': topics, 'payload': payload, 'priority': priority, 'ttl': ttl } return self._call('shh_post', [whisper_object]) def shh_newIdentinty(self): """ Creates new whisper identity in the client. """ return self._call('shh_newIdentinty') def shh_hasIdentity(self, address): """ Checks if the client hold the private keys for a given identity. """ return self._call('shh_hasIdentity', [address]) def shh_newGroup(self): """ """ return self._call('shh_hasIdentity') def shh_addToGroup(self): """ """ return self._call('shh_addToGroup') def shh_newFilter(self, to, topics): """ Creates filter to notify, when client receives whisper message matching the filter options. """ _filter = {'to': to, 'topics': topics} return self._call('shh_newFilter', [_filter]) def shh_uninstallFilter(self, filter_id): """ Uninstalls a filter with given id. Should always be called when watch is no longer needed. Additonally Filters timeout when they aren't requested with shh_getFilterChanges for a period of time. """ return self._call('shh_uninstallFilter', [hex(filter_id)]) def shh_getFilterChanges(self, filter_id): """ Polling method for whisper filters. """ return self._call('shh_getFilterChanges', [hex(filter_id)]) def shh_getMessages(self, filter_id): """ Get all messages matching a filter, which are still existing in the node. """ return self._call('shh_getMessages', [hex(filter_id)])
class EthJsonRpc(object): DEFAULT_GAS_FOR_TRANSACTIONS = 500000 DEFAULT_GAS_PRICE = 10 * 10 ** 12 # 10 szabo def __init__( self, host="localhost", port=GETH_DEFAULT_RPC_PORT, tls=False, contract_code=None, contract_address=None ): self.host = host self.port = port self.tls = tls self.contract_code = None self.signature = None self.translation = None self.contract_address = contract_address self.update_code(contract_code) self.compilers = {} try: import serpent self.compilers["serpent"] = serpent.compile self.compilers["lll"] = serpent.compile_lll except ImportError: print '[WARNING] Could not import module "serpent". Compiler will not be available.' try: import solidity self.compilers["solidity"] = solidity.compile except ImportError: try: from ethereum._solidity import solc_wrapper self.compilers["solidity"] = solc_wrapper.compile except ImportError: print '[WARNING] Could not import module "solidity" or "solc_wrapper". Compiler will not be available.' def update_code(self, contract_code): if contract_code: self.contract_code = contract_code self.signature = serpent.mk_full_signature(contract_code) self.translation = ContractTranslator(self.signature) def _call(self, method, params=None, _id=0): params = params or [] data = json.dumps({"jsonrpc": "2.0", "method": method, "params": params, "id": _id}) scheme = "http" if self.tls: scheme += "s" url = "{}://{}:{}".format(scheme, self.host, self.port) response = requests.post(url, data=data).json() if "result" in response: return response["result"] else: raise RuntimeError("Error from RPC call. Returned payload: {0}".format(response)) 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 def _install_contract(self, language, contract_code, value=0, from_address=None, gas=None, gas_price=None): byte_code = self.compilers[language](contract_code) return self.eth_sendTransaction( data=byte_code, value=value, from_address=from_address, gas=gas, gas_price=gas_price ) def install_solidity_contract(self, contract_code, value=0, from_address=None, gas=None, gas_price=None): """ Installs a solidity contract into ethereum node """ return self._install_contract("solidity", contract_code, value, from_address, gas, gas_price) def install_serpent_contract(self, contract_code, value=0, from_address=None, gas=None, gas_price=None): """ Installs a serpent contract into ethereum node """ return self._install_contract("serpent", contract_code, value, from_address, gas, gas_price) def install_lll_contract(self, contract_code, value=0, from_address=None, gas=None, gas_price=None): """ Installs a lll contract into ethereum node """ return self._install_contract("lll", contract_code, value, from_address, gas, gas_price) def contract_instant_call( self, to_address, function_signature, function_parameters=None, result_types=None, default_block=BLOCK_TAG_LATEST, ): """ This method makes a instant call on a contract function without the need to have the contract source code. Examples of function_signature in solidity: mult(uint x, uint y) => sig: mult(uint256,uint256) (all uint should be transformed to uint256) setAddress(address entity_address) => sig:setAddress(address) doSomething() => sig: doSomething() (functions with no parameters must end with the '()') In serpent, all functions parameter signatures are int256. Example: setXYZ(x, y, z) => sig: setXYZ(int256,int256,int256) """ data = self._encode_function(function_signature, function_parameters) params = [{"to": to_address, "data": "0x{0}".format(data.encode("hex"))}, default_block] response = self._call("eth_call", params) return decode_abi(result_types, response[2:].decode("hex")) def contract_transaction_call( self, to_address, function_signature, function_parameters=None, from_address=None, gas=None, gas_price=None, default_block=BLOCK_TAG_LATEST, ): """ This method makes a call on a contract function through a transaction. Returns the transaction_id. Examples of function_signature in solidity: mult(uint x, uint y) => sig: mult(uint256,uint256) (all uint should be transformed to uint256) setAddress(address entity_address) => sig:setAddress(address) doSomething() => sig: doSomething() (functions with no parameters must end with the '()') In serpent, all functions parameter signatures are int256. Example: setXYZ(x, y, z) => sig: setXYZ(int256,int256,int256) """ # Default values for gas and gas_price gas = gas or self.DEFAULT_GAS_FOR_TRANSACTIONS gas_price = gas_price or self.DEFAULT_GAS_PRICE # Default value for from_address from_address = from_address or self.eth_accounts()[0] data = self._encode_function(function_signature, function_parameters) params = { "from": from_address, "to": to_address, "gas": "0x{0:x}".format(gas), "gasPrice": "0x{0:x}".format(gas_price), "value": None, "data": "0x{0}".format(data.encode("hex")) if data else None, } response = self._call("eth_sendTransaction", [params]) return response def create_contract(self, contract_code, value=0, from_address=None, gas=None, gas_price=None): self.update_code(contract_code) byte_code = serpent.compile(contract_code) self.contract_address = self.eth_sendTransaction( data=byte_code, value=value, from_address=from_address, gas=gas, gas_price=gas_price ) return self.contract_address ################################################################################ def web3_clientVersion(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#web3_clientversion TESTED """ return self._call("web3_clientVersion") def web3_sha3(self, data): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#web3_sha3 """ data = str(data).encode("hex") return self._call("web3_sha3", [data]) def net_version(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#net_version TESTED """ return self._call("net_version") def net_peerCount(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#net_peercount TESTED """ return hex_to_int(self._call("net_peerCount")) def net_listening(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#net_listening TESTED """ return self._call("net_listening") def eth_protocolVersion(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_protocolversion TESTED """ return self._call("eth_protocolVersion") def eth_coinbase(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_coinbase TESTED """ return self._call("eth_coinbase") def eth_mining(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_mining TESTED """ return self._call("eth_mining") def eth_hashrate(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_hashrate TESTED """ return hex_to_int(self._call("eth_hashrate")) def eth_gasPrice(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gasprice TESTED """ return hex_to_int(self._call("eth_gasPrice")) def eth_accounts(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_accounts TESTED """ return self._call("eth_accounts") def eth_blockNumber(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_blocknumber TESTED """ return hex_to_int(self._call("eth_blockNumber")) def eth_getBalance(self, address=None, default_block=BLOCK_TAG_LATEST): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getbalance """ if isinstance(default_block, basestring): if default_block not in BLOCK_TAGS: raise ValueError address = address or self.eth_coinbase() return self._call("eth_getBalance", [address, default_block]) def eth_getStorageAt(self, address, position, default_block=BLOCK_TAG_LATEST): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getstorageat """ if isinstance(default_block, basestring): if default_block not in BLOCK_TAGS: raise ValueError return self._call("eth_getStorageAt", [address, hex(position), default_block]) def eth_getTransactionCount(self, address, block=BLOCK_TAG_LATEST): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactioncount TESTED """ block = validate_block(block) return hex_to_int(self._call("eth_getTransactionCount", [address, block])) def eth_getBlockTransactionCountByHash(self, block_hash): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblocktransactioncountbyhash TESTED """ return hex_to_int(self._call("eth_getBlockTransactionCountByHash", [block_hash])) def eth_getBlockTransactionCountByNumber(self, block=BLOCK_TAG_LATEST): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblocktransactioncountbynumber TESTED """ block = validate_block(block) return hex_to_int(self._call("eth_getBlockTransactionCountByNumber", [block])) def eth_getUncleCountByBlockHash(self, block_hash): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getunclecountbyblockhash TESTED """ return hex_to_int(self._call("eth_getUncleCountByBlockHash", [block_hash])) def eth_getUncleCountByBlockNumber(self, block=BLOCK_TAG_LATEST): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getunclecountbyblocknumber TESTED """ block = validate_block(block) return hex_to_int(self._call("eth_getUncleCountByBlockNumber", [block])) def eth_getCode(self, address, default_block=BLOCK_TAG_LATEST): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getcode """ if isinstance(default_block, basestring): if default_block not in BLOCK_TAGS: raise ValueError return self._call("eth_getCode", [address, default_block]) def eth_sign(self, address, data): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign """ return self._call("eth_sign", [address, data]) def eth_sendTransaction( self, to_address=None, function_name=None, data=None, value=0, from_address=None, gas=None, gas_price=None ): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction """ # Default values for gas and gas_price gas = gas or self.DEFAULT_GAS_FOR_TRANSACTIONS gas_price = gas_price or self.DEFAULT_GAS_PRICE # Default value for from_address from_address = from_address or self.eth_accounts()[0] if function_name: if data is None: data = [] data = self.translation.encode(function_name, data) params = { "from": from_address, "to": to_address, "gas": "0x{0:x}".format(gas), "gasPrice": "0x{0:x}".format(gas_price), "value": "0x{0:x}".format(value) if value else None, "data": "0x{0}".format(data.encode("hex")) if data else None, } return self._call("eth_sendTransaction", [params]) def eth_call(self, to_address, function_name, data=None, code=None, default_block=BLOCK_TAG_LATEST): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_call """ if isinstance(default_block, basestring): if default_block not in BLOCK_TAGS: raise ValueError data = data or [] data = self.translation.encode(function_name, data) params = [{"to": to_address, "data": "0x{0}".format(data.encode("hex"))}, default_block] response = self._call("eth_call", params) if function_name: response = self.translation.decode(function_name, response[2:].decode("hex")) return response def eth_estimateGas(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_estimategas """ return self._call("eth_estimateGas") def eth_getBlockByHash(self, block_hash, tx_objects=True): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbyhash TESTED """ return self._call("eth_getBlockByHash", [block_hash, tx_objects]) def eth_getBlockByNumber(self, block=BLOCK_TAG_LATEST, tx_objects=True): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbynumber TESTED """ block = validate_block(block) return self._call("eth_getBlockByNumber", [block, tx_objects]) def eth_getTransactionByHash(self, tx_hash): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyhash TESTED """ return self._call("eth_getTransactionByHash", [tx_hash]) def eth_getTransactionByBlockHashAndIndex(self, block_hash, index): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyblockhashandindex """ return self._call("eth_getTransactionByBlockHashAndIndex", [block_hash, hex(index)]) def eth_getTransactionByBlockNumberAndIndex(self, block_number, index): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionbyblocknumberandindex """ return self._call("eth_getTransactionByBlockNumberAndIndex", [block_number, hex(index)]) def eth_getTransactionReceipt(self, tx_hash): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionreceipt """ return self._call("eth_getTransactionReceipt", [tx_hash]) def eth_getUncleByBlockHashAndIndex(self, block_hash, index, transaction_objects=True): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getunclebyblockhashandindex """ return self._call("eth_getUncleByBlockHashAndIndex", [block_hash, hex(index), transaction_objects]) def eth_getUncleByBlockNumberAndIndex(self, block_number, index, transaction_objects=True): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getunclebyblocknumberandindex """ return self._call("eth_getUncleByBlockNumberAndIndex", [block_number, hex(index), transaction_objects]) def eth_getCompilers(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getcompilers TESTED """ return self._call("eth_getCompilers") def eth_compileLLL(self, code): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compilelll """ return self._call("eth_compileLLL", [code]) def eth_compileSolidity(self, code): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compilesolidity """ return self._call("eth_compileSolidity", [code]) def eth_compileSerpent(self, code): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_compileserpent """ return self._call("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 """ _filter = {"fromBlock": from_block, "toBlock": to_block, "address": address, "topics": topics} return self._call("eth_newFilter", [_filter]) def eth_newBlockFilter(self, default_block=BLOCK_TAG_LATEST): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newblockfilter """ return self._call("eth_newBlockFilter", [default_block]) def eth_newPendingTransactionFilter(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newpendingtransactionfilter TESTED """ return hex_to_int(self._call("eth_newPendingTransactionFilter")) def eth_uninstallFilter(self, filter_id): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_uninstallfilter """ return self._call("eth_uninstallFilter", [filter_id]) def eth_getFilterChanges(self, filter_id): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterchanges """ return self._call("eth_getFilterChanges", [filter_id]) def eth_getFilterLogs(self, filter_id): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getfilterlogs """ return self._call("eth_getFilterLogs", [filter_id]) def eth_getLogs(self, filter_object): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs """ return self._call("eth_getLogs", [filter_object]) def eth_getWork(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getwork TESTED """ return self._call("eth_getWork") def eth_submitWork(self, nonce, header, mix_digest): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_submitwork """ return self._call("eth_submitWork", [nonce, header, mix_digest]) def eth_submitHashrate(self, hash_rate, client_id): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_submithashrate """ return self._call("eth_submitHashrate", [hash_rate, client_id]) def db_putString(self, db_name, key, value): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#db_putstring TESTED """ warnings.warn("deprecated", DeprecationWarning) return self._call("db_putString", [db_name, key, value]) def db_getString(self, db_name, key): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#db_getstring TESTED """ warnings.warn("deprecated", DeprecationWarning) return self._call("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._call("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._call("db_getHex", [db_name, key]) def shh_post(self, topics, payload, priority, ttl, _from=None, to=None): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_post """ 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_version(self): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_version N/A """ return self._call("shh_version") 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 """ 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 """ return self._call("shh_addToGroup") def shh_newFilter(self, to, topics): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_newfilter """ _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 """ return self._call("shh_uninstallFilter", [filter_id]) def shh_getFilterChanges(self, filter_id): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_getfilterchanges """ return self._call("shh_getFilterChanges", [filter_id]) def shh_getMessages(self, filter_id): """ https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_getmessages """ return self._call("shh_getMessages", [filter_id])
from ethereum import transactions as t from ethereum.abi import ContractTranslator from ethereum._solidity import get_solidity import rlp solidity = get_solidity() key = '7942db5f27595d040231a44b95de331d45eaa78cfa3f21663c95d4bbc97afbe4' addr = 'ce7fb4c38949d7c09bd95197c3981ec8bb0638e5' args, kwargs = [], {} i = 0 while i < len(sys.argv): if sys.argv[i][:2] == '--': kwargs[sys.argv[i][2:]] = sys.argv[i+1] i += 2 else: args.append(sys.argv[i]) i += 1 adStorer_abi = solidity.mk_full_signature(open('one_phase_auction.sol').read() + open('two_phase_auction.sol').read() + open('adStorer.sol').read(), contract_name='adStorer') ct = ContractTranslator(adStorer_abi) nonce = int(kwargs['nonce']) data = ct.encode('initialize', [240, 240, 240, 120, 50, 10]) o = '[' for i in range(8): tx = t.Transaction(nonce, 60 * 10**9, 2500000, kwargs['address'], 0, data) o += '"0x' + rlp.encode(tx.sign(key)).encode('hex') + '",' nonce += 1 print o[:-1] + ']'
class EthJsonRpc: def __init__(self, host, port, contract_code=None, contract_address=None): self.host = host self.port = port self.contract_code = None self.signature = None self.translation = None self.contract_address = contract_address self.update_code(contract_code) def update_code(self, contract_code): if contract_code: self.contract_code = contract_code self.signature = serpent.mk_full_signature(contract_code) self.translation = ContractTranslator(self.signature) def _call(self, method, params=None, _id=0): if params is None: params = [] data = json.dumps({ 'jsonrpc': '2.0', 'method': method, 'params': params, 'id': _id }) response = requests.post("http://{}:{}".format(self.host, self.port), data=data).json() return response def create_contract(self, contract_code, value=0, from_address=None, gas=0, gas_price=0): self.update_code(contract_code) byte_code = serpent.compile(contract_code) self.contract_address = self.eth_sendTransaction(data=byte_code, value=value, from_address=from_address, gas=gas, gas_price=gas_price) return self.contract_address def eth_sendTransaction(self, to_address=None, function_name=None, data=None, value=0, from_address=None, gas=0, gas_price=0, code=None): """ Creates new message call transaction or a contract creation, if the data field contains code. """ if code: self.update_code(code) else: self.update_code(self.eth_getCode(to_address)) if function_name: if data is None: data = [] data = self.translation.encode(function_name, data) params = { 'from': from_address, 'to': to_address, 'gas': hex(gas) if gas else None, 'gasPrice': hex(gas_price) if gas_price else None, 'value': hex(value) if value else None, 'data': '0x{}'.format(data.encode('hex')) if data else None } return self._call('eth_sendTransaction', [params]) def eth_call(self, to_address, function_name, data=None, code=None, default_block="latest"): """ Executes a new message call immediately without creating a transaction on the block chain. """ if code: self.update_code(code) else: self.update_code(self.eth_getCode(to_address)) if data is None: data = [] data = self.translation.encode(function_name, data) params = [ { 'to': to_address, 'data': '0x{}'.format(data.encode('hex')) }, default_block ] response = self._call('eth_call', params) if function_name: response = self.translation.decode(function_name, response[2:].decode('hex')) return response def web3_clientVersion(self): """ Returns the current client version. """ return self._call('web3_clientVersion') def web3_sha3(self, data): """ Returns SHA3 of the given data. """ data = str(data).encode('hex') return self._call('web3_sha3', [data]) def net_version(self): """ Returns the current network protocol version. """ return self._call('net_version') def net_listening(self): """ Returns true if client is actively listening for network connections. """ return self._call('net_listening') def net_peerCount(self): """ Returns number of peers currenly connected to the client. """ return self._call('net_peerCount') def eth_version(self): """ Returns the current ethereum protocol version. """ return self._call('eth_version') def eth_coinbase(self): """ Returns the client coinbase address. """ return self._call('eth_coinbase') def eth_mining(self): """ Returns true if client is actively mining new blocks. """ return self._call('eth_mining') def eth_gasPrice(self): """ Returns the current price per gas in wei. """ return self._call('eth_gasPrice') def eth_accounts(self): """ Returns a list of addresses owned by client. """ return self._call('eth_accounts') def eth_blockNumber(self): """ Returns the number of most recent block. """ return self._call('eth_blockNumber') def eth_getBalance(self, address, default_block="latest"): """ Returns the balance of the account of given address. """ return self._call('eth_getBalance', [address, default_block]) def eth_getStorageAt(self, address, position, default_block="latest"): """ Returns the value from a storage position at a given address. """ return self._call('eth_getStorageAt', [address, hex(position), default_block]) def eth_getTransactionCount(self, address, default_block="latest"): """ Returns the number of transactions send from a address. """ return self._call('eth_getTransactionCount', [address, default_block]) def eth_getBlockTransactionCountByHash(self, block_hash): """ Returns the number of transactions in a block from a block matching the given block hash. """ return self._call('eth_getTransactionCount', [block_hash]) def eth_getBlockTransactionCountByNumber(self, block_number): """ Returns the number of transactions in a block from a block matching the given block number. """ return self._call('eth_getBlockTransactionCountByNumber', [hex(block_number)]) def eth_getUncleCountByblockHash(self, block_hash): """ Returns the number of uncles in a block from a block matching the given block hash. """ return self._call('eth_getUncleCountByblockHash', [block_hash]) def eth_getUncleCountByblockNumber(self, block_number): """ Returns the number of uncles in a block from a block matching the given block number. """ return self._call('eth_getUncleCountByblockNumber', [hex(block_number)]) def eth_getCode(self, address, default_block="latest"): """ Returns code at a given address. """ return self._call('eth_getCode', [address, default_block]) def eth_getBlockByHash(self, block_hash, transaction_objects=True): """ Returns information about a block by hash. """ return self._call('eth_getBlockByHash', [block_hash, transaction_objects]) def eth_flush(self): """ """ return self._call('eth_flush') def eth_getBlockByNumber(self, block_number, transaction_objects=True): """ Returns information about a block by hash. """ return self._call('eth_getBlockByNumber', [block_number, transaction_objects]) def eth_getTransactionByHash(self, transaction_hash): """ Returns the information about a transaction requested by transaction hash. """ return self._call('eth_getTransactionByHash', [transaction_hash]) def eth_getTransactionByblockHashAndIndex(self, block_hash, index): """ Returns information about a transaction by block hash and transaction index position. """ return self._call('eth_getTransactionByblock_hashAndIndex', [block_hash, hex(index)]) def eth_getTransactionByblockNumberAndIndex(self, block_number, index): """ Returns information about a transaction by block number and transaction index position. """ return self._call('eth_getTransactionByblock_numberAndIndex', [block_number, hex(index)]) def eth_getUncleByblockHashAndIndex(self, block_hash, index, transaction_objects=True): """ Returns information about a uncle of a block by hash and uncle index position. """ return self._call('eth_getUncleByblock_hashAndIndex', [block_hash, hex(index), transaction_objects]) def eth_getUncleByblockNumberAndIndex(self, block_number, index, transaction_objects=True): """ Returns information about a uncle of a block by number and uncle index position. """ return self._call('eth_getUncleByblock_numberAndIndex', [block_number, hex(index), transaction_objects]) def eth_getCompilers(self): """ Returns a list of available compilers in the client. """ return self._call('eth_getCompilers') def eth_compileSolidity(self, code): """ Returns compiled solidity code. """ return self._call('eth_compileSolidity', [code]) def eth_compileLLL(self, code): """ Returns compiled LLL code. """ return self._call('eth_compileLLL', [code]) def eth_compileSerpent(self, code): """ Returns compiled serpent code. """ return self._call('eth_compileSerpent', [code]) def eth_newFilter(self, from_block="latest", to_block="latest", address=None, topics=None): """ Creates a filter object, based on filter options, to notify when the state changes (logs). To check if the state has changed, call eth_getFilterChanges. """ _filter = { 'fromBlock': from_block, 'toBlock': to_block, 'address': address, 'topics': topics } return self._call('eth_newFilter', [_filter]) def eth_newBlockFilter(self, default_block="latest"): """ Creates a filter object, based on an option string, to notify when state changes (logs). To check if the state has changed, call eth_getFilterChanges. """ return self._call('eth_newBlockFilter', [default_block]) def eth_uninstallFilter(self, filter_id): """ Uninstalls a filter with given id. Should always be called when watch is no longer needed. Additonally Filters timeout when they aren't requested with eth_getFilterChanges for a period of time. """ return self._call('eth_uninstallFilter', [hex(filter_id)]) def eth_getFilterChanges(self, filter_id): """ Polling method for a filter, which returns an array of logs which occurred since last poll. """ return self._call('eth_getFilterChanges', [hex(filter_id)]) def eth_getFilterLogs(self, filter_id): """ Returns an array of all logs matching filter with given id. """ return self._call('eth_getFilterLogs', [hex(filter_id)]) def eth_getLogs(self, filter_object): """ Returns an array of all logs matching a given filter object. """ return self._call('eth_getLogs', [filter_object]) def eth_getWork(self): """ Returns the hash of the current block, the seedHash, and the difficulty to be met. """ return self._call('eth_getWork') def eth_submitWork(self, nonce, header, mix_digest): """ Used for submitting a proof-of-work solution. """ return self._call('eth_submitWork', [nonce, header, mix_digest]) def db_putString(self, database_name, key_name, string): """ Stores a string in the local database. """ return self._call('db_putString', [database_name, key_name, string]) def db_getString(self, database_name, key_name): """ Stores a string in the local database. """ return self._call('db_getString', [database_name, key_name]) def db_putHex(self, database_name, key_name, string): """ Stores binary data in the local database. """ return self._call('db_putHex', [database_name, key_name, string.encode('hex')]) def db_getHex(self, database_name, key_name): """ Returns binary data from the local database. """ return self._call('db_getString', [database_name, key_name]).decode('hex') def shh_version(self): """ Returns the current whisper protocol version. """ return self._call('shh_version') def shh_post(self, topics, payload, priority, ttl, _from=None, to=None): """ Sends a whisper message. """ whisper_object = { 'from': _from, 'to': to, 'topics': topics, 'payload': payload, 'priority': priority, 'ttl': ttl } return self._call('shh_post', [whisper_object]) def shh_newIdentinty(self): """ Creates new whisper identity in the client. """ return self._call('shh_newIdentinty') def shh_hasIdentity(self, address): """ Checks if the client hold the private keys for a given identity. """ return self._call('shh_hasIdentity', [address]) def shh_newGroup(self): """ """ return self._call('shh_hasIdentity') def shh_addToGroup(self): """ """ return self._call('shh_addToGroup') def shh_newFilter(self, to, topics): """ Creates filter to notify, when client receives whisper message matching the filter options. """ _filter = { 'to': to, 'topics': topics } return self._call('shh_newFilter', [_filter]) def shh_uninstallFilter(self, filter_id): """ Uninstalls a filter with given id. Should always be called when watch is no longer needed. Additonally Filters timeout when they aren't requested with shh_getFilterChanges for a period of time. """ return self._call('shh_uninstallFilter', [hex(filter_id)]) def shh_getFilterChanges(self, filter_id): """ Polling method for whisper filters. """ return self._call('shh_getFilterChanges', [hex(filter_id)]) def shh_getMessages(self, filter_id): """ Get all messages matching a filter, which are still existing in the node. """ return self._call('shh_getMessages', [hex(filter_id)])