Beispiel #1
0
    def get_tx_receipt(tx_hash: str, timeout=20):
        """
        Get the receipt of a tx.
        :param tx_hash: hash of the transaction
        :param timeout: int in seconds to wait for transaction receipt
        :return: Tx receipt
        """
        try:
            Web3Provider.get_web3().eth.wait_for_transaction_receipt(
                HexBytes(tx_hash), timeout=timeout
            )
        except ValueError as e:
            logger.error(f"Waiting for transaction receipt failed: {e}")
            return None
        except Timeout as e:
            logger.info(f"Waiting for transaction receipt may have timed out: {e}.")
            return None
        except ConnectionClosed as e:
            logger.info(
                f"ConnectionClosed error waiting for transaction receipt failed: {e}."
            )
            raise
        except Exception as e:
            logger.info(f"Unknown error waiting for transaction receipt: {e}.")
            raise

        return Web3Provider.get_web3().eth.get_transaction_receipt(tx_hash)
    def _load(contract_name, address=None):
        """Retrieve the contract instance for `contract_name`.
        That instance represents the smart contract in the ethereum network.
        Handles two cases:
        1. One deployment of contract, eg DTFactory. 'address' can be None, or specified
        2. 1 deployments, eg DataTokenTemplate. 'address' must be specified.
        :param contract_name: str name of the solidity smart contract.
        :param address: hex str -- address of smart contract
        """
        assert (ContractHandler.artifacts_path
                is not None), "artifacts_path should be already set."
        contract_definition = ContractHandler.read_abi_from_file(
            contract_name, ContractHandler.artifacts_path)

        if not address and "address" in contract_definition:
            address = contract_definition.get("address")
            assert address, "Cannot find contract address in the abi file."
            address = Web3.toChecksumAddress(address)
        assert address is not None, "address shouldn't be None at this point"

        abi = contract_definition["abi"]
        bytecode = contract_definition["bytecode"]
        contract = Web3Provider.get_web3().eth.contract(address=address,
                                                        abi=abi,
                                                        bytecode=bytecode)
        if contract.address is None:  # if web3 drops address, fix it
            contract.address = address
        assert contract.address is not None

        ContractHandler._set(contract_name, contract)

        ContractHandler._verifyContractsConsistency(contract_name)
Beispiel #3
0
    def get_event_logs(
        self, event_name, from_block, to_block, filters, web3=None, chunk_size=1000
    ):
        """
        Fetches the list of event logs between the given block numbers.
        :param event_name: str
        :param from_block: int
        :param to_block: int
        :param filters:
        :param web3: Wallet instance
        :param chunk_size: int
        :return: List of event logs. List will have the structure as below.
        ```Python
            [AttributeDict({
                'args': AttributeDict({}),
                'event': 'LogNoArguments',
                'logIndex': 0,
                'transactionIndex': 0,
                'transactionHash': HexBytes('...'),
                'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b',
                'blockHash': HexBytes('...'),
                'blockNumber': 3
                }),
            AttributeDict(...),
            ...
            ]
        ```
        """
        event = getattr(self.events, event_name)
        if not web3:
            web3 = Web3Provider.get_web3()

        chunk = chunk_size
        _from = from_block
        _to = _from + chunk - 1

        all_logs = []
        error_count = 0
        _to = min(_to, to_block)
        while _from <= to_block:
            try:
                logs = self.getLogs(
                    event, web3, argument_filters=filters, fromBlock=_from, toBlock=_to
                )
                all_logs.extend(logs)
                _from = _to + 1
                _to = min(_from + chunk - 1, to_block)
                error_count = 0
                if (_from - from_block) % 1000 == 0:
                    print(
                        f"    So far processed {len(all_logs)} Transfer events from {_from-from_block} blocks."
                    )
            except requests.exceptions.ReadTimeout as err:
                print(f"ReadTimeout ({_from}, {_to}): {err}")
                error_count += 1

            if error_count > 1:
                break

        return all_logs
Beispiel #4
0
def get_ether_balance(address: str) -> int:
    """
    Get balance of an ethereum address.
    :param address: address, bytes32
    :return: balance, int
    """
    return Web3Provider.get_web3().eth.get_balance(address, block_identifier="latest")
