ERC165 is an Ethereum Request for Comments (ERC) standard that provides a mechanism for a smart contract to publish and detect which interfaces it implements. The core function, supportsInterface, allows other contracts or off-chain systems to query whether a specific interface identifier (a 4-byte function selector) is supported. This creates a foundational layer for type introspection on the blockchain, allowing for the development of more flexible and interoperable systems by programmatically verifying a contract's capabilities before interacting with it.
ERC165
What is ERC165?
ERC165 is a formal Ethereum standard that defines a method for smart contracts to declare and detect the interfaces they implement, enabling standardized on-chain interoperability checks.
The standard is critical for the broader Ethereum ecosystem because it underpins many other major standards. For instance, ERC721 (Non-Fungible Tokens) and ERC1155 (Multi-Token) mandates the implementation of ERC165. This allows marketplaces, wallets, and other services to reliably detect if a contract is an NFT contract and which specific features (like metadata or enumeration) it supports. Without this standard, applications would need to rely on error-prone methods like trial-and-error calls or off-chain registries to determine a contract's functions.
Technically, an interface identifier is calculated as the XOR of all function selectors in the interface. A contract declares its support by returning true when its supportsInterface(bytes4 interfaceId) function is called with the correct ID. The standard also defines a mechanism for registering interfaces in a global EIP-165 registry, although direct contract implementation is more common. This design ensures the check is both gas-efficient and secure, as it's a simple, read-only call that cannot be spoofed without breaking the contract's own functionality.
For developers, implementing ERC165 involves overriding the supportsInterface function to check against a hardcoded set of supported interface IDs, often using a mapping or a series of if statements. A common practice is to combine IDs using the bitwise OR operator (|) for interfaces that are composed of others. This standard is a prerequisite for creating composable and upgradeable contracts, as it allows proxy contracts or managers to verify the compatibility of new logic implementations before an upgrade is executed.
The widespread adoption of ERC165 has made it a cornerstone of Ethereum's infrastructure. It enables a contract-first discovery paradigm where dApps can dynamically adapt to the contracts they interact with. This is essential for the evolving DeFi and NFT landscapes, where new token standards and financial primitives constantly emerge. By providing a reliable, on-chain method for interface detection, ERC165 reduces integration complexity and fosters a more connected and automated smart contract ecosystem.
How ERC165 Works
A technical breakdown of the mechanism that allows smart contracts to declare and query the interfaces they implement, enabling secure and gas-efficient interoperability.
ERC165 is an Ethereum Request for Comments standard that defines a method for smart contracts to publish and detect the interfaces they implement. At its core, a contract compliant with ERC165 must implement a function called supportsInterface(bytes4 interfaceId) that returns true if the contract implements the interface identified by the 4-byte interfaceId, and false otherwise. This function acts as a standardized query mechanism, allowing other contracts and off-chain systems to programmatically verify a contract's capabilities before interacting with it, preventing runtime errors and failed transactions.
The standard operates using interface identifiers, which are calculated as the XOR (exclusive OR) of all function selectors within an interface. A function selector is the first four bytes of the Keccak-256 hash of a function's signature (e.g., balanceOf(address)). For example, the interfaceId for ERC721 is 0x80ac58cd, derived from hashing its core functions. When a contract's supportsInterface is called with 0x80ac58cd, it should return true only if it implements the full ERC721 specification. This precise, cryptographic method ensures unambiguous identification.
Implementation involves two key steps. First, a contract must declare its support for ERC165 itself by returning true for the ERC165 interface ID (0x01ffc9a7). Second, it must override the supportsInterface function to check both the ERC165 ID and any other interface IDs it supports, typically using a mapping or a series of if statements. For instance, an ERC721 contract would return true for 0x01ffc9a7 (ERC165) and 0x80ac58cd (ERC721). This layered check allows a caller to first confirm a contract uses ERC165, then query for specific functionality.
The primary use case for ERC165 is enabling safe composability in the Ethereum ecosystem. Wallets and marketplaces use it to detect if a contract is an ERC721 NFT or an ERC1155 multi-token before attempting to display assets. Upgradable proxy patterns use it to verify new implementation contracts support required interfaces. It also prevents the common error of sending tokens to a contract that cannot handle them, as the receiving contract can reject interactions if it does not supportInterface for the token standard. This creates a more robust and predictable environment for decentralized applications.
While essential, developers must be aware of nuances. Manually calculating and hardcoding interface IDs is error-prone; using helper functions from libraries like OpenZeppelin is recommended. The standard also defines that supportsInterface must return false for any unverified interfaceId, not throw an error. Furthermore, ERC165 does not validate the correctness of an implementation, only its declared adherence to an interface's function signatures. It is a foundational standard upon which more complex interoperability, such as ERC-3668's CCIP Read, is built for cross-chain and off-chain data retrieval.
Key Features of ERC165
ERC165 is a standard that allows smart contracts to declare and detect the interfaces they implement, enabling on-chain interoperability and type safety.
Interface Identification
ERC165 provides a standard method for a contract to publish the interface identifiers it supports. This is done via the supportsInterface(bytes4 interfaceId) function, which returns true if the contract implements the queried interface. The identifier is typically the XOR of all function selectors in the interface.
On-Chain Introspection
This feature enables runtime verification of a contract's capabilities. Other contracts or off-chain clients can query supportsInterface before interacting, preventing errors. This is critical for composable systems like decentralized exchanges (DEXs) or NFT marketplaces that need to verify if a token supports metadata (ERC721) or enumeration (ERC721Enumerable).
Backwards Compatibility
ERC165 is designed for graceful evolution. A contract can implement multiple interfaces and new interfaces can be added over time without breaking existing integrations. The standard itself is minimal, requiring only the supportsInterface function, making it easy to add to any contract.
Gas-Efficient Verification
The interfaceId is a 4-byte function selector hash, making queries extremely gas-efficient. Checking support is a simple SLOAD and bitwise comparison. This low overhead makes it practical to perform checks within transaction execution, unlike more expensive proxy pattern checks.
Foundation for Other Standards
ERC165 is a prerequisite or strongly recommended for many major Ethereum standards, including:
- ERC721 (Non-Fungible Tokens)
- ERC1155 (Multi-Token Standard)
- ERC2981 (NFT Royalty Standard)
- ERC4337 (Account Abstraction) It provides the foundational mechanism these standards use to declare their compliance.
Preventing Interface Collision
By using the XOR of all function selectors to create a unique interfaceId, ERC165 minimizes the risk of accidental interface collisions. Two different interfaces with different functions will almost certainly have different IDs, ensuring accurate detection.
Code Example
A practical implementation of the ERC165 standard interface detection protocol.
The following Solidity code demonstrates a minimal implementation of ERC165 for a hypothetical ERC721 token contract. The core function is supportsInterface(bytes4 interfaceId), which returns true if the contract implements the interface queried. The example shows how to calculate and store the interface identifier for the ERC721 interface (0x80ac58cd) and the ERC165 interface itself (0x01ffc9a7) in the contract's constructor, enabling other contracts to programmatically discover its capabilities.
This pattern is fundamental for composable smart contract systems. By implementing ERC165, a contract declares its adherence to a known standard, allowing wallets, marketplaces, and other contracts to interact with it safely and predictably. For instance, a decentralized exchange can query an unknown token contract to verify it is a valid ERC20 or ERC721 before attempting to list it, preventing runtime errors and enhancing security through runtime interface checking.
Developers should note that the interface ID is not the contract's ABI or bytecode hash; it is a 4-byte selector derived from the XOR of all function selectors in the interface. The example uses type(IERC721).interfaceId for clarity, which Solidity calculates automatically. For custom interfaces, developers must compute this value manually. Proper implementation requires overriding supportsInterface to check for ERC165's own interface ID and any other supported interfaces, typically using a private mapping or inline logic.
Ecosystem Usage
ERC-165 is a standard interface detection protocol that allows smart contracts to declare and query the interfaces they implement, enabling dynamic and safe interoperability within the Ethereum ecosystem.
Core Mechanism: Interface Detection
ERC-165 provides a standard method for a contract to publish the interfaces it implements. A contract that complies with ERC-165 must implement a function called supportsInterface(bytes4 interfaceId) that returns true if the contract implements the interface identified by the 4-byte interfaceId. This allows other contracts and off-chain systems to query for compatibility before interacting, preventing runtime errors from calling unimplemented functions.
Interface Identifiers (Interface IDs)
An Interface ID is a 4-byte (32-bit) identifier, typically calculated as the XOR of all function selectors in the interface. For example, the ERC-20 interface ID is 0x36372b07. This deterministic calculation ensures that the same interface always has the same ID across all implementations. The supportsInterface function checks against these IDs to confirm support for standards like ERC-20, ERC-721, or custom interfaces.
Essential for ERC-721 & ERC-1155
Major token standards mandate ERC-165 for safe composability. ERC-721 (NFTs) and ERC-1155 (Multi-Token) require it to distinguish between different token types and their metadata extensions (like ERC721Metadata or ERC1155Metadata_URI). Marketplaces and wallets use supportsInterface to detect if a contract is an NFT, what metadata it provides, and if it supports advanced features like enumeration.
Registry & Proxy Patterns
ERC-165 is critical in upgradeable proxy architectures and decentralized registries. Proxy contracts (e.g., UUPS or Transparent proxies) use it to expose the logic contract's interfaces. Registries (like ENS or protocol-wide registries) use it to validate that registered contracts adhere to expected standards, ensuring system-wide compatibility and preventing the integration of non-conformant contracts.
On-Chain Composability & Safety
By enabling runtime interface checks, ERC-165 is foundational for on-chain composability. DeFi protocols, DAO tooling, and cross-protocol integrations can programmatically verify that an external contract supports a required function set before making a call. This moves integration errors from runtime failures to validation steps, making complex, interconnected smart contract systems more robust and secure.
ERC165 vs. Manual Interface Assumptions
A comparison of the standard ERC165 interface detection mechanism against ad-hoc, manual checks.
| Feature / Characteristic | ERC165 (Standard) | Manual Assumptions (Ad-hoc) |
|---|---|---|
Detection Method | On-chain function call (supportsInterface) | Off-chain code inspection or assumption |
Reliability | ||
Standardization | EIP-165 specification | No formal specification |
Gas Cost for Check | ~2.5k - 5k gas | 0 gas (off-chain) |
Upgrade Safety | Dynamic, survives interface additions | Brittle, breaks on interface changes |
Interoperability | Universal for compliant contracts | Project-specific, non-portable |
Implementation Overhead | Requires interface ID calculation & registry | None required |
Audit & Security | Formally verifiable behavior | High risk of false positives/negatives |
Technical Details
ERC-165 is a formal standard for publishing and detecting the interfaces a smart contract implements, enabling secure and reliable on-chain interoperability.
ERC-165 is a standard that allows smart contracts to declare which interfaces they support, enabling other contracts and off-chain systems to detect capabilities programmatically. It works by implementing a function called supportsInterface(bytes4 interfaceId) that returns true if the contract implements the interface corresponding to the 4-byte identifier (interfaceId). This identifier is typically derived by calculating the Ethereum function selector (the first 4 bytes of the keccak256 hash) of the interface's function signatures. This mechanism prevents errors where a contract is called with functions it does not support, forming the foundation for secure composability in systems like ERC-721 (NFTs) and ERC-1155 (Multi-Token).
Common Misconceptions
ERC165 is a standard for interface detection, but its purpose and implementation are often misunderstood. This section clarifies frequent points of confusion for developers working with smart contract interoperability.
ERC165 is a standard that allows a smart contract to publish and detect which interfaces it implements. It works by having a contract implement a supportsInterface function that returns true when queried with the bytes4 interface ID of a standard it supports. The interface ID is typically derived via the XOR of all function selectors in that interface's ABI. This mechanism enables other contracts and off-chain systems to programmatically verify a contract's capabilities before interacting with it, preventing errors and enabling dynamic integration.
Key Mechanism:
- A contract declares support by returning
truefromsupportsInterface(interfaceId). - The
interfaceIdis calculated usingtype(MyInterface).interfaceIdin Solidity. - The standard itself is defined by the interface ID
0x01ffc9a7.
Frequently Asked Questions (FAQ)
ERC165 is a standard interface detection protocol that allows smart contracts to declare which interfaces they implement. These questions cover its purpose, mechanics, and practical use cases.
ERC165 is an Ethereum Request for Comments (ERC) standard that provides a mechanism for smart contracts to publish and detect the interfaces they implement. It works by having a contract implement a supportsInterface function that takes a 4-byte interface identifier (the XOR of all function selectors in the interface) and returns a boolean true if the contract supports that interface. This allows other contracts and off-chain systems to query a contract to discover its capabilities before interacting with it, preventing runtime errors from calling unsupported functions.
Key Mechanism:
- A contract declares its support by returning
truefor specific interface IDs. - The standard interface ID for ERC165 itself is
0x01ffc9a7. - This creates a foundational layer for composable interoperability within the Ethereum ecosystem.
Get In Touch
today.
Our experts will offer a free quote and a 30min call to discuss your project.