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)
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
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
def test_event_id(build_node, source, signature_hash): node = build_node(source) event = Event.from_EventDef(node) assert event.event_id == signature_hash