diff --git a/tests/contracts/test_contract_transact_interface.py b/tests/contracts/test_contract_transact_interface.py index dc3d503..9b3fca7 100644 --- a/tests/contracts/test_contract_transact_interface.py +++ b/tests/contracts/test_contract_transact_interface.py @@ -143,4 +143,4 @@ def test_auto_gas_computation_when_transacting(web3, assert force_bytes(final_value) == force_bytes("ÄLÄMÖLÖ") txn = web3.eth.getTransaction(txn_hash) - assert txn['gas'] == gas_estimate + string_contract.gas_buffer + assert txn['gas'] == gas_estimate + 100000 diff --git a/tests/eth-module/test_eth_sendTransaction.py b/tests/eth-module/test_eth_sendTransaction.py index 37636c0..71ee1c4 100644 --- a/tests/eth-module/test_eth_sendTransaction.py +++ b/tests/eth-module/test_eth_sendTransaction.py @@ -38,3 +38,17 @@ def test_eth_sendTransaction_with_data(web3, wait_for_transaction, MATH_CODE, MA contract_address = txn_receipt['contractAddress'] assert force_bytes(web3.eth.getCode(contract_address)) == MATH_RUNTIME + + +def test_eth_sendTransaction_auto_estimates_gas_if_not_provided(web3, wait_for_transaction, MATH_CODE, MATH_RUNTIME): + txn_hash = web3.eth.sendTransaction({ + "from": web3.eth.coinbase, + "data": MATH_CODE, + }) + + wait_for_transaction(web3, txn_hash) + + txn_receipt = web3.eth.getTransactionReceipt(txn_hash) + contract_address = txn_receipt['contractAddress'] + + assert force_bytes(web3.eth.getCode(contract_address)) == MATH_RUNTIME diff --git a/web3/contract.py b/web3/contract.py index de95a66..a58cf92 100644 --- a/web3/contract.py +++ b/web3/contract.py @@ -39,9 +39,6 @@ from web3.utils.abi import ( from web3.utils.decorators import ( combomethod, ) -from web3.utils.transactions import ( - get_block_gas_limit, -) from web3.utils.events import ( get_event_data, ) @@ -78,9 +75,6 @@ class Contract(object): # instance level properties address = None - # extra gas to include when auto-computing transaction gas. - gas_buffer = 100000 - def __init__(self, abi=None, address=None, code=None, code_runtime=None, source=None): """Create a new smart contract proxy object. @@ -246,30 +240,10 @@ class Contract(object): deploy_transaction['data'] = cls.encodeConstructorData(arguments) - if 'gas' not in deploy_transaction: - deploy_transaction['gas'] = cls.getBufferedGasEstimate(deploy_transaction) - # TODO: handle asynchronous contract creation txn_hash = cls.web3.eth.sendTransaction(deploy_transaction) return txn_hash - @classmethod - def getBufferedGasEstimate(cls, transaction): - gas_estimate_transaction = dict(**transaction) - - gas_estimate = cls.web3.eth.estimateGas(gas_estimate_transaction) - - gas_limit = get_block_gas_limit(cls.web3) - - if gas_estimate > gas_limit: - raise ValueError( - "Contract does not appear to be delpoyable within the " - "current network gas limits. Estimated: {0}. Current gas " - "limit: {1}".format(gas_estimate, gas_limit) - ) - - return min(gas_limit, gas_estimate + cls.gas_buffer) - # # ABI Helpers # @@ -756,9 +730,6 @@ def transact_with_contract_function(contract=None, data=function_selector, ) - if 'gas' not in transact_transaction: - transact_transaction['gas'] = contract.getBufferedGasEstimate(transact_transaction) - txn_hash = contract.web3.eth.sendTransaction(transact_transaction) return txn_hash diff --git a/web3/eth.py b/web3/eth.py index 0f3a7b6..a3072b1 100644 --- a/web3/eth.py +++ b/web3/eth.py @@ -12,6 +12,9 @@ from web3.utils.types import ( from web3.utils.functional import ( apply_formatters_to_return, ) +from web3.utils.transactions import ( + get_buffered_gas_estimate, +) from web3.utils.filters import ( BlockFilter, TransactionFilter, @@ -204,6 +207,11 @@ class Eth(object): def sendTransaction(self, transaction): formatted_transaction = formatters.input_transaction_formatter(self, transaction) + if 'gas' not in formatted_transaction and 'data' in formatted_transaction: + formatted_transaction['gas'] = get_buffered_gas_estimate( + self.web3, + transaction=formatted_transaction, + ) return self.request_manager.request_blocking( "eth_sendTransaction", diff --git a/web3/utils/transactions.py b/web3/utils/transactions.py index a747bba..4f0d5a6 100644 --- a/web3/utils/transactions.py +++ b/web3/utils/transactions.py @@ -17,3 +17,20 @@ def get_block_gas_limit(web3, block_identifier=None): block_identifier = web3.eth.blockNumber block = web3.eth.getBlock(block_identifier) return block['gasLimit'] + + +def get_buffered_gas_estimate(web3, transaction, gas_buffer=100000): + gas_estimate_transaction = dict(**transaction) + + gas_estimate = web3.eth.estimateGas(gas_estimate_transaction) + + gas_limit = get_block_gas_limit(web3) + + if gas_estimate > gas_limit: + raise ValueError( + "Contract does not appear to be delpoyable within the " + "current network gas limits. Estimated: {0}. Current gas " + "limit: {1}".format(gas_estimate, gas_limit) + ) + + return min(gas_limit, gas_estimate + gas_buffer)