An Interface ID is a 4-byte (32-bit) hexadecimal identifier, derived from the Ethereum Request for Comment 165 (ERC-165) standard, that uniquely represents the set of function signatures defined in a smart contract's Application Binary Interface (ABI). It is calculated as the bitwise XOR of the function selectors (the first 4 bytes of the Keccak-256 hash of the function signature) for all functions in the interface. This compact fingerprint allows other contracts and off-chain systems to programmatically query and verify whether a deployed contract supports a specific set of functions, such as ERC-20 for tokens or ERC-721 for NFTs, before attempting to interact with it.
Interface ID
What is an Interface ID?
A unique identifier for smart contract interfaces, enabling standardized interaction and discovery on EVM-compatible blockchains.
The primary mechanism for using an Interface ID is through the supportsInterface(bytes4 interfaceId) function, which is mandated by ERC-165. When called, a compliant contract must return true if it implements the interface corresponding to the provided interfaceId. This enables safe, retroactive composability, as new standards can be added to existing contracts, and dApps can reliably detect support. For example, a wallet can check if a contract supports the ERC-721Metadata interface (0x5b5e139f) to know if it can safely call functions like name() or symbol() without causing a transaction revert.
Calculating an Interface ID is a deterministic off-chain process. Developers use tools like the ethers.js library or online calculators to XOR the selectors of their interface's functions. For instance, the Interface ID for the core ERC-721 standard (0x80ac58cd) is derived from the selectors of functions like balanceOf(address), ownerOf(uint256), safeTransferFrom(...), and others. This precise identification is foundational for upgradeable proxy patterns and diamond proxies (EIP-2535), where a single contract delegate calls to multiple implementation contracts, each potentially supporting different interfaces.
Beyond simple support checks, Interface IDs are integral to the broader ecosystem of contract discovery and registry services. Projects like Ethereum Name Service (ENS) use them to identify resolver interfaces, and marketplaces use them to filter asset types. The concept also extends to ERC-1820, a universal registry for interface implementations. By providing a standardized method for runtime interface detection, Interface IDs reduce integration errors, foster interoperability between independently developed smart contracts, and form a critical piece of infrastructure for the decentralized web.
How Does an Interface ID Work?
An Interface ID is a unique 4-byte identifier, defined by the ERC-165 standard, that acts as a fingerprint for a smart contract's public function signatures.
An Interface ID is a 32-bit, or 4-byte, hexadecimal value calculated as the XOR (exclusive OR) of the function selectors for all functions defined in a specific Ethereum Request for Comment (ERC) interface. This deterministic calculation allows any contract or off-chain tool to programmatically verify if another contract implements a known set of functions, such as ERC-20 (0x36372b07) or ERC-721 (0x80ac58cd). The core mechanism is defined in the ERC-165 standard, which provides a standard function, supportsInterface(bytes4 interfaceId), that contracts can implement to declare their capabilities.
The primary workflow involves a calling contract, like a decentralized application (dApp) or another smart contract, querying a target contract using the supportsInterface function. If the target returns true for a given Interface ID, the caller can safely assume the contract adheres to the associated interface's specification and can proceed to call its functions. This process is fundamental for composability and safe integration, preventing runtime errors by ensuring a contract has the expected API before interacting with it. Tools like Etherscan and wallet interfaces use this to correctly identify and display token types.
From a developer's perspective, generating an Interface ID is straightforward when using development frameworks. For example, in Solidity with Hardhat or Foundry, the IERC165 interface's interfaceId property or helper functions automatically compute the XOR of function selectors. Manually, one would take the first four bytes of the Keccak-256 hash (the selector) of each function's signature (e.g., balanceOf(address)), then XOR them all together. This precise, on-chain verifiable identifier is what makes dynamic discovery and type-safe interoperability possible across the decentralized ecosystem.
Key Features of Interface IDs
Interface IDs are 4-byte identifiers defined by the ERC-165 standard, enabling smart contracts to declare and detect the interfaces they implement. This is a foundational mechanism for interoperability and type safety on Ethereum.
Unique 4-Byte Identifier
An Interface ID is a unique 4-byte (32-bit) identifier, typically represented as 0x followed by 8 hexadecimal characters (e.g., 0x01ffc9a7 for ERC-165 itself). It is calculated as the XOR (exclusive OR) of all function selectors (the first 4 bytes of the function signature's Keccak-256 hash) defined in the interface. This deterministic calculation ensures global uniqueness for a given set of functions.
Standardized Discovery (ERC-165)
The ERC-165 standard formalizes how contracts publish and query interface support. A compliant contract implements a supportsInterface(bytes4 interfaceId) function that returns true if it implements the queried interface. This allows other contracts and clients to discover a contract's capabilities programmatically before interacting with it, preventing runtime errors from calling unimplemented functions.
Enabling Upgradeable Proxies
Interface IDs are critical for upgradeable proxy patterns. The proxy contract can use supportsInterface to route calls to different implementation logic based on the interface being called. This allows for granular upgrades where new interfaces can be added to a deployed contract system without breaking existing integrations that query for specific functionality.
Critical for ERC-721 & ERC-1155
Major token standards like ERC-721 (NFTs) and ERC-1155 (Multi-Token) rely on ERC-165 for feature detection. Their core interfaces have defined IDs (e.g., 0x80ac58cd for ERC-721). Wallets and marketplaces query these IDs to confirm a contract is a valid NFT contract before displaying assets. Optional extension interfaces (like metadata or enumeration) also have their own IDs for detecting added features.
Calculation Method
To calculate an Interface ID:
- Take the function signature (e.g.,
balanceOf(address)). - Compute its Keccak-256 hash and take the first 4 bytes (the function selector).
- For an interface with multiple functions, compute the XOR (
^) of all its function selectors.
Example: The ERC-721 interface ID 0x80ac58cd is the XOR of selectors for balanceOf(address), ownerOf(uint256), etc. Tools like cast from Foundry can perform this calculation automatically.
Gas Efficiency & Security
Using a 4-byte identifier is highly gas-efficient for on-chain lookups compared to storing full function signatures. It provides a security benefit by creating a formal, verifiable declaration of a contract's external API. This prevents signature collisions and ensures that a contract claiming to support an interface implements all required functions, not just a subset.
How is an Interface ID Calculated?
The Interface ID is a unique, 4-byte identifier for a smart contract interface, defined by the ERC-165 standard, enabling contracts to programmatically declare which functions they implement.
An Interface ID is calculated by performing a bitwise XOR operation on the function selectors of all functions defined within the interface. A function selector is the first four bytes of the Keccak-256 hash of the function's signature (e.g., balanceOf(address)). For example, the ERC-20 interface includes functions like totalSupply() and transfer(address,uint256); their individual selectors are XORed together to produce the single, compact identifier for the entire ERC-20 interface, which is 0x36372b07.
This deterministic calculation ensures that any contract claiming to support an interface must implement all the functions whose selectors were used in the XOR operation. The process is critical for the ERC-165 supportsInterface(bytes4 interfaceId) function, which allows other contracts or external callers to query a contract to verify its capabilities before interacting with it. This prevents errors and enables secure, composable smart contract systems where functionality can be discovered on-chain.
For interfaces that include the ERC-165 standard itself (which is recursive), the calculation must exclude the selector of the supportsInterface function to avoid a circular dependency. Developers typically use pre-calculated constants or libraries like OpenZeppelin's to avoid manual computation errors. The resulting 4-byte interfaceId acts as a fingerprint, enabling robust, type-safe interoperability across the Ethereum ecosystem and other EVM-compatible blockchains.
Common Standard Interface IDs
Interface IDs are unique 4-byte identifiers derived from function signatures, enabling smart contracts to programmatically declare and detect compliance with standards like ERC-20 or ERC-721 via ERC-165.
ERC-165: The Detection Standard
ERC-165 is the foundational standard that defines how to calculate and query an Interface ID. A contract implements supportsInterface(bytes4 interfaceId) to return true if it supports a given interface. The ID is calculated as the XOR of all function selectors in the interface.
- Purpose: Enables safe, on-chain discovery of a contract's capabilities.
- Mechanism:
interfaceId = bytes4(keccak256('function signature()')) ^ bytes4(keccak256('anotherFunction()'))
ERC-20 Token Interface (0x36372b07)
The ERC-20 token standard interface ID is 0x36372b07. This ID is derived from the XOR of the selectors for its core functions:
totalSupply()balanceOf(address)transfer(address,uint256)transferFrom(address,address,uint256)approve(address,uint256)allowance(address,address)
This allows wallets and decentralized exchanges to reliably identify standard fungible token contracts.
ERC-721 NFT Interface (0x80ac58cd)
The ERC-721 Non-Fungible Token standard uses the interface ID 0x80ac58cd. It is calculated from the selectors of functions like:
balanceOf(address)ownerOf(uint256)safeTransferFrom(address,address,uint256,bytes)transferFrom(address,address,uint256)approve(address,uint256)setApprovalForAll(address,bool)getApproved(uint256)isApprovedForAll(address,address)
This ID is critical for NFT marketplaces to verify compliance.
ERC-1155 Multi-Token Interface (0xd9b67a26)
The ERC-1155 Multi-Token standard, which can represent both fungible and non-fungible assets in a single contract, has the interface ID 0xd9b67a26. Key functions contributing to this ID include:
balanceOf(address,uint256)balanceOfBatch(address[],uint256[])setApprovalForAll(address,bool)isApprovedForAll(address,address)safeTransferFrom(address,address,uint256,uint256,bytes)safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)
This enables efficient batch operations and mixed asset types.
ERC-2981 NFT Royalty Interface (0x2a55205a)
ERC-2981 defines a standard way to retrieve royalty payment information for NFTs. Its interface ID is 0x2a55205a, derived from the single function selector for royaltyInfo(uint256 _tokenId, uint256 _salePrice). This function returns the recipient address and royalty amount.
- Utility: Allows marketplaces to automatically pay out royalties to creators on secondary sales.
- Adoption: Widely implemented by major NFT collections and marketplaces.
Calculating an Interface ID
An Interface ID is not arbitrary; it is computed deterministically. For any Solidity interface, the ID is the bitwise XOR (^) of the function selectors (the first 4 bytes of keccak256("functionSignature")) of all functions in the interface.
Example Calculation (Simplified ERC-20):
solidity// Selectors (simplified for example) bytes4 a = bytes4(keccak256('totalSupply()')); // 0x18160ddd bytes4 b = bytes4(keccak256('balanceOf(address)')); // 0x70a08231 // ... XOR all selectors interfaceId = a ^ b ^ c ^ d ^ e ^ f; // Result: 0x36372b07
Tools and libraries like OpenZeppelin's IERC165 helper perform this calculation.
Ecosystem Usage & Applications
An Interface ID (IID) is a unique identifier for a smart contract's function signatures, enabling secure and standardized discovery of its capabilities. These applications demonstrate how IIDs are used to build interoperable and verifiable systems.
ERC-165 Standard Compliance
The primary application of an Interface ID is to declare a smart contract's compliance with a standard, most notably ERC-165. A contract's supportsInterface function returns true when queried with a specific IID, enabling other contracts and user interfaces to programmatically verify its capabilities.
- Key Use: Enables wallets and dApps to detect if a contract is an NFT (ERC-721), fungible token (ERC-20), or other standard.
- Mechanism: The IID is a 4-byte hash (typically the XOR of the function selectors) of the interface's functions.
Secure Upgradeable Proxies
Interface IDs are critical for managing upgradeable proxy patterns. When a proxy's logic contract is upgraded, the new implementation must guarantee it supports all the interface IDs of the previous version to maintain compatibility.
- Prevents Breaking Changes: Tools can verify that an upgrade doesn't remove required functionality by checking IID support.
- Security Check: Auditors use IID checks to ensure upgrade safety and prevent accidental interface violations.
Decentralized Exchange (DEX) Routing
Advanced DEX aggregators and routers use Interface IDs to identify the capabilities of liquidity pools dynamically. This allows a router to determine if a pool contract supports specific functions like swap, addLiquidity, or flash loans without prior knowledge of its exact type.
- Dynamic Integration: Enables support for new pool types (e.g., Uniswap v2, v3, Balancer) as long as they publish a standard IID.
- Efficiency: Avoids failed transactions by checking for required function support before interacting.
Wallet & dApp Feature Detection
User-facing applications like MetaMask and blockchain explorers use Interface ID queries to provide accurate contextual interfaces. When you connect to a contract, your wallet can detect if it's a token, a marketplace, or a lending vault and display relevant buttons (e.g., 'Approve', 'List for Sale', 'Deposit').
- Improved UX: Automatically tailors the UI based on discovered contract features.
- Error Prevention: Prevents users from calling non-existent functions on a contract.
Multi-Chain Interoperability Protocols
Cross-chain messaging and bridging protocols (e.g., LayerZero, Axelar) use Interface IDs to standardize message formats and payloads across different blockchain environments. A target chain's contract can verify an incoming message is destined for a contract that supports a specific interface, ensuring proper execution.
- Standardized Communication: Defines a canonical way to identify contract types across heterogeneous chains.
- Security: Adds a layer of validation to cross-chain calls, reducing the risk of executing calls on incompatible contracts.
DAO Plugin & Module Registries
In modular DAO frameworks (e.g., Aragon OSx), Interface IDs act as a registry key for plugins and governance modules. The DAO core can query if an attached module supports the required interfaces for voting, token distribution, or treasury management.
- Modular Design: Allows DAOs to safely compose functionality from verified, standards-compliant modules.
- Composability: Developers can build new modules that are automatically discoverable and integrable by any DAO using the standard IID system.
Interface ID vs. Related Concepts
A technical comparison of the Interface ID with related on-chain identifiers and standards.
| Feature / Concept | Interface ID (EIP-165) | Function Selector (4-byte) | Contract Address |
|---|---|---|---|
Purpose | Uniquely identifies a smart contract interface (set of functions) | Uniquely identifies a single function signature | Uniquely identifies a deployed smart contract instance |
Format | bytes4 (e.g., 0x01ffc9a7) | bytes4 (e.g., 0xa9059cbb) | address (20 bytes, e.g., 0x...) |
Derivation | XOR of all function selectors in the interface | First 4 bytes of keccak256 hash of function signature | Determined at deployment (CREATE/CREATE2) |
Standard | EIP-165 | Native EVM ABI specification | Native EVM specification |
Primary Use | Runtime interface detection via | Encoding call data for contract interactions | Target for transactions and calls |
Mutability | Immutable for a given interface definition | Immutable for a given function signature | Immutable after deployment |
Example | ERC-721 interface: 0x80ac58cd | transfer(address,uint256): 0xa9059cbb | USDC contract: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 |
Security & Implementation Considerations
An Interface ID is a unique 4-byte identifier derived from the XOR of all function selectors in an interface, used to verify contract compliance with the ERC-165 standard.
Core Definition & Calculation
An Interface ID is the unique identifier for a smart contract interface, calculated as the bitwise XOR of all the function selectors (the first 4 bytes of the keccak256 hash of the function signature) defined within that interface. For example, the Interface ID for ERC-721 is 0x80ac58cd. This deterministic calculation ensures that any contract claiming to support an interface must implement all its functions.
Primary Use: ERC-165 Compliance
The primary purpose of an Interface ID is to enable the ERC-165 standard, which allows contracts to publish and detect the interfaces they implement. A contract declares support by returning true when its supportsInterface(bytes4 interfaceId) function is called with the correct ID. This prevents errors by allowing other contracts or clients to programmatically verify a contract's capabilities before interacting with it.
Critical Security Consideration
Incorrect Interface ID calculation or declaration is a major security risk. If a contract incorrectly reports support for an interface it does not fully implement, it can cause catastrophic interaction failures for integrating protocols and users. Auditors must verify that:
- The declared Interface ID matches the XOR of all live functions.
- The
supportsInterfacefunction is present and correct. - Interface support is not removed in future upgrades without proper signaling.
Implementation Pitfalls
Common implementation errors include:
- Forgotten Functions: Omitting a function from the XOR calculation after adding it to the interface.
- Selector Collisions: While statistically near-impossible for defined interfaces, using
type(IInterface).interfaceIdin Solidity (v0.8.x+) is the safest method to avoid manual calculation errors. - Upgrade Inconsistency: Adding or removing functions in a new interface version without creating a new, corresponding Interface ID, breaking existing integrations.
Tooling & Verification
Developers should use established tools to avoid manual errors:
- Solidity Compiler: Use
type(IMyInterface).interfaceIdfor compile-time calculation. - Testing Suites: Include rigorous tests that call
supportsInterfacefor all claimed IDs. - Blockchain Explorers: Platforms like Etherscan display verified Interface IDs for audited contracts, providing a public reference.
Related Concept: Function Selector
A Function Selector is the foundational element of an Interface ID. It is the first 4 bytes of the keccak256 hash of a function's signature (e.g., balanceOf(address)). The Interface ID is the aggregate of these selectors. Understanding this relationship is crucial for low-level debugging and writing secure proxy patterns or fallback handlers that decode calldata.
Frequently Asked Questions (FAQ)
Common questions about Interface IDs, the unique identifiers for smart contract function signatures defined by the Ethereum ABI specification.
An Interface ID is a unique 4-byte identifier, derived from the XOR of all function selectors within a smart contract interface, used to programmatically identify and verify that a contract implements a specific set of functions. Defined by the Ethereum Application Binary Interface (ABI), it acts as a fingerprint for a contract's external API. This identifier is crucial for standards like ERC-165, which enables contracts to declare their supported interfaces. When a contract supports ERC-165, other contracts or clients can call supportsInterface(interfaceId) to check for compatibility before interacting, preventing errors and enabling secure, interoperable protocol design.
Get In Touch
today.
Our experts will offer a free quote and a 30min call to discuss your project.