--- title: Introspection --- To smooth interoperability, often standards require smart contracts to implement [introspection mechanisms](https://en.wikipedia.org/wiki/Type_introspection). In Ethereum, the [EIP165](https://eips.ethereum.org/EIPS/eip-165) standard defines how contracts should declare their support for a given interface, and how other contracts may query this support. Starknet offers a similar mechanism for interface introspection defined by the [SRC5](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md) standard. ## SRC5 Similar to its Ethereum counterpart, the [SRC5](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md) standard requires contracts to implement the `supports_interface` function, which can be used by others to query if a given interface is supported. ### Usage To expose this functionality, the contract must implement the [SRC5Component](/contracts-cairo/3.x/api/introspection#SRC5Component), which defines the `supports_interface` function. Here is an example contract: ```rust #[starknet::contract] mod MyContract { use openzeppelin_introspection::src5::SRC5Component; component!(path: SRC5Component, storage: src5, event: SRC5Event); #[abi(embed_v0)] impl SRC5Impl = SRC5Component::SRC5Impl; impl SRC5InternalImpl = SRC5Component::InternalImpl; #[storage] struct Storage { #[substorage(v0)] src5: SRC5Component::Storage } #[event] #[derive(Drop, starknet::Event)] enum Event { #[flat] SRC5Event: SRC5Component::Event } #[constructor] fn constructor(ref self: ContractState) { self.src5.register_interface(selector!("some_interface")); } } ``` ### Interface ```rust #[starknet::interface] pub trait ISRC5 { /// Query if a contract implements an interface. /// Receives the interface identifier as specified in SRC-5. /// Returns `true` if the contract implements `interface_id`, `false` otherwise. fn supports_interface(interface_id: felt252) -> bool; } ``` ## Computing the interface ID The interface ID, as specified in the standard, is the [XOR](https://en.wikipedia.org/wiki/Exclusive_or) of all the [Extended Function Selectors](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md#extended-function-selector) of the interface. We strongly advise reading the SNIP to understand the specifics of computing these extended function selectors. There are tools such as [src5-rs](https://github.com/ericnordelo/src5-rs) that can help with this process. ## Registering interfaces For a contract to declare its support for a given interface, we recommend using the SRC5 component to register support upon contract deployment through a constructor either directly or indirectly (as an initializer) like this: ```rust #[starknet::contract] mod MyContract { use openzeppelin_interfaces::accounts as interface; use openzeppelin_introspection::src5::SRC5Component; component!(path: SRC5Component, storage: src5, event: SRC5Event); #[abi(embed_v0)] impl SRC5Impl = SRC5Component::SRC5Impl; impl InternalImpl = SRC5Component::InternalImpl; #[storage] struct Storage { #[substorage(v0)] src5: SRC5Component::Storage } #[event] #[derive(Drop, starknet::Event)] enum Event { #[flat] SRC5Event: SRC5Component::Event } #[constructor] fn constructor(ref self: ContractState) { // Register the contract's support for the ISRC6 interface self.src5.register_interface(interface::ISRC6_ID); } (...) } ``` ## Querying interfaces Use the `supports_interface` function to query a contract’s support for a given interface. ```rust #[starknet::contract] mod MyContract { use openzeppelin_interfaces::accounts as interface; use openzeppelin_interfaces::introspection::ISRC5DispatcherTrait; use openzeppelin_interfaces::introspection::ISRC5Dispatcher; use starknet::ContractAddress; #[storage] struct Storage {} #[external(v0)] fn query_is_account(self: @ContractState, target: ContractAddress) -> bool { let dispatcher = ISRC5Dispatcher { contract_address: target }; dispatcher.supports_interface(interface::ISRC6_ID) } } ``` If you are unsure whether a contract implements SRC5 or not, you can follow the process described in [here](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md#how-to-detect-if-a-contract-implements-src-5).