content: from typing import (
      TYPE_CHECKING,
      Any,
      Awaitable,
      Callable,
      Iterable,
      Sequence,
      cast,
  )
  
  from eth_typing import (
      ABI,
      ChecksumAddress,
  )
  from eth_utils import (
      combomethod,
  )
  from eth_utils.abi import (
      abi_to_signature,
      get_abi_input_names,
  )
  from eth_utils.toolz import (
      partial,
  )
  from hexbytes import (
      HexBytes,
  )
  
  from web3._utils.abi import (
      fallback_func_abi_exists,
      receive_func_abi_exists,
  )
  from web3._utils.abi_element_identifiers import (
      FallbackFn,
      ReceiveFn,
  )
  from web3._utils.async_transactions import (
      async_fill_transaction_defaults,
  )
  from web3._utils.compat import (
      Self,
  )
  from web3._utils.contracts import (
      async_parse_block_identifier,
  )
  from web3._utils.datatypes import (
      PropertyCheckingFactory,
  )
  from web3._utils.events import (
      AsyncEventFilterBuilder,
      get_event_data,
  )
  from web3._utils.filters import (
      AsyncLogFilter,
  )
  from web3._utils.normalizers import (
      normalize_abi,
      normalize_address_no_ens,
      normalize_bytecode,
  )
  from web3.contract.base_contract import (
      BaseContract,
      BaseContractCaller,
      BaseContractConstructor,
      BaseContractEvent,
      BaseContractEvents,
      BaseContractFunction,
      BaseContractFunctions,
      NonExistentFallbackFunction,
      NonExistentReceiveFunction,
  )
  from web3.contract.utils import (
      async_build_transaction_for_function,
      async_call_contract_function,
      async_estimate_gas_for_function,
      async_transact_with_contract_function,
      find_events_by_identifier,
      find_functions_by_identifier,
      get_event_by_identifier,
      get_function_by_identifier,
  )
  from web3.exceptions import (
      Web3AttributeError,
      Web3TypeError,
      Web3ValidationError,
      Web3ValueError,
  )
  from web3.types import (
      BlockIdentifier,
      EventData,
      StateOverride,
      TxParams,
  )
  
  if TYPE_CHECKING:
      from ens import AsyncENS  # noqa: F401
      from web3 import AsyncWeb3  # noqa: F401
  
  
  class AsyncContractEvent(BaseContractEvent):
      # mypy types
      w3: "AsyncWeb3[Any]"
  
      @combomethod
      async def get_logs(
          self,
          argument_filters: dict[str, Any] | None = None,
          from_block: BlockIdentifier | None = None,
          to_block: BlockIdentifier | None = None,
          block_hash: HexBytes | None = None,
      ) -> Awaitable[Iterable[EventData]]:
          """
          Get events for this contract instance using eth_getLogs API.
  
          This is a stateless method, as opposed to createFilter.
          It can be safely called against nodes which do not provide
          eth_newFilter API, like Infura nodes.
  
          If there are many events,
          like ``Transfer`` events for a popular token,
          the Ethereum node might be overloaded and timeout
          on the underlying JSON-RPC call.
  
          Example - how to get all ERC-20 token transactions
          for the latest 10 blocks:
  
          .. code-block:: python
  
              from = max(mycontract.web3.eth.block_number - 10, 1)
              to = mycontract.web3.eth.block_number
  
              events = mycontract.events.Transfer.get_logs(from_block=from, to_block=to)
  
              for e in events:
                  print(e["args"]["from"],
                      e["args"]["to"],
                      e["args"]["value"])
  
          The returned processed log values will look like:
  
          .. code-block:: python
  
              (
                  AttributeDict({
                   'args': AttributeDict({}),
                   'event': 'LogNoArguments',
                   'logIndex': 0,
                   'transactionIndex': 0,
                   'transactionHash': HexBytes('...'),
                   'address': '0xF2E246BB76DF876Cef8b38ae84130F4F55De395b',
                   'blockHash': HexBytes('...'),
                   'blockNumber': 3
                  }),
                  AttributeDict(...),
                  ...
              )
  
          See also: :func:`web3.middleware.filter.LocalFilterMiddleware`.
  
          :param argument_filters: Filter by argument values. Indexed arguments are
            filtered by the node while non-indexed arguments are filtered by the library.
          :param from_block: block number or "latest", defaults to "latest"
          :param to_block: block number or "latest". Defaults to "latest"
          :param block_hash: block hash. Cannot be set at the
            same time as ``from_block`` or ``to_block``
          :yield: Tuple of :class:`AttributeDict` instances
          """
          # validate ``argument_filters`` if present
          if argument_filters is not None:
              event_arg_names = get_abi_input_names(self.abi)
              if not all(arg in event_arg_names for arg in argument_filters.keys()):
                  raise Web3ValidationError(
                      "When filtering by argument names, all argument names must be "
                      "present in the contract's event ABI."
                  )
  
          _filter_params = self._get_event_filter_params(
              self.abi, argument_filters, from_block, to_block, block_hash
          )
          # call JSON-RPC API
          logs = await self.w3.eth.get_logs(_filter_params)
  
          # convert raw binary data to Python proxy objects as described by ABI:
          all_event_logs = tuple(
              get_event_data(self.w3.codec, self.abi, entry) for entry in logs
          )
          filtered_logs = self._process_get_logs_argument_filters(
              self.abi,
              all_event_logs,
              argument_filters,
          )
          sorted_logs = sorted(filtered_logs, key=lambda e: e["logIndex"])
          sorted_logs = sorted(sorted_logs, key=lambda e: e["blockNumber"])
          return cast(Awaitable[Iterable[EventData]], sorted_logs)
  
      @combomethod
      async def create_filter(
          self,
          *,  # PEP 3102
          argument_filters: dict[str, Any] | None = None,
          from_block: BlockIdentifier | None = None,
          to_block: BlockIdentifier = "latest",
          address: ChecksumAddress | None = None,
          topics: Sequence[Any] | None = None,
      ) -> AsyncLogFilter:
          """
          Create filter object that tracks logs emitted by this contract event.
          """
          filter_builder = AsyncEventFilterBuilder(self.abi, self.w3.codec)
          self._set_up_filter_builder(
              argument_filters,
              from_block,
              to_block,
              address,
              topics,
              filter_builder,
          )
          log_filter = await filter_builder.deploy(self.w3)
          log_filter.log_entry_formatter = get_event_data(self.w3.codec, self.abi)
          log_filter.builder = filter_builder
  
          return log_filter
  
      @combomethod
      def build_filter(self) -> AsyncEventFilterBuilder:
          builder = AsyncEventFilterBuilder(
              self.abi,
              self.w3.codec,
              formatter=get_event_data(self.w3.codec, self.abi),
          )
          builder.address = self.address
          return builder
  
  
  class AsyncContractEvents(BaseContractEvents[AsyncContractEvent]):
      def __init__(
          self, abi: ABI, w3: "AsyncWeb3[Any]", address: ChecksumAddress | None = None
      ) -> None:
          super().__init__(abi, w3, AsyncContractEvent, address)
  
  
  class AsyncContractFunction(BaseContractFunction):
      # mypy types
      w3: "AsyncWeb3[Any]"
  
      async def call(
          self,
          transaction: TxParams | None = None,
          block_identifier: BlockIdentifier = None,
          state_override: StateOverride | None = None,
          ccip_read_enabled: bool | None = None,
      ) -> Any:
          """
          Execute a contract function call using the `eth_call` interface.
  
          This method prepares a ``Caller`` object that exposes the contract
          functions and public variables as callable Python functions.
  
          Reading a public ``owner`` address variable example:
  
          .. code-block:: python
  
              ContractFactory = w3.eth.contract(
                  abi=wallet_contract_definition["abi"]
              )
  
              # Not a real contract address
              contract = ContractFactory("0x2f70d3d26829e412A602E83FE8EeBF80255AEeA5")
  
              # Read "owner" public variable
              addr = contract.functions.owner().call()
  
          :param transaction: Dictionary of transaction info for web3 interface
          :param block_identifier TODO
          :param state_override TODO
          :param ccip_read_enabled TODO
          :return: ``Caller`` object that has contract public functions
              and variables exposed as Python methods
          """
          call_transaction = self._get_call_txparams(transaction)
  
          block_id = await async_parse_block_identifier(self.w3, block_identifier)
  
          abi_element_identifier = abi_to_signature(self.abi)
  
          return await async_call_contract_function(
              self.w3,
              self.address,
              self._return_data_normalizers,
              abi_element_identifier,
              call_transaction,
              block_id,
              self.contract_abi,
              self.abi,
              state_override,
              ccip_read_enabled,
              self.decode_tuples,
              *self.args or (),
              **self.kwargs or {},
          )
  
      async def transact(self, transaction: TxParams | None = None) -> HexBytes:
          setup_transaction = self._transact(transaction)
          abi_element_identifier = abi_to_signature(self.abi)
          return await async_transact_with_contract_function(
              self.address,
              self.w3,
              abi_element_identifier,
              setup_transaction,
              self.contract_abi,
              self.abi,
              *self.args or (),
              **self.kwargs or {},
          )
  
      async def estimate_gas(
          self,
          transaction: TxParams | None = None,
          block_identifier: BlockIdentifier | None = None,
          state_override: StateOverride | None = None,
      ) -> int:
          setup_transaction = self._estimate_gas(transaction)
          abi_element_identifier = abi_to_signature(self.abi)
          return await async_estimate_gas_for_function(
              self.address,
              self.w3,
              abi_element_identifier,
              setup_transaction,
              self.contract_abi,
              self.abi,
              block_identifier,
              state_override,
              *self.args or (),
              **self.kwargs or {},
          )
  
      async def build_transaction(self, transaction: TxParams | None = None) -> TxParams:
          built_transaction = self._build_transaction(transaction)
          abi_element_identifier = abi_to_signature(self.abi)
          return await async_build_transaction_for_function(
              self.address,
              self.w3,
              abi_element_identifier,
              built_transaction,
              self.contract_abi,
              self.abi,
              *self.args or (),
              **self.kwargs or {},
          )
  
      @staticmethod
      def get_fallback_function(
          abi: ABI,
          async_w3: "AsyncWeb3[Any]",
          address: ChecksumAddress | None = None,
      ) -> "AsyncContractFunction":
          if abi and fallback_func_abi_exists(abi):
              return AsyncContractFunction.factory(
                  "fallback",
                  w3=async_w3,
                  contract_abi=abi,
                  address=address,
                  abi_element_identifier=FallbackFn,
              )()
          return cast(AsyncContractFunction, NonExistentFallbackFunction())
  
      @staticmethod
      def get_receive_function(
          abi: ABI,
          async_w3: "AsyncWeb3[Any]",
          address: ChecksumAddress | None = None,
      ) -> "AsyncContractFunction":
          if abi and receive_func_abi_exists(abi):
              return AsyncContractFunction.factory(
                  "receive",
                  w3=async_w3,
                  contract_abi=abi,
                  address=address,
                  abi_element_identifier=ReceiveFn,
              )()
          return cast(AsyncContractFunction, NonExistentReceiveFunction())
  
  
  class AsyncContractFunctions(BaseContractFunctions[AsyncContractFunction]):
      def __init__(
          self,
          abi: ABI,
          w3: "AsyncWeb3[Any]",
          address: ChecksumAddress | None = None,
          decode_tuples: bool | None = False,
      ) -> None:
          super().__init__(abi, w3, AsyncContractFunction, address, decode_tuples)
  
  
  class AsyncContract(BaseContract):
      functions: AsyncContractFunctions = None
      caller: "AsyncContractCaller" = None
  
      # mypy types
      w3: "AsyncWeb3[Any]"
  
      #: Instance of :class:`ContractEvents` presenting available Event ABIs
      events: AsyncContractEvents = None
  
      def __init__(self, address: ChecksumAddress | None = None) -> None:
          """
          Create a new smart contract proxy object.
  
          :param address: Contract address as 0x hex string
          """
          if self.w3 is None:
              raise Web3AttributeError(
                  "The `Contract` class has not been initialized.  Please use the "
                  "`web3.contract` interface to create your contract class."
              )
  
          if address:
              self.address = normalize_address_no_ens(address)
  
          if not self.address:
              raise Web3TypeError(
                  "The address argument is required to instantiate a contract."
              )
          self.functions = AsyncContractFunctions(
              self.abi, self.w3, self.address, decode_tuples=self.decode_tuples
          )
          self.caller = AsyncContractCaller(
              self.abi,
              self.w3,
              self.address,
              decode_tuples=self.decode_tuples,
              contract_functions=self.functions,
          )
          self.events = AsyncContractEvents(self.abi, self.w3, self.address)
          self.fallback = AsyncContract.get_fallback_function(
              self.abi, self.w3, AsyncContractFunction, self.address
          )
          self.receive = AsyncContract.get_receive_function(
              self.abi, self.w3, AsyncContractFunction, self.address
          )
  
      @classmethod
      def factory(
          cls, w3: "AsyncWeb3[Any]", class_name: str | None = None, **kwargs: Any
      ) -> type[Self]:
          kwargs["w3"] = w3
  
          normalizers = {
              "abi": normalize_abi,
              "address": normalize_address_no_ens,
              "bytecode": normalize_bytecode,
              "bytecode_runtime": normalize_bytecode,
          }
  
          contract = cast(
              type[Self],
              PropertyCheckingFactory(
                  class_name or cls.__name__,
                  (cls,),
                  kwargs,
                  normalizers=normalizers,
              ),
          )
  
          if contract.abi:
              for abi in contract.abi:
                  abi_name = abi.get("name")
                  if abi_name in ["abi", "address"]:
                      raise Web3AttributeError(
                          f"Contract contains a reserved word `{abi_name}` "
                          f"and could not be instantiated."
                      )
  
          contract.functions = AsyncContractFunctions(
              contract.abi, contract.w3, decode_tuples=contract.decode_tuples
          )
          contract.caller = AsyncContractCaller(
              contract.abi,
              contract.w3,
              contract.address,
              decode_tuples=contract.decode_tuples,
              contract_functions=contract.functions,
          )
          contract.events = AsyncContractEvents(contract.abi, contract.w3)
          contract.fallback = AsyncContract.get_fallback_function(
              contract.abi,
              contract.w3,
              AsyncContractFunction,
          )
          contract.receive = AsyncContract.get_receive_function(
              contract.abi,
              contract.w3,
              AsyncContractFunction,
          )
          return contract
  
      @classmethod
      def constructor(cls, *args: Any, **kwargs: Any) -> "AsyncContractConstructor":
          """
          :param args: The contract constructor arguments as positional arguments
          :param kwargs: The contract constructor arguments as keyword arguments
          :return: a contract constructor object
          """
          if cls.bytecode is None:
              raise Web3ValueError(
                  "Cannot call constructor on a contract that does not have "
                  "'bytecode' associated with it"
              )
  
          return AsyncContractConstructor(cls.w3, cls.abi, cls.bytecode, *args, **kwargs)
  
      @combomethod
      def find_functions_by_identifier(
          cls,
          contract_abi: ABI,
          w3: "AsyncWeb3[Any]",
          address: ChecksumAddress,
          callable_check: Callable[..., Any],
      ) -> list["AsyncContractFunction"]:
          return cast(
              list[AsyncContractFunction],
              find_functions_by_identifier(
                  contract_abi, w3, address, callable_check, AsyncContractFunction
              ),
          )
  
      @combomethod
      def get_function_by_identifier(
          cls, fns: Sequence["AsyncContractFunction"], identifier: str
      ) -> "AsyncContractFunction":
          return get_function_by_identifier(fns, identifier)
  
      @combomethod
      def find_events_by_identifier(
          cls,
          contract_abi: ABI,
          w3: "AsyncWeb3[Any]",
          address: ChecksumAddress,
          callable_check: Callable[..., Any],
      ) -> list["AsyncContractEvent"]:
          return find_events_by_identifier(
              contract_abi, w3, address, callable_check, AsyncContractEvent
          )
  
      @combomethod
      def get_event_by_identifier(
          cls, events: Sequence["AsyncContractEvent"], identifier: str
      ) -> "AsyncContractEvent":
          return get_event_by_identifier(events, identifier)
  
  
  class AsyncContractCaller(BaseContractCaller):
      # mypy types
      w3: "AsyncWeb3[Any]"
  
      def __init__(
          self,
          abi: ABI,
          w3: "AsyncWeb3[Any]",
          address: ChecksumAddress,
          transaction: TxParams | None = None,
          block_identifier: BlockIdentifier = None,
          ccip_read_enabled: bool | None = None,
          decode_tuples: bool | None = False,
          contract_functions: AsyncContractFunctions | None = None,
      ) -> None:
          super().__init__(abi, w3, address, decode_tuples=decode_tuples)
  
          if self.abi:
              if transaction is None:
                  transaction = {}
  
              if contract_functions is None:
                  contract_functions = AsyncContractFunctions(
                      abi, w3, address, decode_tuples=decode_tuples
                  )
  
              self._functions = contract_functions._functions
              for fn in contract_functions.__iter__():
                  caller_method = partial(
                      self.call_function,
                      fn,
                      transaction=transaction,
                      block_identifier=block_identifier,
                      ccip_read_enabled=ccip_read_enabled,
                  )
                  setattr(self, str(fn.abi_element_identifier), caller_method)
  
      def __call__(
          self,
          transaction: TxParams | None = None,
          block_identifier: BlockIdentifier = None,
          ccip_read_enabled: bool | None = None,
      ) -> "AsyncContractCaller":
          if transaction is None:
              transaction = {}
          return type(self)(
              self.abi,
              self.w3,
              self.address,
              transaction=transaction,
              block_identifier=block_identifier,
              ccip_read_enabled=ccip_read_enabled,
              decode_tuples=self.decode_tuples,
          )
  
  
  class AsyncContractConstructor(BaseContractConstructor):
      # mypy types
      w3: "AsyncWeb3[Any]"
  
      @combomethod
      async def transact(self, transaction: TxParams | None = None) -> HexBytes:
          return await self.w3.eth.send_transaction(self._get_transaction(transaction))
  
      @combomethod
      async def build_transaction(self, transaction: TxParams | None = None) -> TxParams:
          """
          Build the transaction dictionary without sending
          """
          built_transaction = self._build_transaction(transaction)
          return await async_fill_transaction_defaults(self.w3, built_transaction)
  
      @combomethod
      async def estimate_gas(
          self,
          transaction: TxParams | None = None,
          block_identifier: BlockIdentifier | None = None,
      ) -> int:
          transaction = self._estimate_gas(transaction)
  
          return await self.w3.eth.estimate_gas(
              transaction, block_identifier=block_identifier
          )
  