def build_transaction_for_function(abi, address, web3, function_name=None, transaction=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( abi, address, web3, fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) prepared_transaction = fill_transaction_defaults(web3, prepared_transaction) return prepared_transaction
def build_transaction_for_function(abi, address, web3, function_name=None, transaction=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( abi, address, web3, fn_identifier=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) prepared_transaction = fill_transaction_defaults(web3, prepared_transaction) return prepared_transaction
def estimate_gas_for_function( address, web3, fn_identifier=None, transaction=None, contract_abi=None, fn_abi=None, block_identifier=None, *args, **kwargs, ): """Temporary workaround until next web3.py release (5.X.X)""" estimate_transaction = prepare_transaction( address, web3, fn_identifier=fn_identifier, contract_abi=contract_abi, fn_abi=fn_abi, transaction=transaction, fn_args=args, fn_kwargs=kwargs, ) try: gas_estimate = web3.eth.estimateGas(estimate_transaction, block_identifier) except ValueError as e: if check_value_error_for_parity(e, ParityCallType.ESTIMATE_GAS): gas_estimate = None else: # else the error is not denoting estimate gas failure and is something else raise e return gas_estimate
def estimate_gas_for_function( address, web3, fn_identifier=None, transaction=None, contract_abi=None, fn_abi=None, block_identifier=None, *args, **kwargs, ): """Temporary workaround until next web3.py release (5.X.X)""" estimate_transaction = prepare_transaction( address, web3, fn_identifier=fn_identifier, contract_abi=contract_abi, fn_abi=fn_abi, transaction=transaction, fn_args=args, fn_kwargs=kwargs, ) gas_estimate = web3.eth.estimateGas(estimate_transaction, block_identifier) return gas_estimate
def transact_with_contract_function(address, web3, function_name=None, transaction=None, contract_abi=None, fn_abi=None, *args, **kwargs): """ Helper function for interacting with a contract function by sending a transaction. This is copied from web3 `transact_with_contract_function` so we can use `personal_sendTransaction` when possible. """ transact_transaction = prepare_transaction( address, web3, fn_identifier=function_name, contract_abi=contract_abi, transaction=transaction, fn_abi=fn_abi, fn_args=args, fn_kwargs=kwargs, ) passphrase = None account_key = None if transaction and 'passphrase' in transaction: passphrase = transaction['passphrase'] transact_transaction.pop('passphrase') if 'account_key' in transaction: account_key = transaction['account_key'] transact_transaction.pop('account_key') # Restrict transactions to raw transactions for now (security first) # if not (passphrase and key_file): # raise AssertionError( # 'password and key file are required for signing transactions locally.' # ) if account_key: raw_tx = Wallet(web3, account_key, passphrase).sign_tx(transact_transaction) logging.debug( f'sending raw tx: function: {function_name}, tx hash: {raw_tx.hex()}' ) txn_hash = web3.eth.sendRawTransaction(raw_tx) elif passphrase: txn_hash = web3.personal.sendTransaction(transact_transaction, passphrase) else: txn_hash = web3.eth.sendTransaction(transact_transaction) return txn_hash
def _prepare_transaction(cls, fn_name, fn_args=None, fn_kwargs=None, transaction=None): return prepare_transaction(cls.abi, cls.address, cls.web3, fn_identifier=fn_name, fn_args=fn_args, fn_kwargs=fn_kwargs, transaction=transaction)
def _prepare_transaction(cls, fn_name, fn_args=None, fn_kwargs=None, transaction=None): return prepare_transaction(cls.abi, cls.address, cls.web3, fn_name=fn_name, fn_args=fn_args, fn_kwargs=fn_kwargs, transaction=transaction)
def call_contract_function(abi, web3, address, normalizers, function_name, transaction, *args, **kwargs): """ Helper function for interacting with a contract function using the `eth_call` API. """ call_transaction = prepare_transaction( abi, address, web3, fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) return_data = web3.eth.call(call_transaction) function_abi = find_matching_fn_abi(abi, function_name, args, kwargs) output_types = get_abi_output_types(function_abi) try: output_data = decode_abi(output_types, return_data) except DecodingError as e: # Provide a more helpful error message than the one provided by # eth-abi-utils is_missing_code_error = (return_data in ACCEPTABLE_EMPTY_STRINGS and web3.eth.getCode(address) in ACCEPTABLE_EMPTY_STRINGS) if is_missing_code_error: msg = ( "Could not transact with/call contract function, is contract " "deployed correctly and chain synced?") else: msg = ( "Could not decode contract function call {} return data {} for " "output_types {}".format(function_name, return_data, output_types)) raise BadFunctionCallOutput(msg) from e _normalizers = itertools.chain( BASE_RETURN_NORMALIZERS, normalizers, ) normalized_data = map_abi_data(_normalizers, output_types, output_data) if len(normalized_data) == 1: return normalized_data[0] else: return normalized_data
def transact_with_contract_function(abi, address, web3, function_name=None, transaction=None, *args, **kwargs): """ Helper function for interacting with a contract function by sending a transaction. """ transact_transaction = prepare_transaction( abi, address, web3, fn_identifier=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) txn_hash = web3.eth.sendTransaction(transact_transaction) return txn_hash
def transact_with_contract_function(abi, address, web3, function_name=None, transaction=None, *args, **kwargs): """ Helper function for interacting with a contract function by sending a transaction. """ transact_transaction = prepare_transaction( abi, address, web3, fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) txn_hash = web3.eth.sendTransaction(transact_transaction) return txn_hash
def estimate_gas_for_function(abi, address, web3, fn_identifier=None, transaction=None, *args, **kwargs): """Estimates gas cost a function call would take. Don't call this directly, instead use :meth:`Contract.estimateGas` on your contract instance. """ estimate_transaction = prepare_transaction( abi, address, web3, fn_identifier=fn_identifier, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) gas_estimate = web3.eth.estimateGas(estimate_transaction) return gas_estimate
def transact_with_contract_function(address, web3, function_name=None, transaction=None, contract_abi=None, fn_abi=None, *args, **kwargs): """ Helper function for interacting with a contract function by sending a transaction. This is copied from web3 `transact_with_contract_function` so we can use `personal_sendTransaction` when possible. """ transact_transaction = prepare_transaction( address, web3, fn_identifier=function_name, contract_abi=contract_abi, transaction=transaction, fn_abi=fn_abi, fn_args=args, fn_kwargs=kwargs, ) passphrase = None if transaction and 'passphrase' in transaction: passphrase = transaction['passphrase'] transact_transaction.pop('passphrase') if passphrase: txn_hash = web3.personal.sendTransaction(transact_transaction, passphrase) else: txn_hash = web3.eth.sendTransaction(transact_transaction) return txn_hash
def estimate_gas_for_function(abi, address, web3, function_name=None, transaction=None, *args, **kwargs): """Estimates gas cost a function call would take. Don't call this directly, instead use :meth:`Contract.estimateGas` on your contract instance. """ estimate_transaction = prepare_transaction( abi, address, web3, fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) gas_estimate = web3.eth.estimateGas(estimate_transaction) return gas_estimate
def call_contract_function(abi, web3, address, normalizers, function_name, transaction, *args, **kwargs): """ Helper function for interacting with a contract function using the `eth_call` API. """ call_transaction = prepare_transaction( abi, address, web3, fn_name=function_name, fn_args=args, fn_kwargs=kwargs, transaction=transaction, ) return_data = web3.eth.call(call_transaction) function_abi = find_matching_fn_abi(abi, function_name, args, kwargs) output_types = get_abi_output_types(function_abi) try: output_data = decode_abi(output_types, return_data) except DecodingError as e: # Provide a more helpful error message than the one provided by # eth-abi-utils is_missing_code_error = ( return_data in ACCEPTABLE_EMPTY_STRINGS and web3.eth.getCode(address) in ACCEPTABLE_EMPTY_STRINGS ) if is_missing_code_error: msg = ( "Could not transact with/call contract function, is contract " "deployed correctly and chain synced?" ) else: msg = ( "Could not decode contract function call {} return data {} for " "output_types {}".format( function_name, return_data, output_types ) ) raise BadFunctionCallOutput(msg) from e _normalizers = itertools.chain( BASE_RETURN_NORMALIZERS, normalizers, ) normalized_data = map_abi_data(_normalizers, output_types, output_data) if len(normalized_data) == 1: return normalized_data[0] else: return normalized_data