Пример #1
0
def encode_calldata(func_name, arg_types, args):
    """

    :param func_name:
    :param arg_types:
    :param args:
    :return:
    """
    mid = method_id(func_name, arg_types)
    function_selector = zpad(encode_int(mid), 4)
    args = encode_abi(arg_types, args)
    return "0x" + function_selector.hex() + args.hex()
Пример #2
0
 def _get_method_abi(cls, method):
     m_as = inspect.getargspec(method)
     arg_names = list(m_as.args)[1:]
     if 'returns' not in arg_names:  # indicates, this is an abi method
         return None
     arg_types = list(m_as.defaults)
     assert len(arg_names) == len(arg_types) == len(set(arg_names))
     assert arg_names.pop() == 'returns'  # must be last element
     return_types = arg_types.pop()  # can be list or multiple
     name = method.__func__.func_name
     m_id = abi.method_id(name, arg_types)
     return dict(id=m_id, arg_types=arg_types, arg_names=arg_names, return_types=return_types,
                 name=name, method=method)
Пример #3
0
 def _get_method_abi(cls, method):
     m_as = inspect.getargspec(method)
     arg_names = list(m_as.args)[1:]
     if 'returns' not in arg_names:  # indicates, this is an abi method
         return None
     arg_types = list(m_as.defaults)
     assert len(arg_names) == len(arg_types) == len(set(arg_names))
     assert arg_names.pop() == 'returns'  # must be last element
     return_types = arg_types.pop()  # can be list or multiple
     name = method.__func__.func_name
     m_id = abi.method_id(name, arg_types)
     return dict(id=m_id,
                 arg_types=arg_types,
                 arg_names=arg_names,
                 return_types=return_types,
                 name=name,
                 method=method)
Пример #4
0
def test_function_selector():
    # https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#function-selector-and-argument-encoding
    baz_selector = big_endian_to_int(decode_hex('CDCD77C0'))
    bar_selector = big_endian_to_int(decode_hex('AB55044D'))
    sam_selector = big_endian_to_int(decode_hex('A5643BF2'))
    f_selector = big_endian_to_int(decode_hex('8BE65246'))

    assert big_endian_to_int(sha3('baz(uint32,bool)')[:4]) == baz_selector
    assert big_endian_to_int(sha3('bar(fixed128x128[2])')[:4]) == bar_selector
    assert big_endian_to_int(
        sha3('sam(bytes,bool,uint256[])')[:4]) == sam_selector
    assert big_endian_to_int(
        sha3('f(uint256,uint32[],bytes10,bytes)')[:4]) == f_selector

    assert method_id('baz', ['uint32', 'bool']) == baz_selector
    assert method_id('bar', ['fixed128x128[2]']) == bar_selector
    assert method_id('sam', ['bytes', 'bool', 'uint256[]']) == sam_selector
    assert method_id('f',
                     ['uint256', 'uint32[]', 'bytes10', 'bytes']) == f_selector

    assert method_id('bar', ['fixed[2]']) == bar_selector
    assert method_id('sam', ['bytes', 'bool', 'uint[]']) == sam_selector
    assert method_id('f',
                     ['uint', 'uint32[]', 'bytes10', 'bytes']) == f_selector
Пример #5
0
def encode_calldata(func_name, arg_types, args):

    mid = method_id(func_name, arg_types)
    function_selector = zpad(encode_int(mid), 4)
    args = encode_abi(arg_types, args)
    return "0x" + function_selector + args
Пример #6
0
def method_id(method_name, method_params):
    return abi.method_id(method_name, method_params)
Пример #7
0
    def __init__(self, contract_interface):
        if isinstance(contract_interface, str):
            contract_interface = json.dumps(contract_interface)

        self.fallback_data = None
        self.constructor_data = None
        self.function_data = {}
        self.event_data = {}

        for description in contract_interface:
            entry_type = description.get('type', 'function')
            encode_types = []
            signature = []

            # If it's a function/constructor/event
            if entry_type != 'fallback' and 'inputs' in description:
                encode_types = []
                signature = []
                for element in description.get('inputs', []):
                    encode_type = process_abi_type(element)
                    encode_types.append(encode_type)
                    signature.append((encode_type, element['name']))

            if entry_type == 'function':
                normalized_name = normalize_name(description['name'])
                prefix = method_id(normalized_name, encode_types)

                decode_types = []
                for element in description.get('outputs', []):
                    decode_type = process_abi_type(element)
                    decode_types.append(decode_type)

                # 1st is 0.6.0 way, 2nd is old
                is_constant = description.get('stateMutability', '') == 'view' \
                    or description.get('constant', False)
                self.function_data[normalized_name] = {
                    'prefix': prefix,
                    'encode_types': encode_types,
                    'decode_types': decode_types,
                    'is_constant': is_constant,
                    'signature': signature,
                    'payable': description.get('payable', False),
                }

            elif entry_type == 'event':
                normalized_name = normalize_name(description['name'])

                indexed = [
                    element['indexed'] for element in description['inputs']
                ]
                names = [element['name'] for element in description['inputs']]
                # event_id == topics[0]
                self.event_data[event_id(normalized_name, encode_types)] = {
                    'types': encode_types,
                    'name': normalized_name,
                    'names': names,
                    'indexed': indexed,
                    'anonymous': description.get('anonymous', False),
                }

            elif entry_type == 'constructor':
                if self.constructor_data is not None:
                    raise ValueError('Only one constructor is supported.')

                self.constructor_data = {
                    'encode_types': encode_types,
                    'signature': signature,
                }

            elif entry_type == 'fallback':
                if self.fallback_data is not None:
                    raise ValueError(
                        'Only one fallback function is supported.')
                self.fallback_data = {'payable': description['payable']}

            else:
                raise ValueError('Unknown type {}'.format(description['type']))