Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
LABS
Glossary

ERC-165

ERC-165 is a formal Ethereum standard that defines a method for smart contracts to publish and detect the interfaces they implement.
Chainscore © 2026
definition
STANDARD INTERFACE DETECTION

What is ERC-165?

ERC-165 is a standard that allows smart contracts to publish and detect the interfaces they implement, enabling on-chain interoperability and type safety.

ERC-165 is an Ethereum Request for Comments that defines a standard method for smart contracts to declare the interfaces they support. A contract publishes its supported interfaces by implementing a function called supportsInterface(bytes4 interfaceId) that returns true if the contract implements the interface identified by the 4-byte interfaceId. This mechanism allows other contracts and off-chain systems to query a contract's capabilities before interacting with it, preventing runtime errors from calling unimplemented functions. The standard is foundational for creating modular and composable smart contract systems.

The core of ERC-165 is the calculation of the interface identifier, or interface ID. This is a bytes4 value computed as the XOR (exclusive OR) of all function selectors in the interface. For example, the interface ID for ERC-721 is 0x80ac58cd. A contract can support multiple interfaces, and its supportsInterface function must return true for each valid identifier it supports. This design allows for efficient on-chain lookups and is a critical component of the Ethereum Name Service (ENS), upgradeable proxy patterns, and multi-facet Diamond Proxies (EIP-2535).

Developers implement ERC-165 to enable safe interactions in a decentralized ecosystem. Wallets and decentralized applications (dApps) can use it to verify if a contract is a legitimate ERC-20 token or an ERC-721 NFT before displaying it to users. Furthermore, it is a prerequisite for other major standards; ERC-721 and ERC-1155 both mandate ERC-165 support. By providing a reliable discovery mechanism, ERC-165 reduces integration errors and forms the backbone of Ethereum's interoperable smart contract landscape, ensuring that contracts can reliably communicate their functionality.

how-it-works
STANDARD INTERFACE DETECTION

How ERC-165 Works

A technical breakdown of the mechanism that enables smart contracts to declare and query the interfaces they implement.

ERC-165 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, it provides a lightweight, gas-efficient mechanism for on-chain interface discovery, solving the problem of determining a contract's capabilities without relying on off-chain data or brittle function signature checks. A contract that complies with ERC-165 is said to support the standard, and it does so by implementing a specific function: supportsInterface(bytes4 interfaceId). This function returns true if the contract implements the interface identified by the 4-byte interfaceId, and false otherwise.

The standard operates using interface identifiers, which are 4-byte function signature hashes calculated using the XOR of all function selectors within an interface. For example, the interface ID for ERC-721 is 0x80ac58cd, derived from hashing its core functions like balanceOf(address) and ownerOf(uint256). A contract declares support by returning true when its supportsInterface function is called with that specific bytes4 value. This creates a reliable, on-chain registry of a contract's advertised functionality, which is critical for wallets, marketplaces, and other contracts that need to interact with it safely and predictably.

Implementation involves two key steps. First, the contract must calculate and store the interface IDs it supports, often within the constructor. Second, it must expose the function supportsInterface(bytes4 interfaceId) external view returns (bool) function, which contains the logic to check the stored IDs. Many modern smart contract libraries, like OpenZeppelin Contracts, provide abstract base contracts that handle this logic automatically. When a contract implements multiple standards—such as both ERC-721 and ERC-2981 (royalties)—its supportsInterface function will return true for each of their respective interface IDs, providing a complete picture of its compliance.

The primary use case for ERC-165 is enabling safe interoperability within the Ethereum ecosystem. An NFT marketplace can query a token contract to verify it is a genuine ERC-721 before listing it. A decentralized application can check if a wallet contract supports ERC-1271 for signature validation. This prevents errors and potential loss of funds by ensuring that interacting contracts speak a compatible language. Without this standard, applications would need to use risky methods like low-level calls to probe for specific functions, which can fail silently or be exploited.

