Ejemplo n.º 1
0
    async def get_block_by_hash(
        self,
        block_id: eth_types.Hash32,
        full: bool = False,
    ) -> Optional[eth_models.Block]:
        """Returns information about a block by hash.

        Calls the eth_getBlockByHash.

        :param block_id: eth_types.Hash32 of a block.
        :param full: If True it returns the full transaction objects, if False
                     only the hashes of the transactions.

        :returns
            Union[eth_models.Block, None]: A block object, or None when no block found.
        """
        data = await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.get_block_by_hash[0],
                id=self.rpc_schema.get_block_by_hash[1],
                params=[
                    eth_utils.to_eth_converters[eth_types.Hash32](block_id),
                    full
                ],
            ))
        return eth_models.Block.parse_obj(data)
Ejemplo n.º 2
0
    async def get_shh_messages(
            self, identifier: int) -> Union[List[eth_models.Message], bool]:
        """Get all messages matching a filter. Unlike shh_getFilterChanges
        this returns all messages.

        Calls shh_getMessages.

        :param identifier: The filter id.

        :returns
            List[eth_models.Messages]: Array of messages received.
            bool: False if no messages.
        """
        result = await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.get_shh_messages[0],
                id=self.rpc_schema.get_shh_messages[1],
                params=[conversions.to_hex(identifier)],
            ))

        truthiness = eth_utils.result_truthiness(result)
        if isinstance(truthiness, bool):
            return truthiness

        return eth_models.iterate_list(eth_models.Message, result)
Ejemplo n.º 3
0
    async def sign(self, address: eth_types.HexAddress,
                   message: eth_types.HexStr) -> eth_types.Data:
        """Returns an signed message.

        sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)))

        By adding a prefix to the message makes the calculated signature recognizable
        as an Ethereum specific signature. This prevents misuse where a malicious
        DApp can sign arbitrary data (e.g. transaction) and use the signature to
        impersonate the victim.

        Note the address to sign with must be unlocked.

        Calls eth_sign.

        TODO(Add tests for this function)

        :param address: address to sign with.
        :param message: hex string of n bytes, message to sign.

        :returns
            eth_types.Data: signature
        """
        return await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.sign[0],
                id=self.rpc_schema.sign[1],
                params=[address, message],
            ))
Ejemplo n.º 4
0
    async def estimate_gas(
        self,
        transaction: eth_models.Transaction,
        block_identifier: eth_types.DefaultBlockIdentifier,
    ) -> int:
        """Returns an estimate of how much gas is necessary to complete the transaction.

        Generates and returns an estimate of how much gas is necessary to allow the
        transaction to complete. The transaction will not be added to the blockchain.
        Note that the estimate may be significantly more than the amount of gas
        actually used by the transaction, for a variety of reasons including EVM
        mechanics and node performance.

        Calls eth_estimateGas.

        :param transaction: eth_models.Transaction call object.
        :param block_identifier: block to call the transaction against.

        :returns
           int: The amount of gas used.
        """
        ret: int = eth_utils.to_py_converters[int](await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.estimate_gas[0],
                id=self.rpc_schema.estimate_gas[1],
                params=[transaction.dict(), block_identifier],
            )))
        return ret
Ejemplo n.º 5
0
    async def get_block_by_number(self,
                                  block_id: eth_types.DefaultBlockIdentifier,
                                  full: bool) -> Optional[eth_models.Block]:
        """Returns information about a block by block number.

        Calls the eth_getBlockByNumber.

        :param block_id: Integer of a block number, or the string
                          "earliest", "latest" or "pending", as in the
                          default block parameter.
        :param full: If true it returns the full transaction objects, if false
                     only the hashes of the transactions.

        :returns
            Union[eth_models.Block, None]: A block object, or None when no block was
                                         found.
        """
        if block_id not in ["pending", "latest", "earliest"]:
            block_id = eth_utils.to_eth_converters[int](block_id)
        return eth_models.Block.parse_obj(await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.get_block_by_number[0],
                id=self.rpc_schema.get_block_by_number[1],
                params=[block_id, full],
            )))
