def decode_input(self, calldata: Union[str, bytes]) -> Tuple[str, Any]: """ Decode input calldata for this contract. Arguments --------- calldata : str | bytes Calldata for a call to this contract Returns ------- str Signature of the function that was called Any Decoded input arguments """ if not isinstance(calldata, HexBytes): calldata = HexBytes(calldata) abi = next( (i for i in self.abi if i["type"] == "function" and build_function_selector(i) == calldata[:4].hex()), None, ) if abi is None: raise ValueError( "Four byte selector does not match the ABI for this contract") function_sig = build_function_signature(abi) types_list = get_type_strings(abi["inputs"]) result = eth_abi.decode_abi(types_list, calldata[4:]) input_args = format_input(abi, result) return function_sig, input_args
def _contract_method_autosuggest(method: Any) -> List: types_list = get_type_strings(method.abi["inputs"], {"fixed168x10": "decimal"}) params = zip([i["name"] for i in method.abi["inputs"]], types_list) if method.payable: tx_hint = [" {'from': Account", " 'value': Wei}"] else: tx_hint = [" {'from': Account}"] return [f" {i[1]}{' '+i[0] if i[0] else ''}" for i in params] + tx_hint
def encode_input(self, *args: Tuple) -> str: """Returns encoded ABI data to call the method with the given arguments. Args: *args: Contract method inputs Returns: Hexstring of encoded ABI data.""" data = format_input(self.abi, args) types_list = get_type_strings(self.abi["inputs"]) return self.signature + eth_abi.encode_abi(types_list, data).hex()
def _contract_method_autosuggest(args: List, is_transaction: bool, is_payable: bool) -> List: types_list = get_type_strings(args, {"fixed168x10": "decimal"}) params = zip([i["name"] for i in args], types_list) if not is_transaction: tx_hint: List = [] elif is_payable: tx_hint = [" {'from': Account", " 'value': Wei}"] else: tx_hint = [" {'from': Account}"] return [f" {i[1]}{' '+i[0] if i[0] else ''}" for i in params] + tx_hint
def decode_output(self, hexstr: str) -> Tuple: """Decodes hexstring data returned by this method. Args: hexstr: Hexstring of returned call data Returns: Decoded values.""" types_list = get_type_strings(self.abi["outputs"]) result = eth_abi.decode_abi(types_list, HexBytes(hexstr)) result = format_output(self.abi, result) if len(result) == 1: result = result[0] return result
def encode_input(self, *args: tuple) -> str: bytecode = self._parent.bytecode # find and replace unlinked library pointers in bytecode for marker in re.findall("_{1,}[^_]*_{1,}", bytecode): library = marker.strip("_") if not self._parent._project[library]: raise UndeployedLibrary( f"Contract requires '{library}' library, but it has not been deployed yet" ) address = self._parent._project[library][-1].address[-40:] bytecode = bytecode.replace(marker, address) data = format_input(self.abi, args) types_list = get_type_strings(self.abi["inputs"]) return bytecode + eth_abi.encode_abi(types_list, data).hex()
def decode_input(self, hexstr: str) -> List: """ Decode input call data for this method. Arguments --------- hexstr : str Hexstring of input call data Returns ------- Decoded values """ types_list = get_type_strings(self.abi["inputs"]) result = eth_abi.decode_abi(types_list, HexBytes(hexstr)[4:]) return format_input(self.abi, result)
def _inputs(abi: Dict) -> str: types_list = get_type_strings(abi["inputs"], {"fixed168x10": "decimal"}) params = zip([i["name"] for i in abi["inputs"]], types_list) return ", ".join( f"{i[1]}{color('bright blue')}{' '+i[0] if i[0] else ''}{color}" for i in params)
def _signature(abi: Dict) -> str: types_list = get_type_strings(abi["inputs"]) key = f"{abi['name']}({','.join(types_list)})".encode() return "0x" + keccak(key).hex()[:8]