<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def validate_attr_dict(self, attr_dict: Dict[str, str]) -> None: """ Validates that ContractType keys in attr_dict reference existing manifest ContractTypes. """

        attr_dict_names = list(attr_dict.keys())

        if not self.unlinked_references and not self.linked_references:
            raise BytecodeLinkingError(
                "Unable to validate attr dict, this contract has no linked/unlinked references."
            )

        unlinked_refs = self.unlinked_references or ({},)
        linked_refs = self.linked_references or ({},)
        all_link_refs = unlinked_refs + linked_refs

        all_link_names = [ref["name"] for ref in all_link_refs]
        if set(attr_dict_names) != set(all_link_names):
            raise BytecodeLinkingError(
                "All link references must be defined when calling "
                "`link_bytecode` on a contract factory."
            )
        for address in attr_dict.values():
            if not is_canonical_address(address):
                raise BytecodeLinkingError(
                    f"Address: {address} as specified in the attr_dict is not "
                    "a valid canoncial address."
                )