What is ERC-165?
The tiny function behind interface detection for NFTs, multi-tokens, royalties, and LSPs.
ERC-165 is easy to miss because it is just one function. But it is the reason a marketplace can ask whether a contract is an ERC-721, an ERC-1155, or an ERC-2981 royalty source before it starts calling token-specific functions.
on this page
The standard, in one card.
- Standard
- ERC-165 / EIP-165
- Core function
- supportsInterface(bytes4)
- Used by
- ERC-721 · ERC-1155 · ERC-2981 · LSPs
- Canonical spec
- eips.ethereum.org / EIP-165
ERC-165 defines `supportsInterface(bytes4 interfaceId) → bool`, the standard way a contract declares which interfaces it implements. Finalized in January 2018 by Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, and William Entriken, it's the runtime introspection primitive that ERC-721, ERC-1155, ERC-2981, ERC-1363, ERC-1271, and most LUKSO LSPs (LSP0, LSP7, LSP8) build on. Without it, callers have no on-chain way to know whether a contract will accept a safeTransferFrom, honor a royalty query, or validate a signature.
How ERC-165 came to be.#
As Ethereum contracts became more composable, callers needed a standard way to discover interfaces without relying only on ABI registries or failed calls. ERC-165 standardized that discovery path.
What ERC-165 actually is.#
function supportsInterface(bytes4 interfaceID) external view returns (bool);
supportsInterface wallets · marketplaces · protocol adapters A contract returns true for the ERC-165 interface ID and for every interface ID it supports. Callers use a static call to supportsInterface and branch from there.
What's broken about ERC-165.#
Interface detection is useful, but it is not a guarantee of behavior. Contracts can lie, implement an interface badly, or support the base interface while leaving important optional behavior out.
-
It is a claim, not a proof.#
supportsInterface says what a contract claims to implement. It does not prove the implementation is correct, complete, or safe for the caller's assumptions.
ERC-165supportsInterface(id) == truetestsprobe behaviorworkarounds tried- runtime probing
- try/catch calls
- audited implementations
- conformance tests
-
ERC-20 never adopted it.#
The most common token standard predates ERC-165 and does not expose supportsInterface. That is why ERC-20 detection still relies on ABI assumptions, calls, token lists, and indexers.
ERC-20no supportsInterfaceERC-165standard detectionworkarounds tried- static call balanceOf
- token lists
- indexer heuristics
-
Interface support can be too coarse.#
A contract can support an interface but still vary in optional extensions, metadata conventions, or permission behavior. Callers still need feature-specific checks.
interface IDone bytes4ERC-725Ytyped data keysworkarounds tried- extension-specific IDs
- metadata reads
- capability registries
LUKSO designed it differently.#
LUKSO standards keep ERC-165 where it is useful, then add ERC-725Y-backed data for richer metadata and capability description.
- LSP7 Digital Asset LSP7 publishes interface support so integrations can detect the token shape.
- LSP8 Identifiable Digital Asset LSP8 uses interface detection alongside typed metadata and receiver-aware transfers.
- ERC725Y Key-value data store Typed data keys can expose richer metadata and capabilities than one interface ID.
How ERC-165 and ERC-725Y typed data compare.#
| row | ERC-165 | ERC-725Y typed data |
|---|---|---|
| question answered | does this contract claim interface X? | what typed data and standards does this account or asset expose? |
| return type | bool | bytes under known keys |
| used by LSPs | yes | yes, alongside ERC-725Y |
FAQ.#
-
What is ERC-165 used for? #
It lets contracts declare support for interfaces through supportsInterface(bytes4), so callers can detect standards such as ERC-721, ERC-1155, and ERC-2981.
-
Does ERC-20 support ERC-165? #
No. ERC-20 predates ERC-165 and does not include supportsInterface in its standard interface.
-
How is an ERC-165 interface ID calculated? #
An interface ID is the XOR of the function selectors in the interface, with special handling described in the EIP.