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 utils #3313

Closed
wants to merge 3 commits into from
Closed

Abi utils #3313

wants to merge 3 commits into from

Conversation

reedsa
Copy link
Contributor

@reedsa reedsa commented Mar 28, 2024

What was wrong?

This PR is a redesign from #3286

Related to #1596, #3036, #3279

How was it fixed?

Added utilities for dealing with ABIs and contract data that do not require a w3 instance.

ABIElement is a type in web3.py which is composed of ABIFunctions and ABIEvents. These represent fragments of an ABI which are useful when decoding/encoding contract data. These utilities will make it easier to work with contract logs.

The codec is using the default registry which may not be desired. The idea is to eliminate the need to pass in a codec when retrieving event data from a log. web3._utils.events.get_event_data() requires a codec, but the new parse_transaction_for_event is set up with an argument to enable strict.

I'm not totally sure if this is the correct way to enable strict mode for encoding/decoding. Does the codec itself need to be initialized with the proper registry, or is the flag all that is needed?

ABI utils tests to be added in tests/core/abi-utils.

The following methods are now available for the ABI utility API.

Public ABI Utils

def encode_transaction(
    address: ChecksumAddress,
    abi: Optional[ABI] = None,
    function_identifier: Union[str, Type[FallbackFn], Type[ReceiveFn]] = None,
    function_args: Optional[Sequence[Any]] = None,
    function_kwargs: Optional[Any] = None,
    transaction: Optional[TxParams] = None,
) -> TxParams:
    """
    Return encoded transaction data without sending a transaction.
    """


def encode_transaction_data(
    abi: Optional[ABI],
    function_identifier: Union[str, Type[FallbackFn], Type[ReceiveFn]],
    function_args: Optional[Sequence[Any]] = None,
    function_kwargs: Optional[Any] = None,
    is_async: bool = False,
    provider: BaseProvider = HTTPProvider(),
    abi_codec: ABICodec = ABICodec(default_registry),
) -> HexStr:
    """
    Return encoded data to be used in a transaction.
    """


def encode_abi(
    function_abi: ABIFunction,
    data: Optional[HexStr] = None,
    arguments: Sequence[Any] = None,
    is_async: bool = False,
    provider: HTTPProvider = HTTPProvider(),
    abi_codec: ABICodec = ABICodec(default_registry),
) -> HexStr:
    """
    Return encoded data from a function ABI and arguments.
    """


def encode_event_filter_params(
    event_abi: ABIEvent,
    contract_address: Optional[ChecksumAddress] = None,
    argument_filters: Optional[Dict[str, Any]] = None,
    topics: Optional[Sequence[HexStr]] = None,
    fromBlock: Optional[BlockIdentifier] = None,
    toBlock: Optional[BlockIdentifier] = None,
    address: Optional[ChecksumAddress] = None,
    abi_codec: ABICodec = ABICodec(default_registry),
) -> Tuple[List[List[Optional[HexStr]]], FilterParams]:
    """
    Return a raw event filter for a JSON-RPC query.
    """


def encode_event_filter_topics(
    event_abi: ABIEvent,
    arguments: Optional[Union[Sequence[Any], Dict[str, Any]]] = None,
    abi_codec: ABICodec = ABICodec(default_registry),
) -> List[HexStr]:
    """
    Return encoded filter topics for an event.
    """


def encode_event_arguments(
    event_abi: ABIEvent,
    arguments: Optional[Union[Sequence[Any], Dict[str, Any]]] = None,
    abi_codec: ABICodec = ABICodec(default_registry),
) -> List[List[Optional[HexStr]]]:
    """
    Return encoded arguments for transaction data.
    """


def decode_transaction_data_for_event(
    event_abi: ABIEvent,
    log: Optional[LogReceipt] = None,
    abi_codec: ABICodec = ABICodec(default_registry),
) -> EventData:
    """
    Return decoded event data from a log in a transaction.
    """


def decode_data_for_transaction(
    function_abi: ABIFunction,
    log: Optional[LogReceipt] = None,
    abi_codec: ABICodec = ABICodec(default_registry),
) -> TxParams:
    """
    Return decoded transaction parameters from a log in a transaction.
    """


def decode_event_args(
    event_abi: ABIEvent,
    data: HexBytes = None,
    topics: Optional[Sequence[HexBytes]] = None,
    abi_codec: Optional[ABICodec] = ABICodec(default_registry),
) -> EventDataArgs:
    """
    Return the name and arguments of an event.

    Recommend using `web3.utils.parse_log_for_event` which takes a LogReceipt and
    returns all event data.
    """

def decode_function_outputs(
    function_abi: ABIFunction,
    data: HexStr,
    normalizers: Sequence[Callable[[TypeStr, Any], Tuple[TypeStr, Any]]] = None,
    abi_codec: ABICodec = ABICodec(default_registry),
) -> Dict[str, Any]:
    """
    Return result inputs and outputs from a function.
    """


def get_abi_input_names(abi_element: ABIElement) -> List[str]:
    """
    Return names for each input from the function or event ABI.
    """


def get_abi_input_types(abi_element: ABIElement) -> List[str]:
    """
    Return types for each input from the function or event ABI.
    """


def get_abi_output_names(function_abi: ABIFunction) -> List[str]:
    """
    Return names for each output from the function ABI.
    """


def get_abi_output_types(function_abi: ABIFunction) -> List[str]:
    """
    Return types for each output from the function ABI.
    """


def get_all_event_abis(abi: ABI) -> ABIEvent:
    """
    Return interfaces for each event in the contract ABI.
    """


def get_event_abi(
    abi: ABI,
    event_name: Optional[str] = None,
    argument_names: Optional[Sequence[str]] = None,
) -> ABIEvent:
    """
    Find the event interface with the given name and arguments.
    """


def get_event_log_topics(
    event_abi: ABIEvent,
    topics: Optional[Sequence[HexBytes]] = None,
) -> Sequence[HexBytes]:
    """
    Return topics from an event ABI.
    """


def get_all_function_abis(abi: ABI) -> ABIFunction:
    """
    Return interfaces for each function in the contract ABI.
    """

def get_function_abi(
    abi: ABI,
    function_identifier: Optional[Union[str, Type[FallbackFn], Type[ReceiveFn]]] = None,
    args: Optional[Sequence[Any]] = None,
    kwargs: Optional[Any] = None,
    abi_codec: ABICodec = ABICodec(default_registry),
) -> ABIFunction:
    """
    Return the interface for a contract function.
    """

def get_function_info(
    abi: ABI,
    function_identifier: Union[str, Type[FallbackFn], Type[ReceiveFn]],
    args: Optional[Sequence[Any]] = None,
    kwargs: Optional[Any] = None,
) -> ABIFunctionInfo:
    """
    Return the function ABI, selector and input arguments.
    """

Todo:

Cute Animal Picture

Screen Shot 2024-03-28 at 10 35 02 AM

@reedsa reedsa force-pushed the abi-utils branch 3 times, most recently from 56cc7e4 to 8674825 Compare March 29, 2024 22:11
Utilities for transaction log encoding and decoding.
Convenience methods for retrieving elements of a Contract ABI.
@@ -47,6 +47,9 @@ build-docs:
docs: build-docs validate-docs
open docs/_build/html/index.html

autodocs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be added to the help section at the top

@@ -21,6 +21,7 @@
"docs": [
"sphinx>=5.3.0",
"sphinx_rtd_theme>=1.0.0",
"sphinx-autobuild>=2024.2.4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to dop the sphinx-autobuild version back a bit:

ERROR: Ignored the following versions that require a different python version: 2024.2.4 Requires-Python >=3.9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants