Skip to content

Commit e117b6b

Browse files
dbfreempacrob
authored and
pacrob
committed
Feature/asyncify contract (ethereum#2392)
* asyncify contract.transact and contract.estimate_gas
1 parent 253f114 commit e117b6b

File tree

1 file changed

+130
-28
lines changed

1 file changed

+130
-28
lines changed

web3/contract.py

Lines changed: 130 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,7 @@ def _get_call_txparams(self, transaction: Optional[TxParams] = None) -> TxParams
11141114

11151115
return call_transaction
11161116

1117-
def transact(self, transaction: Optional[TxParams] = None) -> HexBytes:
1117+
def _transact(self, transaction: Optional[TxParams] = None) -> TxParams:
11181118
if transaction is None:
11191119
transact_transaction: TxParams = {}
11201120
else:
@@ -1139,22 +1139,11 @@ def transact(self, transaction: Optional[TxParams] = None) -> HexBytes:
11391139
raise ValueError(
11401140
"Please ensure that this contract instance has an address."
11411141
)
1142+
return transact_transaction
11421143

1143-
return transact_with_contract_function(
1144-
self.address,
1145-
self.w3,
1146-
self.function_identifier,
1147-
transact_transaction,
1148-
self.contract_abi,
1149-
self.abi,
1150-
*self.args,
1151-
**self.kwargs
1152-
)
1153-
1154-
def estimateGas(
1155-
self, transaction: Optional[TxParams] = None,
1156-
block_identifier: Optional[BlockIdentifier] = None
1157-
) -> int:
1144+
def _estimate_gas(
1145+
self, transaction: Optional[TxParams] = None
1146+
) -> TxParams:
11581147
if transaction is None:
11591148
estimate_gas_transaction: TxParams = {}
11601149
else:
@@ -1181,18 +1170,7 @@ def estimateGas(
11811170
raise ValueError(
11821171
"Please ensure that this contract instance has an address."
11831172
)
1184-
1185-
return estimate_gas_for_function(
1186-
self.address,
1187-
self.w3,
1188-
self.function_identifier,
1189-
estimate_gas_transaction,
1190-
self.contract_abi,
1191-
self.abi,
1192-
block_identifier,
1193-
*self.args,
1194-
**self.kwargs
1195-
)
1173+
return estimate_gas_transaction
11961174

11971175
def buildTransaction(self, transaction: Optional[TxParams] = None) -> TxParams:
11981176
"""
@@ -1315,6 +1293,43 @@ def call(self, transaction: Optional[TxParams] = None,
13151293
def factory(cls, class_name: str, **kwargs: Any) -> 'ContractFunction':
13161294
return PropertyCheckingFactory(class_name, (cls,), kwargs)(kwargs.get('abi'))
13171295

1296+
def transact(self, transaction: Optional[TxParams] = None) -> HexBytes:
1297+
setup_transaction = self._transact(transaction)
1298+
return transact_with_contract_function(
1299+
self.address,
1300+
self.w3,
1301+
self.function_identifier,
1302+
setup_transaction,
1303+
self.contract_abi,
1304+
self.abi,
1305+
*self.args,
1306+
**self.kwargs
1307+
)
1308+
1309+
def estimate_gas(
1310+
self, transaction: Optional[TxParams] = None,
1311+
block_identifier: Optional[BlockIdentifier] = None
1312+
) -> int:
1313+
setup_transaction = self._estimate_gas(transaction)
1314+
return estimate_gas_for_function(
1315+
self.address,
1316+
self.w3,
1317+
self.function_identifier,
1318+
setup_transaction,
1319+
self.contract_abi,
1320+
self.abi,
1321+
block_identifier,
1322+
*self.args,
1323+
**self.kwargs
1324+
)
1325+
1326+
@deprecated_for("estimate_gas")
1327+
def estimateGas(
1328+
self, transaction: Optional[TxParams] = None,
1329+
block_identifier: Optional[BlockIdentifier] = None
1330+
) -> int:
1331+
return self.estimate_gas(transaction, block_identifier)
1332+
13181333

13191334
class AsyncContractFunction(BaseContractFunction):
13201335

@@ -1385,6 +1400,36 @@ async def call(
13851400
def factory(cls, class_name: str, **kwargs: Any) -> 'AsyncContractFunction':
13861401
return PropertyCheckingFactory(class_name, (cls,), kwargs)(kwargs.get('abi'))
13871402

1403+
async def transact(self, transaction: Optional[TxParams] = None) -> HexBytes:
1404+
setup_transaction = self._transact(transaction)
1405+
return await async_transact_with_contract_function(
1406+
self.address,
1407+
self.w3,
1408+
self.function_identifier,
1409+
setup_transaction,
1410+
self.contract_abi,
1411+
self.abi,
1412+
*self.args,
1413+
**self.kwargs
1414+
)
1415+
1416+
async def estimate_gas(
1417+
self, transaction: Optional[TxParams] = None,
1418+
block_identifier: Optional[BlockIdentifier] = None
1419+
) -> int:
1420+
setup_transaction = self._estimate_gas(transaction)
1421+
return await async_estimate_gas_for_function(
1422+
self.address,
1423+
self.w3,
1424+
self.function_identifier,
1425+
setup_transaction,
1426+
self.contract_abi,
1427+
self.abi,
1428+
block_identifier,
1429+
*self.args,
1430+
**self.kwargs
1431+
)
1432+
13881433

13891434
class BaseContractEvent:
13901435
"""Base class for contract events
@@ -2091,6 +2136,34 @@ def transact_with_contract_function(
20912136
return txn_hash
20922137

20932138

2139+
async def async_transact_with_contract_function(
2140+
address: ChecksumAddress,
2141+
w3: 'Web3',
2142+
function_name: Optional[FunctionIdentifier] = None,
2143+
transaction: Optional[TxParams] = None,
2144+
contract_abi: Optional[ABI] = None,
2145+
fn_abi: Optional[ABIFunction] = None,
2146+
*args: Any,
2147+
**kwargs: Any) -> HexBytes:
2148+
"""
2149+
Helper function for interacting with a contract function by sending a
2150+
transaction.
2151+
"""
2152+
transact_transaction = prepare_transaction(
2153+
address,
2154+
w3,
2155+
fn_identifier=function_name,
2156+
contract_abi=contract_abi,
2157+
transaction=transaction,
2158+
fn_abi=fn_abi,
2159+
fn_args=args,
2160+
fn_kwargs=kwargs,
2161+
)
2162+
2163+
txn_hash = await w3.eth.send_transaction(transact_transaction) # type: ignore
2164+
return txn_hash
2165+
2166+
20942167
def estimate_gas_for_function(
20952168
address: ChecksumAddress,
20962169
w3: 'Web3',
@@ -2120,6 +2193,35 @@ def estimate_gas_for_function(
21202193
return w3.eth.estimate_gas(estimate_transaction, block_identifier)
21212194

21222195

2196+
async def async_estimate_gas_for_function(
2197+
address: ChecksumAddress,
2198+
w3: 'Web3',
2199+
fn_identifier: Optional[FunctionIdentifier] = None,
2200+
transaction: Optional[TxParams] = None,
2201+
contract_abi: Optional[ABI] = None,
2202+
fn_abi: Optional[ABIFunction] = None,
2203+
block_identifier: Optional[BlockIdentifier] = None,
2204+
*args: Any,
2205+
**kwargs: Any) -> int:
2206+
"""Estimates gas cost a function call would take.
2207+
2208+
Don't call this directly, instead use :meth:`Contract.estimateGas`
2209+
on your contract instance.
2210+
"""
2211+
estimate_transaction = prepare_transaction(
2212+
address,
2213+
w3,
2214+
fn_identifier=fn_identifier,
2215+
contract_abi=contract_abi,
2216+
fn_abi=fn_abi,
2217+
transaction=transaction,
2218+
fn_args=args,
2219+
fn_kwargs=kwargs,
2220+
)
2221+
2222+
return await w3.eth.estimate_gas(estimate_transaction, block_identifier) # type: ignore
2223+
2224+
21232225
def build_transaction_for_function(
21242226
address: ChecksumAddress,
21252227
w3: 'Web3',

0 commit comments

Comments
 (0)