[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`