web3 7.4.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/arrays_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
- web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
- web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/event_contracts.py +50 -5
- web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
- web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
- web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
- web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
- web3/_utils/contracts.py +48 -7
- web3/_utils/method_formatters.py +109 -1
- web3/_utils/module_testing/__init__.py +4 -0
- web3/_utils/module_testing/eth_module.py +11 -0
- web3/_utils/module_testing/go_ethereum_debug_module.py +128 -0
- web3/_utils/rpc_abi.py +4 -0
- web3/_utils/validation.py +3 -0
- web3/contract/async_contract.py +191 -41
- web3/contract/base_contract.py +373 -152
- web3/contract/contract.py +182 -34
- web3/contract/utils.py +51 -2
- web3/eth/async_eth.py +11 -0
- web3/eth/eth.py +11 -0
- web3/geth.py +59 -0
- web3/main.py +4 -0
- web3/manager.py +10 -0
- web3/providers/eth_tester/defaults.py +1 -0
- web3/types.py +87 -2
- web3/utils/abi.py +308 -76
- {web3-7.4.0.dist-info → web3-7.6.0.dist-info}/METADATA +3 -2
- {web3-7.4.0.dist-info → web3-7.6.0.dist-info}/RECORD +46 -45
- {web3-7.4.0.dist-info → web3-7.6.0.dist-info}/WHEEL +1 -1
- {web3-7.4.0.dist-info → web3-7.6.0.dist-info}/LICENSE +0 -0
- {web3-7.4.0.dist-info → web3-7.6.0.dist-info}/top_level.txt +0 -0
|
@@ -246,6 +246,7 @@ API_ENDPOINTS = {
|
|
|
246
246
|
"chainId": static_return(131277322940537), # from fixture generation file
|
|
247
247
|
"feeHistory": call_eth_tester("get_fee_history"),
|
|
248
248
|
"maxPriorityFeePerGas": static_return(10**9),
|
|
249
|
+
"blobBaseFee": static_return(10**9),
|
|
249
250
|
"gasPrice": static_return(10**9), # must be >= base fee post-London
|
|
250
251
|
"accounts": call_eth_tester("get_accounts"),
|
|
251
252
|
"blockNumber": compose(
|
web3/types.py
CHANGED
|
@@ -36,8 +36,14 @@ from web3._utils.compat import (
|
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
if TYPE_CHECKING:
|
|
39
|
-
from web3.contract.async_contract import
|
|
40
|
-
|
|
39
|
+
from web3.contract.async_contract import ( # noqa: F401
|
|
40
|
+
AsyncContractEvent,
|
|
41
|
+
AsyncContractFunction,
|
|
42
|
+
)
|
|
43
|
+
from web3.contract.contract import ( # noqa: F401
|
|
44
|
+
ContractEvent,
|
|
45
|
+
ContractFunction,
|
|
46
|
+
)
|
|
41
47
|
from web3.main import ( # noqa: F401
|
|
42
48
|
AsyncWeb3,
|
|
43
49
|
Web3,
|
|
@@ -469,6 +475,84 @@ class TxPoolStatus(TypedDict, total=False):
|
|
|
469
475
|
queued: int
|
|
470
476
|
|
|
471
477
|
|
|
478
|
+
#
|
|
479
|
+
# debug types
|
|
480
|
+
#
|
|
481
|
+
class TraceConfig(TypedDict, total=False):
|
|
482
|
+
disableStorage: bool
|
|
483
|
+
disableStack: bool
|
|
484
|
+
enableMemory: bool
|
|
485
|
+
enableReturnData: bool
|
|
486
|
+
tracer: str
|
|
487
|
+
tracerConfig: Dict[str, Any]
|
|
488
|
+
timeout: int
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
class CallTraceLog(TypedDict):
|
|
492
|
+
address: ChecksumAddress
|
|
493
|
+
data: HexBytes
|
|
494
|
+
topics: Sequence[HexBytes]
|
|
495
|
+
position: int
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
# syntax b/c "from" keyword not allowed w/ class construction
|
|
499
|
+
CallTrace = TypedDict(
|
|
500
|
+
"CallTrace",
|
|
501
|
+
{
|
|
502
|
+
"type": str,
|
|
503
|
+
"from": ChecksumAddress,
|
|
504
|
+
"to": ChecksumAddress,
|
|
505
|
+
"value": Wei,
|
|
506
|
+
"gas": int,
|
|
507
|
+
"gasUsed": int,
|
|
508
|
+
"input": HexBytes,
|
|
509
|
+
"output": HexBytes,
|
|
510
|
+
"error": str,
|
|
511
|
+
"revertReason": str,
|
|
512
|
+
"calls": Sequence["CallTrace"],
|
|
513
|
+
"logs": Sequence[CallTraceLog],
|
|
514
|
+
},
|
|
515
|
+
total=False,
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
class TraceData(TypedDict, total=False):
|
|
520
|
+
balance: int
|
|
521
|
+
nonce: int
|
|
522
|
+
code: str
|
|
523
|
+
storage: Dict[str, str]
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
class DiffModeTrace(TypedDict):
|
|
527
|
+
post: Dict[ChecksumAddress, TraceData]
|
|
528
|
+
pre: Dict[ChecksumAddress, TraceData]
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
PrestateTrace = Dict[ChecksumAddress, TraceData]
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
# 4byte tracer returns something like:
|
|
535
|
+
# { '0x27dc297e-128' : 1 }
|
|
536
|
+
# which is: { 4byte signature - calldata size : # of occurrences of key }
|
|
537
|
+
FourByteTrace = Dict[str, int]
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
class StructLog(TypedDict):
|
|
541
|
+
pc: int
|
|
542
|
+
op: str
|
|
543
|
+
gas: int
|
|
544
|
+
gasCost: int
|
|
545
|
+
depth: int
|
|
546
|
+
stack: List[HexStr]
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
class OpcodeTrace(TypedDict, total=False):
|
|
550
|
+
gas: int
|
|
551
|
+
failed: bool
|
|
552
|
+
returnValue: str
|
|
553
|
+
structLogs: List[StructLog]
|
|
554
|
+
|
|
555
|
+
|
|
472
556
|
#
|
|
473
557
|
# web3.geth types
|
|
474
558
|
#
|
|
@@ -483,6 +567,7 @@ class GethWallet(TypedDict):
|
|
|
483
567
|
# Contract types
|
|
484
568
|
|
|
485
569
|
TContractFn = TypeVar("TContractFn", "ContractFunction", "AsyncContractFunction")
|
|
570
|
+
TContractEvent = TypeVar("TContractEvent", "ContractEvent", "AsyncContractEvent")
|
|
486
571
|
|
|
487
572
|
|
|
488
573
|
# Tracing types
|
web3/utils/abi.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
from typing import (
|
|
3
3
|
Any,
|
|
4
|
+
Callable,
|
|
4
5
|
Dict,
|
|
5
6
|
List,
|
|
6
7
|
Optional,
|
|
@@ -47,7 +48,6 @@ from eth_utils.toolz import (
|
|
|
47
48
|
)
|
|
48
49
|
from eth_utils.types import (
|
|
49
50
|
is_list_like,
|
|
50
|
-
is_text,
|
|
51
51
|
)
|
|
52
52
|
from hexbytes import (
|
|
53
53
|
HexBytes,
|
|
@@ -55,17 +55,21 @@ from hexbytes import (
|
|
|
55
55
|
|
|
56
56
|
from web3._utils.abi import (
|
|
57
57
|
filter_by_argument_name,
|
|
58
|
+
filter_by_argument_type,
|
|
59
|
+
get_abi_element_signature,
|
|
60
|
+
get_name_from_abi_element_identifier,
|
|
58
61
|
)
|
|
59
|
-
from web3._utils.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
from web3._utils.decorators import (
|
|
63
|
+
deprecated_for,
|
|
64
|
+
)
|
|
65
|
+
from web3._utils.validation import (
|
|
66
|
+
validate_abi,
|
|
62
67
|
)
|
|
63
68
|
from web3.exceptions import (
|
|
64
69
|
ABIConstructorNotFound,
|
|
65
70
|
ABIFallbackNotFound,
|
|
66
71
|
ABIReceiveNotFound,
|
|
67
72
|
MismatchedABI,
|
|
68
|
-
Web3TypeError,
|
|
69
73
|
Web3ValidationError,
|
|
70
74
|
Web3ValueError,
|
|
71
75
|
)
|
|
@@ -81,9 +85,14 @@ from eth_utils.abi import ( # noqa
|
|
|
81
85
|
function_abi_to_4byte_selector,
|
|
82
86
|
get_aligned_abi_inputs,
|
|
83
87
|
get_normalized_abi_inputs,
|
|
88
|
+
get_abi_input_types,
|
|
84
89
|
)
|
|
85
90
|
|
|
86
91
|
|
|
92
|
+
def _filter_by_signature(signature: str, contract_abi: ABI) -> List[ABIElement]:
|
|
93
|
+
return [abi for abi in contract_abi if abi_to_signature(abi) == signature]
|
|
94
|
+
|
|
95
|
+
|
|
87
96
|
def _filter_by_argument_count(
|
|
88
97
|
num_arguments: int, contract_abi: ABI
|
|
89
98
|
) -> List[ABIElement]:
|
|
@@ -98,9 +107,9 @@ def _filter_by_argument_count(
|
|
|
98
107
|
|
|
99
108
|
def _filter_by_encodability(
|
|
100
109
|
abi_codec: codec.ABIEncoder,
|
|
110
|
+
args: Sequence[Any],
|
|
111
|
+
kwargs: Dict[str, Any],
|
|
101
112
|
contract_abi: ABI,
|
|
102
|
-
*args: Optional[Sequence[Any]],
|
|
103
|
-
**kwargs: Optional[Dict[str, Any]],
|
|
104
113
|
) -> List[ABICallable]:
|
|
105
114
|
return [
|
|
106
115
|
cast(ABICallable, function_abi)
|
|
@@ -158,13 +167,118 @@ def _get_fallback_function_abi(contract_abi: ABI) -> ABIFallback:
|
|
|
158
167
|
raise ABIFallbackNotFound("No fallback function was found in the contract ABI.")
|
|
159
168
|
|
|
160
169
|
|
|
170
|
+
def _get_any_abi_signature_with_name(element_name: str, contract_abi: ABI) -> str:
|
|
171
|
+
"""
|
|
172
|
+
Find an ABI identifier signature by element name. A signature identifier is
|
|
173
|
+
returned, "name(arg1Type,arg2Type,...)".
|
|
174
|
+
|
|
175
|
+
This function forces one result to be returned even if multiple are found.
|
|
176
|
+
If multiple ABIs are found and all contain arguments, the first result is returned.
|
|
177
|
+
Otherwise when one of the ABIs has zero arguments, that signature is returned.
|
|
178
|
+
"""
|
|
179
|
+
try:
|
|
180
|
+
# search for function abis with the same name
|
|
181
|
+
function_abi = get_abi_element(
|
|
182
|
+
contract_abi, get_name_from_abi_element_identifier(element_name)
|
|
183
|
+
)
|
|
184
|
+
return abi_to_signature(function_abi)
|
|
185
|
+
except MismatchedABI:
|
|
186
|
+
# If all matching functions have arguments, cannot determine which one
|
|
187
|
+
# to use. Instead of an exception, return the first matching function.
|
|
188
|
+
function_abis = filter_abi_by_name(element_name, contract_abi)
|
|
189
|
+
if len(function_abis) > 0 and all(
|
|
190
|
+
len(get_abi_input_types(fn)) > 0 for fn in function_abis
|
|
191
|
+
):
|
|
192
|
+
return abi_to_signature(function_abis[0])
|
|
193
|
+
|
|
194
|
+
# Use signature for function that does not take arguments
|
|
195
|
+
return str(get_abi_element_signature(element_name))
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _build_abi_input_error(
|
|
199
|
+
abi: ABI,
|
|
200
|
+
num_args: int,
|
|
201
|
+
*args: Any,
|
|
202
|
+
abi_codec: ABICodec,
|
|
203
|
+
**kwargs: Any,
|
|
204
|
+
) -> str:
|
|
205
|
+
"""
|
|
206
|
+
Build a string representation of the ABI input error.
|
|
207
|
+
"""
|
|
208
|
+
errors: Dict[str, str] = dict(
|
|
209
|
+
{
|
|
210
|
+
"zero_args": "",
|
|
211
|
+
"invalid_args": "",
|
|
212
|
+
"encoding": "",
|
|
213
|
+
"unexpected_args": "",
|
|
214
|
+
}
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
for abi_element in abi:
|
|
218
|
+
abi_element_input_types = get_abi_input_types(abi_element)
|
|
219
|
+
abi_signature = abi_to_signature(abi_element)
|
|
220
|
+
abi_element_name = get_name_from_abi_element_identifier(abi_signature)
|
|
221
|
+
types: Tuple[str, ...] = tuple()
|
|
222
|
+
aligned_args: Tuple[Any, ...] = tuple()
|
|
223
|
+
|
|
224
|
+
if len(abi_element_input_types) == num_args:
|
|
225
|
+
if num_args == 0:
|
|
226
|
+
if not errors["zero_args"]:
|
|
227
|
+
errors["zero_args"] += (
|
|
228
|
+
"The provided identifier matches multiple elements.\n"
|
|
229
|
+
f"If you meant to call `{abi_element_name}()`, "
|
|
230
|
+
"please specify the full signature.\n"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
errors["zero_args"] += (
|
|
234
|
+
f" - signature: {abi_to_signature(abi_element)}, "
|
|
235
|
+
f"type: {abi_element['type']}\n"
|
|
236
|
+
)
|
|
237
|
+
else:
|
|
238
|
+
try:
|
|
239
|
+
arguments = get_normalized_abi_inputs(abi_element, *args, **kwargs)
|
|
240
|
+
types, aligned_args = get_aligned_abi_inputs(abi_element, arguments)
|
|
241
|
+
except TypeError as e:
|
|
242
|
+
errors["invalid_args"] += (
|
|
243
|
+
f"Signature: {abi_signature}, type: {abi_element['type']}\n"
|
|
244
|
+
f"Arguments do not match types in `{abi_signature}`.\n"
|
|
245
|
+
f"Error: {e}\n"
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
argument_errors = ""
|
|
249
|
+
for position, (_type, arg) in enumerate(zip(types, aligned_args), start=1):
|
|
250
|
+
if abi_codec.is_encodable(_type, arg):
|
|
251
|
+
argument_errors += f"Argument {position} value `{arg}` is valid.\n"
|
|
252
|
+
else:
|
|
253
|
+
argument_errors += (
|
|
254
|
+
f"Argument {position} value `{arg}` is not compatible with "
|
|
255
|
+
f"type `{_type}`.\n"
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
if argument_errors != "":
|
|
259
|
+
errors["encoding"] += (
|
|
260
|
+
f"Signature: {abi_signature}, type: {abi_element['type']}\n"
|
|
261
|
+
+ argument_errors
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
else:
|
|
265
|
+
errors["unexpected_args"] += (
|
|
266
|
+
f"Signature: {abi_signature}, type: {abi_element['type']}\n"
|
|
267
|
+
f"Expected {len(abi_element_input_types)} argument(s) but received "
|
|
268
|
+
f"{num_args} argument(s).\n"
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
return "".join(errors.values())
|
|
272
|
+
|
|
273
|
+
|
|
161
274
|
def _mismatched_abi_error_diagnosis(
|
|
162
275
|
abi_element_identifier: ABIElementIdentifier,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
*args: Optional[
|
|
167
|
-
|
|
276
|
+
abi: ABI,
|
|
277
|
+
num_matches: int = 0,
|
|
278
|
+
num_args: int = 0,
|
|
279
|
+
*args: Optional[Any],
|
|
280
|
+
abi_codec: Optional[Any] = None,
|
|
281
|
+
**kwargs: Optional[Any],
|
|
168
282
|
) -> str:
|
|
169
283
|
"""
|
|
170
284
|
Raise a ``MismatchedABI`` when a function ABI lookup results in an error.
|
|
@@ -172,32 +286,59 @@ def _mismatched_abi_error_diagnosis(
|
|
|
172
286
|
An error may result from multiple functions matching the provided signature and
|
|
173
287
|
arguments or no functions are identified.
|
|
174
288
|
"""
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
"Ambiguous argument encoding. "
|
|
183
|
-
"Provided arguments can be encoded to multiple functions "
|
|
184
|
-
"matching this call."
|
|
185
|
-
)
|
|
289
|
+
name = get_name_from_abi_element_identifier(abi_element_identifier)
|
|
290
|
+
abis_matching_names = filter_abi_by_name(name, abi)
|
|
291
|
+
abis_matching_arg_count = [
|
|
292
|
+
abi_to_signature(abi)
|
|
293
|
+
for abi in _filter_by_argument_count(num_args, abis_matching_names)
|
|
294
|
+
]
|
|
295
|
+
num_abis_matching_arg_count = len(abis_matching_arg_count)
|
|
186
296
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
{(k, _extract_argument_types([v])) for k, v in kwargs.items()}
|
|
190
|
-
)
|
|
297
|
+
if abi_codec is None:
|
|
298
|
+
abi_codec = ABICodec(default_registry)
|
|
191
299
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
f"`{
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
300
|
+
error = "ABI Not Found!\n"
|
|
301
|
+
if num_matches == 0 and num_abis_matching_arg_count == 0:
|
|
302
|
+
error += f"No element named `{name}` with {num_args} argument(s).\n"
|
|
303
|
+
elif num_matches > 1 or num_abis_matching_arg_count > 1:
|
|
304
|
+
error += (
|
|
305
|
+
f"Found multiple elements named `{name}` that accept {num_args} "
|
|
306
|
+
"argument(s).\n"
|
|
307
|
+
)
|
|
308
|
+
elif num_abis_matching_arg_count == 1:
|
|
309
|
+
error += (
|
|
310
|
+
f"Found {num_abis_matching_arg_count} element(s) named `{name}` that "
|
|
311
|
+
f"accept {num_args} argument(s).\n"
|
|
312
|
+
"The provided arguments are not valid.\n"
|
|
313
|
+
)
|
|
314
|
+
elif num_matches == 0:
|
|
315
|
+
error += (
|
|
316
|
+
f"Unable to find an element named `{name}` that matches the provided "
|
|
317
|
+
"identifier and argument types.\n"
|
|
318
|
+
)
|
|
319
|
+
arg_types = _extract_argument_types(*args)
|
|
320
|
+
kwarg_types = dict({(k, _extract_argument_types([v])) for k, v in kwargs.items()})
|
|
321
|
+
error += (
|
|
322
|
+
f"Provided argument types: ({arg_types})\n"
|
|
323
|
+
f"Provided keyword argument types: {kwarg_types}\n\n"
|
|
199
324
|
)
|
|
200
325
|
|
|
326
|
+
if abis_matching_names:
|
|
327
|
+
error += (
|
|
328
|
+
f"Tried to find a matching ABI element named `{name}`, but encountered "
|
|
329
|
+
"the following problems:\n"
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
error += _build_abi_input_error(
|
|
333
|
+
abis_matching_names,
|
|
334
|
+
num_args,
|
|
335
|
+
*args,
|
|
336
|
+
abi_codec=abi_codec,
|
|
337
|
+
**kwargs,
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
return f"\n{error}"
|
|
341
|
+
|
|
201
342
|
|
|
202
343
|
def _extract_argument_types(*args: Sequence[Any]) -> str:
|
|
203
344
|
"""
|
|
@@ -231,6 +372,102 @@ def _get_argument_readable_type(arg: Any) -> str:
|
|
|
231
372
|
return arg.__class__.__name__
|
|
232
373
|
|
|
233
374
|
|
|
375
|
+
def _build_abi_filters(
|
|
376
|
+
abi_element_identifier: ABIElementIdentifier,
|
|
377
|
+
*args: Optional[Any],
|
|
378
|
+
abi_type: Optional[str] = None,
|
|
379
|
+
argument_names: Optional[Sequence[str]] = None,
|
|
380
|
+
argument_types: Optional[Sequence[str]] = None,
|
|
381
|
+
abi_codec: Optional[Any] = None,
|
|
382
|
+
**kwargs: Optional[Any],
|
|
383
|
+
) -> List[Callable[..., Sequence[ABIElement]]]:
|
|
384
|
+
"""
|
|
385
|
+
Build a list of ABI filters to find an ABI element within a contract ABI. Each
|
|
386
|
+
filter is a partial function that takes a contract ABI and returns a filtered list.
|
|
387
|
+
Each parameter is checked before applying the relevant filter.
|
|
388
|
+
|
|
389
|
+
When the ``abi_element_identifier`` is a function name or signature and no arguments
|
|
390
|
+
are provided, the returned filters include the function name or signature.
|
|
391
|
+
|
|
392
|
+
A function ABI may take arguments and keyword arguments. When the ``args`` and
|
|
393
|
+
``kwargs`` values are passed, several filters are combined together. Available
|
|
394
|
+
filters include the function name, argument count, argument name, argument type,
|
|
395
|
+
and argument encodability.
|
|
396
|
+
|
|
397
|
+
``constructor``, ``fallback``, and ``receive`` ABI elements are handled only with a
|
|
398
|
+
filter by type.
|
|
399
|
+
"""
|
|
400
|
+
if not isinstance(abi_element_identifier, str):
|
|
401
|
+
abi_element_identifier = get_abi_element_signature(abi_element_identifier)
|
|
402
|
+
|
|
403
|
+
if abi_element_identifier in ["constructor", "fallback", "receive"]:
|
|
404
|
+
return [functools.partial(filter_abi_by_type, abi_element_identifier)]
|
|
405
|
+
|
|
406
|
+
filters: List[Callable[..., Sequence[ABIElement]]] = []
|
|
407
|
+
|
|
408
|
+
if abi_type:
|
|
409
|
+
filters.append(functools.partial(filter_abi_by_type, abi_type))
|
|
410
|
+
|
|
411
|
+
arg_count = 0
|
|
412
|
+
if argument_names:
|
|
413
|
+
arg_count = len(argument_names)
|
|
414
|
+
elif args or kwargs:
|
|
415
|
+
arg_count = len(args) + len(kwargs)
|
|
416
|
+
|
|
417
|
+
if arg_count > 0:
|
|
418
|
+
filters.append(
|
|
419
|
+
functools.partial(
|
|
420
|
+
filter_abi_by_name,
|
|
421
|
+
get_name_from_abi_element_identifier(abi_element_identifier),
|
|
422
|
+
)
|
|
423
|
+
)
|
|
424
|
+
filters.append(functools.partial(_filter_by_argument_count, arg_count))
|
|
425
|
+
|
|
426
|
+
if args or kwargs:
|
|
427
|
+
if abi_codec is None:
|
|
428
|
+
abi_codec = ABICodec(default_registry)
|
|
429
|
+
|
|
430
|
+
filters.append(
|
|
431
|
+
functools.partial(
|
|
432
|
+
_filter_by_encodability,
|
|
433
|
+
abi_codec,
|
|
434
|
+
args,
|
|
435
|
+
kwargs,
|
|
436
|
+
)
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
if argument_names:
|
|
440
|
+
filters.append(functools.partial(filter_by_argument_name, argument_names))
|
|
441
|
+
|
|
442
|
+
if argument_types:
|
|
443
|
+
if arg_count != len(argument_types):
|
|
444
|
+
raise Web3ValidationError(
|
|
445
|
+
"The number of argument names and types must match."
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
filters.append(
|
|
449
|
+
functools.partial(filter_by_argument_type, argument_types)
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
if "(" in abi_element_identifier:
|
|
453
|
+
filters.append(
|
|
454
|
+
functools.partial(_filter_by_signature, abi_element_identifier)
|
|
455
|
+
)
|
|
456
|
+
else:
|
|
457
|
+
filters.append(
|
|
458
|
+
functools.partial(
|
|
459
|
+
filter_abi_by_name,
|
|
460
|
+
get_name_from_abi_element_identifier(abi_element_identifier),
|
|
461
|
+
)
|
|
462
|
+
)
|
|
463
|
+
if "(" in abi_element_identifier:
|
|
464
|
+
filters.append(
|
|
465
|
+
functools.partial(_filter_by_signature, abi_element_identifier)
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
return filters
|
|
469
|
+
|
|
470
|
+
|
|
234
471
|
def get_abi_element_info(
|
|
235
472
|
abi: ABI,
|
|
236
473
|
abi_element_identifier: ABIElementIdentifier,
|
|
@@ -306,16 +543,21 @@ def get_abi_element_info(
|
|
|
306
543
|
def get_abi_element(
|
|
307
544
|
abi: ABI,
|
|
308
545
|
abi_element_identifier: ABIElementIdentifier,
|
|
309
|
-
*args: Optional[
|
|
546
|
+
*args: Optional[Any],
|
|
310
547
|
abi_codec: Optional[Any] = None,
|
|
311
|
-
**kwargs: Optional[
|
|
548
|
+
**kwargs: Optional[Any],
|
|
312
549
|
) -> ABIElement:
|
|
313
550
|
"""
|
|
314
|
-
Return the interface for an ``ABIElement``
|
|
315
|
-
and arguments.
|
|
551
|
+
Return the interface for an ``ABIElement`` from the ``abi`` that matches the
|
|
552
|
+
provided identifier and arguments.
|
|
553
|
+
|
|
554
|
+
``abi`` may be a list of all ABI elements in a contract or a subset of elements.
|
|
555
|
+
Passing only functions or events can be useful when names are not deterministic.
|
|
556
|
+
For example, if names overlap between functions and events.
|
|
316
557
|
|
|
317
|
-
The
|
|
318
|
-
|
|
558
|
+
The ``ABIElementIdentifier`` value may be a function name, signature, or a
|
|
559
|
+
``FallbackFn`` or ``ReceiveFn``. When named arguments (``args``) and/or keyword args
|
|
560
|
+
(``kwargs``) are provided, they are included in the search filters.
|
|
319
561
|
|
|
320
562
|
The `abi_codec` may be overridden if custom encoding and decoding is required. The
|
|
321
563
|
default is used if no codec is provided. More details about customizations are in
|
|
@@ -323,7 +565,9 @@ def get_abi_element(
|
|
|
323
565
|
|
|
324
566
|
:param abi: Contract ABI.
|
|
325
567
|
:type abi: `ABI`
|
|
326
|
-
:param abi_element_identifier: Find an element ABI with matching identifier.
|
|
568
|
+
:param abi_element_identifier: Find an element ABI with matching identifier. The \
|
|
569
|
+
identifier may be a function name, signature, or ``FallbackFn`` or ``ReceiveFn``. \
|
|
570
|
+
A function signature is in the form ``name(arg1Type,arg2Type,...)``.
|
|
327
571
|
:type abi_element_identifier: `ABIElementIdentifier`
|
|
328
572
|
:param args: Find an element ABI with matching args.
|
|
329
573
|
:type args: `Optional[Sequence[Any]]`
|
|
@@ -358,55 +602,38 @@ def get_abi_element(
|
|
|
358
602
|
'type': 'uint256'}], 'payable': False, 'stateMutability': 'nonpayable', \
|
|
359
603
|
'type': 'function'}
|
|
360
604
|
"""
|
|
605
|
+
validate_abi(abi)
|
|
606
|
+
|
|
361
607
|
if abi_codec is None:
|
|
362
608
|
abi_codec = ABICodec(default_registry)
|
|
363
609
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
filtered_abis_by_name: Sequence[ABIElement]
|
|
374
|
-
if abi_element_identifier == "constructor":
|
|
375
|
-
filtered_abis_by_name = [_get_constructor_function_abi(abi)]
|
|
376
|
-
else:
|
|
377
|
-
filtered_abis_by_name = filter_abi_by_name(
|
|
378
|
-
cast(str, abi_element_identifier), abi
|
|
379
|
-
)
|
|
380
|
-
|
|
381
|
-
arg_count = len(args) + len(kwargs)
|
|
382
|
-
filtered_abis_by_arg_count = _filter_by_argument_count(
|
|
383
|
-
arg_count, filtered_abis_by_name
|
|
384
|
-
)
|
|
385
|
-
|
|
386
|
-
if not args and not kwargs and len(filtered_abis_by_arg_count) == 1:
|
|
387
|
-
return filtered_abis_by_arg_count[0]
|
|
388
|
-
|
|
389
|
-
elements_with_encodable_args = _filter_by_encodability(
|
|
390
|
-
abi_codec, filtered_abis_by_arg_count, *args, **kwargs
|
|
610
|
+
abi_element_matches: Sequence[ABIElement] = pipe(
|
|
611
|
+
abi,
|
|
612
|
+
*_build_abi_filters(
|
|
613
|
+
abi_element_identifier,
|
|
614
|
+
*args,
|
|
615
|
+
abi_codec=abi_codec,
|
|
616
|
+
**kwargs,
|
|
617
|
+
),
|
|
391
618
|
)
|
|
392
619
|
|
|
393
|
-
|
|
394
|
-
matching_function_signatures = [
|
|
395
|
-
abi_to_signature(func) for func in filtered_abis_by_name
|
|
396
|
-
]
|
|
620
|
+
num_matches = len(abi_element_matches)
|
|
397
621
|
|
|
622
|
+
# Raise MismatchedABI when more than one found
|
|
623
|
+
if num_matches != 1:
|
|
398
624
|
error_diagnosis = _mismatched_abi_error_diagnosis(
|
|
399
625
|
abi_element_identifier,
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
len(
|
|
626
|
+
abi,
|
|
627
|
+
num_matches,
|
|
628
|
+
len(args) + len(kwargs),
|
|
403
629
|
*args,
|
|
630
|
+
abi_codec=abi_codec,
|
|
404
631
|
**kwargs,
|
|
405
632
|
)
|
|
406
633
|
|
|
407
634
|
raise MismatchedABI(error_diagnosis)
|
|
408
635
|
|
|
409
|
-
return
|
|
636
|
+
return abi_element_matches[0]
|
|
410
637
|
|
|
411
638
|
|
|
412
639
|
def check_if_arguments_can_be_encoded(
|
|
@@ -472,12 +699,17 @@ def check_if_arguments_can_be_encoded(
|
|
|
472
699
|
)
|
|
473
700
|
|
|
474
701
|
|
|
702
|
+
@deprecated_for("get_abi_element")
|
|
475
703
|
def get_event_abi(
|
|
476
704
|
abi: ABI,
|
|
477
705
|
event_name: str,
|
|
478
706
|
argument_names: Optional[Sequence[str]] = None,
|
|
479
707
|
) -> ABIEvent:
|
|
480
708
|
"""
|
|
709
|
+
.. warning::
|
|
710
|
+
This function is deprecated. It is unable to distinguish between
|
|
711
|
+
overloaded events. Use ``get_abi_element`` instead.
|
|
712
|
+
|
|
481
713
|
Find the event interface with the given name and/or arguments.
|
|
482
714
|
|
|
483
715
|
:param abi: Contract ABI.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: web3
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.6.0
|
|
4
4
|
Summary: web3: A Python library for interacting with Ethereum
|
|
5
5
|
Home-page: https://github.com/ethereum/web3.py
|
|
6
6
|
Author: The Ethereum Foundation
|
|
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
21
|
Requires-Python: >=3.8, <4
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
22
23
|
License-File: LICENSE
|
|
@@ -31,7 +32,7 @@ Requires-Dist: pydantic >=2.4.0
|
|
|
31
32
|
Requires-Dist: requests >=2.23.0
|
|
32
33
|
Requires-Dist: typing-extensions >=4.0.1
|
|
33
34
|
Requires-Dist: types-requests >=2.0.0
|
|
34
|
-
Requires-Dist: websockets
|
|
35
|
+
Requires-Dist: websockets <14.0.0,>=10.0.0
|
|
35
36
|
Requires-Dist: pyunormalize >=15.0.0
|
|
36
37
|
Requires-Dist: pywin32 >=223 ; platform_system == "Windows"
|
|
37
38
|
Provides-Extra: dev
|