Esempio n. 1
0
def decode_contract_call(contract_abi: list, call_data: str):
    call_data_bin = decode_hex(call_data)
    method_signature = call_data_bin[:4]
    for description in contract_abi:
        if description.get('type') != 'function':
            continue
        method_name = normalize_abi_method_name(description['name'])
        arg_types = [item['type'] for item in description['inputs']]
        method_id = get_abi_method_id(method_name, arg_types)
        if zpad(encode_int(method_id), 4) == method_signature:
            args = decode_abi(arg_types, call_data_bin[4:])
            return method_name, args
Esempio n. 2
0
def decode_contract_call(contract_abi, call_data):
    call_data = call_data.lower().replace("0x", "")
    call_data_bin = decode_hex(call_data)
    method_signature = call_data_bin[:4]
    for description in contract_abi:
        if description.get('type') != 'function':
            continue
        method_name = normalize_abi_method_name(description['name'])
        arg_types = [item['type'] for item in description['inputs']]
        method_id = get_abi_method_id(method_name, arg_types)
        if zpad(encode_int(method_id), 4) == method_signature:
            try:
                # TODO: ethereum.abi.decode_abi vs eth_abi.decode_abi
                args = decode_abi(arg_types, call_data_bin[4:])
            except AssertionError:
                # Invalid args
                continue
            return method_name, args
Esempio n. 3
0
 def decode_contract_call(self, contract_abi: list, TID: str):
     Transaction = self.w3.eth.getTransaction(TID)
     call_data = str(Transaction.input)
     call_data_bin = decode_hex(call_data)
     method_signature = call_data_bin[:4]
     for description in contract_abi:
         if description.get('type') != 'function':
             continue
         method_name = normalize_abi_method_name(description['name'])
         arg_types = [item['type'] for item in description['inputs']]
         method_id = get_abi_method_id(method_name, arg_types)
         if zpad(encode_int(method_id), 4) == method_signature:
             try:
                 args = decode_abi(arg_types, call_data_bin[4:])
             except AssertionError:
                 # Invalid args
                 continue
             return method_name, args
def _decode_input(contract_abi, call_data):
    """
    Decode input data of a transaction according to a contract ABI

    Solution from https://ethereum.stackexchange.com/questions/20897/how-to-decode-input-data-from-tx-using-python3?rq=1

    Parameters
    ----------
    contract_abi : list
        List of contract methods specifications
    call_data : str
        Input of transaction in a form of 0x(4 bytes of method)(arguments),
        i.e. 0x12345678000000000000....

    Returns
    -------
    dict
        Name and parsed parameters extracted from the input
        None, if there is no such method in ABI, or there was a problem with method arguments
    """
    call_data_bin = decode_hex(call_data)
    method_signature = call_data_bin[:4]
    for description in contract_abi:
        if description.get('type') not in ['function', 'event']:
            continue
        method_name = normalize_abi_method_name(description['name'])
        arg_types = [item['type'] for item in description['inputs']]
        method_id = get_abi_method_id(method_name, arg_types)
        if zpad(encode_int(method_id), 4) == method_signature:
            try:
                args = decode_abi(arg_types, call_data_bin[4:])
                args = [{'type': arg_types[index], 'value': str(value)} for index, value in enumerate(args)]
            except AssertionError:
                continue
            return {
                'name': method_name,
                'params.type': [arg["type"] for arg in args],
                'params.value': [arg["value"] for arg in args]
            }