Ejemplo n.º 6
0
    async def get_storage_at(
        self,
        address: eth_types.HexAddress,
        position: int = 0,
        block_identifier: eth_types.DefaultBlockIdentifier = default_block_id,
    ) -> eth_types.Data:
        """Returns storage from position at a given address during block_identifier.

        Calls eth_getStorageAt.

        See: https://eth.wiki/json-rpc/API#eth_getstorageat

        There are some usage examples at that link which are useful.

        eth_utils.keccak and eth-hash are useful here as well.

        :param address: eth_types.Address address of the storage.
        :param position: integer as eth_types.Data of the position in the storage.
        :param block_identifier: eth_types.DefaultBlockIdentifier for the block to
                                 retrieve from.

        :returns eth_types.Data: containing the data at the address, position,
                                 block_identifier.
        """
        return eth_utils.to_py_converters[eth_types.Data](await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.get_storage_at[0],
                id=self.rpc_schema.get_storage_at[1],
                params=[
                    address,
                    eth_utils.to_eth_converters[int](position),
                    block_identifier,
                ],
            )))
Ejemplo n.º 7
0
    async def shh_version(self) -> str:
        """Returns the current whisper protocol version.

        Calls shh_version.

        :returns
            str: The current whisper protocol version.
        """
        return await self.rpc(
            eth_models.JSONRPCRequest(method=self.rpc_schema.shh_version[0],
                                      id=self.rpc_schema.shh_version[1]))
Ejemplo n.º 8
0
    async def gas_price(self) -> int:
        """Returns the current gas price as an integer in wei.

        Calls eth_gasPrice.

        :returns
            int:integer of the current gas price in wei.
        """
        return eth_utils.to_py_converters[int](await self.rpc(
            eth_models.JSONRPCRequest(method=self.rpc_schema.gas_price[0],
                                      id=self.rpc_schema.gas_price[1])))
Ejemplo n.º 9
0
    async def hashrate(self) -> int:
        """Returns the number of hashes per second that the node is mining with.

        Calls eth_hashrate.

        :returns:
            int:Number of hashes per second.
        """
        return eth_utils.to_py_converters[int](await self.rpc(
            eth_models.JSONRPCRequest(method=self.rpc_schema.hashrate[0],
                                      id=self.rpc_schema.mining[1])))
Ejemplo n.º 10
0
    async def network_listening(self) -> bool:
        """Returns true if client is actively listening for network connections.

        Calls net_listening.

        :returns
            bool: True when listening, otherwise False"""
        return await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.network_listening[0],
                id=self.rpc_schema.network_listening[1],
            ))
Ejemplo n.º 11
0
    async def mining(self) -> bool:
        """Returns True if the client is actively mining new blocks.

        Calls eth_mining.

        :returns
            bool: True if the client is mining, otherwise False
        """
        # Why can this RPC actually return a bool?
        return eth_utils.result_truthiness(await self.rpc(
            eth_models.JSONRPCRequest(method=self.rpc_schema.mining[0],
                                      id=self.rpc_schema.mining[1])))
Ejemplo n.º 12
0
    async def protocol_version(self) -> int:
        """Returns the current ethereum protocol version.

        Calls eth_protocolVersion.

        :returns
            int: The current Ethereum protocol version as an Integer."""
        return eth_utils.to_py_converters[int](await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.protocol_version[0],
                id=self.rpc_schema.protocol_version[1],
            )))
Ejemplo n.º 13
0
    async def block_number(self) -> int:
        """Returns the number of most recent block.

        Calls eth_blockNumber.

        :returns
            eth_types.BlockNumber: The current block number a client is on as an int.
        """
        return eth_utils.to_py_converters[int](await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.block_number[0],
                id=self.rpc_schema.block_number[1],
            )))
Ejemplo n.º 14
0
    async def shh_new_group(self) -> eth_types.Data:
        """Create a new whisper group (?).

        Calls shh_newGroup.

        :returns
            eth_types.Data: The address of the new group (60 Bytes).
        """
        return await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.shh_new_group[0],
                id=self.rpc_schema.shh_new_group[1],
            ))
