2021-10-11 17:51:38 +00:00

61 lines
1.5 KiB
Python

from enum import Enum
from typing import List, Optional, Union
from typing_extensions import Literal
import eth_utils.abi
from hexbytes import HexBytes
from pydantic import BaseModel
from web3 import Web3
class ABIDescriptionType(str, Enum):
function = "function"
constructor = "constructor"
fallback = "fallback"
event = "event"
receive = "receive"
NON_FUNCTION_DESCRIPTION_TYPES = Union[
Literal[ABIDescriptionType.constructor],
Literal[ABIDescriptionType.fallback],
Literal[ABIDescriptionType.event],
Literal[ABIDescriptionType.receive],
]
class ABIDescriptionInput(BaseModel):
name: str
type: str
components: Optional[List["ABIDescriptionInput"]]
ABIDescriptionInput.update_forward_refs()
class ABIGenericDescription(BaseModel):
type: NON_FUNCTION_DESCRIPTION_TYPES
class ABIFunctionDescription(BaseModel):
type: Literal[ABIDescriptionType.function]
name: str
inputs: List[ABIDescriptionInput]
def get_selector(self) -> HexBytes:
signature = self.get_signature()
return Web3.sha3(text=signature)[0:4]
def get_signature(self) -> str:
joined_input_types = ",".join(
input.type
if input.type != "tuple"
else eth_utils.abi.collapse_if_tuple(input.dict())
for input in self.inputs
)
return f"{self.name}({joined_input_types})"
ABIDescription = Union[ABIFunctionDescription, ABIGenericDescription]
ABI = List[ABIDescription]