ethereum / web3.py

A python interface for interacting with the Ethereum blockchain and ecosystem.
http://web3py.readthedocs.io
MIT License
4.95k stars 1.69k forks source link

Abi utils #3313

Closed reedsa closed 3 months ago

reedsa commented 5 months ago

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