Пример #1
0
 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))
Пример #2
0
 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))
Пример #3
0
def call_const_function(priv_key, value, contract_hash, contract_abi,
                        function_name, args):
    src_address = b2h(utils.privtoaddr(priv_key))
    translator = ContractTranslator(contract_abi)
    call = translator.encode_function_call(function_name, args)
    nonce = get_num_transactions(src_address)
    gas_price = get_gas_price_in_wei()

    start_gas = eval_startgas(src_address, contract_hash, value, b2h(call),
                              gas_price)
    nonce = int(nonce, 16)
    gas_price = int(gas_price, 16)
    start_gas = int(start_gas, 16) + 100000

    params = {
        "from": "0x" + src_address,
        "to": "0x" + contract_hash,
        "gas": "0x" + str(start_gas),
        "gasPrice": "0x" + str(gas_price),
        "value": str(value),
        "data": "0x" + b2h(call)
    }

    return_value = json_call("eth_call", [params])
    return_value = h2b(return_value[2:])  # remove 0x
    return translator.decode(function_name, return_value)
Пример #4
0
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:]
Пример #5
0
 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))
Пример #6
0
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)
Пример #7
0
def call_const_function( priv_key, value, contract_hash, contract_abi, function_name, args ):
    src_address = b2h( utils.privtoaddr(priv_key) )    
    translator = ContractTranslator(contract_abi)
    call = translator.encode_function_call(function_name, args)  
    nonce = get_num_transactions( src_address )
    gas_price = get_gas_price_in_wei()
    
    start_gas = eval_startgas( src_address, contract_hash, value, b2h(call), gas_price )    
    nonce = int( nonce, 16 )
    gas_price = int( gas_price, 16 )
    start_gas = int( start_gas, 16 ) + 100000
    
    params = { "from" : "0x" + src_address,
               "to"   : "0x" + contract_hash,
               "gas"  : "0x" + str(start_gas),
               "gasPrice" : "0x" + str(gas_price),
               "value" : str(value),
               "data" : "0x" + b2h(call) }
    
    return_value = json_call( "eth_call", [params])
    return_value = h2b(return_value[2:]) # remove 0x
    return translator.decode(function_name, return_value)
Пример #8
0
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)])
Пример #9
0
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])
Пример #10
0
class Contract(object):
    """A class for interacting with Ethereum contracts."""

    def __init__(self, address: str, interface: Sequence[Mapping],
                 rpc_address: str, sender: str = None, gas: int = MAX_GAS):
        """Create a new Contract instance. Batch requests not supported!

        Arguments:
        address -- The address of the smart contract you want to use.
        interface -- The full signature of the smart contract.
        rpc_address -- The address of the RPC server for your Ethereum node.
        sender -- The address to send from. If None, the default sender for your node is used.
        gas --  The maximum amount of gas to use per transaction/call.
        """
        err_fmt = 'Invalid {} address, must be 40 digit hex starting with \'0x\': {!r}'

        if not ETH_ADDR.match(address):
            raise ContractError(err_fmt.format('contract', address))

        self.translator = ContractTranslator(interface)
        self.rpc_client = rpc_factory(rpc_address, False)
        self.common_params = {'to': address, 'gas': hex(gas)}

        if sender is None:
            pass
        elif ETH_ADDR.match(sender):
            self.common_params['from'] = sender
        else:
            raise ContractError(err_fmt.format('sender', sender))

        def proxy_factory(name):
            # Generates proxy functions that use rpc methods under the hood.
            pyname = name.split('(')[0]  # a python compatible name

            def proxy(*args, **kwds):
                """Calls function {} in contract {}.


                If the optional `call` keyword is True, then the result of the function call
                is decoded into a Python object and returned, otherwise the transaction hash
                is returned.
                """
                tx = self.common_params.copy()
                data = self.translator.encode_function_call(pyname, args)
                tx['data'] = '0x{}'.format(data.encode('hex'))
                if kwds.get('call', False):
                    return self._call(pyname, tx)
                else:
                    return self._send(tx)

            proxy.__name__ = pyname
            proxy.__doc__ = proxy.__doc__.format(name, address)
            return proxy

        for item in interface:
            if item['type'] == 'function':
                proxy = proxy_factory(item['name'])
                if hasattr(self, proxy.__name__):
                    raise ContractError('Polymorphism not supported!')
                setattr(self, proxy.__name__, proxy)

    def _call(self, func_name, tx):
        # Uses call to interact with a contract.
        response = self.rpc_client.eth_call(tx, 'latest')
        self._check_response(response)
        raw_result = response['result'].lstrip('0x').decode('hex')
        return self.translator.decode(func_name, raw_result)

    def _send(self, tx):
        response = self.rpc_client.eth_sendTransaction(tx)
        return response['result']
Пример #11
0
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)])