Exemple #1
0
    def deploy_compatibility_fallback_handler(
            cls, ethereum_client: EthereumClient,
            deployer_account: LocalAccount) -> EthereumTxSent:
        """
        Deploy Compatibility Fallback handler v1.3.0

        :param ethereum_client:
        :param deployer_account: Ethereum account
        :return: deployed contract address
        """

        contract = get_compatibility_fallback_handler_V1_3_0_contract(
            ethereum_client.w3)
        constructor_tx = contract.constructor().buildTransaction()
        tx_hash = ethereum_client.send_unsigned_transaction(
            constructor_tx, private_key=deployer_account.key)
        tx_receipt = ethereum_client.get_transaction_receipt(tx_hash,
                                                             timeout=60)
        assert tx_receipt
        assert tx_receipt["status"]

        ethereum_tx_sent = EthereumTxSent(tx_hash, constructor_tx,
                                          tx_receipt["contractAddress"])
        logger.info(
            "Deployed and initialized Compatibility Fallback Handler version=%s on address %s by %s",
            "1.3.0",
            ethereum_tx_sent.contract_address,
            deployer_account.address,
        )
        return ethereum_tx_sent
Exemple #2
0
    def deploy_master_contract(
            ethereum_client: EthereumClient,
            deployer_account: LocalAccount) -> EthereumTxSent:
        """
        Deploy master contract. Takes deployer_account (if unlocked in the node) or the deployer private key
        Safe with version > v1.1.1 doesn't need to be initialized as it already has a constructor
        :param ethereum_client:
        :param deployer_account: Ethereum account
        :return: deployed contract address
        """

        safe_contract = get_safe_contract(ethereum_client.w3)
        constructor_tx = safe_contract.constructor().buildTransaction()
        tx_hash = ethereum_client.send_unsigned_transaction(
            constructor_tx, private_key=deployer_account.key)
        tx_receipt = ethereum_client.get_transaction_receipt(tx_hash,
                                                             timeout=60)
        assert tx_receipt
        assert tx_receipt['status']

        ethereum_tx_sent = EthereumTxSent(tx_hash, constructor_tx,
                                          tx_receipt['contractAddress'])
        logger.info("Deployed and initialized Safe Master Contract=%s by %s",
                    ethereum_tx_sent.contract_address,
                    deployer_account.address)
        return ethereum_tx_sent
Exemple #3
0
    def _deploy_master_contract(
        ethereum_client: EthereumClient,
        deployer_account: LocalAccount,
        contract_fn: Callable[[Web3, Optional[str]], Contract],
    ) -> EthereumTxSent:
        """
        Deploy master contract. Takes deployer_account (if unlocked in the node) or the deployer private key
        Safe with version > v1.1.1 doesn't need to be initialized as it already has a constructor

        :param ethereum_client:
        :param deployer_account: Ethereum account
        :param contract_fn: get contract function
        :return: deployed contract address
        """
        safe_contract = contract_fn(ethereum_client.w3)
        constructor_tx = safe_contract.constructor().buildTransaction()
        tx_hash = ethereum_client.send_unsigned_transaction(
            constructor_tx, private_key=deployer_account.key)
        tx_receipt = ethereum_client.get_transaction_receipt(tx_hash,
                                                             timeout=60)
        assert tx_receipt
        assert tx_receipt["status"]

        ethereum_tx_sent = EthereumTxSent(tx_hash, constructor_tx,
                                          tx_receipt["contractAddress"])
        logger.info(
            "Deployed and initialized Safe Master Contract version=%s on address %s by %s",
            contract_fn(
                ethereum_client.w3,
                ethereum_tx_sent.contract_address).functions.VERSION().call(),
            ethereum_tx_sent.contract_address,
            deployer_account.address,
        )
        return ethereum_tx_sent
Exemple #4
0
    def create(ethereum_client: EthereumClient,
               deployer_account: LocalAccount,
               master_copy_address: str,
               owners: List[str],
               threshold: int,
               fallback_handler: str = NULL_ADDRESS,
               proxy_factory_address: Optional[str] = None,
               payment_token: str = NULL_ADDRESS,
               payment: int = 0,
               payment_receiver: str = NULL_ADDRESS) -> EthereumTxSent:
        """
        Deploy new Safe proxy pointing to the specified `master_copy` address and configured
        with the provided `owners` and `threshold`. By default, payment for the deployer of the tx will be `0`.
        If `proxy_factory_address` is set deployment will be done using the proxy factory instead of calling
        the `constructor` of a new `DelegatedProxy`
        Using `proxy_factory_address` is recommended, as it takes less gas.
        (Testing with `Ganache` and 1 owner 261534 without proxy vs 229022 with Proxy)
        """

        assert owners, 'At least one owner must be set'
        assert threshold >= len(owners), 'Threshold=%d must be >= %d' % (
            threshold, len(owners))

        initializer = get_safe_contract(
            ethereum_client.w3, NULL_ADDRESS
        ).functions.setup(
            owners,
            threshold,
            NULL_ADDRESS,  # Contract address for optional delegate call
            b'',  # Data payload for optional delegate call
            fallback_handler,  # Handler for fallback calls to this contract,
            payment_token,
            payment,
            payment_receiver).buildTransaction({
                'gas': 1,
                'gasPrice': 1
            })['data']

        if proxy_factory_address:
            proxy_factory = ProxyFactory(proxy_factory_address,
                                         ethereum_client)
            return proxy_factory.deploy_proxy_contract(deployer_account,
                                                       master_copy_address,
                                                       initializer=initializer)

        proxy_contract = get_delegate_constructor_proxy_contract(
            ethereum_client.w3)
        tx = proxy_contract.constructor(master_copy_address,
                                        initializer).buildTransaction(
                                            {'from': deployer_account.address})
        tx['gas'] = tx['gas'] * 100000
        tx_hash = ethereum_client.send_unsigned_transaction(
            tx, private_key=deployer_account.key)
        tx_receipt = ethereum_client.get_transaction_receipt(tx_hash,
                                                             timeout=60)
        assert tx_receipt.status

        contract_address = tx_receipt.contractAddress
        return EthereumTxSent(tx_hash, tx, contract_address)