A critical nuance is that ERC-165 is itself an interface, with its own interface ID of 0x01ffc9a7. Therefore, a contract that implements ERC-165 must return true for 0x01ffc9a7 in its own supportsInterface function. This creates a recursive foundation: you can first check if a contract supports ERC-165, and if it does, you can then reliably query it for any other interface. This layered approach ensures backward compatibility and forms the bedrock for a composable and verifiable smart contract landscape, where capabilities are not assumed but proven on-chain.

key-features
ERC-165

Key Features

ERC-165 is a standard interface detection protocol that allows smart contracts to declare and query the interfaces they implement.

01

Standard Interface Detection

ERC-165 provides a standard method for a smart contract to publish which interfaces it supports. This is done by implementing a supportsInterface function that returns true or false for a given interface identifier (a 4-byte function signature hash). This prevents errors from calling non-existent functions.

02

Interface Identifiers (IIDs)

An Interface Identifier is a 32-bit identifier, typically the XOR of all function selectors in an interface. For example, the IID for ERC-721 is 0x80ac58cd. ERC-165 itself has the IID 0x01ffc9a7. This deterministic calculation allows for unambiguous identification of any standard or custom interface.

03

The `supportsInterface` Function

The core of ERC-165 is a single function: function supportsInterface(bytes4 interfaceId) external view returns (bool);. A compliant contract must implement this to return true for 0x01ffc9a7 (its own interface ID) and for the IDs of any other standards it supports, like ERC-20 or ERC-721.

04

Prevents Contract Interaction Failures

By querying supportsInterface before interacting, dApps and other contracts can verify support for required functionality. This is critical for composability, ensuring that a wallet or marketplace only attempts to call transferFrom on a contract that is confirmed to be an ERC-721, avoiding costly transaction reverts.

05

Foundation for Other Standards

Most major Ethereum standards, including ERC-20, ERC-721, and ERC-1155, recommend or require ERC-165 compliance. It acts as a foundational meta-standard, enabling a reliable discovery layer for the entire ecosystem of interoperable smart contracts.

06

How to Query Support

Support can be checked on-chain via a static call to supportsInterface or off-chain using tools like Etherscan or blockchain explorers. For example, to check for ERC-721 support, you would call myContract.supportsInterface(0x80ac58cd).

ecosystem-usage
ERC-165

Ecosystem Usage

ERC-165 is a standard interface detection protocol that allows smart contracts to declare and query the interfaces they implement, enabling composability and safe interactions within the Ethereum ecosystem.

01

Core Mechanism: Interface Detection

ERC-165 provides a standard method for a contract to publish the interface identifiers it supports. The core function supportsInterface(bytes4 interfaceId) returns true if the contract implements the queried interface. This prevents errors by allowing other contracts or clients to verify compatibility before calling functions.

  • How it works: An interface ID is typically the XOR of all function selectors in that interface.
  • Example: The ERC-721 interface ID is 0x80ac58cd. A wallet can call supportsInterface(0x80ac58cd) to confirm an address is an NFT contract.
02

Enabling Safe Upgrades & Extensions

This standard is foundational for upgradeable contracts and extensible standards. By checking for new interface IDs, systems can safely introduce new functionality without breaking existing integrations.

  • Proxy Patterns: Upgradeable proxies use ERC-165 to expose the current implementation's capabilities.
  • Extended Standards: ERC-721 and ERC-1155 have optional extensions (like metadata or enumeration) defined by their own interface IDs, which can be detected via ERC-165.
03

Critical for ERC-721 & ERC-1155 NFTs

Major NFT standards mandate ERC-165 to declare their core and optional features. This allows marketplaces, wallets, and other tools to interact with NFTs correctly.

  • ERC-721: Must implement supportsInterface for its core interface (0x80ac58cd) and can add others like ERC721Metadata (0x5b5e139f).
  • ERC-1155: Uses a single interface ID (0xd9b67a26) for its multi-token standard, with extensions for metadata and supply tracking.
05

The Registry Pattern: ERC-1820

