web3 7.5.0__py3-none-any.whl → 7.6.0__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/event_contracts.py +49 -4
- web3/_utils/contracts.py +48 -7
- 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 +159 -52
- web3/contract/base_contract.py +138 -102
- web3/contract/contract.py +154 -47
- web3/contract/utils.py +3 -2
- web3/eth/async_eth.py +11 -0
- web3/eth/eth.py +11 -0
- web3/providers/eth_tester/defaults.py +1 -0
- web3/utils/abi.py +308 -76
- {web3-7.5.0.dist-info → web3-7.6.0.dist-info}/METADATA +2 -2
- {web3-7.5.0.dist-info → web3-7.6.0.dist-info}/RECORD +20 -20
- {web3-7.5.0.dist-info → web3-7.6.0.dist-info}/LICENSE +0 -0
- {web3-7.5.0.dist-info → web3-7.6.0.dist-info}/WHEEL +0 -0
- {web3-7.5.0.dist-info → web3-7.6.0.dist-info}/top_level.txt +0 -0
web3/contract/base_contract.py
CHANGED
|
@@ -48,7 +48,10 @@ from hexbytes import (
|
|
|
48
48
|
|
|
49
49
|
from web3._utils.abi import (
|
|
50
50
|
fallback_func_abi_exists,
|
|
51
|
+
filter_by_types,
|
|
51
52
|
find_constructor_abi_element_by_type,
|
|
53
|
+
get_abi_element_signature,
|
|
54
|
+
get_name_from_abi_element_identifier,
|
|
52
55
|
is_array_type,
|
|
53
56
|
receive_func_abi_exists,
|
|
54
57
|
)
|
|
@@ -96,7 +99,6 @@ from web3.exceptions import (
|
|
|
96
99
|
InvalidEventABI,
|
|
97
100
|
LogTopicError,
|
|
98
101
|
MismatchedABI,
|
|
99
|
-
NoABIEventsFound,
|
|
100
102
|
NoABIFound,
|
|
101
103
|
NoABIFunctionsFound,
|
|
102
104
|
Web3AttributeError,
|
|
@@ -121,10 +123,10 @@ from web3.types import (
|
|
|
121
123
|
TxReceipt,
|
|
122
124
|
)
|
|
123
125
|
from web3.utils.abi import (
|
|
126
|
+
_get_any_abi_signature_with_name,
|
|
124
127
|
check_if_arguments_can_be_encoded,
|
|
125
128
|
get_abi_element,
|
|
126
129
|
get_abi_element_info,
|
|
127
|
-
get_event_abi,
|
|
128
130
|
)
|
|
129
131
|
|
|
130
132
|
if TYPE_CHECKING:
|
|
@@ -153,13 +155,20 @@ class BaseContractEvent:
|
|
|
153
155
|
|
|
154
156
|
address: ChecksumAddress = None
|
|
155
157
|
event_name: str = None
|
|
158
|
+
abi_element_identifier: ABIElementIdentifier = None
|
|
156
159
|
w3: Union["Web3", "AsyncWeb3"] = None
|
|
157
160
|
contract_abi: ABI = None
|
|
158
161
|
abi: ABIEvent = None
|
|
162
|
+
argument_types: Tuple[str] = None
|
|
163
|
+
args: Any = None
|
|
164
|
+
kwargs: Any = None
|
|
159
165
|
|
|
160
|
-
def __init__(self, *argument_names: Tuple[str]
|
|
166
|
+
def __init__(self, *argument_names: Tuple[str]) -> None:
|
|
167
|
+
self.event_name = get_name_from_abi_element_identifier(type(self).__name__)
|
|
168
|
+
self.abi_element_identifier = type(self).__name__
|
|
169
|
+
abi = self._get_event_abi()
|
|
170
|
+
self.name = abi_to_signature(abi)
|
|
161
171
|
self.abi = abi
|
|
162
|
-
self.name = type(self).__name__
|
|
163
172
|
|
|
164
173
|
if argument_names is None:
|
|
165
174
|
# https://github.com/python/mypy/issues/6283
|
|
@@ -168,11 +177,26 @@ class BaseContractEvent:
|
|
|
168
177
|
self.argument_names = argument_names
|
|
169
178
|
|
|
170
179
|
def __repr__(self) -> str:
|
|
171
|
-
|
|
180
|
+
if self.abi:
|
|
181
|
+
return f"<Event {abi_to_signature(self.abi)}>"
|
|
182
|
+
return f"<Event {get_abi_element_signature(self.abi_element_identifier)}>"
|
|
172
183
|
|
|
173
|
-
@
|
|
184
|
+
@combomethod
|
|
174
185
|
def _get_event_abi(cls) -> ABIEvent:
|
|
175
|
-
|
|
186
|
+
if cls.abi:
|
|
187
|
+
return cls.abi
|
|
188
|
+
|
|
189
|
+
return cast(
|
|
190
|
+
ABIEvent,
|
|
191
|
+
get_abi_element(
|
|
192
|
+
filter_abi_by_type("event", cls.contract_abi),
|
|
193
|
+
cls.abi_element_identifier,
|
|
194
|
+
abi_codec=cls.w3.codec,
|
|
195
|
+
),
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
def _set_event_info(self) -> None:
|
|
199
|
+
self.abi = self._get_event_abi()
|
|
176
200
|
|
|
177
201
|
@combomethod
|
|
178
202
|
def process_receipt(
|
|
@@ -275,9 +299,7 @@ class BaseContractEvent:
|
|
|
275
299
|
def factory(
|
|
276
300
|
cls, class_name: str, **kwargs: Any
|
|
277
301
|
) -> Union["ContractEvent", "AsyncContractEvent"]:
|
|
278
|
-
return PropertyCheckingFactory(class_name, (cls,), kwargs)(
|
|
279
|
-
abi=kwargs.get("abi")
|
|
280
|
-
)
|
|
302
|
+
return PropertyCheckingFactory(class_name, (cls,), kwargs)()
|
|
281
303
|
|
|
282
304
|
@staticmethod
|
|
283
305
|
def check_for_forbidden_api_filter_arguments(
|
|
@@ -367,12 +389,10 @@ class BaseContractEvent:
|
|
|
367
389
|
|
|
368
390
|
_filters = dict(**argument_filters)
|
|
369
391
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
self.check_for_forbidden_api_filter_arguments(event_abi, _filters)
|
|
392
|
+
self.check_for_forbidden_api_filter_arguments(self.abi, _filters)
|
|
373
393
|
|
|
374
394
|
_, event_filter_params = construct_event_filter_params(
|
|
375
|
-
self.
|
|
395
|
+
self.abi,
|
|
376
396
|
self.w3.codec,
|
|
377
397
|
contract_address=self.address,
|
|
378
398
|
argument_filters=_filters,
|
|
@@ -435,48 +455,26 @@ class BaseContractEvents:
|
|
|
435
455
|
contract_event_type: Union[Type["ContractEvent"], Type["AsyncContractEvent"]],
|
|
436
456
|
address: Optional[ChecksumAddress] = None,
|
|
437
457
|
) -> None:
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
setattr(
|
|
443
|
-
self,
|
|
444
|
-
event["name"],
|
|
445
|
-
contract_event_type.factory(
|
|
446
|
-
event["name"],
|
|
447
|
-
w3=w3,
|
|
448
|
-
contract_abi=self.abi,
|
|
449
|
-
address=address,
|
|
450
|
-
event_name=event["name"],
|
|
451
|
-
abi=event,
|
|
452
|
-
),
|
|
453
|
-
)
|
|
454
|
-
|
|
455
|
-
def __getattr__(self, event_name: str) -> Type["BaseContractEvent"]:
|
|
456
|
-
if "_events" not in self.__dict__:
|
|
457
|
-
raise NoABIEventsFound(
|
|
458
|
-
"The abi for this contract contains no event definitions. ",
|
|
459
|
-
"Are you sure you provided the correct contract abi?",
|
|
460
|
-
)
|
|
461
|
-
elif event_name not in self.__dict__["_events"]:
|
|
462
|
-
raise ABIEventNotFound(
|
|
463
|
-
f"The event '{event_name}' was not found in this contract's abi. ",
|
|
464
|
-
"Are you sure you provided the correct contract abi?",
|
|
465
|
-
)
|
|
466
|
-
else:
|
|
467
|
-
return super().__getattribute__(event_name)
|
|
468
|
-
|
|
469
|
-
def __getitem__(self, event_name: str) -> Type["BaseContractEvent"]:
|
|
470
|
-
return getattr(self, event_name)
|
|
458
|
+
self.abi = abi
|
|
459
|
+
self.w3 = w3
|
|
460
|
+
self.address = address
|
|
461
|
+
_events: Sequence[ABIEvent] = None
|
|
471
462
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
463
|
+
if self.abi:
|
|
464
|
+
_events = filter_abi_by_type("event", abi)
|
|
465
|
+
for event in _events:
|
|
466
|
+
abi_signature = abi_to_signature(event)
|
|
467
|
+
event_factory = contract_event_type.factory(
|
|
468
|
+
abi_signature,
|
|
469
|
+
w3=self.w3,
|
|
470
|
+
contract_abi=self.abi,
|
|
471
|
+
address=self.address,
|
|
472
|
+
event_name=event["name"],
|
|
473
|
+
)
|
|
474
|
+
setattr(self, abi_signature, event_factory)
|
|
475
475
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
for event in self._events:
|
|
479
|
-
yield self[event["name"]]
|
|
476
|
+
if _events:
|
|
477
|
+
self._events = _events
|
|
480
478
|
|
|
481
479
|
def __hasattr__(self, event_name: str) -> bool:
|
|
482
480
|
try:
|
|
@@ -494,52 +492,80 @@ class BaseContractFunction:
|
|
|
494
492
|
"""
|
|
495
493
|
|
|
496
494
|
address: ChecksumAddress = None
|
|
495
|
+
fn_name: str = None
|
|
496
|
+
name: str = None
|
|
497
497
|
abi_element_identifier: ABIElementIdentifier = None
|
|
498
498
|
w3: Union["Web3", "AsyncWeb3"] = None
|
|
499
499
|
contract_abi: ABI = None
|
|
500
500
|
abi: ABIFunction = None
|
|
501
501
|
transaction: TxParams = None
|
|
502
502
|
arguments: Tuple[Any, ...] = None
|
|
503
|
-
decode_tuples: Optional[bool] =
|
|
503
|
+
decode_tuples: Optional[bool] = None
|
|
504
504
|
args: Any = None
|
|
505
505
|
kwargs: Any = None
|
|
506
506
|
|
|
507
507
|
def __init__(self, abi: Optional[ABIFunction] = None) -> None:
|
|
508
|
-
self.
|
|
509
|
-
|
|
508
|
+
if not self.abi_element_identifier:
|
|
509
|
+
self.abi_element_identifier = type(self).__name__
|
|
510
|
+
|
|
511
|
+
self.fn_name = get_name_from_abi_element_identifier(self.abi_element_identifier)
|
|
512
|
+
self.abi = cast(
|
|
513
|
+
ABIFunction,
|
|
514
|
+
get_abi_element(
|
|
515
|
+
filter_by_types(
|
|
516
|
+
["function", "constructor", "fallback", "receive"],
|
|
517
|
+
self.contract_abi,
|
|
518
|
+
),
|
|
519
|
+
self.abi_element_identifier,
|
|
520
|
+
),
|
|
521
|
+
)
|
|
522
|
+
self.name = abi_to_signature(self.abi)
|
|
510
523
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
524
|
+
@combomethod
|
|
525
|
+
def _get_abi(cls) -> ABIFunction:
|
|
526
|
+
if not cls.args and not cls.kwargs:
|
|
527
|
+
# If no args or kwargs are provided, get the ABI element by name
|
|
528
|
+
return cast(
|
|
514
529
|
ABIFunction,
|
|
515
530
|
get_abi_element(
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
abi_codec=self.w3.codec,
|
|
520
|
-
**self.kwargs,
|
|
531
|
+
cls.contract_abi,
|
|
532
|
+
get_abi_element_signature(cls.abi_element_identifier),
|
|
533
|
+
abi_codec=cls.w3.codec,
|
|
521
534
|
),
|
|
522
535
|
)
|
|
523
536
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
537
|
+
return cast(
|
|
538
|
+
ABIFunction,
|
|
539
|
+
get_abi_element(
|
|
540
|
+
cls.contract_abi,
|
|
541
|
+
get_name_from_abi_element_identifier(cls.abi_element_identifier),
|
|
542
|
+
*cls.args,
|
|
543
|
+
abi_codec=cls.w3.codec,
|
|
544
|
+
**cls.kwargs,
|
|
545
|
+
),
|
|
546
|
+
)
|
|
533
547
|
|
|
548
|
+
def _set_function_info(self) -> None:
|
|
549
|
+
self.selector = encode_hex(b"")
|
|
534
550
|
if self.abi_element_identifier in [
|
|
551
|
+
"fallback",
|
|
552
|
+
"receive",
|
|
535
553
|
FallbackFn,
|
|
536
554
|
ReceiveFn,
|
|
537
555
|
]:
|
|
556
|
+
self.abi = self._get_abi()
|
|
557
|
+
|
|
558
|
+
self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
|
|
538
559
|
self.arguments = None
|
|
539
|
-
|
|
560
|
+
elif is_text(self.abi_element_identifier):
|
|
561
|
+
self.abi = self._get_abi()
|
|
562
|
+
|
|
563
|
+
self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
|
|
540
564
|
self.arguments = get_normalized_abi_inputs(
|
|
541
565
|
self.abi, *self.args, **self.kwargs
|
|
542
566
|
)
|
|
567
|
+
else:
|
|
568
|
+
raise Web3TypeError("Unsupported function identifier")
|
|
543
569
|
|
|
544
570
|
def _get_call_txparams(self, transaction: Optional[TxParams] = None) -> TxParams:
|
|
545
571
|
if transaction is None:
|
|
@@ -671,20 +697,20 @@ class BaseContractFunction:
|
|
|
671
697
|
if self.arguments is not None:
|
|
672
698
|
_repr += f" bound to {self.arguments!r}"
|
|
673
699
|
return _repr + ">"
|
|
674
|
-
return f"<Function {self.
|
|
700
|
+
return f"<Function {get_abi_element_signature(self.abi_element_identifier)}>"
|
|
675
701
|
|
|
676
702
|
@classmethod
|
|
677
703
|
def factory(
|
|
678
704
|
cls, class_name: str, **kwargs: Any
|
|
679
705
|
) -> Union["ContractFunction", "AsyncContractFunction"]:
|
|
680
|
-
return PropertyCheckingFactory(class_name, (cls,), kwargs)(
|
|
681
|
-
abi=kwargs.get("abi")
|
|
682
|
-
)
|
|
706
|
+
return PropertyCheckingFactory(class_name, (cls,), kwargs)()
|
|
683
707
|
|
|
684
708
|
|
|
685
709
|
class BaseContractFunctions:
|
|
686
710
|
"""Class containing contract function objects"""
|
|
687
711
|
|
|
712
|
+
_functions: Sequence[ABIFunction] = None
|
|
713
|
+
|
|
688
714
|
def __init__(
|
|
689
715
|
self,
|
|
690
716
|
abi: ABI,
|
|
@@ -698,32 +724,26 @@ class BaseContractFunctions:
|
|
|
698
724
|
self.abi = abi
|
|
699
725
|
self.w3 = w3
|
|
700
726
|
self.address = address
|
|
727
|
+
_functions: Sequence[ABIFunction] = None
|
|
701
728
|
|
|
702
729
|
if self.abi:
|
|
703
|
-
|
|
704
|
-
for func in
|
|
730
|
+
_functions = filter_abi_by_type("function", self.abi)
|
|
731
|
+
for func in _functions:
|
|
732
|
+
abi_signature = abi_to_signature(func)
|
|
705
733
|
setattr(
|
|
706
734
|
self,
|
|
707
|
-
|
|
735
|
+
abi_signature,
|
|
708
736
|
contract_function_class.factory(
|
|
709
|
-
|
|
737
|
+
abi_signature,
|
|
710
738
|
w3=self.w3,
|
|
711
739
|
contract_abi=self.abi,
|
|
712
740
|
address=self.address,
|
|
713
741
|
decode_tuples=decode_tuples,
|
|
714
|
-
abi_element_identifier=func["name"],
|
|
715
742
|
),
|
|
716
743
|
)
|
|
717
744
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
return
|
|
721
|
-
|
|
722
|
-
for func in self._functions:
|
|
723
|
-
yield self[func["name"]]
|
|
724
|
-
|
|
725
|
-
def __getitem__(self, function_name: str) -> ABIFunction:
|
|
726
|
-
return getattr(self, function_name)
|
|
745
|
+
if _functions:
|
|
746
|
+
self._functions = _functions
|
|
727
747
|
|
|
728
748
|
def __hasattr__(self, function_name: str) -> bool:
|
|
729
749
|
try:
|
|
@@ -813,7 +833,7 @@ class BaseContract:
|
|
|
813
833
|
@combomethod
|
|
814
834
|
def all_functions(
|
|
815
835
|
self,
|
|
816
|
-
) -> "BaseContractFunction":
|
|
836
|
+
) -> List["BaseContractFunction"]:
|
|
817
837
|
"""
|
|
818
838
|
Return all functions in the contract.
|
|
819
839
|
"""
|
|
@@ -843,7 +863,7 @@ class BaseContract:
|
|
|
843
863
|
return self.get_function_by_identifier(fns, "signature")
|
|
844
864
|
|
|
845
865
|
@combomethod
|
|
846
|
-
def find_functions_by_name(self, fn_name: str) -> "BaseContractFunction":
|
|
866
|
+
def find_functions_by_name(self, fn_name: str) -> List["BaseContractFunction"]:
|
|
847
867
|
"""
|
|
848
868
|
Return all functions with matching name.
|
|
849
869
|
Raises a Web3ValueError if there is no match or more than one is found.
|
|
@@ -1138,6 +1158,9 @@ class BaseContract:
|
|
|
1138
1158
|
*args: Sequence[Any],
|
|
1139
1159
|
**kwargs: Dict[str, Any],
|
|
1140
1160
|
) -> ABIElement:
|
|
1161
|
+
if not args and not kwargs:
|
|
1162
|
+
fn_identifier = get_abi_element_signature(fn_identifier)
|
|
1163
|
+
|
|
1141
1164
|
return get_abi_element(
|
|
1142
1165
|
cls.abi,
|
|
1143
1166
|
fn_identifier,
|
|
@@ -1152,8 +1175,13 @@ class BaseContract:
|
|
|
1152
1175
|
event_name: Optional[str] = None,
|
|
1153
1176
|
argument_names: Optional[Sequence[str]] = None,
|
|
1154
1177
|
) -> ABIEvent:
|
|
1155
|
-
return
|
|
1156
|
-
|
|
1178
|
+
return cast(
|
|
1179
|
+
ABIEvent,
|
|
1180
|
+
get_abi_element(
|
|
1181
|
+
abi=cls.abi,
|
|
1182
|
+
abi_element_identifier=event_name,
|
|
1183
|
+
argument_names=argument_names,
|
|
1184
|
+
),
|
|
1157
1185
|
)
|
|
1158
1186
|
|
|
1159
1187
|
@combomethod
|
|
@@ -1219,7 +1247,9 @@ class BaseContractCaller:
|
|
|
1219
1247
|
|
|
1220
1248
|
def __getattr__(self, function_name: str) -> Any:
|
|
1221
1249
|
function_names = [
|
|
1222
|
-
fn["name"]
|
|
1250
|
+
get_name_from_abi_element_identifier(fn["name"])
|
|
1251
|
+
for fn in self._functions
|
|
1252
|
+
if fn.get("type") == "function"
|
|
1223
1253
|
]
|
|
1224
1254
|
if self.abi is None:
|
|
1225
1255
|
raise NoABIFound(
|
|
@@ -1230,7 +1260,7 @@ class BaseContractCaller:
|
|
|
1230
1260
|
"The ABI for this contract contains no function definitions. ",
|
|
1231
1261
|
"Are you sure you provided the correct contract ABI?",
|
|
1232
1262
|
)
|
|
1233
|
-
elif function_name not in function_names:
|
|
1263
|
+
elif get_name_from_abi_element_identifier(function_name) not in function_names:
|
|
1234
1264
|
functions_available = ", ".join(function_names)
|
|
1235
1265
|
raise ABIFunctionNotFound(
|
|
1236
1266
|
f"The function '{function_name}' was not found in this contract's ABI.",
|
|
@@ -1239,11 +1269,17 @@ class BaseContractCaller:
|
|
|
1239
1269
|
"Did you mean to call one of those functions?",
|
|
1240
1270
|
)
|
|
1241
1271
|
else:
|
|
1242
|
-
|
|
1272
|
+
function_identifier = function_name
|
|
1243
1273
|
|
|
1244
|
-
|
|
1274
|
+
if "(" not in function_name:
|
|
1275
|
+
function_identifier = _get_any_abi_signature_with_name(
|
|
1276
|
+
function_name, self._functions
|
|
1277
|
+
)
|
|
1278
|
+
return super().__getattribute__(function_identifier)
|
|
1279
|
+
|
|
1280
|
+
def __hasattr__(self, function_name: str) -> bool:
|
|
1245
1281
|
try:
|
|
1246
|
-
return
|
|
1282
|
+
return function_name in self.__dict__["_functions"]
|
|
1247
1283
|
except ABIFunctionNotFound:
|
|
1248
1284
|
return False
|
|
1249
1285
|
|