Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ABI types for utils #61

Merged
merged 7 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 7 additions & 21 deletions docs/eth_typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,12 @@ i.e.

from eth_typing import TypeStr

ABI
---

TypeStr
~~~~~~~

String representation of a data type.

.. code-block:: python

TypeStr = str

Decodable
~~~~~~~~~

Binary data to be decoded.

.. code-block:: python
Application Binary Interface
----------------------------

Decodable = Union[bytes, bytearray]
.. automodule:: eth_typing.abi
:members:
:undoc-members:

Enumerables
-----------
Expand Down Expand Up @@ -67,8 +53,8 @@ The list of chain ids is available from the `ethereum-lists/chains`_ repository.

class ChainId(IntEnum):
# L1 networks
ETH = 1
EXP = 2
ETH = 1
EXP = 2
ROP = 3
RIN = 4
GOR = 5
Expand Down
30 changes: 30 additions & 0 deletions eth_typing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
)

from .abi import (
ABI,
ABIConstructor,
ABIElement,
ABIEvent,
ABIEventParam,
ABIFallback,
ABIFunction,
ABIFunctionComponent,
ABIFunctionInfo,
ABIFunctionParam,
ABIReceive,
Decodable,
TypeStr,
)
Expand Down Expand Up @@ -30,11 +41,27 @@
Hash32,
HexAddress,
)
from .exceptions import (
MismatchedABI,
ValidationError,
)
from .networks import (
URI,
ChainId,
)

__all__ = (
"ABI",
"ABIConstructor",
"ABIElement",
"ABIEvent",
"ABIEventParam",
"ABIFallback",
"ABIFunction",
"ABIFunctionComponent",
"ABIFunctionInfo",
"ABIFunctionParam",
"ABIReceive",
"Decodable",
"TypeStr",
"BLSPrivateKey",
Expand All @@ -52,6 +79,9 @@
"ChecksumAddress",
"Hash32",
"HexAddress",
"URI",
"ValidationError",
"MismatchedABI",
)

__version__ = __version("eth-typing")
156 changes: 156 additions & 0 deletions eth_typing/abi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,162 @@
from typing import (
Any,
Literal,
Sequence,
Tuple,
TypedDict,
Union,
)

from eth_typing.encoding import (
HexStr,
)

TypeStr = str
"""String representation of a data type."""
Decodable = Union[bytes, bytearray]
"""Binary data to be decoded."""


class ABIEventParam(TypedDict, total=False):
"""
TypedDict to represent the `ABI` for event parameters.
"""

indexed: bool
"""If True, event parameter can be used as a topic filter."""
name: str
"""Name of the event parameter."""
type: str
"""Type of the event parameter."""


class ABIEvent(TypedDict, total=False):
"""
TypedDict to represent the `ABI` for an event.
"""

anonymous: bool
"""If True, event is anonymous. Cannot filter the event by name."""
inputs: Sequence["ABIEventParam"]
"""Input parameters for the event."""
name: str
"""Event name identifier."""
type: Literal["event"]
"""Event ABI type."""


class ABIFunctionComponent(TypedDict, total=False):
"""
TypedDict representing the `ABI` for nested function parameters.

Used as a component of `ABIFunctionParams`.
"""

components: Sequence["ABIFunctionComponent"]
"""List of nested function parameters"""
name: str
"""Name of the function parameter."""
type: str
"""Type of the function parameter."""


class ABIFunctionParam(TypedDict, total=False):
"""
TypedDict representing the `ABI` for function parameters.
"""

components: Sequence["ABIFunctionComponent"]
"""List of function parameters"""
name: str
"""Name of the function parameter."""
type: str
"""Type of the function parameter."""


class ABIFunctionType(TypedDict, total=False):
"""
TypedDict representing the `ABI` for all function types.

This is the base type for functions.
Please use ABIFunction, ABIConstructor, ABIFallback or ABIReceive instead.
"""

stateMutability: Literal["pure", "view", "nonpayable", "payable"]
"""State mutability of the constructor."""
payable: bool
"""
Contract is payable to receive ether on deployment.
Deprecated in favor of stateMutability payable and nonpayable.
"""
constant: bool
"""
Function is constant and does not change state.
Deprecated in favor of stateMutability pure and view.
"""


class ABIFunction(ABIFunctionType, total=False):
"""
TypedDict representing the `ABI` for a function.
"""

type: Literal["function"]
"""Type of the function."""
inputs: Sequence["ABIFunctionParam"]
"""Function input parameters."""
name: str
"""Name of the function."""
outputs: Sequence["ABIFunctionParam"]
"""Function return values."""


class ABIConstructor(ABIFunctionType, total=False):
"""
TypedDict representing the `ABI` for a constructor function.
"""

type: Literal["constructor"]
"""Type of the constructor function."""
inputs: Sequence["ABIFunctionParam"]
"""Function input parameters."""


class ABIFallback(ABIFunctionType, total=False):
"""
TypedDict representing the `ABI` for a fallback function.
"""

type: Literal["fallback"]
"""Type of the fallback function."""


class ABIReceive(ABIFunctionType, total=False):
"""
TypedDict representing the `ABI` for a receive function.
"""

type: Literal["receive"]
"""Type of the receive function."""


class ABIFunctionInfo(TypedDict, total=False):
"""
TypedDict to represent an `ABIFunction` with the function selector and
corresponding arguments.
"""

abi: ABIFunction
"""ABI for the function interface."""
selector: HexStr
"""Solidity Function selector sighash."""
arguments: Tuple[Any, ...]
"""Function input parameters."""


ABIElement = Union[ABIFunction, ABIEvent]
"""Base type for `ABIFunction` and `ABIEvent` types."""
ABI = Sequence[Union[ABIFunction, ABIEvent]]
"""
List of components representing function and event interfaces
(elements of an ABI).
"""
11 changes: 11 additions & 0 deletions eth_typing/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ValidationError(Exception):
"""
Raised when something does not pass a validation check.
"""


class MismatchedABI(ValidationError):
"""
Raised when an ABI does not match with supplied parameters, or when an
attempt is made to access a function/event that does not exist in the ABI.
"""
6 changes: 6 additions & 0 deletions eth_typing/networks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from enum import (
IntEnum,
)
from typing import (
NewType,
)

URI = NewType("URI", str)
"""Any string that represents a URI."""


class ChainId(IntEnum):
Expand Down
1 change: 1 addition & 0 deletions newsfragments/61.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add type definitions to represent contract ``ABI``s.
8 changes: 6 additions & 2 deletions newsfragments/validate_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import pathlib
import sys

from eth_typing.exceptions import (
ValidationError,
)

ALLOWED_EXTENSIONS = {
".breaking.rst",
".bugfix.rst",
Expand Down Expand Up @@ -36,9 +40,9 @@
elif num_args == 0:
full_extension = "".join(fragment_file.suffixes)
if full_extension not in ALLOWED_EXTENSIONS:
raise Exception(f"Unexpected file: {fragment_file}")
raise ValidationError(f"Unexpected file: {fragment_file}")
elif sys.argv[1] == "is-empty":
raise Exception(f"Unexpected file: {fragment_file}")
raise ValidationError(f"Unexpected file: {fragment_file}")
else:
raise RuntimeError(
f"Strange: arguments {sys.argv} were validated, but not found"
Expand Down