ERC-165 has a limitation: it only works for direct contract queries. ERC-1820 extends this concept with a universal registry, allowing any address (including Externally Owned Accounts) to register which interfaces they implement for others to discover.

  • Use Case: Used by some decentralized identity and wallet schemes where an EOA needs to declare it can handle certain interactions.
06

Gas Optimization & Best Practices

While lightweight, implementing ERC-165 requires consideration for gas efficiency.

  • Storage vs. Computation: Interface support is often hardcoded in a view function or stored as a mapping for dynamic support.
  • Best Practice: Contracts should override supportsInterface to check parent contract support (e.g., super.supportsInterface(interfaceId)) to correctly handle inherited interfaces.
technical-details
STANDARD INTERFACE DETECTION

ERC-165

A core Ethereum standard that provides a standardized method to publish and detect what interfaces a smart contract implements.

ERC-165 is an Ethereum Request for Comments standard that defines a minimal, gas-efficient method for smart contracts to declare the interfaces they support, enabling other contracts and user interfaces to query this information programmatically. It solves a critical interoperability problem: without a standard detection mechanism, it is impossible for a calling contract to know if another contract supports a specific function, such as balanceOf for ERC-721 tokens or safeTransferFrom for ERC-1155, before attempting an interaction that could fail.

The standard's primary mechanism is the supportsInterface(bytes4 interfaceId) function. Each interface is identified by a unique four-byte function selector known as an interfaceId, which is typically calculated as the XOR of all function selectors within that interface. A contract compliant with ERC-165 returns true when queried with the correct interfaceId for an interface it implements. This allows for a simple, reliable check before proceeding with more complex interactions, preventing errors and wasted gas.

Implementation involves two key steps. First, a contract must implement the supportsInterface function itself. Second, it must register the interface IDs it supports, which is commonly done in the constructor using _registerInterface or by mapping the IDs in the function's logic. Many major token standards, including ERC-20, ERC-721, and ERC-1155, explicitly recommend or require ERC-165 compliance. This creates a foundational layer for the composable "money legos" of DeFi and NFTs, as contracts can safely discover each other's capabilities.

For developers, using ERC-165 is considered a best practice for any contract that implements a published interface. Wallets, block explorers, and decentralized applications (dApps) rely on this standard to correctly identify contract types and enable appropriate features. For instance, a marketplace can verify a contract is an ERC-721 before listing it for sale, and a wallet can show NFT holdings only for addresses that return true for the ERC-721 interface ID (0x80ac58cd).

Beyond basic detection, ERC-165 facilitates more advanced patterns like proxy upgradeability and diamond (EIP-2535) implementations, where a single contract address can support multiple, upgradeable facets. In these architectures, the supportsInterface function becomes the central lookup mechanism for routing function calls to the correct internal logic module. Its simplicity and low gas cost have made it an indispensable utility standard within the Ethereum ecosystem.

security-considerations
ERC-165

Security Considerations

While ERC-165 is a core utility for interface detection, its implementation introduces specific security considerations for developers and auditors.

01

Interface ID Collisions

An interface ID is a 4-byte hash of the function signatures in an interface. A collision occurs when two different interfaces produce the same ID, causing a contract to falsely report support for an interface it does not implement. While statistically improbable, developers should be aware of the risk, especially when using custom or less common interfaces.

  • The standard mitigates this by requiring the supportsInterface function to return true for type(I).interfaceId.
  • Auditors should verify that the calculated interfaceId in the contract matches the intended standard.
02

Insecure `supportsInterface` Overrides

The security of the entire detection mechanism depends on a correct supportsInterface function. Common vulnerabilities include:

  • Incorrect Logic: Returning true for unhandled interfaceId values or failing to call super.supportsInterface(interfaceId) in inherited contracts, breaking support for parent interface IDs.
  • Gas Exhaustion: Implementing an inefficient lookup (e.g., a loop over an unbounded array) can be exploited in a gas-griefing attack when the function is called on-chain.
  • Best practice is to use pure, constant-time logic or inherit from OpenZeppelin's ERC165 implementation.