Ejemplo n.º 15
0
    async def client_version(self) -> str:
        """Return the current ethereum client version as a string.

        Calls web3_clientVersion

        :returns
            string: The current client version.
        """
        return await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.client_version[0],
                id=self.rpc_schema.client_version[1],
            ))
Ejemplo n.º 16
0
    async def accounts(self) -> list[eth_types.HexAddress]:
        """Returns a list of addresses owned by the client.

        Calls eth_accounts.

        :returns
            list: A list of eth_types.Address owned by the client.
        """
        result = await self.rpc(
            eth_models.JSONRPCRequest(method=self.rpc_schema.accounts[0],
                                      id=self.rpc_schema.accounts[1]))

        return result or []
Ejemplo n.º 17
0
    async def coinbase(self) -> eth_types.HexAddress:
        """Returns the client coinbase address

        Calls eth_coinbase.

        :returns
            str:The current coinbase address.
        :raises
           :exception JSONRPCError: when this method is not supported.
        """
        return eth_types.HexAddress(await self.rpc(
            eth_models.JSONRPCRequest(method=self.rpc_schema.coinbase[0],
                                      id=self.rpc_schema.coinbase[1])))
Ejemplo n.º 18
0
    async def network_peer_count(self) -> int:
        """Returns number of peers currently connected to the client

        Calls net_peerCount.

        :returns
            int: number of connected peers
        """
        return eth_utils.to_py_converters[int](await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.network_peer_count[0],
                id=self.rpc_schema.network_peer_count[1],
            )))
Ejemplo n.º 19
0
    async def shh_new_identity(self) -> eth_types.Data:
        """Creates new whisper identity in the client.

        Calls shh_newIdentity.

        :returns
            eth_types.Data: The address of the new identity (60 Bytes).
        """
        return await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.shh_new_identity[0],
                id=self.rpc_schema.shh_new_identity[1],
            ))
Ejemplo n.º 20
0
    async def shh_post(self, whisper: eth_models.Message) -> bool:
        """Sends a whisper message.

        Calls shh_post.

        :param whisper: The whisper post object.

        :returns
            bool: Returns true if the message was send, otherwise false.
        """
        return await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.shh_post[0],
                id=self.rpc_schema.shh_post[1],
                params=[whisper.dict()],
            ))
Ejemplo n.º 21
0
    async def sha3(self, data: eth_types.Data) -> eth_types.Data:
        """Returns the Keccak-256 of the given data.

        Consider using eth_utils.sha3 instead to save the round trip.

        :param data: Bytes of eth_types.Data to Keccak-256 hash.

        :returns
            eth_types.Data: Keccak-256 bytes of eth_types.Data
        """
        return eth_utils.to_py_converters[eth_types.Hash32](await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.sha3[0],
                id=self.rpc_schema.sha3[1],
                params=[eth_utils.to_eth_converters[eth_types.Data](data)],
            )))
Ejemplo n.º 22
0
    async def shh_has_identity(self, identifier: eth_types.Data) -> bool:
        """Checks if the client hold the private keys for a given identity.

        Calls shh_hasIdentity.

        :params id: The identity address to check.

        :returns
            bool: Returns true if the message was send, otherwise false.
        """
        return eth_utils.result_truthiness(await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.shh_has_identity[0],
                id=self.rpc_schema.shh_has_identity[1],
                params=[identifier],
            )))
Ejemplo n.º 23
0
    async def network_version(self) -> eth_models.Network:
        """Returns the current network ID.

        Calls net_version.

        :returns
            Network:Enum populated with network ID.
        """
        # noinspection PyArgumentList
        # PyCharm is incorrect here.
        return eth_models.Network(
            int(await self.rpc(
                eth_models.JSONRPCRequest(
                    method=self.rpc_schema.network_version[0],
                    id=self.rpc_schema.network_version[1],
                ))))
