Exemple #1
0
    def deploy(
        self,
        contract: Any,
        *args: Tuple,
        amount: Optional[int] = None,
        gas_limit: Optional[int] = None,
        gas_price: Optional[int] = None,
    ) -> Any:
        """Deploys a contract.

        Args:
            contract: ContractContainer instance.
            *args: Constructor arguments. The last argument may optionally be
                   a dictionary of transaction values.

        Kwargs:
            amount: Amount of ether to send with transaction, in wei.
            gas_limit: Gas limit of the transaction.
            gas_price: Gas price of the transaction.

        Returns:
            * Contract instance if the transaction confirms
            * TransactionReceipt if the transaction is pending or reverts"""

        evm = contract._build["compiler"]["evm_version"]
        if rpc.is_active() and not rpc.evm_compatible(evm):
            raise IncompatibleEVMVersion(
                f"Local RPC using '{rpc.evm_version()}' but contract was compiled for '{evm}'"
            )
        data = contract.deploy.encode_input(*args)
        try:
            txid = self._transact(  # type: ignore
                {
                    "from": self.address,
                    "value": Wei(amount),
                    "nonce": self.nonce,
                    "gasPrice": Wei(gas_price) or self._gas_price(),
                    "gas": Wei(gas_limit) or self._gas_limit("", amount, data),
                    "data": HexBytes(data),
                }
            )
            revert_data = None
        except ValueError as e:
            txid, revert_data = _raise_or_return_tx(e)
        tx = TransactionReceipt(txid,
                                self,
                                name=contract._name + ".constructor",
                                revert_data=revert_data)
        add_thread = threading.Thread(target=contract._add_from_tx,
                                      args=(tx, ),
                                      daemon=True)
        add_thread.start()
        if tx.status != 1:
            return tx
        add_thread.join()
        return contract.at(tx.contract_address)
Exemple #2
0
    def deploy(self, contract, *args, amount=None, gas_limit=None, gas_price=None):
        '''Deploys a contract.

        Args:
            contract: ContractContainer instance.
            *args: Constructor arguments. The last argument may optionally be
                   a dictionary of transaction values.

        Kwargs:
            amount: Amount of ether to send with transaction, in wei.
            gas_limit: Gas limit of the transaction.
            gas_price: Gas price of the transaction.

        Returns:
            * Contract instance if the transaction confirms
            * TransactionReceipt if the transaction is pending or reverts'''
        evm = contract._build['compiler']['evm_version']
        if rpc.is_active() and not rpc.evm_compatible(evm):
            raise IncompatibleEVMVersion(
                f"Local RPC using '{rpc.evm_version()}' but contract was compiled for '{evm}'"
            )
        data = contract.deploy.encode_abi(*args)
        try:
            txid = self._transact({
                'from': self.address,
                'value': Wei(amount),
                'nonce': self.nonce,
                'gasPrice': Wei(gas_price) or self._gas_price(),
                'gas': Wei(gas_limit) or self._gas_limit("", amount, data),
                'data': HexBytes(data)
            })
            revert_data = None
        except ValueError as e:
            txid, revert_data = _raise_or_return_tx(e)
        self.nonce += 1
        tx = TransactionReceipt(
            txid,
            self,
            name=contract._name + ".constructor",
            revert_data=revert_data
        )
        add_thread = threading.Thread(target=contract._add_from_tx, args=(tx,), daemon=True)
        add_thread.start()
        if tx.status != 1:
            return tx
        add_thread.join()
        return history.find_contract(tx.contract_address)
