faster-eth-utils 5.3.19__cp310-cp310-win32.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.

Potentially problematic release.


This version of faster-eth-utils might be problematic. Click here for more details.

Files changed (53) hide show
  1. faster_eth_utils/__init__.py +144 -0
  2. faster_eth_utils/__json/eth_networks.json +1 -0
  3. faster_eth_utils/__main__.py +5 -0
  4. faster_eth_utils/abi.cp310-win32.pyd +0 -0
  5. faster_eth_utils/abi.py +847 -0
  6. faster_eth_utils/address.cp310-win32.pyd +0 -0
  7. faster_eth_utils/address.py +145 -0
  8. faster_eth_utils/applicators.cp310-win32.pyd +0 -0
  9. faster_eth_utils/applicators.py +209 -0
  10. faster_eth_utils/conversions.cp310-win32.pyd +0 -0
  11. faster_eth_utils/conversions.py +191 -0
  12. faster_eth_utils/crypto.cp310-win32.pyd +0 -0
  13. faster_eth_utils/crypto.py +21 -0
  14. faster_eth_utils/currency.cp310-win32.pyd +0 -0
  15. faster_eth_utils/currency.py +141 -0
  16. faster_eth_utils/curried/__init__.py +306 -0
  17. faster_eth_utils/debug.cp310-win32.pyd +0 -0
  18. faster_eth_utils/debug.py +20 -0
  19. faster_eth_utils/decorators.cp310-win32.pyd +0 -0
  20. faster_eth_utils/decorators.py +119 -0
  21. faster_eth_utils/encoding.cp310-win32.pyd +0 -0
  22. faster_eth_utils/encoding.py +6 -0
  23. faster_eth_utils/exceptions.cp310-win32.pyd +0 -0
  24. faster_eth_utils/exceptions.py +11 -0
  25. faster_eth_utils/functional.cp310-win32.pyd +0 -0
  26. faster_eth_utils/functional.py +89 -0
  27. faster_eth_utils/hexadecimal.cp310-win32.pyd +0 -0
  28. faster_eth_utils/hexadecimal.py +80 -0
  29. faster_eth_utils/humanize.cp310-win32.pyd +0 -0
  30. faster_eth_utils/humanize.py +201 -0
  31. faster_eth_utils/logging.py +146 -0
  32. faster_eth_utils/module_loading.cp310-win32.pyd +0 -0
  33. faster_eth_utils/module_loading.py +31 -0
  34. faster_eth_utils/network.cp310-win32.pyd +0 -0
  35. faster_eth_utils/network.py +92 -0
  36. faster_eth_utils/numeric.cp310-win32.pyd +0 -0
  37. faster_eth_utils/numeric.py +43 -0
  38. faster_eth_utils/py.typed +0 -0
  39. faster_eth_utils/pydantic.py +101 -0
  40. faster_eth_utils/toolz.cp310-win32.pyd +0 -0
  41. faster_eth_utils/toolz.py +84 -0
  42. faster_eth_utils/types.cp310-win32.pyd +0 -0
  43. faster_eth_utils/types.py +68 -0
  44. faster_eth_utils/typing/__init__.py +18 -0
  45. faster_eth_utils/typing/misc.py +14 -0
  46. faster_eth_utils/units.cp310-win32.pyd +0 -0
  47. faster_eth_utils/units.py +31 -0
  48. faster_eth_utils-5.3.19.dist-info/METADATA +193 -0
  49. faster_eth_utils-5.3.19.dist-info/RECORD +53 -0
  50. faster_eth_utils-5.3.19.dist-info/WHEEL +5 -0
  51. faster_eth_utils-5.3.19.dist-info/licenses/LICENSE +21 -0
  52. faster_eth_utils-5.3.19.dist-info/top_level.txt +3 -0
  53. faster_eth_utils__mypyc.cp310-win32.pyd +0 -0