Beispiel #5
0
    def __init__(self, options_dict=None):

        filename = getenv('CONFIG_FILE', './config.ini')
        if not os.path.exists(filename) and not options_dict:
            raise FileNotFoundError(f'please provider the config first')

        config_parser = ConfigParser()
        if os.path.exists(filename):
            config_parser.read(filename)
        if options_dict:
            config_parser.read_dict(options_dict)

        artifacts_path = config_parser.get('keeper', 'artifacts_path')
        network_url = config_parser.get('keeper', 'network_url')
        network_name = config_parser.get('keeper', 'network_name')
        address_file = config_parser.get('keeper', 'address_file')

        ContractHandler.set_artifacts_path(artifacts_path)
        addresses = ContractHandler.get_contracts_addresses(
            network_name, address_file)

        self._web3 = Web3Provider.get_web3(network_url=network_url)

        self.role_controller = RoleController(
            addresses.get(RoleController.CONTRACT_NAME))
        self.asset_provider = AssetProvider(
            addresses.get(AssetProvider.CONTRACT_NAME))
        self.op_template = OpTemplate(addresses.get(OpTemplate.CONTRACT_NAME))
        self.dt_factory = DTFactory(addresses.get(DTFactory.CONTRACT_NAME))
        self.task_market = TaskMarket(addresses.get(TaskMarket.CONTRACT_NAME))

        logger.debug('Keeper instance initialized: ')
Beispiel #6
0
def add_ethereum_prefix_and_hash_msg(text):
    """
    This method of adding the ethereum prefix seems to be used in web3.personal.sign/ecRecover.
    :param text: str any str to be signed / used in recovering address from a signature
    :return: hash of prefixed text according to the recommended ethereum prefix
    """
    prefixed_msg = f"\x19Ethereum Signed Message:\n{len(text)}{text}"
    return Web3Provider.get_web3().keccak(text=prefixed_msg)
Beispiel #7
0
def generate_multi_value_hash(types, values):
    """
    Return the hash of the given list of values.
    This is equivalent to packing and hashing values in a solidity smart contract
    hence the use of `soliditySha3`.
    :param types: list of solidity types expressed as strings
    :param values: list of values matching the `types` list
    :return: bytes
    """
    assert len(types) == len(values)
    return Web3Provider.get_web3().solidityKeccak(types, values)
Beispiel #8
0
def ec_recover(message, signed_message):
    """
    This method does not prepend the message with the prefix `\x19Ethereum Signed Message:\n32`.
    The caller should add the prefix to the msg/hash before calling this if the signature was
    produced for an ethereum-prefixed message.
    :param message:
    :param signed_message:
    :return:
    """
    w3 = Web3Provider.get_web3()
    v, r, s = split_signature(w3, w3.toBytes(hexstr=signed_message))
    signature_object = SignatureFix(vrs=(v, big_endian_to_int(r), big_endian_to_int(s)))
    return w3.eth.account.recoverHash(
        message, signature=signature_object.to_hex_v_hacked()
    )
Beispiel #9
0
def cancel_or_replace_transaction(from_wallet,
                                  nonce_value,
                                  gas_price=None,
                                  gas_limit=None):
    w3 = Web3Provider.get_web3()
    tx = {"from": from_wallet.address, "to": from_wallet.address, "value": 0}
    gas = gas_limit if gas_limit is not None else w3.eth.estimate_gas(tx)
    tx = {
        "from": from_wallet.address,
        "to": from_wallet.address,
        "value": 0,
        "gas": gas + 1,
    }

    wallet = Wallet(w3,
                    private_key=from_wallet.key,
                    address=from_wallet.address)
    raw_tx = wallet.sign_tx(tx, fixed_nonce=nonce_value, gas_price=gas_price)
    tx_hash = w3.eth.send_raw_transaction(raw_tx)
    receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=30)
    return receipt
Beispiel #10
0
def send_ether(from_wallet: Wallet, to_address: str, ether_amount: int):
    w3 = Web3Provider.get_web3()
    if not w3.isChecksumAddress(to_address):
        to_address = w3.toChecksumAddress(to_address)

    tx = {
        "from": from_wallet.address,
        "to": to_address,
        "value": w3.toWei(ether_amount, "ether"),
    }
    _ = w3.eth.estimate_gas(tx)
    tx = {
        "from": from_wallet.address,
        "to": to_address,
        "value": w3.toWei(ether_amount, "ether"),
        "gas": 500000,
    }
    wallet = Wallet(w3,
                    private_key=from_wallet.key,
                    address=from_wallet.address)
    raw_tx = wallet.sign_tx(tx)
    tx_hash = w3.eth.send_raw_transaction(raw_tx)
    receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=30)
    return receipt
Beispiel #11
0
 def web3(self):
     """Get the web3 provider of the network."""
     return Web3Provider.get_web3(network_url=self.network_url)
 def uninstall(self):
     Web3Provider.get_web3().eth.uninstall_filter(self._filter.filter_id)
Beispiel #13
0
def private_key_to_address(private_key: str) -> str:
    return Web3Provider.get_web3().eth.account.from_key(private_key).address
Beispiel #14
0
def from_wei(wei_value: int) -> Decimal:
    return Web3Provider.get_web3().fromWei(wei_value, "ether")
Beispiel #15
0
def get_network_id() -> int:
    """
    Return the ethereum network id calling the `web3.version.network` method.
    :return: Network id, int
    """
    return int(Web3Provider.get_web3().net.version)