Exemple #3
0
    def deploy(
        self,
        contract: Any,
        *args: Tuple,
        amount: int = 0,
        gas_limit: Optional[int] = None,
        gas_buffer: Optional[float] = None,
        gas_price: Optional[int] = None,
        nonce: Optional[int] = None,
        required_confs: int = 1,
        allow_revert: bool = None,
        silent: bool = None,
        publish_source: bool = False,
    ) -> Any:
        """Deploys a contract.

        Args:
            contract: ContractContainer instance.
            *args: Constructor arguments. The last argument may optionally be
                   a dictionary of transaction values.

        Kwargs:
            amount: Amount of ether to send with transaction, in wei.
            gas_limit: Gas limit of the transaction.
            gas_buffer: Multiplier to apply to gas limit.
            gas_price: Gas price of the transaction.
            nonce: Nonce to use for the transaction.

        Returns:
            * Contract instance if the transaction confirms and the contract exists
            * TransactionReceipt if the transaction is pending or reverts
        """
        if gas_limit and gas_buffer:
            raise ValueError("Cannot set gas_limit and gas_buffer together")

        evm = contract._build["compiler"]["evm_version"]
        if rpc.is_active() and not rpc.evm_compatible(evm):
            raise IncompatibleEVMVersion(
                f"Local RPC using '{rpc.evm_version()}' but contract was compiled for '{evm}'"
            )
        data = contract.deploy.encode_input(*args)
        if silent is None:
            silent = bool(CONFIG.mode == "test" or CONFIG.argv["silent"])
        with self._lock:
            try:
                gas_price, gas_strategy, gas_iter = self._gas_price(gas_price)
                gas_limit = Wei(gas_limit) or self._gas_limit(
                    None, amount, gas_price, gas_buffer, data)
                txid = self._transact(  # type: ignore
                    {
                        "from": self.address,
                        "value": Wei(amount),
                        "nonce": nonce if nonce is not None else self._pending_nonce(),
                        "gasPrice": gas_price,
                        "gas": gas_limit,
                        "data": HexBytes(data),
                    },
                    allow_revert,
                )
                exc, revert_data = None, None
            except ValueError as e:
                exc = VirtualMachineError(e)
                if not hasattr(exc, "txid"):
                    raise exc from None
                txid = exc.txid
                revert_data = (exc.revert_msg, exc.pc, exc.revert_type)

            receipt = TransactionReceipt(
                txid,
                self,
                silent=silent,
                required_confs=required_confs,
                is_blocking=False,
                name=contract._name + ".constructor",
                revert_data=revert_data,
            )

        receipt = self._await_confirmation(receipt, required_confs,
                                           gas_strategy, gas_iter)

        add_thread = threading.Thread(target=contract._add_from_tx,
                                      args=(receipt, ),
                                      daemon=True)
        add_thread.start()

        if rpc.is_active():
            undo_thread = threading.Thread(
                target=Chain()._add_to_undo_buffer,
                args=(
                    receipt,
                    self.deploy,
                    (contract, *args),
                    {
                        "amount": amount,
                        "gas_limit": gas_limit,
                        "gas_buffer": gas_buffer,
                        "gas_price": gas_price,
                    },
                ),
                daemon=True,
            )
            undo_thread.start()

        if receipt.status != 1:
            receipt._raise_if_reverted(exc)
            return receipt

        add_thread.join()
        try:
            deployed_contract = contract.at(receipt.contract_address)
            if publish_source:
                contract.publish_source(deployed_contract, silent=silent)
            return deployed_contract
        except ContractNotFound:
            # if the contract self-destructed during deployment
            return receipt
Exemple #4
0
    def deploy(
        self,
        contract: Any,
        *args: Tuple,
        amount: int = 0,
        gas_limit: Optional[int] = None,
        gas_price: Optional[int] = None,
        nonce: Optional[int] = None,
        required_confs: int = 1,
    ) -> Any:
        """Deploys a contract.

        Args:
            contract: ContractContainer instance.
            *args: Constructor arguments. The last argument may optionally be
                   a dictionary of transaction values.

        Kwargs:
            amount: Amount of ether to send with transaction, in wei.
            gas_limit: Gas limit of the transaction.
            gas_price: Gas price of the transaction.
            nonce: Nonce to use for the transaction.

        Returns:
            * Contract instance if the transaction confirms and the contract exists
            * TransactionReceipt if the transaction is pending or reverts
        """

        evm = contract._build["compiler"]["evm_version"]
        if rpc.is_active() and not rpc.evm_compatible(evm):
            raise IncompatibleEVMVersion(
                f"Local RPC using '{rpc.evm_version()}' but contract was compiled for '{evm}'"
            )
        data = contract.deploy.encode_input(*args)
        with self._lock:
            try:
                txid = self._transact(  # type: ignore
                    {
                        "from": self.address,
                        "value": Wei(amount),
                        "nonce": nonce if nonce is not None else self._pending_nonce(),
                        "gasPrice": Wei(gas_price) or self._gas_price(),
                        "gas": Wei(gas_limit) or self._gas_limit(None, amount, data),
                        "data": HexBytes(data),
                    }
                )
                exc, revert_data = None, None
            except ValueError as e:
                exc = VirtualMachineError(e)
                if not hasattr(exc, "txid"):
                    raise exc from None
                txid = exc.txid
                revert_data = (exc.revert_msg, exc.pc, exc.revert_type)

            receipt = TransactionReceipt(
                txid,
                self,
                required_confs=required_confs,
                name=contract._name + ".constructor",
                revert_data=revert_data,
            )
        add_thread = threading.Thread(target=contract._add_from_tx,
                                      args=(receipt, ),
                                      daemon=True)
        add_thread.start()

        if rpc.is_active():
            undo_thread = threading.Thread(
                target=rpc._add_to_undo_buffer,
                args=(
                    receipt,
                    self.deploy,
                    (contract, *args),
                    {
                        "amount": amount,
                        "gas_limit": gas_limit,
                        "gas_price": gas_price
                    },
                ),
                daemon=True,
            )
            undo_thread.start()

        if receipt.status != 1:
            receipt._raise_if_reverted(exc)
            return receipt

        add_thread.join()
        try:
            return contract.at(receipt.contract_address)
        except ContractNotFound:
            # if the contract self-destructed during deployment
            return receipt