@@ -0,0 +1,847 @@
1
+ from collections import (
2
+ abc,
3
+ )
4
+ import copy
5
+ import itertools
6
+ import re
7
+ from typing import (
8
+ Any,
9
+ Dict,
10
+ Final,
11
+ Iterable,
12
+ List,
13
+ Literal,
14
+ Mapping,
15
+ Optional,
16
+ Sequence,
17
+ Tuple,
18
+ Union,
19
+ cast,
20
+ overload,
21
+ )
22
+
23
+ from eth_typing import (
24
+ ABI,
25
+ ABIComponent,
26
+ ABIConstructor,
27
+ ABIElement,
28
+ ABIError,
29
+ ABIEvent,
30
+ ABIFallback,
31
+ ABIFunction,
32
+ ABIReceive,
33
+ )
34
+
35
+ from faster_eth_utils.types import (
36
+ is_list_like,
37
+ )
38
+
39
+ from .crypto import (
40
+ keccak,
41
+ )
42
+
43
+
44
+ ABIType = Literal["function", "constructor", "fallback", "receive", "event", "error"]
45
+
46
+
47
+ def _align_abi_input(
48
+ arg_abi: ABIComponent, normalized_arg: Any
49
+ ) -> Union[Any, Tuple[Any, ...]]:
50
+ """
51
+ Aligns the values of any mapping at any level of nesting in ``normalized_arg``
52
+ according to the layout of the corresponding abi spec.
53
+ """
54
+ tuple_parts = _get_tuple_type_str_and_dims(arg_abi.get("type", ""))
55
+
56
+ if tuple_parts is None:
57
+ # normalized_arg is non-tuple. Just return value.
58
+ return normalized_arg
59
+
60
+ tuple_prefix, tuple_dims = tuple_parts
61
+ if tuple_dims is None:
62
+ # normalized_arg is non-list tuple. Each sub arg in `normalized_arg` will be
63
+ # aligned according to its corresponding abi.
64
+ sub_abis = cast(Iterable[ABIComponent], arg_abi.get("components", []))
65
+ else:
66
+ num_dims = tuple_dims.count("[")
67
+
68
+ # normalized_arg is list tuple. A non-list version of its abi will be used to
69
+ # align each element in `normalized_arg`.
70
+ new_abi = copy.copy(arg_abi)
71
+ new_abi["type"] = tuple_prefix + "[]" * (num_dims - 1)
72
+
73
+ sub_abis = itertools.repeat(new_abi)
74
+
75
+ aligned_arg: Any
76
+ if isinstance(normalized_arg, abc.Mapping):
77
+ # normalized_arg is mapping. Align values according to abi order.
78
+ aligned_arg = tuple(normalized_arg[abi["name"]] for abi in sub_abis)
79
+ else:
80
+ aligned_arg = normalized_arg
81
+
82
+ if not is_list_like(aligned_arg):
83
+ raise TypeError(
84
+ f'Expected non-string sequence for "{arg_abi.get("type")}" '
85
+ f"component type: got {aligned_arg}"
86
+ )
87
+
88
+ # convert NamedTuple to regular tuple
89
+ typing = tuple if isinstance(aligned_arg, tuple) else type(aligned_arg)
90
+
91
+ return typing( # type: ignore [call-arg]
92
+ _align_abi_input(sub_abi, sub_arg)
93
+ for sub_abi, sub_arg in zip(sub_abis, aligned_arg)
94
+ )
95
+
96
+
97
+ def _get_tuple_type_str_and_dims(s: str) -> Optional[Tuple[str, Optional[str]]]:
98
+ """
99
+ Takes a JSON ABI type string. For tuple type strings, returns the separated
100
+ prefix and array dimension parts. For all other strings, returns ``None``.
101
+ """
102
+ tuple_type_str_re = "^(tuple)((\\[([1-9]\\d*\b)?])*)??$"
103
+ match = re.compile(tuple_type_str_re).match(s)
104
+
105
+ return None if match is None else (match[1], match[2])
106
+
107
+
108
+ def _raise_if_not_function_abi(abi_element: ABIElement) -> None:
109
+ if abi_element["type"] != "function":
110
+ raise ValueError(
111
+ f"Outputs only supported for ABI type `function`. Provided"
112
+ f" ABI type was `{abi_element.get('type')}` and outputs were "
113
+ f"`{abi_element.get('outputs')}`."
114
+ )
115
+
116
+
117
+ def _raise_if_fallback_or_receive_abi(abi_element: ABIElement) -> None:
118
+ if abi_element["type"] in ["fallback", "receive"]:
119
+ raise ValueError(
120
+ f"Inputs not supported for function types `fallback` or `receive`. Provided"
121
+ f" ABI type was `{abi_element.get('type')}` with inputs "
122
+ f"`{abi_element.get('inputs')}`."
123
+ )
124
+
125
+
126
+ def collapse_if_tuple(abi: Union[ABIComponent, Dict[str, Any], str]) -> str:
127
+ """
128
+ Extract argument types from a function or event ABI parameter.
129
+
130
+ With tuple argument types, return a Tuple of each type.
131
+ Returns the param if `abi` is an instance of str or another non-tuple
132
+ type.
133
+
134
+ :param abi: A Function or Event ABI component or a string with type info.
135
+ :type abi: `Union[ABIComponent, Dict[str, Any], str]`
136
+ :return: Type(s) for the function or event ABI param.
137
+ :rtype: `str`
138
+
139
+ .. doctest::
140
+
141
+ >>> from eth_utils.abi import collapse_if_tuple
142
+ >>> abi = {
143
+ ... 'components': [
144
+ ... {'name': 'anAddress', 'type': 'address'},
145
+ ... {'name': 'anInt', 'type': 'uint256'},
146
+ ... {'name': 'someBytes', 'type': 'bytes'},
147
+ ... ],
148
+ ... 'type': 'tuple',
149
+ ... }
150
+ >>> collapse_if_tuple(abi)
151
+ '(address,uint256,bytes)'
152
+ """
153
+ if isinstance(abi, str):
154
+ return abi
155
+
156
+ element_type = abi.get("type")
157
+ if not isinstance(element_type, str):
158
+ raise TypeError(
159
+ f"The 'type' must be a string, but got {repr(element_type)} of type "
160
+ f"{type(element_type)}"
161
+ )
162
+ elif not element_type.startswith("tuple"):
163
+ return element_type
164
+
165
+ delimited = ",".join(collapse_if_tuple(c) for c in abi["components"])
166
+ # Whatever comes after "tuple" is the array dims. The ABI spec states that
167
+ # this will have the form "", "[]", or "[k]".
168
+ array_dim = element_type[5:]
169
+ return f"({delimited}){array_dim}"
170
+
171
+
172
+ def abi_to_signature(abi_element: ABIElement) -> str:
173
+ """
174
+ Returns a string signature representation of the function or event ABI
175
+ and arguments.
176
+
177
+ Signatures consist of the name followed by a list of arguments.
178
+
179
+ :param abi_element: ABI element.
180
+ :type abi_element: `ABIElement`
181
+ :return: Stringified ABI signature
182
+ :rtype: `str`
183
+
184
+ .. doctest::
185
+
186
+ >>> from eth_utils import abi_to_signature
187
+ >>> abi_element = {
188
+ ... 'constant': False,
189
+ ... 'inputs': [
190
+ ... {
191
+ ... 'name': 's',
192
+ ... 'type': 'uint256'
193
+ ... }
194
+ ... ],
195
+ ... 'name': 'f',
196
+ ... 'outputs': [],
197
+ ... 'payable': False,
198
+ ... 'stateMutability': 'nonpayable',
199
+ ... 'type': 'function'
200
+ ... }
201
+ >>> abi_to_signature(abi_element)
202
+ 'f(uint256)'
203
+ """
204
+ signature = "{name}({input_types})"
205
+
206
+ abi_type = str(abi_element.get("type", ""))
207
+ if abi_type in {"fallback", "receive"}:
208
+ return signature.format(name=abi_type, input_types="")
209
+
210
+ if abi_type == "constructor":
211
+ fn_name = abi_type
212
+ else:
213
+ fn_name = str(abi_element.get("name", abi_type))
214
+
215
+ return signature.format(
216
+ name=fn_name, input_types=",".join(get_abi_input_types(abi_element))
217
+ )
218
+
219
+
220
+ def filter_abi_by_name(abi_name: str, contract_abi: ABI) -> Sequence[ABIElement]:
221
+ """
222
+ Get one or more function and event ABIs by name.
223
+
224
+ :param abi_name: Name of the function, event or error.
225
+ :type abi_name: `str`
226
+ :param contract_abi: Contract ABI.
227
+ :type contract_abi: `ABI`
228
+ :return: Function or event ABIs with matching name.
229
+ :rtype: `Sequence[ABIElement]`
230
+
231
+ .. doctest::
232
+
233
+ >>> from eth_utils.abi import filter_abi_by_name
234
+ >>> abi = [
235
+ ... {
236
+ ... "constant": False,
237
+ ... "inputs": [],
238
+ ... "name": "func_1",
239
+ ... "outputs": [],
240
+ ... "type": "function",
241
+ ... },
242
+ ... {
243
+ ... "constant": False,
244
+ ... "inputs": [
245
+ ... {"name": "a", "type": "uint256"},
246
+ ... ],
247
+ ... "name": "func_2",
248
+ ... "outputs": [],
249
+ ... "type": "function",
250
+ ... },
251
+ ... {
252
+ ... "constant": False,
253
+ ... "inputs": [
254
+ ... {"name": "a", "type": "uint256"},
255
+ ... {"name": "b", "type": "uint256"},
256
+ ... ],
257
+ ... "name": "func_3",
258
+ ... "outputs": [],
259
+ ... "type": "function",
260
+ ... },
261
+ ... {
262
+ ... "constant": False,
263
+ ... "inputs": [
264
+ ... {"name": "a", "type": "uint256"},
265
+ ... {"name": "b", "type": "uint256"},
266
+ ... {"name": "c", "type": "uint256"},
267
+ ... ],
268
+ ... "name": "func_4",
269
+ ... "outputs": [],
270
+ ... "type": "function",
271
+ ... },
272
+ ... ]
273
+ >>> filter_abi_by_name("func_1", abi)
274
+ [{'constant': False, 'inputs': [], 'name': 'func_1', 'outputs': [], \
275
+ 'type': 'function'}]
276
+ """
277
+ return [
278
+ abi
279
+ for abi in contract_abi
280
+ if abi["type"] in ["function", "event", "error"]
281
+ and abi["name"] == abi_name # type: ignore [typeddict-item]
282
+ ]
283
+
284
+
285
+ __ABI_TYPE_LITERALS: Final = {
286
+ Literal["function"]: "function",
287
+ Literal["constructor"]: "constructor",
288
+ Literal["fallback"]: "fallback",
289
+ Literal["receive"]: "receive",
290
+ Literal["event"]: "event",
291
+ Literal["error"]: "error",
292
+ }
293
+
294
+
295
+ @overload
296
+ def filter_abi_by_type(
297
+ abi_type: Literal["function"],
298
+ contract_abi: ABI,
299
+ ) -> List[ABIFunction]:
300
+ pass
301
+
302
+
303
+ @overload
304
+ def filter_abi_by_type(
305
+ abi_type: Literal["constructor"],
306
+ contract_abi: ABI,
307
+ ) -> List[ABIConstructor]:
308
+ pass
309
+
310
+
311
+ @overload
312
+ def filter_abi_by_type(
313
+ abi_type: Literal["fallback"],
314
+ contract_abi: ABI,
315
+ ) -> List[ABIFallback]:
316
+ pass
317
+
318
+
319
+ @overload
320
+ def filter_abi_by_type(
321
+ abi_type: Literal["receive"],
322
+ contract_abi: ABI,
323
+ ) -> List[ABIReceive]:
324
+ pass
325
+
326
+
327
+ @overload
328
+ def filter_abi_by_type(
329
+ abi_type: Literal["event"],
330
+ contract_abi: ABI,
331
+ ) -> List[ABIEvent]:
332
+ pass
333
+
334
+
335
+ @overload
336
+ def filter_abi_by_type(
337
+ abi_type: Literal["error"],
338
+ contract_abi: ABI,
339
+ ) -> List[ABIError]:
340
+ pass
341
+
342
+
343
+ def filter_abi_by_type(
344
+ abi_type: ABIType,
345
+ contract_abi: ABI,
346
+ ) -> Union[
347
+ List[ABIFunction], List[ABIConstructor], List[ABIFallback], List[ABIReceive], List[ABIEvent], List[ABIError]
348
+ ]:
349
+ """
350
+ Return a list of each ``ABIElement`` that is of type ``abi_type``.
351
+
352
+ For mypy, function overloads ensures the correct type is returned based on the
353
+ ``abi_type``. For example, if ``abi_type`` is "function", the return type will be
354
+ ``Sequence[ABIFunction]``.
355
+
356
+ :param abi_type: Type of ABI element to filter by.
357
+ :type abi_type: `str`
358
+ :param contract_abi: Contract ABI.
359
+ :type contract_abi: `ABI`
360
+ :return: List of ABI elements of the specified type.
361
+ :rtype: `Sequence[Union[ABIFunction, ABIConstructor, ABIFallback, ABIReceive, \
362
+ ABIEvent, ABIError]]`
363
+
364
+ .. doctest::
365
+
366
+ >>> from eth_utils import filter_abi_by_type
367
+ >>> abi = [
368
+ ... {"type": "function", "name": "myFunction", "inputs": [], "outputs": []},
369
+ ... {"type": "function", "name": "myFunction2", "inputs": [], "outputs": []},
370
+ ... {"type": "event", "name": "MyEvent", "inputs": []}
371
+ ... ]
372
+ >>> filter_abi_by_type("function", abi)
373
+ [{'type': 'function', 'name': 'myFunction', 'inputs': [], 'outputs': []}, \
374
+ {'type': 'function', 'name': 'myFunction2', 'inputs': [], 'outputs': []}]
375
+ """
376
+ if abi_type in ("function", "constructor", "fallback", "receive", "event", "error"):
377
+ return [abi for abi in contract_abi if abi["type"] == abi_type] # type: ignore [return-value]
378
+ abi_type_string: Optional[ABIType] = __ABI_TYPE_LITERALS.get(abi_type) # type: ignore [call-overload]
379
+ if abi_type_string is None:
380
+ raise ValueError(f"Unsupported ABI type: {abi_type}")
381
+ return [abi for abi in contract_abi if abi["type"] == abi_type_string] # type: ignore [return-value]
382
+
383
+
384
+ def get_all_function_abis(contract_abi: ABI) -> Sequence[ABIFunction]:
385
+ """
386
+ Return interfaces for each function in the contract ABI.
387
+
388
+ :param contract_abi: Contract ABI.
389
+ :type contract_abi: `ABI`
390
+ :return: List of ABIs for each function interface.
391
+ :rtype: `Sequence[ABIFunction]`
392
+
393
+ .. doctest::
394
+
395
+ >>> from eth_utils import get_all_function_abis
396
+ >>> contract_abi = [
397
+ ... {"type": "function", "name": "myFunction", "inputs": [], "outputs": []},
398
+ ... {"type": "function", "name": "myFunction2", "inputs": [], "outputs": []},
399
+ ... {"type": "event", "name": "MyEvent", "inputs": []}
400
+ ... ]
401
+ >>> get_all_function_abis(contract_abi)
402
+ [{'type': 'function', 'name': 'myFunction', 'inputs': [], 'outputs': []}, \
403
+ {'type': 'function', 'name': 'myFunction2', 'inputs': [], 'outputs': []}]
404
+ """
405
+ return filter_abi_by_type("function", contract_abi)
406
+
407
+
408
+ def get_all_event_abis(contract_abi: ABI) -> Sequence[ABIEvent]:
409
+ """
410
+ Return interfaces for each event in the contract ABI.
411
+
412
+ :param contract_abi: Contract ABI.
413
+ :type contract_abi: `ABI`
414
+ :return: List of ABIs for each event interface.
415
+ :rtype: `Sequence[ABIEvent]`
416
+
417
+ .. doctest::
418
+
419
+ >>> from eth_utils import get_all_event_abis
420
+ >>> contract_abi = [
421
+ ... {"type": "function", "name": "myFunction", "inputs": [], "outputs": []},
422
+ ... {"type": "function", "name": "myFunction2", "inputs": [], "outputs": []},
423
+ ... {"type": "event", "name": "MyEvent", "inputs": []}
424
+ ... ]
425
+ >>> get_all_event_abis(contract_abi)
426
+ [{'type': 'event', 'name': 'MyEvent', 'inputs': []}]
427
+ """
428
+ return filter_abi_by_type("event", contract_abi)
429
+
430
+
431
+ def get_normalized_abi_inputs(
432
+ abi_element: ABIElement,
433
+ *args: Any,
434
+ **kwargs: Any,
435
+ ) -> Tuple[Any, ...]:
436
+ r"""
437
+ Flattens positional args (``args``) and keyword args (``kwargs``) into a Tuple and
438
+ uses the ``abi_element`` for validation.
439
+
440
+ Checks to ensure that the correct number of args were given, no duplicate args were
441
+ given, and no unknown args were given. Returns a list of argument values aligned
442
+ to the order of inputs defined in ``abi_element``.
443
+
444
+ :param abi_element: ABI element.
445
+ :type abi_element: `ABIElement`
446
+ :param args: Positional arguments for the function.
447
+ :type args: `Optional[Sequence[Any]]`
448
+ :param kwargs: Keyword arguments for the function.
449
+ :type kwargs: `Optional[Dict[str, Any]]`
450
+ :return: Arguments list.
451
+ :rtype: `Tuple[Any, ...]`
452
+
453
+ .. doctest::
454
+
455
+ >>> from eth_utils import get_normalized_abi_inputs
456
+ >>> abi = {
457
+ ... 'constant': False,
458
+ ... 'inputs': [
459
+ ... {
460
+ ... 'name': 'name',
461
+ ... 'type': 'string'
462
+ ... },
463
+ ... {
464
+ ... 'name': 's',
465
+ ... 'type': 'uint256'
466
+ ... },
467
+ ... {
468
+ ... 'name': 't',
469
+ ... 'components': [
470
+ ... {'name': 'anAddress', 'type': 'address'},
471
+ ... {'name': 'anInt', 'type': 'uint256'},
472
+ ... {'name': 'someBytes', 'type': 'bytes'},
473
+ ... ],
474
+ ... 'type': 'tuple'
475
+ ... }
476
+ ... ],
477
+ ... 'name': 'f',
478
+ ... 'outputs': [],
479
+ ... 'payable': False,
480
+ ... 'stateMutability': 'nonpayable',
481
+ ... 'type': 'function'
482
+ ... }
483
+ >>> get_normalized_abi_inputs(
484
+ ... abi, *('myName', 123), **{'t': ('0x1', 1, b'\x01')}
485
+ ... )
486
+ ('myName', 123, ('0x1', 1, b'\x01'))
487
+ """
488
+ _raise_if_fallback_or_receive_abi(abi_element)
489
+
490
+ function_inputs = cast(Sequence[ABIComponent], abi_element.get("inputs", []))
491
+ if len(args) + len(kwargs) != len(function_inputs):
492
+ raise TypeError(
493
+ f"Incorrect argument count. Expected '{len(function_inputs)}'"
494
+ f", got '{len(args) + len(kwargs)}'."
495
+ )
496
+
497
+ # If no keyword args were given, we don't need to align them
498
+ if not kwargs:
499
+ return args
500
+
501
+ kwarg_names = set(kwargs.keys())
502
+ sorted_arg_names = tuple(arg_abi["name"] for arg_abi in function_inputs)
503
+ args_as_kwargs = dict(zip(sorted_arg_names, args))
504
+
505
+ # Check for duplicate args
506
+ if duplicate_args := kwarg_names.intersection(args_as_kwargs.keys()):
507
+ raise TypeError(
508
+ f"{abi_element.get('name')}() got multiple values for argument(s) "
509
+ f"'{', '.join(duplicate_args)}'."
510
+ )
511
+
512
+ # Check for unknown args
513
+ # Arg names sorted to raise consistent error messages
514
+ if unknown_args := tuple(sorted(kwarg_names.difference(sorted_arg_names))):
515
+ message = "{} got unexpected keyword argument(s) '{}'."
516
+ if abi_element.get("name"):
517
+ raise TypeError(
518
+ message.format(f"{abi_element.get('name')}()", ", ".join(unknown_args))
519
+ )
520
+ raise TypeError(
521
+ message.format(
522
+ f"Type: '{abi_element.get('type')}'", ", ".join(unknown_args)
523
+ )
524
+ )
525
+
526
+ # Sort args according to their position in the ABI and unzip them from their
527
+ # names
528
+ sorted_args = tuple(
529
+ zip(
530
+ *sorted(
531
+ itertools.chain(kwargs.items(), args_as_kwargs.items()),
532
+ key=lambda kv: sorted_arg_names.index(kv[0]),
533
+ )
534
+ )
535
+ )
536
+
537
+ return tuple(sorted_args[1]) if sorted_args else ()
538
+
539
+
540
+ def get_aligned_abi_inputs(
541
+ abi_element: ABIElement,
542
+ normalized_args: Union[Tuple[Any, ...], Mapping[Any, Any]],
543
+ ) -> Tuple[Tuple[str, ...], Tuple[Any, ...]]:
544
+ """
545
+ Returns a pair of nested Tuples containing a list of types and a list of input
546
+ values sorted by the order specified by the ``abi``.
547
+
548
+ ``normalized_args`` can be obtained by using
549
+ :py:meth:`eth_utils.abi.get_normalized_abi_inputs`, which returns nested mappings
550
+ or sequences corresponding to tuple-encoded values in ``abi``.
551
+
552
+ :param abi_element: ABI element.
553
+ :type abi_element: `ABIElement`
554
+ :param normalized_args: Normalized arguments for the function.
555
+ :type normalized_args: `Union[Tuple[Any, ...], Mapping[Any, Any]]`
556
+ :return: Tuple of types and aligned arguments.
557
+ :rtype: `Tuple[Tuple[str, ...], Tuple[Any, ...]]`
558
+
559
+ .. doctest::
560
+
561
+ >>> from eth_utils import get_aligned_abi_inputs
562
+ >>> abi = {
563
+ ... 'constant': False,
564
+ ... 'inputs': [
565
+ ... {
566
+ ... 'name': 'name',
567
+ ... 'type': 'string'
568
+ ... },
569
+ ... {
570
+ ... 'name': 's',
571
+ ... 'type': 'uint256'
572
+ ... }
573
+ ... ],
574
+ ... 'name': 'f',
575
+ ... 'outputs': [],
576
+ ... 'payable': False,
577
+ ... 'stateMutability': 'nonpayable',
578
+ ... 'type': 'function'
579
+ ... }
580
+ >>> get_aligned_abi_inputs(abi, ('myName', 123))
581
+ (('string', 'uint256'), ('myName', 123))
582
+ """
583
+ _raise_if_fallback_or_receive_abi(abi_element)
584
+
585
+ abi_element_inputs = cast(Sequence[ABIComponent], abi_element.get("inputs", []))
586
+ if isinstance(normalized_args, abc.Mapping):
587
+ # `args` is mapping. Align values according to abi order.
588
+ normalized_args = tuple(
589
+ normalized_args[abi["name"]] for abi in abi_element_inputs
590
+ )
591
+
592
+ return (
593
+ tuple(collapse_if_tuple(abi) for abi in abi_element_inputs),
594
+ type(normalized_args)(
595
+ _align_abi_input(abi, arg)
596
+ for abi, arg in zip(abi_element_inputs, normalized_args)
597
+ ),
598
+ )
599
+
600
+
601
+ def get_abi_input_names(abi_element: ABIElement) -> List[Optional[str]]:
602
+ """
603
+ Return names for each input from the function or event ABI.
604
+
605
+ :param abi_element: ABI element.
606
+ :type abi_element: `ABIElement`
607
+ :return: Names for each input in the function or event ABI.
608
+ :rtype: `List[Optional[str]]`
609
+
610
+ .. doctest::
611
+
612
+ >>> from eth_utils import get_abi_input_names
613
+ >>> abi = {
614
+ ... 'constant': False,
615
+ ... 'inputs': [
616
+ ... {
617
+ ... 'name': 's',
618
+ ... 'type': 'uint256'
619
+ ... }
620
+ ... ],
621
+ ... 'name': 'f',
622
+ ... 'outputs': [],
623
+ ... 'payable': False,
624
+ ... 'stateMutability': 'nonpayable',
625
+ ... 'type': 'function'
626
+ ... }
627
+ >>> get_abi_input_names(abi)
628
+ ['s']
629
+ """
630
+ _raise_if_fallback_or_receive_abi(abi_element)
631
+ return [
632
+ arg.get("name", None)
633
+ for arg in cast(Sequence[ABIComponent], abi_element.get("inputs", []))
634
+ ]
635
+
636
+
637
+ def get_abi_input_types(abi_element: ABIElement) -> List[str]:
638
+ """
639
+ Return types for each input from the function or event ABI.
640
+
641
+ :param abi_element: ABI element.
642
+ :type abi_element: `ABIElement`
643
+ :return: Types for each input in the function or event ABI.
644
+ :rtype: `List[str]`
645
+
646
+ .. doctest::
647
+
648
+ >>> from eth_utils import get_abi_input_types
649
+ >>> abi = {
650
+ ... 'constant': False,
651
+ ... 'inputs': [
652
+ ... {
653
+ ... 'name': 's',
654
+ ... 'type': 'uint256'
655
+ ... }
656
+ ... ],
657
+ ... 'name': 'f',
658
+ ... 'outputs': [],
659
+ ... 'payable': False,
660
+ ... 'stateMutability': 'nonpayable',
661
+ ... 'type': 'function'
662
+ ... }
663
+ >>> get_abi_input_types(abi)
664
+ ['uint256']
665
+ """
666
+ _raise_if_fallback_or_receive_abi(abi_element)
667
+ return [
668
+ collapse_if_tuple(arg)
669
+ for arg in cast(Sequence[ABIComponent], abi_element.get("inputs", []))
670
+ ]
671
+
672
+
673
+ def get_abi_output_names(abi_element: ABIElement) -> List[Optional[str]]:
674
+ """
675
+ Return names for each output from the ABI element.
676
+
677
+ :param abi_element: ABI element.
678
+ :type abi_element: `ABIElement`
679
+ :return: Names for each function output in the function ABI.
680
+ :rtype: `List[Optional[str]]`
681
+
682
+ .. doctest::
683
+
684
+ >>> from eth_utils import get_abi_output_names
685
+ >>> abi = {
686
+ ... 'constant': False,
687
+ ... 'inputs': [
688
+ ... {
689
+ ... 'name': 's',
690
+ ... 'type': 'uint256'
691
+ ... }
692
+ ... ],
693
+ ... 'name': 'f',
694
+ ... 'outputs': [
695
+ ... {
696
+ ... 'name': 'name',
697
+ ... 'type': 'string'
698
+ ... },
699
+ ... {
700
+ ... 'name': 's',
701
+ ... 'type': 'uint256'
702
+ ... }
703
+ ... ],
704
+ ... 'payable': False,
705
+ ... 'stateMutability': 'nonpayable',
706
+ ... 'type': 'function'
707
+ ... }
708
+ >>> get_abi_output_names(abi)
709
+ ['name', 's']
710
+ """
711
+ _raise_if_not_function_abi(abi_element)
712
+ return [
713
+ arg.get("name", None)
714
+ for arg in cast(Sequence[ABIComponent], abi_element.get("outputs", []))
715
+ ]
716
+
717
+
718
+ def get_abi_output_types(abi_element: ABIElement) -> List[str]:
719
+ """
720
+ Return types for each output from the function ABI.
721
+
722
+ :param abi_element: ABI element.
723
+ :type abi_element: `ABIElement`
724
+ :return: Types for each function output in the function ABI.
725
+ :rtype: `List[str]`
726
+
727
+ .. doctest::
728
+
729
+ >>> from eth_utils import get_abi_output_types
730
+ >>> abi = {
731
+ ... 'constant': False,
732
+ ... 'inputs': [
733
+ ... {
734
+ ... 'name': 's',
735
+ ... 'type': 'uint256'
736
+ ... }
737
+ ... ],
738
+ ... 'name': 'f',
739
+ ... 'outputs': [
740
+ ... {
741
+ ... 'name': 'name',
742
+ ... 'type': 'string'
743
+ ... },
744
+ ... {
745
+ ... 'name': 's',
746
+ ... 'type': 'uint256'
747
+ ... }
748
+ ... ],
749
+ ... 'payable': False,
750
+ ... 'stateMutability': 'nonpayable',
751
+ ... 'type': 'function'
752
+ ... }
753
+ >>> get_abi_output_types(abi)
754
+ ['string', 'uint256']
755
+
756
+ """
757
+ _raise_if_not_function_abi(abi_element)
758
+ return [
759
+ collapse_if_tuple(arg)
760
+ for arg in cast(Sequence[ABIComponent], abi_element.get("outputs", []))
761
+ ]
762
+
763
+
764
+ def function_signature_to_4byte_selector(function_signature: str) -> bytes:
765
+ r"""
766
+ Return the 4-byte function selector from a function signature string.
767
+
768
+ :param function_signature: String representation of the function name and arguments.
769
+ :type function_signature: `str`
770
+ :return: 4-byte function selector.
771
+ :rtype: `bytes`
772
+
773
+ .. doctest::
774
+
775
+ >>> from eth_utils import function_signature_to_4byte_selector
776
+ >>> function_signature_to_4byte_selector('myFunction()')
777
+ b'\xc3x\n:'
778
+ """
779
+ return keccak(text=function_signature.replace(" ", ""))[:4]
780
+
781
+
782
+ def function_abi_to_4byte_selector(abi_element: ABIElement) -> bytes:
783
+ r"""
784
+ Return the 4-byte function signature of the provided function ABI.
785
+
786
+ :param abi_element: ABI element.
787
+ :type abi_element: `ABIElement`
788
+ :return: 4-byte function signature.
789
+ :rtype: `bytes`
790
+
791
+ .. doctest::
792
+
793
+ >>> from eth_utils import function_abi_to_4byte_selector
794
+ >>> abi_element = {
795
+ ... 'type': 'function',
796
+ ... 'name': 'myFunction',
797
+ ... 'inputs': [],
798
+ ... 'outputs': []
799
+ ... }
800
+ >>> function_abi_to_4byte_selector(abi_element)
801
+ b'\xc3x\n:'
802
+ """
803
+ function_signature = abi_to_signature(abi_element)
804
+ return function_signature_to_4byte_selector(function_signature)
805
+
806
+
807
+ def event_signature_to_log_topic(event_signature: str) -> bytes:
808
+ r"""
809
+ Return the 32-byte keccak signature of the log topic for an event signature.
810
+
811
+ :param event_signature: String representation of the event name and arguments.
812
+ :type event_signature: `str`
813
+ :return: Log topic bytes.
814
+ :rtype: `bytes`
815
+
816
+ .. doctest::
817
+
818
+ >>> from eth_utils import event_signature_to_log_topic
819
+ >>> event_signature_to_log_topic('MyEvent()')
820
+ b'M\xbf\xb6\x8bC\xdd\xdf\xa1+Q\xeb\xe9\x9a\xb8\xfd\xedb\x0f\x9a\n\xc21B\x87\x9aO\x19*\x1byR\xd2'
821
+ """
822
+ return keccak(text=event_signature.replace(" ", ""))
823
+
824
+
825
+ def event_abi_to_log_topic(event_abi: ABIEvent) -> bytes:
826
+ r"""
827
+ Return the 32-byte keccak signature of the log topic from an event ABI.
828
+
829
+ :param event_abi: Event ABI.
830
+ :type event_abi: `ABIEvent`
831
+ :return: Log topic bytes.
832
+ :rtype: `bytes`
833
+
834
+ .. doctest::
835
+
836
+ >>> from eth_utils import event_abi_to_log_topic
837
+ >>> abi = {
838
+ ... 'type': 'event',
839
+ ... 'anonymous': False,
840
+ ... 'name': 'MyEvent',
841
+ ... 'inputs': []
842
+ ... }
843
+ >>> event_abi_to_log_topic(abi)
844
+ b'M\xbf\xb6\x8bC\xdd\xdf\xa1+Q\xeb\xe9\x9a\xb8\xfd\xedb\x0f\x9a\n\xc21B\x87\x9aO\x19*\x1byR\xd2'
845
+ """
846
+ event_signature = abi_to_signature(event_abi)
847
+ return event_signature_to_log_topic(event_signature)