예제 #1
0
파일: interface.py 프로젝트: pir8aye/vyper
def abi_type_to_ast(atype):
    if atype in ('int128', 'uint256', 'bool', 'address', 'bytes32'):
        return ast.Name(id=atype)
    elif atype == 'decimal':
        return ast.Name(id='int128')
    elif atype == 'bytes':
        return ast.Subscript(value=ast.Name(id='bytes'), slice=ast.Index(256))
    elif atype == 'string':
        return ast.Subscript(value=ast.Name(id='string'), slice=ast.Index(256))
    else:
        raise ParserException(f'Type {atype} not supported by vyper.')
예제 #2
0
def abi_type_to_ast(atype, expected_size):
    if atype in ('int128', 'uint256', 'bool', 'address', 'bytes32'):
        return ast.Name(id=atype)
    elif atype == 'fixed168x10':
        return ast.Name(id='decimal')
    elif atype in ('bytes', 'string'):
        # expected_size is the maximum length for inputs, minimum length for outputs
        return ast.Subscript(value=ast.Name(id=atype),
                             slice=ast.Index(value=ast.Num(n=expected_size)))
    else:
        raise ParserException(f'Type {atype} not supported by vyper.')
예제 #3
0
파일: interface.py 프로젝트: erdnaag/vyper
def abi_type_to_ast(atype, expected_size):
    if atype in ("int128", "uint256", "bool", "address", "bytes32"):
        return vy_ast.Name(id=atype)
    elif atype == "fixed168x10":
        return vy_ast.Name(id="decimal")
    elif atype in ("bytes", "string"):
        # expected_size is the maximum length for inputs, minimum length for outputs
        return vy_ast.Subscript(
            value=vy_ast.Name(id=atype), slice=vy_ast.Index(value=vy_ast.Int(value=expected_size))
        )
    else:
        raise StructureException(f"Type {atype} not supported by vyper.")
예제 #4
0
파일: interface.py 프로젝트: aihuawu/vyper
def mk_full_signature_from_json(abi):
    funcs = [func for func in abi if func["type"] == "function"]
    sigs = []

    for func in funcs:
        args = []
        returns = None
        for a in func["inputs"]:
            arg = vy_ast.arg(
                arg=a["name"],
                annotation=abi_type_to_ast(a["type"], 1048576),
                lineno=0,
                col_offset=0,
            )
            args.append(arg)

        if len(func["outputs"]) == 1:
            returns = abi_type_to_ast(func["outputs"][0]["type"], 1)
        elif len(func["outputs"]) > 1:
            returns = vy_ast.Tuple(elements=[
                abi_type_to_ast(a["type"], 1) for a in func["outputs"]
            ])

        decorator_list = [vy_ast.Name(id="external")]
        # Handle either constant/payable or stateMutability field
        if ("constant" in func
                and func["constant"]) or ("stateMutability" in func and
                                          func["stateMutability"] == "view"):
            decorator_list.append(vy_ast.Name(id="view"))
        if ("payable" in func
                and func["payable"]) or ("stateMutability" in func and
                                         func["stateMutability"] == "payable"):
            decorator_list.append(vy_ast.Name(id="payable"))

        sig = FunctionSignature.from_definition(
            code=vy_ast.FunctionDef(
                name=func["name"],
                args=vy_ast.arguments(args=args),
                decorator_list=decorator_list,
                returns=returns,
            ),
            custom_structs=dict(),
            constants=Constants(),
            is_from_json=True,
        )
        sigs.append(sig)
    return sigs
예제 #5
0
파일: interface.py 프로젝트: vaniisgh/vyper
def mk_full_signature_from_json(abi):
    funcs = [func for func in abi if func['type'] == 'function']
    sigs = []

    for func in funcs:
        args = []
        returns = None
        for a in func['inputs']:
            arg = ast.arg(
                arg=a['name'],
                annotation=abi_type_to_ast(a['type']),
                lineno=0,
                col_offset=0
            )
            args.append(arg)

        if len(func['outputs']) == 1:
            returns = abi_type_to_ast(func['outputs'][0]['type'])
        elif len(func['outputs']) > 1:
            returns = ast.Tuple(
                elts=[
                    abi_type_to_ast(a['type'])
                    for a in func['outputs']
                ]
            )

        decorator_list = [ast.Name(id='public')]
        if func['constant']:
            decorator_list.append(ast.Name(id='constant'))
        if func['payable']:
            decorator_list.append(ast.Name(id='payable'))

        sig = FunctionSignature.from_definition(
            code=ast.FunctionDef(
                name=func['name'],
                args=ast.arguments(args=args),
                decorator_list=decorator_list,
                returns=returns,
            ),
            custom_units=set(),
            custom_structs=dict(),
            constants=Constants()
        )
        sigs.append(sig)
    return sigs
예제 #6
0
def generate_public_variable_getters(vyper_module: vy_ast.Module) -> None:
    """
    Create getter functions for public variables.

    Arguments
    ---------
    vyper_module : Module
        Top-level Vyper AST node.
    """

    for node in vyper_module.get_children(vy_ast.AnnAssign, {"annotation.func.id": "public"}):
        func_type = node._metadata["type"]
        input_types, return_type = func_type.get_signature()
        input_nodes = []

        # use the annotation node as a base to build the input args and return type
        # starting with `args[0]` to remove the surrounding `public()` call`
        annotation = copy.deepcopy(node.annotation.args[0])

        # the base return statement is an `Attribute` node, e.g. `self.<var_name>`
        # for each input type we wrap it in a `Subscript` to access a specific member
        return_stmt: vy_ast.VyperNode = vy_ast.Attribute(
            value=vy_ast.Name(id="self"), attr=func_type.name
        )

        for i, type_ in enumerate(input_types):
            if not isinstance(annotation, vy_ast.Subscript):
                # if we get here something has failed in type checking
                raise CompilerPanic("Mismatch between node and input type while building getter")
            if annotation.value.get("id") == "HashMap":  # type: ignore
                # for a HashMap, split the key/value types and use the key type as the next arg
                arg, annotation = annotation.slice.value.elements  # type: ignore
            else:
                # for other types, build an input arg node from the expected type
                # and remove the outer `Subscript` from the annotation
                arg = vy_ast.Name(id=type_._id)
                annotation = annotation.value
            input_nodes.append(vy_ast.arg(arg=f"arg{i}", annotation=arg))

            # wrap the return statement in a `Subscript`
            return_stmt = vy_ast.Subscript(
                value=return_stmt, slice=vy_ast.Index(value=vy_ast.Name(id=f"arg{i}"))
            )

        # after iterating the input types, the remaining annotation node is our return type
        return_node = annotation
        if isinstance(return_node, vy_ast.Name) and return_node.id != return_type._id:
            # special case when the return type is an interface
            # TODO allow interfaces as return types and remove this
            return_node.id = return_type._id

        # join everything together as a new `FunctionDef` node, annotate it
        # with the type, and append it to the existing `Module` node
        expanded = vy_ast.FunctionDef.from_node(
            node.annotation,
            name=func_type.name,
            args=vy_ast.arguments(args=input_nodes, defaults=[],),
            body=[vy_ast.Return(value=return_stmt)],
            decorator_list=[vy_ast.Name(id="external"), vy_ast.Name(id="view")],
            returns=return_node,
        )
        expanded._metadata["type"] = func_type
        vyper_module.add_to_body(expanded)