Ejemplo n.º 24
0
    async def shh_add_to_group(self, identifier: eth_types.Data) -> bool:
        """Add an identity to a group (?).

        Calls shh_addToGroup.

        :params id: The identity address to add to a group.

        :returns
            bool: Returns true if the identity was successfully added to the
                  group, otherwise false (?).
        """
        return eth_utils.result_truthiness(await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.shh_add_to_group[0],
                id=self.rpc_schema.shh_add_to_group[1],
                params=[identifier],
            )))
Ejemplo n.º 25
0
    async def send_transaction(
            self, transaction: eth_models.Transaction) -> eth_types.HexStr:
        """Creates new message call transaction or a contract creation.

        :param transaction: eth_models.Transaction object to send.

        :returns
           eth_types.HexStr: the transaction hash, or the zero hash if the transaction
                             is not yet available.
        """

        return eth_types.HexStr(await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.send_transaction[0],
                id=self.rpc_schema.send_transaction[1],
                params=[transaction.dict()],
            )))
Ejemplo n.º 26
0
    async def send_raw_transaction(self,
                                   data: eth_types.HexStr) -> eth_types.HexStr:
        """Creates new transaction or a contract creation for signed transactions.

        # TODO(Handle reverted execution)

        :param data: The signed transaction data.

        :returns
           eth_types.HexStr: the transaction hash, or the zero hash if the transaction
                             is not yet available.
        """
        return eth_types.HexStr(await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.send_raw_transaction[0],
                id=self.rpc_schema.send_raw_transaction[1],
                params=[data],
            )))
Ejemplo n.º 27
0
    async def shh_new_filter(self,
                             whisper_filter: eth_models.WhisperFilter) -> int:
        """Creates filter to notify, when client receives whisper message
        matching the filter options.

        Calls shh_newFilter.

        :params filter: The filter options.

        :returns
            int: The newly created filter.
        """
        return eth_utils.conversions.to_int(await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.shh_new_filter[0],
                id=self.rpc_schema.shh_new_filter[1],
                params=[whisper_filter.dict()],
            )))
Ejemplo n.º 28
0
    async def get_uncle_count_by_block_number(
            self, block_identifier: eth_types.DefaultBlockIdentifier) -> int:
        """Returns the number of uncles block matching the given block_identifier.

        Calls eth_getUncleCountByBlockNumber.

        Can raise an exception converting integer if block_identifier is is invalid.

        :param block_identifier: eth_types.DefaultBlockIdentifier of the block.

        :returns
            int: number of uncles in this block.
        """
        return eth_utils.conversions.to_int(hexstr=await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.get_uncle_count_by_block_number[0],
                id=self.rpc_schema.get_uncle_count_by_block_number[1],
                params=[block_identifier],
            )))
Ejemplo n.º 29
0
    async def shh_uninstall_filter(self, identifier: int) -> bool:
        """Uninstalls a filter with given id. Should always be called when
        watch is no longer needed. Additionally, filters timeout when they
        are not requested with shh_getFilterChanges for a period of time.

        Calls shh_uninstallFilter.

        :params id: The filter id.

        :returns
            bool: True if the filter was successfully uninstalled,
                  otherwise false.
        """
        return await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.shh_uninstall_filter[0],
                id=self.rpc_schema.shh_uninstall_filter[1],
                params=[conversions.to_hex(identifier)],
            ))
Ejemplo n.º 30
0
    async def get_code(
        self,
        address: eth_types.HexAddress,
        block_identifier: eth_types.DefaultBlockIdentifier = default_block_id,
    ) -> eth_types.Data:
        """Return code at a given address during specified block.

        :param address: The address to retrieve the code from.
        :param block_identifier: the block during which to get the code from.

        :returns
            eth_types.HexStr: string in hex format containing the code as data.
        """
        return eth_utils.to_py_converters[eth_types.Data](await self.rpc(
            eth_models.JSONRPCRequest(
                method=self.rpc_schema.get_code[0],
                id=self.rpc_schema.get_code[1],
                params=[address, block_identifier],
            )))