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/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,
|
|
@@ -31,6 +32,16 @@ from eth_typing import (
|
|
|
31
32
|
HexStr,
|
|
32
33
|
Primitives,
|
|
33
34
|
)
|
|
35
|
+
from eth_utils.abi import (
|
|
36
|
+
abi_to_signature,
|
|
37
|
+
event_abi_to_log_topic,
|
|
38
|
+
filter_abi_by_name,
|
|
39
|
+
filter_abi_by_type,
|
|
40
|
+
function_abi_to_4byte_selector,
|
|
41
|
+
get_abi_input_types,
|
|
42
|
+
get_aligned_abi_inputs,
|
|
43
|
+
get_normalized_abi_inputs,
|
|
44
|
+
)
|
|
34
45
|
from eth_utils.address import (
|
|
35
46
|
is_binary_address,
|
|
36
47
|
is_checksum_address,
|
|
@@ -47,7 +58,6 @@ from eth_utils.toolz import (
|
|
|
47
58
|
)
|
|
48
59
|
from eth_utils.types import (
|
|
49
60
|
is_list_like,
|
|
50
|
-
is_text,
|
|
51
61
|
)
|
|
52
62
|
from hexbytes import (
|
|
53
63
|
HexBytes,
|
|
@@ -55,17 +65,20 @@ from hexbytes import (
|
|
|
55
65
|
|
|
56
66
|
from web3._utils.abi import (
|
|
57
67
|
filter_by_argument_name,
|
|
68
|
+
get_abi_element_signature,
|
|
69
|
+
get_name_from_abi_element_identifier,
|
|
70
|
+
)
|
|
71
|
+
from web3._utils.decorators import (
|
|
72
|
+
deprecated_for,
|
|
58
73
|
)
|
|
59
|
-
from web3._utils.
|
|
60
|
-
|
|
61
|
-
ReceiveFn,
|
|
74
|
+
from web3._utils.validation import (
|
|
75
|
+
validate_abi,
|
|
62
76
|
)
|
|
63
77
|
from web3.exceptions import (
|
|
64
78
|
ABIConstructorNotFound,
|
|
65
79
|
ABIFallbackNotFound,
|
|
66
80
|
ABIReceiveNotFound,
|
|
67
81
|
MismatchedABI,
|
|
68
|
-
Web3TypeError,
|
|
69
82
|
Web3ValidationError,
|
|
70
83
|
Web3ValueError,
|
|
71
84
|
)
|
|
@@ -73,15 +86,9 @@ from web3.types import (
|
|
|
73
86
|
ABIElementIdentifier,
|
|
74
87
|
)
|
|
75
88
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
filter_abi_by_name,
|
|
80
|
-
filter_abi_by_type,
|
|
81
|
-
function_abi_to_4byte_selector,
|
|
82
|
-
get_aligned_abi_inputs,
|
|
83
|
-
get_normalized_abi_inputs,
|
|
84
|
-
)
|
|
89
|
+
|
|
90
|
+
def _filter_by_signature(signature: str, contract_abi: ABI) -> List[ABIElement]:
|
|
91
|
+
return [abi for abi in contract_abi if abi_to_signature(abi) == signature]
|
|
85
92
|
|
|
86
93
|
|
|
87
94
|
def _filter_by_argument_count(
|
|
@@ -98,9 +105,9 @@ def _filter_by_argument_count(
|
|
|
98
105
|
|
|
99
106
|
def _filter_by_encodability(
|
|
100
107
|
abi_codec: codec.ABIEncoder,
|
|
108
|
+
args: Sequence[Any],
|
|
109
|
+
kwargs: Dict[str, Any],
|
|
101
110
|
contract_abi: ABI,
|
|
102
|
-
*args: Optional[Sequence[Any]],
|
|
103
|
-
**kwargs: Optional[Dict[str, Any]],
|
|
104
111
|
) -> List[ABICallable]:
|
|
105
112
|
return [
|
|
106
113
|
cast(ABICallable, function_abi)
|
|
@@ -158,13 +165,121 @@ def _get_fallback_function_abi(contract_abi: ABI) -> ABIFallback:
|
|
|
158
165
|
raise ABIFallbackNotFound("No fallback function was found in the contract ABI.")
|
|
159
166
|
|
|
160
167
|
|
|
168
|
+
def _get_any_abi_signature_with_name(
|
|
169
|
+
element_name: str, elements: Sequence[ABIElement]
|
|
170
|
+
) -> str:
|
|
171
|
+
"""
|
|
172
|
+
Find an ABI identifier signature by element name. A signature identifier is
|
|
173
|
+
returned, "name(arg1Type,arg2Type,...)".
|
|
174
|
+
|
|
175
|
+
If multiple ABIs match the name and every one contain arguments, the first
|
|
176
|
+
result is returned. Otherwise the signature without arguments is returned.
|
|
177
|
+
Returns None if no ABI exists with the provided name.
|
|
178
|
+
"""
|
|
179
|
+
element_signatures_with_name = [
|
|
180
|
+
abi_to_signature(element)
|
|
181
|
+
for element in elements
|
|
182
|
+
if element.get("name", "") == get_name_from_abi_element_identifier(element_name)
|
|
183
|
+
]
|
|
184
|
+
|
|
185
|
+
if len(element_signatures_with_name) == 1:
|
|
186
|
+
return element_signatures_with_name[0]
|
|
187
|
+
elif len(element_signatures_with_name) > 1:
|
|
188
|
+
# Check for function signature without args
|
|
189
|
+
signature_without_args = f"{element_name}()"
|
|
190
|
+
if signature_without_args not in element_signatures_with_name:
|
|
191
|
+
# Element without arguments not found, use the first available signature
|
|
192
|
+
return element_signatures_with_name[0]
|
|
193
|
+
else:
|
|
194
|
+
return signature_without_args
|
|
195
|
+
else:
|
|
196
|
+
return None
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _build_abi_input_error(
|
|
200
|
+
abi: ABI,
|
|
201
|
+
num_args: int,
|
|
202
|
+
*args: Any,
|
|
203
|
+
abi_codec: ABICodec,
|
|
204
|
+
**kwargs: Any,
|
|
205
|
+
) -> str:
|
|
206
|
+
"""
|
|
207
|
+
Build a string representation of the ABI input error.
|
|
208
|
+
"""
|
|
209
|
+
errors: Dict[str, str] = dict(
|
|
210
|
+
{
|
|
211
|
+
"zero_args": "",
|
|
212
|
+
"invalid_args": "",
|
|
213
|
+
"encoding": "",
|
|
214
|
+
"unexpected_args": "",
|
|
215
|
+
}
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
for abi_element in abi:
|
|
219
|
+
abi_element_input_types = get_abi_input_types(abi_element)
|
|
220
|
+
abi_signature = abi_to_signature(abi_element)
|
|
221
|
+
abi_element_name = get_name_from_abi_element_identifier(abi_signature)
|
|
222
|
+
types: Tuple[str, ...] = tuple()
|
|
223
|
+
aligned_args: Tuple[Any, ...] = tuple()
|
|
224
|
+
|
|
225
|
+
if len(abi_element_input_types) == num_args:
|
|
226
|
+
if num_args == 0:
|
|
227
|
+
if not errors["zero_args"]:
|
|
228
|
+
errors["zero_args"] += (
|
|
229
|
+
"The provided identifier matches multiple elements.\n"
|
|
230
|
+
f"If you meant to call `{abi_element_name}()`, "
|
|
231
|
+
"please specify the full signature.\n"
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
errors["zero_args"] += (
|
|
235
|
+
f" - signature: {abi_to_signature(abi_element)}, "
|
|
236
|
+
f"type: {abi_element['type']}\n"
|
|
237
|
+
)
|
|
238
|
+
else:
|
|
239
|
+
try:
|
|
240
|
+
arguments = get_normalized_abi_inputs(abi_element, *args, **kwargs)
|
|
241
|
+
types, aligned_args = get_aligned_abi_inputs(abi_element, arguments)
|
|
242
|
+
except TypeError as e:
|
|
243
|
+
errors["invalid_args"] += (
|
|
244
|
+
f"Signature: {abi_signature}, type: {abi_element['type']}\n"
|
|
245
|
+
f"Arguments do not match types in `{abi_signature}`.\n"
|
|
246
|
+
f"Error: {e}\n"
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
argument_errors = ""
|
|
250
|
+
for position, (_type, arg) in enumerate(zip(types, aligned_args), start=1):
|
|
251
|
+
if abi_codec.is_encodable(_type, arg):
|
|
252
|
+
argument_errors += f"Argument {position} value `{arg}` is valid.\n"
|
|
253
|
+
else:
|
|
254
|
+
argument_errors += (
|
|
255
|
+
f"Argument {position} value `{arg}` is not compatible with "
|
|
256
|
+
f"type `{_type}`.\n"
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
if argument_errors != "":
|
|
260
|
+
errors["encoding"] += (
|
|
261
|
+
f"Signature: {abi_signature}, type: {abi_element['type']}\n"
|
|
262
|
+
+ argument_errors
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
else:
|
|
266
|
+
errors["unexpected_args"] += (
|
|
267
|
+
f"Signature: {abi_signature}, type: {abi_element['type']}\n"
|
|
268
|
+
f"Expected {len(abi_element_input_types)} argument(s) but received "
|
|
269
|
+
f"{num_args} argument(s).\n"
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
return "".join(errors.values())
|
|
273
|
+
|
|
274
|
+
|
|
161
275
|
def _mismatched_abi_error_diagnosis(
|
|
162
276
|
abi_element_identifier: ABIElementIdentifier,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
*args: Optional[
|
|
167
|
-
|
|
277
|
+
abi: ABI,
|
|
278
|
+
num_matches: int = 0,
|
|
279
|
+
num_args: int = 0,
|
|
280
|
+
*args: Optional[Any],
|
|
281
|
+
abi_codec: Optional[Any] = None,
|
|
282
|
+
**kwargs: Optional[Any],
|
|
168
283
|
) -> str:
|
|
169
284
|
"""
|
|
170
285
|
Raise a ``MismatchedABI`` when a function ABI lookup results in an error.
|
|
@@ -172,32 +287,59 @@ def _mismatched_abi_error_diagnosis(
|
|
|
172
287
|
An error may result from multiple functions matching the provided signature and
|
|
173
288
|
arguments or no functions are identified.
|
|
174
289
|
"""
|
|
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
|
-
)
|
|
290
|
+
name = get_name_from_abi_element_identifier(abi_element_identifier)
|
|
291
|
+
abis_matching_names = filter_abi_by_name(name, abi)
|
|
292
|
+
abis_matching_arg_count = [
|
|
293
|
+
abi_to_signature(abi)
|
|
294
|
+
for abi in _filter_by_argument_count(num_args, abis_matching_names)
|
|
295
|
+
]
|
|
296
|
+
num_abis_matching_arg_count = len(abis_matching_arg_count)
|
|
186
297
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
{(k, _extract_argument_types([v])) for k, v in kwargs.items()}
|
|
190
|
-
)
|
|
298
|
+
if abi_codec is None:
|
|
299
|
+
abi_codec = ABICodec(default_registry)
|
|
191
300
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
f"`{
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
301
|
+
error = "ABI Not Found!\n"
|
|
302
|
+
if num_matches == 0 and num_abis_matching_arg_count == 0:
|
|
303
|
+
error += f"No element named `{name}` with {num_args} argument(s).\n"
|
|
304
|
+
elif num_matches > 1 or num_abis_matching_arg_count > 1:
|
|
305
|
+
error += (
|
|
306
|
+
f"Found multiple elements named `{name}` that accept {num_args} "
|
|
307
|
+
"argument(s).\n"
|
|
308
|
+
)
|
|
309
|
+
elif num_abis_matching_arg_count == 1:
|
|
310
|
+
error += (
|
|
311
|
+
f"Found {num_abis_matching_arg_count} element(s) named `{name}` that "
|
|
312
|
+
f"accept {num_args} argument(s).\n"
|
|
313
|
+
"The provided arguments are not valid.\n"
|
|
314
|
+
)
|
|
315
|
+
elif num_matches == 0:
|
|
316
|
+
error += (
|
|
317
|
+
f"Unable to find an element named `{name}` that matches the provided "
|
|
318
|
+
"identifier and argument types.\n"
|
|
319
|
+
)
|
|
320
|
+
arg_types = _extract_argument_types(*args)
|
|
321
|
+
kwarg_types = dict({(k, _extract_argument_types([v])) for k, v in kwargs.items()})
|
|
322
|
+
error += (
|
|
323
|
+
f"Provided argument types: ({arg_types})\n"
|
|
324
|
+
f"Provided keyword argument types: {kwarg_types}\n\n"
|
|
199
325
|
)
|
|
200
326
|
|
|
327
|
+
if abis_matching_names:
|
|
328
|
+
error += (
|
|
329
|
+
f"Tried to find a matching ABI element named `{name}`, but encountered "
|
|
330
|
+
"the following problems:\n"
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
error += _build_abi_input_error(
|
|
334
|
+
abis_matching_names,
|
|
335
|
+
num_args,
|
|
336
|
+
*args,
|
|
337
|
+
abi_codec=abi_codec,
|
|
338
|
+
**kwargs,
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
return f"\n{error}"
|
|
342
|
+
|
|
201
343
|
|
|
202
344
|
def _extract_argument_types(*args: Sequence[Any]) -> str:
|
|
203
345
|
"""
|
|
@@ -231,6 +373,84 @@ def _get_argument_readable_type(arg: Any) -> str:
|
|
|
231
373
|
return arg.__class__.__name__
|
|
232
374
|
|
|
233
375
|
|
|
376
|
+
def _build_abi_filters(
|
|
377
|
+
abi_element_identifier: ABIElementIdentifier,
|
|
378
|
+
*args: Optional[Any],
|
|
379
|
+
abi_codec: Optional[Any] = None,
|
|
380
|
+
**kwargs: Optional[Any],
|
|
381
|
+
) -> List[Callable[..., Sequence[ABIElement]]]:
|
|
382
|
+
"""
|
|
383
|
+
Build a list of ABI filters to find an ABI element within a contract ABI. Each
|
|
384
|
+
filter is a partial function that takes a contract ABI and returns a filtered list.
|
|
385
|
+
Each parameter is checked before applying the relevant filter.
|
|
386
|
+
|
|
387
|
+
When the ``abi_element_identifier`` is a function name or signature and no arguments
|
|
388
|
+
are provided, the returned filters include the function name or signature.
|
|
389
|
+
|
|
390
|
+
A function ABI may take arguments and keyword arguments. When the ``args`` and
|
|
391
|
+
``kwargs`` values are passed, several filters are combined together. Available
|
|
392
|
+
filters include the function name, argument count, argument name, argument type,
|
|
393
|
+
and argument encodability.
|
|
394
|
+
|
|
395
|
+
``constructor``, ``fallback``, and ``receive`` ABI elements are handled only with a
|
|
396
|
+
filter by type.
|
|
397
|
+
"""
|
|
398
|
+
if not isinstance(abi_element_identifier, str):
|
|
399
|
+
abi_element_identifier = get_abi_element_signature(abi_element_identifier)
|
|
400
|
+
|
|
401
|
+
if abi_element_identifier in ["constructor", "fallback", "receive"]:
|
|
402
|
+
return [functools.partial(filter_abi_by_type, abi_element_identifier)]
|
|
403
|
+
|
|
404
|
+
filters: List[Callable[..., Sequence[ABIElement]]] = []
|
|
405
|
+
|
|
406
|
+
arg_count = 0
|
|
407
|
+
if args or kwargs:
|
|
408
|
+
arg_count = len(args) + len(kwargs)
|
|
409
|
+
|
|
410
|
+
# Filter by arg count only if the identifier contains arguments
|
|
411
|
+
if "()" not in abi_element_identifier and arg_count:
|
|
412
|
+
filters.append(functools.partial(_filter_by_argument_count, arg_count))
|
|
413
|
+
|
|
414
|
+
if arg_count > 0:
|
|
415
|
+
filters.append(
|
|
416
|
+
functools.partial(
|
|
417
|
+
filter_abi_by_name,
|
|
418
|
+
get_name_from_abi_element_identifier(abi_element_identifier),
|
|
419
|
+
)
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
if args or kwargs:
|
|
423
|
+
if abi_codec is None:
|
|
424
|
+
abi_codec = ABICodec(default_registry)
|
|
425
|
+
|
|
426
|
+
filters.append(
|
|
427
|
+
functools.partial(
|
|
428
|
+
_filter_by_encodability,
|
|
429
|
+
abi_codec,
|
|
430
|
+
args,
|
|
431
|
+
kwargs,
|
|
432
|
+
)
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
if "(" in abi_element_identifier:
|
|
436
|
+
filters.append(
|
|
437
|
+
functools.partial(_filter_by_signature, abi_element_identifier)
|
|
438
|
+
)
|
|
439
|
+
else:
|
|
440
|
+
filters.append(
|
|
441
|
+
functools.partial(
|
|
442
|
+
filter_abi_by_name,
|
|
443
|
+
get_name_from_abi_element_identifier(abi_element_identifier),
|
|
444
|
+
)
|
|
445
|
+
)
|
|
446
|
+
if "(" in abi_element_identifier:
|
|
447
|
+
filters.append(
|
|
448
|
+
functools.partial(_filter_by_signature, abi_element_identifier)
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
return filters
|
|
452
|
+
|
|
453
|
+
|
|
234
454
|
def get_abi_element_info(
|
|
235
455
|
abi: ABI,
|
|
236
456
|
abi_element_identifier: ABIElementIdentifier,
|
|
@@ -306,16 +526,21 @@ def get_abi_element_info(
|
|
|
306
526
|
def get_abi_element(
|
|
307
527
|
abi: ABI,
|
|
308
528
|
abi_element_identifier: ABIElementIdentifier,
|
|
309
|
-
*args: Optional[
|
|
529
|
+
*args: Optional[Any],
|
|
310
530
|
abi_codec: Optional[Any] = None,
|
|
311
|
-
**kwargs: Optional[
|
|
531
|
+
**kwargs: Optional[Any],
|
|
312
532
|
) -> ABIElement:
|
|
313
533
|
"""
|
|
314
|
-
Return the interface for an ``ABIElement``
|
|
315
|
-
and arguments.
|
|
534
|
+
Return the interface for an ``ABIElement`` from the ``abi`` that matches the
|
|
535
|
+
provided identifier and arguments.
|
|
536
|
+
|
|
537
|
+
``abi`` may be a list of all ABI elements in a contract or a subset of elements.
|
|
538
|
+
Passing only functions or events can be useful when names are not deterministic.
|
|
539
|
+
For example, if names overlap between functions and events.
|
|
316
540
|
|
|
317
|
-
The
|
|
318
|
-
|
|
541
|
+
The ``ABIElementIdentifier`` value may be a function name, signature, or a
|
|
542
|
+
``FallbackFn`` or ``ReceiveFn``. When named arguments (``args``) and/or keyword args
|
|
543
|
+
(``kwargs``) are provided, they are included in the search filters.
|
|
319
544
|
|
|
320
545
|
The `abi_codec` may be overridden if custom encoding and decoding is required. The
|
|
321
546
|
default is used if no codec is provided. More details about customizations are in
|
|
@@ -323,7 +548,9 @@ def get_abi_element(
|
|
|
323
548
|
|
|
324
549
|
:param abi: Contract ABI.
|
|
325
550
|
:type abi: `ABI`
|
|
326
|
-
:param abi_element_identifier: Find an element ABI with matching identifier.
|
|
551
|
+
:param abi_element_identifier: Find an element ABI with matching identifier. The \
|
|
552
|
+
identifier may be a function name, signature, or ``FallbackFn`` or ``ReceiveFn``. \
|
|
553
|
+
A function signature is in the form ``name(arg1Type,arg2Type,...)``.
|
|
327
554
|
:type abi_element_identifier: `ABIElementIdentifier`
|
|
328
555
|
:param args: Find an element ABI with matching args.
|
|
329
556
|
:type args: `Optional[Sequence[Any]]`
|
|
@@ -358,55 +585,38 @@ def get_abi_element(
|
|
|
358
585
|
'type': 'uint256'}], 'payable': False, 'stateMutability': 'nonpayable', \
|
|
359
586
|
'type': 'function'}
|
|
360
587
|
"""
|
|
588
|
+
validate_abi(abi)
|
|
589
|
+
|
|
361
590
|
if abi_codec is None:
|
|
362
591
|
abi_codec = ABICodec(default_registry)
|
|
363
592
|
|
|
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
|
|
593
|
+
abi_element_matches: Sequence[ABIElement] = pipe(
|
|
594
|
+
abi,
|
|
595
|
+
*_build_abi_filters(
|
|
596
|
+
abi_element_identifier,
|
|
597
|
+
*args,
|
|
598
|
+
abi_codec=abi_codec,
|
|
599
|
+
**kwargs,
|
|
600
|
+
),
|
|
391
601
|
)
|
|
392
602
|
|
|
393
|
-
|
|
394
|
-
matching_function_signatures = [
|
|
395
|
-
abi_to_signature(func) for func in filtered_abis_by_name
|
|
396
|
-
]
|
|
603
|
+
num_matches = len(abi_element_matches)
|
|
397
604
|
|
|
605
|
+
# Raise MismatchedABI unless one match is found
|
|
606
|
+
if num_matches != 1:
|
|
398
607
|
error_diagnosis = _mismatched_abi_error_diagnosis(
|
|
399
608
|
abi_element_identifier,
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
len(
|
|
609
|
+
abi,
|
|
610
|
+
num_matches,
|
|
611
|
+
len(args) + len(kwargs),
|
|
403
612
|
*args,
|
|
613
|
+
abi_codec=abi_codec,
|
|
404
614
|
**kwargs,
|
|
405
615
|
)
|
|
406
616
|
|
|
407
617
|
raise MismatchedABI(error_diagnosis)
|
|
408
618
|
|
|
409
|
-
return
|
|
619
|
+
return abi_element_matches[0]
|
|
410
620
|
|
|
411
621
|
|
|
412
622
|
def check_if_arguments_can_be_encoded(
|
|
@@ -472,12 +682,17 @@ def check_if_arguments_can_be_encoded(
|
|
|
472
682
|
)
|
|
473
683
|
|
|
474
684
|
|
|
685
|
+
@deprecated_for("get_abi_element")
|
|
475
686
|
def get_event_abi(
|
|
476
687
|
abi: ABI,
|
|
477
688
|
event_name: str,
|
|
478
689
|
argument_names: Optional[Sequence[str]] = None,
|
|
479
690
|
) -> ABIEvent:
|
|
480
691
|
"""
|
|
692
|
+
.. warning::
|
|
693
|
+
This function is deprecated. It is unable to distinguish between
|
|
694
|
+
overloaded events. Use ``get_abi_element`` instead.
|
|
695
|
+
|
|
481
696
|
Find the event interface with the given name and/or arguments.
|
|
482
697
|
|
|
483
698
|
:param abi: Contract ABI.
|
web3/utils/address.py
CHANGED
|
@@ -9,6 +9,9 @@ from eth_utils import (
|
|
|
9
9
|
)
|
|
10
10
|
import rlp
|
|
11
11
|
|
|
12
|
+
from web3.exceptions import (
|
|
13
|
+
Web3ValidationError,
|
|
14
|
+
)
|
|
12
15
|
from web3.types import (
|
|
13
16
|
HexStr,
|
|
14
17
|
Nonce,
|
|
@@ -30,6 +33,11 @@ def get_create2_address(
|
|
|
30
33
|
Determine the resulting `CREATE2` opcode contract address for a sender, salt and
|
|
31
34
|
bytecode.
|
|
32
35
|
"""
|
|
36
|
+
if len(to_bytes(hexstr=salt)) != 32:
|
|
37
|
+
raise Web3ValidationError(
|
|
38
|
+
f"`salt` must be 32 bytes, {len(to_bytes(hexstr=salt))} != 32"
|
|
39
|
+
)
|
|
40
|
+
|
|
33
41
|
contract_address = keccak(
|
|
34
42
|
b"\xff"
|
|
35
43
|
+ to_bytes(hexstr=sender)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: web3
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.6.1
|
|
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
|
|
@@ -32,7 +32,7 @@ Requires-Dist: pydantic >=2.4.0
|
|
|
32
32
|
Requires-Dist: requests >=2.23.0
|
|
33
33
|
Requires-Dist: typing-extensions >=4.0.1
|
|
34
34
|
Requires-Dist: types-requests >=2.0.0
|
|
35
|
-
Requires-Dist: websockets
|
|
35
|
+
Requires-Dist: websockets <14.0.0,>=10.0.0
|
|
36
36
|
Requires-Dist: pyunormalize >=15.0.0
|
|
37
37
|
Requires-Dist: pywin32 >=223 ; platform_system == "Windows"
|
|
38
38
|
Provides-Extra: dev
|
|
@@ -56,8 +56,8 @@ Requires-Dist: hypothesis >=3.31.2 ; extra == 'dev'
|
|
|
56
56
|
Requires-Dist: tox >=4.0.0 ; extra == 'dev'
|
|
57
57
|
Requires-Dist: mypy ==1.10.0 ; extra == 'dev'
|
|
58
58
|
Requires-Dist: pre-commit >=3.4.0 ; extra == 'dev'
|
|
59
|
-
Requires-Dist: eth-tester[py-evm] <0.13.0b1,>=0.
|
|
60
|
-
Requires-Dist: py-geth >=5.
|
|
59
|
+
Requires-Dist: eth-tester[py-evm] <0.13.0b1,>=0.12.0b1 ; extra == 'dev'
|
|
60
|
+
Requires-Dist: py-geth >=5.1.0 ; extra == 'dev'
|
|
61
61
|
Provides-Extra: docs
|
|
62
62
|
Requires-Dist: sphinx >=6.0.0 ; extra == 'docs'
|
|
63
63
|
Requires-Dist: sphinx-autobuild >=2021.3.14 ; extra == 'docs'
|
|
@@ -73,11 +73,11 @@ Requires-Dist: hypothesis >=3.31.2 ; extra == 'test'
|
|
|
73
73
|
Requires-Dist: tox >=4.0.0 ; extra == 'test'
|
|
74
74
|
Requires-Dist: mypy ==1.10.0 ; extra == 'test'
|
|
75
75
|
Requires-Dist: pre-commit >=3.4.0 ; extra == 'test'
|
|
76
|
-
Requires-Dist: eth-tester[py-evm] <0.13.0b1,>=0.
|
|
77
|
-
Requires-Dist: py-geth >=5.
|
|
76
|
+
Requires-Dist: eth-tester[py-evm] <0.13.0b1,>=0.12.0b1 ; extra == 'test'
|
|
77
|
+
Requires-Dist: py-geth >=5.1.0 ; extra == 'test'
|
|
78
78
|
Provides-Extra: tester
|
|
79
|
-
Requires-Dist: eth-tester[py-evm] <0.13.0b1,>=0.
|
|
80
|
-
Requires-Dist: py-geth >=5.
|
|
79
|
+
Requires-Dist: eth-tester[py-evm] <0.13.0b1,>=0.12.0b1 ; extra == 'tester'
|
|
80
|
+
Requires-Dist: py-geth >=5.1.0 ; extra == 'tester'
|
|
81
81
|
|
|
82
82
|
# web3.py
|
|
83
83
|
|