[EIP-165](https://eips.ethereum.org/EIPS/eip-165) Creates a standard method to publish and detect what interfaces a smart contract implements. It standardizes ***how interfaces are identified***, ***how a contract will publish the interfaces it implements*** and ***how to detect if they implement ERC165** **or any given interface.*** ## How is an interface identified? A function within an interface has a [function selector](https://docs.soliditylang.org/en/develop/abi-spec.html#function-selector). *Example*: ```solidity // SPDX-License-Identifier: MIT pragma solidity^0.4.20; interface ITestSelectors { function hello()external pure; function world(int)external pure; } contract Selectors { function getHelloSelector() public pure returns (bytes4) { ITestSelectors i; return i.hello.selector; // returns 0x19ff1d21 } function getWorldSelector() public pure returns (bytes4) { ITestSelectors i; return i.world.selector; // returns 0xdf419679 } function calculateIdentifier() public pure returns (bytes4) { ITestSelectors i; return i.hello.selector ^ i.world.selector; // returns 0xc6be8b58 --> interface identifier } } ``` ## **How does a Contract publish the Interfaces it implements?** Now we know how interfaces are identified; but how do we publish the interfaces we are implementing? A contract that is compliant with ERC-165 shall implement the following interface: ```solidity pragma solidity ^0.4.20; interface ERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface(bytes4 interfaceID) external view returns (bool); } ``` ## H**ow to detect if a contract implements ERC165** **or any given interface** *Example*: ```solidity pragma solidity ^0.4.20; import "./ERC165.sol"; interface Simpson { function is2D() external returns (bool); function skinColor() external returns (string); } contract Homer is ERC165, Simpson { function supportsInterface(bytes4 interfaceID) external view returns (bool) { return interfaceID == this.supportsInterface.selector || // ERC165 interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson } } ``` `supportsInterface()` returns: - `true` when `interfaceID` is `0x01ffc9a7` (EIP165 interface) - `true` for any other `interfaceID` this contract implements - `false` when `interfaceID` is `0xffffffff` - `false` for any other `interfaceID`