web3 7.5.0__py3-none-any.whl → 7.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- web3/_utils/abi.py +59 -1
- web3/_utils/contract_sources/contract_data/ambiguous_function_contract.py +42 -0
- web3/_utils/contract_sources/contract_data/event_contracts.py +49 -4
- web3/_utils/contracts.py +49 -8
- web3/_utils/method_formatters.py +1 -0
- web3/_utils/module_testing/eth_module.py +11 -0
- web3/_utils/rpc_abi.py +1 -0
- web3/_utils/validation.py +3 -0
- web3/contract/async_contract.py +216 -62
- web3/contract/base_contract.py +176 -110
- web3/contract/contract.py +227 -64
- web3/contract/utils.py +7 -3
- web3/eth/async_eth.py +11 -0
- web3/eth/eth.py +11 -0
- web3/providers/eth_tester/defaults.py +1 -0
- web3/providers/ipc.py +1 -1
- web3/providers/persistent/async_ipc.py +1 -1
- web3/utils/abi.py +300 -85
- web3/utils/address.py +8 -0
- {web3-7.5.0.dist-info → web3-7.6.1.dist-info}/METADATA +8 -8
- {web3-7.5.0.dist-info → web3-7.6.1.dist-info}/RECORD +24 -23
- {web3-7.5.0.dist-info → web3-7.6.1.dist-info}/LICENSE +0 -0
- {web3-7.5.0.dist-info → web3-7.6.1.dist-info}/WHEEL +0 -0
- {web3-7.5.0.dist-info → web3-7.6.1.dist-info}/top_level.txt +0 -0
web3/contract/async_contract.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import copy
|
|
2
1
|
from typing import (
|
|
3
2
|
TYPE_CHECKING,
|
|
4
3
|
Any,
|
|
@@ -15,15 +14,16 @@ from typing import (
|
|
|
15
14
|
|
|
16
15
|
from eth_typing import (
|
|
17
16
|
ABI,
|
|
18
|
-
|
|
17
|
+
ABIFunction,
|
|
19
18
|
ChecksumAddress,
|
|
20
19
|
)
|
|
21
20
|
from eth_utils import (
|
|
22
21
|
combomethod,
|
|
23
22
|
)
|
|
24
23
|
from eth_utils.abi import (
|
|
24
|
+
abi_to_signature,
|
|
25
|
+
filter_abi_by_type,
|
|
25
26
|
get_abi_input_names,
|
|
26
|
-
get_all_function_abis,
|
|
27
27
|
)
|
|
28
28
|
from eth_utils.toolz import (
|
|
29
29
|
partial,
|
|
@@ -34,6 +34,7 @@ from hexbytes import (
|
|
|
34
34
|
|
|
35
35
|
from web3._utils.abi import (
|
|
36
36
|
fallback_func_abi_exists,
|
|
37
|
+
get_name_from_abi_element_identifier,
|
|
37
38
|
receive_func_abi_exists,
|
|
38
39
|
)
|
|
39
40
|
from web3._utils.abi_element_identifiers import (
|
|
@@ -48,6 +49,8 @@ from web3._utils.compat import (
|
|
|
48
49
|
)
|
|
49
50
|
from web3._utils.contracts import (
|
|
50
51
|
async_parse_block_identifier,
|
|
52
|
+
copy_contract_event,
|
|
53
|
+
copy_contract_function,
|
|
51
54
|
)
|
|
52
55
|
from web3._utils.datatypes import (
|
|
53
56
|
PropertyCheckingFactory,
|
|
@@ -86,7 +89,10 @@ from web3.contract.utils import (
|
|
|
86
89
|
get_function_by_identifier,
|
|
87
90
|
)
|
|
88
91
|
from web3.exceptions import (
|
|
92
|
+
ABIEventNotFound,
|
|
89
93
|
ABIFunctionNotFound,
|
|
94
|
+
MismatchedABI,
|
|
95
|
+
NoABIEventsFound,
|
|
90
96
|
NoABIFound,
|
|
91
97
|
NoABIFunctionsFound,
|
|
92
98
|
Web3AttributeError,
|
|
@@ -101,6 +107,9 @@ from web3.types import (
|
|
|
101
107
|
TxParams,
|
|
102
108
|
)
|
|
103
109
|
from web3.utils.abi import (
|
|
110
|
+
_filter_by_argument_count,
|
|
111
|
+
_get_any_abi_signature_with_name,
|
|
112
|
+
_mismatched_abi_error_diagnosis,
|
|
104
113
|
get_abi_element,
|
|
105
114
|
)
|
|
106
115
|
|
|
@@ -113,16 +122,8 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
113
122
|
# mypy types
|
|
114
123
|
w3: "AsyncWeb3"
|
|
115
124
|
|
|
116
|
-
def __call__(self) -> "AsyncContractEvent":
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if not self.abi:
|
|
120
|
-
self.abi = cast(
|
|
121
|
-
ABIEvent,
|
|
122
|
-
get_abi_element(self.contract_abi, self.event_name),
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
return clone
|
|
125
|
+
def __call__(self, *args: Any, **kwargs: Any) -> "AsyncContractEvent":
|
|
126
|
+
return copy_contract_event(self, *args, **kwargs)
|
|
126
127
|
|
|
127
128
|
@combomethod
|
|
128
129
|
async def get_logs(
|
|
@@ -188,11 +189,9 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
188
189
|
same time as ``from_block`` or ``to_block``
|
|
189
190
|
:yield: Tuple of :class:`AttributeDict` instances
|
|
190
191
|
"""
|
|
191
|
-
event_abi = self._get_event_abi()
|
|
192
|
-
|
|
193
192
|
# validate ``argument_filters`` if present
|
|
194
193
|
if argument_filters is not None:
|
|
195
|
-
event_arg_names = get_abi_input_names(
|
|
194
|
+
event_arg_names = get_abi_input_names(self.abi)
|
|
196
195
|
if not all(arg in event_arg_names for arg in argument_filters.keys()):
|
|
197
196
|
raise Web3ValidationError(
|
|
198
197
|
"When filtering by argument names, all argument names must be "
|
|
@@ -200,17 +199,17 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
200
199
|
)
|
|
201
200
|
|
|
202
201
|
_filter_params = self._get_event_filter_params(
|
|
203
|
-
|
|
202
|
+
self.abi, argument_filters, from_block, to_block, block_hash
|
|
204
203
|
)
|
|
205
204
|
# call JSON-RPC API
|
|
206
205
|
logs = await self.w3.eth.get_logs(_filter_params)
|
|
207
206
|
|
|
208
207
|
# convert raw binary data to Python proxy objects as described by ABI:
|
|
209
208
|
all_event_logs = tuple(
|
|
210
|
-
get_event_data(self.w3.codec,
|
|
209
|
+
get_event_data(self.w3.codec, self.abi, entry) for entry in logs
|
|
211
210
|
)
|
|
212
211
|
filtered_logs = self._process_get_logs_argument_filters(
|
|
213
|
-
|
|
212
|
+
self.abi,
|
|
214
213
|
all_event_logs,
|
|
215
214
|
argument_filters,
|
|
216
215
|
)
|
|
@@ -231,7 +230,7 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
231
230
|
"""
|
|
232
231
|
Create filter object that tracks logs emitted by this contract event.
|
|
233
232
|
"""
|
|
234
|
-
filter_builder = AsyncEventFilterBuilder(self.
|
|
233
|
+
filter_builder = AsyncEventFilterBuilder(self.abi, self.w3.codec)
|
|
235
234
|
self._set_up_filter_builder(
|
|
236
235
|
argument_filters,
|
|
237
236
|
from_block,
|
|
@@ -241,9 +240,7 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
241
240
|
filter_builder,
|
|
242
241
|
)
|
|
243
242
|
log_filter = await filter_builder.deploy(self.w3)
|
|
244
|
-
log_filter.log_entry_formatter = get_event_data(
|
|
245
|
-
self.w3.codec, self._get_event_abi()
|
|
246
|
-
)
|
|
243
|
+
log_filter.log_entry_formatter = get_event_data(self.w3.codec, self.abi)
|
|
247
244
|
log_filter.builder = filter_builder
|
|
248
245
|
|
|
249
246
|
return log_filter
|
|
@@ -251,18 +248,16 @@ class AsyncContractEvent(BaseContractEvent):
|
|
|
251
248
|
@combomethod
|
|
252
249
|
def build_filter(self) -> AsyncEventFilterBuilder:
|
|
253
250
|
builder = AsyncEventFilterBuilder(
|
|
254
|
-
self.
|
|
251
|
+
self.abi,
|
|
255
252
|
self.w3.codec,
|
|
256
|
-
formatter=get_event_data(self.w3.codec, self.
|
|
253
|
+
formatter=get_event_data(self.w3.codec, self.abi),
|
|
257
254
|
)
|
|
258
255
|
builder.address = self.address
|
|
259
256
|
return builder
|
|
260
257
|
|
|
261
258
|
@classmethod
|
|
262
259
|
def factory(cls, class_name: str, **kwargs: Any) -> Self:
|
|
263
|
-
return PropertyCheckingFactory(class_name, (cls,), kwargs)(
|
|
264
|
-
abi=kwargs.get("abi")
|
|
265
|
-
)
|
|
260
|
+
return PropertyCheckingFactory(class_name, (cls,), kwargs)()
|
|
266
261
|
|
|
267
262
|
|
|
268
263
|
class AsyncContractEvents(BaseContractEvents):
|
|
@@ -271,28 +266,150 @@ class AsyncContractEvents(BaseContractEvents):
|
|
|
271
266
|
) -> None:
|
|
272
267
|
super().__init__(abi, w3, AsyncContractEvent, address)
|
|
273
268
|
|
|
269
|
+
def __iter__(self) -> Iterable["AsyncContractEvent"]:
|
|
270
|
+
if not hasattr(self, "_events") or not self._events:
|
|
271
|
+
return
|
|
272
|
+
|
|
273
|
+
for event in self._events:
|
|
274
|
+
yield self[abi_to_signature(event)]
|
|
275
|
+
|
|
276
|
+
def __getattr__(self, event_name: str) -> "AsyncContractEvent":
|
|
277
|
+
if super().__getattribute__("abi") is None:
|
|
278
|
+
raise NoABIFound(
|
|
279
|
+
"There is no ABI found for this contract.",
|
|
280
|
+
)
|
|
281
|
+
elif "_events" not in self.__dict__ or len(self._events) == 0:
|
|
282
|
+
raise NoABIEventsFound(
|
|
283
|
+
"The abi for this contract contains no event definitions. ",
|
|
284
|
+
"Are you sure you provided the correct contract abi?",
|
|
285
|
+
)
|
|
286
|
+
elif get_name_from_abi_element_identifier(event_name) not in [
|
|
287
|
+
get_name_from_abi_element_identifier(event["name"])
|
|
288
|
+
for event in self._events
|
|
289
|
+
]:
|
|
290
|
+
raise ABIEventNotFound(
|
|
291
|
+
f"The event '{event_name}' was not found in this contract's abi. ",
|
|
292
|
+
"Are you sure you provided the correct contract abi?",
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
if "(" not in event_name:
|
|
296
|
+
event_name = _get_any_abi_signature_with_name(event_name, self._events)
|
|
297
|
+
else:
|
|
298
|
+
event_name = f"_{event_name}"
|
|
299
|
+
|
|
300
|
+
return super().__getattribute__(event_name)
|
|
301
|
+
|
|
302
|
+
def __getitem__(self, event_name: str) -> "AsyncContractEvent":
|
|
303
|
+
return getattr(self, event_name)
|
|
304
|
+
|
|
274
305
|
|
|
275
306
|
class AsyncContractFunction(BaseContractFunction):
|
|
276
307
|
# mypy types
|
|
277
308
|
w3: "AsyncWeb3"
|
|
278
309
|
|
|
279
310
|
def __call__(self, *args: Any, **kwargs: Any) -> "AsyncContractFunction":
|
|
280
|
-
|
|
281
|
-
if args
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
311
|
+
# When a function is called, check arguments to obtain the correct function
|
|
312
|
+
# in the contract. self will be used if all args and kwargs are
|
|
313
|
+
# encodable to self.abi, otherwise the correct function is obtained from
|
|
314
|
+
# the contract.
|
|
315
|
+
if (
|
|
316
|
+
self.abi_element_identifier in [FallbackFn, ReceiveFn]
|
|
317
|
+
or self.abi_element_identifier == "constructor"
|
|
318
|
+
):
|
|
319
|
+
return copy_contract_function(self, *args, **kwargs)
|
|
320
|
+
|
|
321
|
+
all_functions = cast(
|
|
322
|
+
List[ABIFunction],
|
|
323
|
+
filter_abi_by_type(
|
|
324
|
+
"function",
|
|
325
|
+
self.contract_abi,
|
|
326
|
+
),
|
|
327
|
+
)
|
|
328
|
+
# Filter functions by name to obtain function signatures
|
|
329
|
+
function_name = get_name_from_abi_element_identifier(
|
|
330
|
+
self.abi_element_identifier
|
|
331
|
+
)
|
|
332
|
+
function_abis = [
|
|
333
|
+
function for function in all_functions if function["name"] == function_name
|
|
334
|
+
]
|
|
335
|
+
num_args = len(args) + len(kwargs)
|
|
336
|
+
function_abis_with_arg_count = cast(
|
|
337
|
+
List[ABIFunction],
|
|
338
|
+
_filter_by_argument_count(
|
|
339
|
+
num_args,
|
|
340
|
+
function_abis,
|
|
341
|
+
),
|
|
342
|
+
)
|
|
285
343
|
|
|
286
|
-
if
|
|
287
|
-
|
|
344
|
+
if not len(function_abis_with_arg_count):
|
|
345
|
+
# Build an ABI without arguments to determine if one exists
|
|
346
|
+
function_abis_with_arg_count = [
|
|
347
|
+
ABIFunction({"type": "function", "name": function_name})
|
|
348
|
+
]
|
|
349
|
+
|
|
350
|
+
# Check that arguments in call match a function ABI
|
|
351
|
+
num_attempts = 0
|
|
352
|
+
function_abi_matches = []
|
|
353
|
+
contract_function = None
|
|
354
|
+
for abi in function_abis_with_arg_count:
|
|
355
|
+
try:
|
|
356
|
+
num_attempts += 1
|
|
357
|
+
|
|
358
|
+
# Search for a function ABI that matches the arguments used
|
|
359
|
+
function_abi_matches.append(
|
|
360
|
+
cast(
|
|
361
|
+
ABIFunction,
|
|
362
|
+
get_abi_element(
|
|
363
|
+
function_abis,
|
|
364
|
+
abi_to_signature(abi),
|
|
365
|
+
*args,
|
|
366
|
+
abi_codec=self.w3.codec,
|
|
367
|
+
**kwargs,
|
|
368
|
+
),
|
|
369
|
+
)
|
|
370
|
+
)
|
|
371
|
+
except MismatchedABI:
|
|
372
|
+
# ignore exceptions
|
|
373
|
+
continue
|
|
374
|
+
|
|
375
|
+
if len(function_abi_matches) == 1:
|
|
376
|
+
function_abi = function_abi_matches[0]
|
|
377
|
+
if abi_to_signature(self.abi) == abi_to_signature(function_abi):
|
|
378
|
+
contract_function = self
|
|
379
|
+
else:
|
|
380
|
+
# Found a match that is not self
|
|
381
|
+
contract_function = AsyncContractFunction.factory(
|
|
382
|
+
abi_to_signature(function_abi),
|
|
383
|
+
w3=self.w3,
|
|
384
|
+
contract_abi=self.contract_abi,
|
|
385
|
+
address=self.address,
|
|
386
|
+
abi_element_identifier=abi_to_signature(function_abi),
|
|
387
|
+
abi=function_abi,
|
|
388
|
+
)
|
|
288
389
|
else:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
390
|
+
for abi in function_abi_matches:
|
|
391
|
+
if abi_to_signature(self.abi) == abi_to_signature(abi):
|
|
392
|
+
contract_function = self
|
|
393
|
+
break
|
|
394
|
+
else:
|
|
395
|
+
# Raise exception if multiple found
|
|
396
|
+
raise MismatchedABI(
|
|
397
|
+
_mismatched_abi_error_diagnosis(
|
|
398
|
+
function_name,
|
|
399
|
+
self.contract_abi,
|
|
400
|
+
len(function_abi_matches),
|
|
401
|
+
num_args,
|
|
402
|
+
*args,
|
|
403
|
+
abi_codec=self.w3.codec,
|
|
404
|
+
**kwargs,
|
|
405
|
+
)
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
return copy_contract_function(contract_function, *args, **kwargs)
|
|
292
409
|
|
|
293
410
|
@classmethod
|
|
294
411
|
def factory(cls, class_name: str, **kwargs: Any) -> Self:
|
|
295
|
-
return PropertyCheckingFactory(class_name, (cls,), kwargs)(
|
|
412
|
+
return PropertyCheckingFactory(class_name, (cls,), kwargs)()
|
|
296
413
|
|
|
297
414
|
async def call(
|
|
298
415
|
self,
|
|
@@ -332,11 +449,13 @@ class AsyncContractFunction(BaseContractFunction):
|
|
|
332
449
|
|
|
333
450
|
block_id = await async_parse_block_identifier(self.w3, block_identifier)
|
|
334
451
|
|
|
452
|
+
abi_element_identifier = abi_to_signature(self.abi)
|
|
453
|
+
|
|
335
454
|
return await async_call_contract_function(
|
|
336
455
|
self.w3,
|
|
337
456
|
self.address,
|
|
338
457
|
self._return_data_normalizers,
|
|
339
|
-
|
|
458
|
+
abi_element_identifier,
|
|
340
459
|
call_transaction,
|
|
341
460
|
block_id,
|
|
342
461
|
self.contract_abi,
|
|
@@ -350,10 +469,11 @@ class AsyncContractFunction(BaseContractFunction):
|
|
|
350
469
|
|
|
351
470
|
async def transact(self, transaction: Optional[TxParams] = None) -> HexBytes:
|
|
352
471
|
setup_transaction = self._transact(transaction)
|
|
472
|
+
abi_element_identifier = abi_to_signature(self.abi)
|
|
353
473
|
return await async_transact_with_contract_function(
|
|
354
474
|
self.address,
|
|
355
475
|
self.w3,
|
|
356
|
-
|
|
476
|
+
abi_element_identifier,
|
|
357
477
|
setup_transaction,
|
|
358
478
|
self.contract_abi,
|
|
359
479
|
self.abi,
|
|
@@ -368,10 +488,11 @@ class AsyncContractFunction(BaseContractFunction):
|
|
|
368
488
|
state_override: Optional[StateOverride] = None,
|
|
369
489
|
) -> int:
|
|
370
490
|
setup_transaction = self._estimate_gas(transaction)
|
|
491
|
+
abi_element_identifier = abi_to_signature(self.abi)
|
|
371
492
|
return await async_estimate_gas_for_function(
|
|
372
493
|
self.address,
|
|
373
494
|
self.w3,
|
|
374
|
-
|
|
495
|
+
abi_element_identifier,
|
|
375
496
|
setup_transaction,
|
|
376
497
|
self.contract_abi,
|
|
377
498
|
self.abi,
|
|
@@ -385,10 +506,11 @@ class AsyncContractFunction(BaseContractFunction):
|
|
|
385
506
|
self, transaction: Optional[TxParams] = None
|
|
386
507
|
) -> TxParams:
|
|
387
508
|
built_transaction = self._build_transaction(transaction)
|
|
509
|
+
abi_element_identifier = abi_to_signature(self.abi)
|
|
388
510
|
return await async_build_transaction_for_function(
|
|
389
511
|
self.address,
|
|
390
512
|
self.w3,
|
|
391
|
-
|
|
513
|
+
abi_element_identifier,
|
|
392
514
|
built_transaction,
|
|
393
515
|
self.contract_abi,
|
|
394
516
|
self.abi,
|
|
@@ -439,23 +561,45 @@ class AsyncContractFunctions(BaseContractFunctions):
|
|
|
439
561
|
) -> None:
|
|
440
562
|
super().__init__(abi, w3, AsyncContractFunction, address, decode_tuples)
|
|
441
563
|
|
|
564
|
+
def __iter__(self) -> Iterable["AsyncContractFunction"]:
|
|
565
|
+
if not hasattr(self, "_functions") or not self._functions:
|
|
566
|
+
return
|
|
567
|
+
|
|
568
|
+
for func in self._functions:
|
|
569
|
+
yield self[abi_to_signature(func)]
|
|
570
|
+
|
|
442
571
|
def __getattr__(self, function_name: str) -> "AsyncContractFunction":
|
|
443
|
-
if
|
|
572
|
+
if super().__getattribute__("abi") is None:
|
|
444
573
|
raise NoABIFound(
|
|
445
574
|
"There is no ABI found for this contract.",
|
|
446
575
|
)
|
|
447
|
-
|
|
576
|
+
elif "_functions" not in self.__dict__ or len(self._functions) == 0:
|
|
448
577
|
raise NoABIFunctionsFound(
|
|
449
578
|
"The abi for this contract contains no function definitions. ",
|
|
450
579
|
"Are you sure you provided the correct contract abi?",
|
|
451
580
|
)
|
|
452
|
-
elif function_name not in
|
|
581
|
+
elif get_name_from_abi_element_identifier(function_name) not in [
|
|
582
|
+
get_name_from_abi_element_identifier(function["name"])
|
|
583
|
+
for function in self._functions
|
|
584
|
+
]:
|
|
453
585
|
raise ABIFunctionNotFound(
|
|
454
|
-
f"The function '{function_name}' was not found in this
|
|
455
|
-
"
|
|
586
|
+
f"The function '{function_name}' was not found in this ",
|
|
587
|
+
"contract's abi.",
|
|
588
|
+
)
|
|
589
|
+
|
|
590
|
+
if "(" not in function_name:
|
|
591
|
+
function_name = _get_any_abi_signature_with_name(
|
|
592
|
+
function_name, self._functions
|
|
456
593
|
)
|
|
457
594
|
else:
|
|
458
|
-
|
|
595
|
+
function_name = f"_{function_name}"
|
|
596
|
+
|
|
597
|
+
return super().__getattribute__(
|
|
598
|
+
function_name,
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
def __getitem__(self, function_name: str) -> "AsyncContractFunction":
|
|
602
|
+
return getattr(self, function_name)
|
|
459
603
|
|
|
460
604
|
|
|
461
605
|
class AsyncContract(BaseContract):
|
|
@@ -491,7 +635,11 @@ class AsyncContract(BaseContract):
|
|
|
491
635
|
self.abi, self.w3, self.address, decode_tuples=self.decode_tuples
|
|
492
636
|
)
|
|
493
637
|
self.caller = AsyncContractCaller(
|
|
494
|
-
self.abi,
|
|
638
|
+
self.abi,
|
|
639
|
+
self.w3,
|
|
640
|
+
self.address,
|
|
641
|
+
decode_tuples=self.decode_tuples,
|
|
642
|
+
contract_functions=self.functions,
|
|
495
643
|
)
|
|
496
644
|
self.events = AsyncContractEvents(self.abi, self.w3, self.address)
|
|
497
645
|
self.fallback = AsyncContract.get_fallback_function(
|
|
@@ -523,6 +671,16 @@ class AsyncContract(BaseContract):
|
|
|
523
671
|
normalizers=normalizers,
|
|
524
672
|
),
|
|
525
673
|
)
|
|
674
|
+
|
|
675
|
+
if contract.abi:
|
|
676
|
+
for abi in contract.abi:
|
|
677
|
+
abi_name = abi.get("name")
|
|
678
|
+
if abi_name in ["abi", "address"]:
|
|
679
|
+
raise Web3AttributeError(
|
|
680
|
+
f"Contract contains a reserved word `{abi_name}` "
|
|
681
|
+
f"and could not be instantiated."
|
|
682
|
+
)
|
|
683
|
+
|
|
526
684
|
contract.functions = AsyncContractFunctions(
|
|
527
685
|
contract.abi, contract.w3, decode_tuples=contract.decode_tuples
|
|
528
686
|
)
|
|
@@ -531,6 +689,7 @@ class AsyncContract(BaseContract):
|
|
|
531
689
|
contract.w3,
|
|
532
690
|
contract.address,
|
|
533
691
|
decode_tuples=contract.decode_tuples,
|
|
692
|
+
contract_functions=contract.functions,
|
|
534
693
|
)
|
|
535
694
|
contract.events = AsyncContractEvents(contract.abi, contract.w3)
|
|
536
695
|
contract.fallback = AsyncContract.get_fallback_function(
|
|
@@ -613,6 +772,7 @@ class AsyncContractCaller(BaseContractCaller):
|
|
|
613
772
|
block_identifier: BlockIdentifier = None,
|
|
614
773
|
ccip_read_enabled: Optional[bool] = None,
|
|
615
774
|
decode_tuples: Optional[bool] = False,
|
|
775
|
+
contract_functions: Optional[AsyncContractFunctions] = None,
|
|
616
776
|
) -> None:
|
|
617
777
|
super().__init__(abi, w3, address, decode_tuples=decode_tuples)
|
|
618
778
|
|
|
@@ -620,18 +780,13 @@ class AsyncContractCaller(BaseContractCaller):
|
|
|
620
780
|
if transaction is None:
|
|
621
781
|
transaction = {}
|
|
622
782
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
fn = AsyncContractFunction.factory(
|
|
627
|
-
func["name"],
|
|
628
|
-
w3=w3,
|
|
629
|
-
contract_abi=self.abi,
|
|
630
|
-
address=self.address,
|
|
631
|
-
abi_element_identifier=func["name"],
|
|
632
|
-
decode_tuples=decode_tuples,
|
|
783
|
+
if contract_functions is None:
|
|
784
|
+
contract_functions = AsyncContractFunctions(
|
|
785
|
+
abi, w3, address, decode_tuples=decode_tuples
|
|
633
786
|
)
|
|
634
787
|
|
|
788
|
+
self._functions = contract_functions._functions
|
|
789
|
+
for fn in contract_functions.__iter__():
|
|
635
790
|
caller_method = partial(
|
|
636
791
|
self.call_function,
|
|
637
792
|
fn,
|
|
@@ -639,8 +794,7 @@ class AsyncContractCaller(BaseContractCaller):
|
|
|
639
794
|
block_identifier=block_identifier,
|
|
640
795
|
ccip_read_enabled=ccip_read_enabled,
|
|
641
796
|
)
|
|
642
|
-
|
|
643
|
-
setattr(self, func["name"], caller_method)
|
|
797
|
+
setattr(self, str(fn.abi_element_identifier), caller_method)
|
|
644
798
|
|
|
645
799
|
def __call__(
|
|
646
800
|
self,
|