Example #1
0
def build_transaction_for_function(address,
                                   web3,
                                   function_name=None,
                                   transaction=None,
                                   contract_abi=None,
                                   fn_abi=None,
                                   *args,
                                   **kwargs):
    """Builds a dictionary with the fields required to make the given transaction

    Don't call this directly, instead use :meth:`Contract.buildTransaction`
    on your contract instance.
    """
    prepared_transaction = prepare_transaction(
        address,
        web3,
        fn_identifier=function_name,
        contract_abi=contract_abi,
        fn_abi=fn_abi,
        transaction=transaction,
        fn_args=args,
        fn_kwargs=kwargs,
    )

    prepared_transaction = fill_transaction_defaults(web3,
                                                     prepared_transaction)

    return prepared_transaction
def send_transaction(*, web3: Web3, transaction_options: TxParams, private_key=None):
    """
    Send the transaction with given transaction options
    Will either use an account of the node(default), or a local private key(if given) to sign the transaction.
    It will not block until the transaction was successfully mined.

    Returns: The sent transaction hash
    """

    if private_key is not None:
        account = Account.from_key(private_key)

        if (
            "from" in transaction_options
            and transaction_options["from"] != account.address
        ):
            raise ValueError(
                "From can not be set in transaction_options if a private key is used"
            )
        transaction_options["from"] = account.address

        transaction = fill_nonce(web3, transaction_options)
        transaction = fill_transaction_defaults(web3, transaction)
        signed_transaction = account.sign_transaction(transaction)
        tx_hash = web3.eth.sendRawTransaction(signed_transaction.rawTransaction)

    else:
        _set_from_address(web3, transaction_options)
        tx_hash = web3.eth.sendTransaction(transaction_options)

    return tx_hash
Example #3
0
    def sign_and_send_raw_middleware(make_request, w3):

        format_and_fill_tx = compose(
            format_transaction,
            fill_transaction_defaults(w3),
            fill_nonce(w3))

        def middleware(method, params):
            if method != "eth_sendTransaction":
                return make_request(method, params)
            else:
                transaction = format_and_fill_tx(params[0])

            if 'from' not in transaction:
                return make_request(method, params)
            elif transaction.get('from') not in accounts:
                return make_request(method, params)

            account = accounts[transaction['from']]
            raw_tx = account.signTransaction(transaction).rawTransaction.hex()

            return make_request(
                "eth_sendRawTransaction",
                [raw_tx])

        return middleware
Example #4
0
def build_transaction_for_function(
        address,
        web3,
        function_name=None,
        transaction=None,
        contract_abi=None,
        fn_abi=None,
        *args,
        **kwargs):
    """Builds a dictionary with the fields required to make the given transaction

    Don't call this directly, instead use :meth:`Contract.buildTransaction`
    on your contract instance.
    """
    prepared_transaction = prepare_transaction(
        address,
        web3,
        fn_identifier=function_name,
        contract_abi=contract_abi,
        fn_abi=fn_abi,
        transaction=transaction,
        fn_args=args,
        fn_kwargs=kwargs,
    )

    prepared_transaction = fill_transaction_defaults(web3, prepared_transaction)

    return prepared_transaction
Example #5
0
    def sign_and_send_raw_middleware(
            make_request: Callable[[RPCEndpoint, Any], Any],
            w3: "Web3") -> Callable[[RPCEndpoint, Any], RPCResponse]:
        format_and_fill_tx = compose(format_transaction,
                                     fill_transaction_defaults(w3),
                                     fill_nonce(w3))

        def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
            if method != "eth_sendTransaction":
                return make_request(method, params)
            else:
                transaction = format_and_fill_tx(params[0])

            if 'from' not in transaction:
                return make_request(method, params)
            elif transaction.get('from') not in accounts:
                return make_request(method, params)

            account = accounts[transaction['from']]
            raw_tx = account.sign_transaction(transaction).rawTransaction

            return make_request(RPCEndpoint("eth_sendRawTransaction"),
                                [raw_tx])

        return middleware
Example #6
0
    def sign_and_send_raw_middleware(make_request, w3):

        format_and_fill_tx = compose(
            format_transaction,
            fill_transaction_defaults(w3),
            fill_nonce(w3))

        def middleware(method, params):
            if method != "eth_sendTransaction":
                return make_request(method, params)
            else:
                transaction = format_and_fill_tx(params[0])

            if 'from' not in transaction:
                return make_request(method, params)
            elif transaction.get('from') not in accounts:
                return make_request(method, params)

            account = accounts[transaction['from']]
            raw_tx = account.signTransaction(transaction).rawTransaction

            return make_request(
                "eth_sendRawTransaction",
                [raw_tx])

        return middleware
Example #7
0
def test_fill_transaction_defaults_for_all_params(web3):
    default_transaction = fill_transaction_defaults(web3, {})

    assert default_transaction == {
        'chainId': web3.eth.chain_id,
        'data': b'',
        'gas': web3.eth.estimate_gas({}),
        'gasPrice': web3.eth.gas_price,
        'value': 0,
    }
Example #8
0
def test_fill_transaction_defaults_for_all_params(web3):
    default_transaction = fill_transaction_defaults(web3, {})

    assert default_transaction == {
        'chainId': web3.eth.chain_id,
        'data': b'',
        'gas': web3.eth.estimate_gas({}),
        'maxFeePerGas': (
            web3.eth.max_priority_fee + (2 * web3.eth.get_block('latest')['baseFeePerGas'])
        ),
        'maxPriorityFeePerGas': web3.eth.max_priority_fee,
        'value': 0,
    }
Example #9
0
    def buildTransaction(self, transaction=None):
        """
        Build the transaction dictionary without sending
        """

        if transaction is None:
            built_transaction = {}
        else:
            built_transaction = dict(**transaction)
            self.check_forbidden_keys_in_transaction(built_transaction,
                                                     ["data", "to"])

        if self.web3.eth.defaultAccount is not empty:
            built_transaction.setdefault('from', self.web3.eth.defaultAccount)

        built_transaction['data'] = self.data_in_transaction
        built_transaction['to'] = b''
        return fill_transaction_defaults(self.web3, built_transaction)
Example #10
0
    def buildTransaction(self, transaction=None):
        """
        Build the transaction dictionary without sending
        """

        if transaction is None:
            built_transaction = {}
        else:
            built_transaction = dict(**transaction)
            self.check_forbidden_keys_in_transaction(built_transaction,
                                                     ["data", "to"])

        if self.web3.eth.defaultAccount is not empty:
            built_transaction.setdefault('from', self.web3.eth.defaultAccount)

        built_transaction['data'] = self.data_in_transaction
        built_transaction['to'] = b''
        return fill_transaction_defaults(self.web3, built_transaction)
Example #11
0
def test_fill_transaction_defaults_sets_type_with_dynamic_fee_txn_params_and_no_gas_price(
        web3):
    dynamic_fee_transaction = {
        'chainId': 1,
        'data': b'123',
        'gas': 21000,
        'maxFeePerGas': 2000000000,
        'maxPriorityFeePerGas': 1000000000,
        'value': 2,
    }
    dynamic_fee_transaction_type_added = fill_transaction_defaults(
        web3, dynamic_fee_transaction)

    assert dynamic_fee_transaction_type_added == {
        'chainId': 1,
        'data': b'123',
        'gas': 21000,
        'maxFeePerGas': 2000000000,
        'maxPriorityFeePerGas': 1000000000,
        'type':
        '0x2',  # type is added and defaults to '0x2' when dynamic fee txn params present
        'value': 2,
    }