Python eth_abi.decode_abi() Examples
The following are 13
code examples of eth_abi.decode_abi().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
eth_abi
, or try the search function
.
Example #1
Source File: exceptions.py From brownie with MIT License | 5 votes |
def __init__(self, exc: ValueError) -> None: try: exc = yaml.safe_load(str(exc)) except Exception: pass if isinstance(exc, dict) and "message" in exc: if "data" not in exc: raise ValueError(exc["message"]) from None self.message: str = exc["message"].rstrip(".") if isinstance(exc["data"], str): # handle parity exceptions - this logic probably is not perfect if "0x08c379a0" in exc["data"]: revert_type, err_msg = [i.strip() for i in exc["data"].split("0x08c379a0", 1)] err_msg = eth_abi.decode_abi(["string"], HexBytes(err_msg)) err_msg = f"{revert_type} '{err_msg}'" elif exc["data"].endswith("0x"): err_msg = exc["data"][:-2].strip() else: err_msg = exc["data"] raise ValueError(f"{self.message}: {err_msg}") from None try: txid, data = next((k, v) for k, v in exc["data"].items() if k.startswith("0x")) except StopIteration: raise ValueError(exc["message"]) from None self.txid: str = txid self.revert_type: str = data["error"] self.revert_msg: Optional[str] = data.get("reason") self.pc: Optional[str] = data.get("program_counter") self.source: str = "" if self.revert_type == "revert": self.pc -= 1 if self.revert_msg is None and self.revert_type in ("revert", "invalid opcode"): self.revert_msg = brownie.project.build._get_dev_revert(self.pc) else: raise ValueError(str(exc)) from None
Example #2
Source File: transaction.py From brownie with MIT License | 5 votes |
def _reverted_trace(self, trace: Sequence) -> None: self._modified_state = False # get events from trace self._events = _decode_trace(trace) if self.contract_address: step = next((i for i in trace if i["op"] == "CODECOPY"), None) if step is not None and int(step["stack"][-3], 16) > 24577: self._revert_msg = "exceeds EIP-170 size limit" if self._revert_msg is not None: return # iterate over revert instructions in reverse to find revert message for step in (i for i in trace[::-1] if i["op"] in ("REVERT", "INVALID")): if step["op"] == "REVERT" and int(step["stack"][-2], 16): # get returned error string from stack data = _get_memory(step, -1)[4:] self._revert_msg = decode_abi(["string"], data)[0] return if self.contract_address: self._revert_msg = "invalid opcode" if step["op"] == "INVALID" else "" return # check for dev revert string using program counter self._revert_msg = build._get_dev_revert(step["pc"]) if self._revert_msg is not None: return # if none is found, expand the trace and get it from the pcMap self._expand_trace() try: pc_map = _find_contract(step["address"])._build["pcMap"] # if this is the function selector revert, check for a jump if "first_revert" in pc_map[step["pc"]]: i = trace.index(step) - 4 if trace[i]["pc"] != step["pc"] - 4: step = trace[i] self._revert_msg = pc_map[step["pc"]]["dev"] return except (KeyError, AttributeError): pass step = next(i for i in trace[::-1] if i["op"] in ("REVERT", "INVALID")) self._revert_msg = "invalid opcode" if step["op"] == "INVALID" else ""
Example #3
Source File: contract.py From brownie with MIT License | 5 votes |
def call(self, *args: Tuple, block_identifier: Union[int, str, bytes] = None) -> Any: """ Call the contract method without broadcasting a transaction. Arguments --------- *args Contract method inputs. You can optionally provide a dictionary of transaction properties as the last arg. block_identifier : int | str | bytes, optional A block number or hash that the call is executed at. If not given, the latest block used. Raises `ValueError` if this value is too far in the past and you are not using an archival node. Returns ------- Contract method return value(s). """ args, tx = _get_tx(self._owner, args) if tx["from"]: tx["from"] = str(tx["from"]) del tx["required_confs"] tx.update({"to": self._address, "data": self.encode_input(*args)}) try: data = web3.eth.call({k: v for k, v in tx.items() if v}, block_identifier) except ValueError as e: raise VirtualMachineError(e) from None if HexBytes(data)[:4].hex() == "0x08c379a0": revert_str = eth_abi.decode_abi(["string"], HexBytes(data)[4:])[0] raise ValueError(f"Call reverted: {revert_str}") if self.abi["outputs"] and not data: raise ValueError("No data was returned - the call likely reverted") return self.decode_output(data)
Example #4
Source File: contract.py From brownie with MIT License | 5 votes |
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
Example #5
Source File: base.py From clove with GNU General Public License v3.0 | 5 votes |
def extract_secret_from_redeem_transaction(self, tx_address: str) -> str: ''' Extracting secret from redeem transaction. Args: tx_address (str): address of the redeem transaction Returns: str,: Secret string Raises: ValueError: When given transaction was not a redeem type transaction Example: >>> from clove.network import EthereumTestnet >>> network = EthereumTestnet() >>> network.extract_secret_from_redeem_transaction('0x9e41847c3cc780e4cb59902cf55657f0ee92642d9dee4145e090cbf206d4748f') # noqa: E501 b2eefaadbbefeb9d9467092b612464db7c6724f71b5c1d70c85853845728f0e9 ''' tx_dict = self.get_transaction(tx_address) method_id = self.extract_method_id(tx_dict['input']) if method_id != self.redeem: logger.debug('Not a redeem transaction.') raise ValueError('Not a redeem transaction.') method_name = self.get_method_name(method_id) input_types = get_abi_input_types(find_matching_fn_abi(self.abi, fn_identifier=method_name)) input_values = decode_abi(input_types, Web3.toBytes(hexstr=tx_dict['input'][10:])) return input_values[0].hex()
Example #6
Source File: contract.py From clove with GNU General Public License v3.0 | 5 votes |
def __init__(self, network, tx_dict): self.network = network self.tx_dict = tx_dict self.abi = self.network.abi self.method_id = self.network.extract_method_id(tx_dict['input']) self.type = self.network.get_method_name(self.method_id) self.token = None if self.method_id != self.network.initiate: logger.warning('Not a contract transaction.') raise ValueError('Not a contract transaction.') input_types = get_abi_input_types(find_matching_fn_abi(self.abi, fn_identifier=self.type)) input_names = get_abi_input_names(find_matching_fn_abi(self.abi, fn_identifier=self.type)) input_values = decode_abi(input_types, Web3.toBytes(hexstr=self.tx_dict['input'][10:])) self.inputs = dict(zip(input_names, input_values)) self.locktime = datetime.utcfromtimestamp(self.inputs['_expiration']) self.recipient_address = Web3.toChecksumAddress(self.inputs['_participant']) self.refund_address = self.tx_dict['from'] self.secret_hash = self.inputs['_hash'].hex() self.contract_address = Web3.toChecksumAddress(self.tx_dict['to']) self.block_number = self.tx_dict['blockNumber'] self.confirmations = self.network.get_latest_block - self.block_number self.balance = self.get_balance() if self.is_token_contract: self.value_base_units = self.inputs['_value'] self.token_address = Web3.toChecksumAddress(self.inputs['_token']) self.token = self.network.get_token_by_address(self.token_address) self.value = self.token.value_from_base_units(self.value_base_units) self.symbol = self.token.symbol else: self.value_base_units = self.tx_dict['value'] self.value = self.network.value_from_base_units(self.value_base_units) self.symbol = self.network.default_symbol
Example #7
Source File: contract.py From tron-api-python with MIT License | 5 votes |
def decode_function_input(self, data): data = HexBytes(data) selector, params = data[:4], data[4:] func = self.get_function_by_selector(selector) names = [x['name'] for x in func.abi['inputs']] types = [x['type'] for x in func.abi['inputs']] decoded = decode_abi(types, params) normalized = map_abi_data(BASE_RETURN_NORMALIZERS, types, decoded) return func, dict(zip(names, normalized))
Example #8
Source File: sdk.py From erc20token-sdk-python with GNU General Public License v2.0 | 5 votes |
def get_transaction_data(self, tx_id): """Gets transaction data for the provided transaction id. :param str tx_id: transaction id (hash) :return: transaction data :rtype: :class:`~erc20token.TransactionData` """ tx_data = TransactionData() tx = self.web3.eth.getTransaction(tx_id) if not tx: return tx_data tx_data.from_address = tx['from'] tx_data.to_address = tx['to'] tx_data.ether_amount = self.web3.fromWei(tx['value'], 'ether') tx_data.status = self._get_tx_status(tx) if not tx.get('blockNumber'): tx_data.num_confirmations = 0 else: tx_block_number = int(tx['blockNumber']) cur_block_number = int(self.web3.eth.blockNumber) tx_data.num_confirmations = cur_block_number - tx_block_number + 1 tx_input = tx.get('input') if tx_input and (tx_input.lower().startswith(ERC20_TRANSFER_ABI_PREFIX.lower())): to, amount = decode_abi(['uint256', 'uint256'], tx_input[len(ERC20_TRANSFER_ABI_PREFIX):]) tx_data.to_address = to_hex(to) tx_data.token_amount = self.web3.fromWei(amount, 'ether') return tx_data
Example #9
Source File: sdk.py From erc20token-sdk-python with GNU General Public License v2.0 | 5 votes |
def _check_parse_contract_tx(self, tx, filter_args): """Parse contract transaction and check whether it matches the supplied filter. If the transaction matches the filter, the first returned value will be True, and the rest will be correctly filled. If there is no match, the first returned value is False and the rest are empty. :param dict tx: transaction object :param dict filter_args: a filter that contains fields 'to', 'from' or both. :returns: matching status, from address, to address, token amount :rtype: tuple """ if not tx.get('to') or tx['to'].lower() != self.token_contract.address.lower(): # must be sent to our contract return False, '', '', 0 tx_input = tx.get('input') if not tx_input or tx_input == '0x': # not a contract transaction return False, '', '', 0 if not tx_input.lower().startswith(ERC20_TRANSFER_ABI_PREFIX.lower()): # only interested in calls to 'transfer' method return False, '', '', 0 to, amount = decode_abi(['uint256', 'uint256'], tx_input[len(ERC20_TRANSFER_ABI_PREFIX):]) to = to_hex(to) amount = self.web3.fromWei(amount, 'ether') if (('from' in filter_args and tx['from'].lower() == filter_args['from'].lower() and ('to' not in filter_args or to.lower() == filter_args['to'].lower())) or ('to' in filter_args and to.lower() == filter_args['to'].lower())): return True, tx['from'], to, amount return False, '', '', 0
Example #10
Source File: throws_contract.py From eth-tester with MIT License | 5 votes |
def _decode_throws_result(contract_name, fn_name, result): from eth_abi import decode_abi fn_abi = THROWS_ABI[contract_name][fn_name] output_types = [ output_abi['type'] for output_abi in fn_abi['outputs'] ] return decode_abi(output_types, decode_hex(result))
Example #11
Source File: math_contract.py From eth-tester with MIT License | 5 votes |
def _decode_math_result(fn_name, result): from eth_abi import decode_abi fn_abi = MATH_ABI[fn_name] output_types = [ output_abi['type'] for output_abi in fn_abi['outputs'] ] return decode_abi(output_types, decode_hex(result))
Example #12
Source File: test_contract_call_interface.py From web3.py with MIT License | 5 votes |
def test_call_get_string_value(string_contract, call): result = call(contract=string_contract, contract_function='getValue') # eth_abi.decode_abi() does not assume implicit utf-8 # encoding of string return values. Thus, we need to decode # ourselves for fair comparison. assert result == "Caqalai"
Example #13
Source File: decoder.py From django-eth-events with MIT License | 4 votes |
def decode_log(self, log): """ Decodes an ethereum log and returns the recovered parameters along with the method from the abi that was used in decoding. Raises a LookupError if the log's topic is unknown, :param log: ethereum log :return: dictionary of decoded parameters, decoding method reference """ method_id = remove_0x_head(log['topics'][0]) if method_id not in self.methods: raise LookupError("Unknown log topic.") # method item has the event name, inputs and types method = self.methods[method_id] decoded_params = [] data_i = 0 topics_i = 1 data_types = [] # get param types from properties not indexed for param in method['inputs']: if not param['indexed']: data_types.append(param['type']) # decode_abi expect data in bytes format instead of str starting by 0x log_data_bytes = HexBytes(log['data']) decoded_data = decode_abi(data_types, log_data_bytes) for param in method['inputs']: decoded_p = { 'name': param['name'] } if param['indexed']: decoded_p['value'] = log['topics'][topics_i] topics_i += 1 else: decoded_p['value'] = decoded_data[data_i] data_i += 1 if '[]' in param['type']: if 'address' in param['type']: decoded_p['value'] = [self.decode_address(address) for address in decoded_p['value']] else: decoded_p['value'] = list(decoded_p['value']) elif 'address' == param['type']: decoded_p['value'] = self.decode_address(decoded_p['value']) decoded_params.append(decoded_p) decoded_event = { 'params': decoded_params, 'name': method['name'], 'address': self.decode_address(log['address']), 'transaction_hash': self.decode_transaction(log['transactionHash']) } return decoded_event