Example #1
0
def build_primitive_from_abi(name: str, abi: dict) -> InterfacePrimitive:
    """
    Generate an `InterfacePrimitive` object from an ABI.

    Arguments
    ---------
    name : str
        The name of the interface
    abi : dict
        Contract ABI

    Returns
    -------
    InterfacePrimitive
        primitive interface type
    """
    members: OrderedDict = OrderedDict()
    events: Dict = {}

    names = [i["name"] for i in abi if i.get("type") in ("event", "function")]
    collisions = set(i for i in names if names.count(i) > 1)
    if collisions:
        collision_list = ", ".join(sorted(collisions))
        raise NamespaceCollision(
            f"ABI '{name}' has multiple functions or events with the same name: {collision_list}"
        )

    for item in [i for i in abi if i.get("type") == "function"]:
        members[item["name"]] = ContractFunction.from_abi(item)
    for item in [i for i in abi if i.get("type") == "event"]:
        events[item["name"]] = Event.from_abi(item)

    return InterfacePrimitive(name, members, events)
Example #2
0
def _get_module_definitions(
        base_node: vy_ast.Module) -> Tuple[OrderedDict, Dict]:
    functions: OrderedDict = OrderedDict()
    events: Dict = {}
    for node in base_node.get_children(vy_ast.FunctionDef):
        if "external" in [
                i.id for i in node.decorator_list
                if isinstance(i, vy_ast.Name)
        ]:
            func = ContractFunction.from_FunctionDef(node)
            if node.name in functions:
                # compare the input arguments of the new function and the previous one
                # if one function extends the inputs, this is a valid function name overload
                existing_args = list(functions[node.name].arguments)
                new_args = list(func.arguments)
                for a, b in zip(existing_args, new_args):
                    if not isinstance(a, type(b)):
                        raise NamespaceCollision(
                            f"Interface contains multiple functions named '{node.name}' "
                            "with incompatible input types",
                            base_node,
                        )
                if len(new_args) <= len(existing_args):
                    # only keep the `ContractFunction` with the longest set of input args
                    continue
            functions[node.name] = func
    for node in base_node.get_children(vy_ast.AnnAssign,
                                       {"annotation.func.id": "public"}):
        name = node.target.id
        if name in functions:
            raise NamespaceCollision(
                f"Interface contains multiple functions named '{name}'",
                base_node)
        functions[name] = ContractFunction.from_AnnAssign(node)
    for node in base_node.get_children(vy_ast.EventDef):
        name = node.name
        if name in functions or name in events:
            raise NamespaceCollision(
                f"Interface contains multiple objects named '{name}'",
                base_node)
        events[name] = Event.from_EventDef(node)

    return functions, events
Example #3
0
 def visit_EventDef(self, node):
     obj = Event.from_EventDef(node)
     try:
         self.namespace[node.name] = obj
     except VyperException as exc:
         raise exc.with_annotation(node) from None
Example #4
0
def test_event_id(build_node, source, signature_hash):
    node = build_node(source)
    event = Event.from_EventDef(node)

    assert event.event_id == signature_hash