03

Proxy & Upgradeability Risks

In upgradeable proxy patterns (e.g., UUPS, Transparent), the implementation contract's reported interfaces must be carefully managed.

  • A proxy must correctly forward supportsInterface calls to the implementation. A mismatch can break off-chain tooling and integrators' expectations.
  • During an upgrade, if a new implementation removes support for an interface that the proxy previously advertised, dependent contracts may fail.
  • The proxy's own interface (e.g., for upgrade functions) must not collide with the implementation's business logic interfaces.
04

Frontrunning & State Changes

The supportsInterface function is specified as view, meaning it should not modify state. A malicious implementation that changes state within this function violates the standard's expectation and can be used in reentrancy or frontrunning attacks.

  • Integrators and off-chain tools assume calling this function is safe and side-effect free.
  • Auditors must verify the function is truly view and contains no state changes, SSTORE operations, or external calls to untrusted contracts.
05

Off-Chain Tooling Reliance

Wallets, explorers, and dApps rely on ERC-165 to correctly identify a contract's capabilities. Insecure implementation can lead to:

  • UI/UX Failures: A wallet might not show the correct interaction buttons for a token (ERC-20, ERC-721) if interface detection fails.
  • Integration Faults: Automated systems may send transactions to contracts assuming certain functions exist, leading to reverts and lost gas.
  • This creates a trust dependency where the security of higher-level applications hinges on the correct implementation of this low-level standard.
06

Audit Checklist Item

For security auditors, verifying ERC-165 compliance is a standard checklist item. Key verification points include:

  • Does supportsInterface correctly return true for type(I).interfaceId of all intended interfaces?
  • Does it call super.supportsInterface(interfaceId) when inheriting from other ERC-165 contracts?
  • Is the function view and free of state-changing operations?
  • Are all interfaceId constants derived correctly using type(I).interfaceId or bytes4(keccak256(...))?
  • For upgradeable contracts, does the proxy correctly delegate this call?
ERC-165 IMPLEMENTATION

Comparison: Interface Detection Methods

Methods for smart contracts to declare and detect supported interfaces, as defined by the ERC-165 standard.

MethodManual (Pure Function)Automatic (Storage Slot)Hybrid (Lookup Table)

Detection Mechanism

Direct function call to supportsInterface

Read from a pre-defined storage slot

Combines function call with internal mapping

Gas Cost (Detection)

~700 gas

~800 gas

~750 gas

Gas Cost (Registration)

N/A (hardcoded)

~20,000 gas (one-time)

~50,000 gas (per interface)

Interface Flexibility

On-Chain Proof

Implementation Complexity

Low

Medium

High

Standard Compliance

ERC-165 Core

ERC-165 Core

ERC-165 + Extension

Common Use Case

Fixed, known interfaces

Dynamic interface support

Complex contracts with many interfaces

ERC-165

Frequently Asked Questions

ERC-165 is a standard interface detection protocol for Ethereum smart contracts. It allows contracts to declare which interfaces they support, enabling other contracts and clients to query for compatibility.

ERC-165 is a standard that provides a mechanism for smart contracts to publish and detect the interfaces they implement. It works by defining a function, supportsInterface(bytes4 interfaceId), which returns true if the contract implements the interface identified by the 4-byte interfaceId. This identifier is typically derived by XORing the function selectors of the interface's methods. This allows other contracts or off-chain systems to programmatically verify if a contract supports a specific standard, such as ERC-20 or ERC-721, before interacting with it, preventing errors and enabling dynamic composition.

ENQUIRY

Get In Touch
today.

Our experts will offer a free quote and a 30min call to discuss your project.

NDA Protected
24h Response
Directly to Engineering Team
10+
Protocols Shipped
$20M+
TVL Overall
NDA Protected direct pipeline
ERC-165: Ethereum Interface Detection Standard | ChainScore Glossary