mirror of
https://github.com/status-im/EIPs.git
synced 2025-02-03 10:34:24 +00:00
A standard for interface detection, fixes #165
This commit is contained in:
parent
b943077ce8
commit
5e02514334
121
EIPS/eip-165.md
Normal file
121
EIPS/eip-165.md
Normal file
@ -0,0 +1,121 @@
|
||||
## Preamble
|
||||
|
||||
```
|
||||
EIP: <to be assigned>
|
||||
Title: ERC-165 Standard Interface Detection
|
||||
Author: Christian Reitwießner @chriseth, Nick Johnson @Arachnid, RJ Catalano @VoR0220, Fabian Vogelsteller @frozeman, Hudson Jameson @Souptacular, Jordi Baylina @jbaylina, Griff Green @griffgreen, William Entriken <github.com@phor.net>
|
||||
Type: Standard Track
|
||||
Category: ERC
|
||||
Status: Draft
|
||||
Created: 2018-01-23
|
||||
```
|
||||
|
||||
## Simple Summary
|
||||
|
||||
Creates a standard method to publish and detect what interfaces a smart contract implements.
|
||||
|
||||
## Abstract
|
||||
|
||||
Herein, we standardize the following:
|
||||
|
||||
1. How interfaces are identified
|
||||
2. How a contract will publish the interfaces it implements
|
||||
3. How to detect if a contract implements ERC-165
|
||||
4. How to detect if a contract implements any given interface
|
||||
|
||||
## Motivation
|
||||
|
||||
For some "standard interfaces" like [the ERC-20 token interface](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), it is sometimes useful to query whether a contract supports the interface and if yes, which version of the interface, in order to adapt the way in which the contract is to be interfaced with. Specifically for ERC-20, a version identifier has already been proposed. This proposal stadardizes the concept of interfaces and standardizes the identification (naming) of interfaces.
|
||||
|
||||
## Specification
|
||||
|
||||
### How Interfaces are Identified
|
||||
|
||||
For this standard, an *interface* is a set of [function selectors as calculated in Solidity](http://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector). This a subset of [Solidity's concept of interfaces](http://solidity.readthedocs.io/en/develop/abi-spec.html) and the `interface` keyword definition which also define return types, mutability and events.
|
||||
|
||||
We define the interface identifier as the XOR of all function selectors in the interface. This code example shows how to calculate an interface identifier:
|
||||
|
||||
```solidity
|
||||
pragma solidity ^0.4.19;
|
||||
|
||||
interface Solidity101 {
|
||||
function hello() public pure;
|
||||
function world(int) public pure;
|
||||
}
|
||||
|
||||
contract Selector {
|
||||
function calculateSelector() public pure returns (bytes4) {
|
||||
Solidity101 i;
|
||||
return i.hello.selector ^ i.world.selector;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note: interfaces do not permit optional functions, therefore, the interface identity will not them.
|
||||
|
||||
### How a Contract will Publish the Interfaces it Implements
|
||||
|
||||
A contract that is compliant with ERC-165 shall implement the following function:
|
||||
|
||||
```solidity
|
||||
pragma solidity ^0.4.19;
|
||||
|
||||
interface ERC165 {
|
||||
/// @notice Query if a contract implements an interface
|
||||
/// @param interfaceID The interface identifier, as specified in ERC-165
|
||||
/// @dev Interface identification is specified in ERC-165. This function
|
||||
/// use less than 30000 gas.
|
||||
/// @return `true` if the contract implements `interfaceID` and
|
||||
/// `interfaceID` is not 0xffffffff, `false` otherwise
|
||||
function supportsInterface(bytes4 interfaceID) external view returns (bool);
|
||||
}
|
||||
```
|
||||
|
||||
The interface identifier for this interface is `0x01ffc9a7`. You can calculate this by running ` bytes4(keccak256('supportsInterface(bytes4)'));` or using the `Selector` contract above.
|
||||
|
||||
Therefore the implementing contract will have a `supportsInterface` function that returns:
|
||||
|
||||
- `true` when `interfaceID` is `0x01ffc9a7` (EIP165 interface)
|
||||
- `false` when `interfaceID` is `0xffffffff`
|
||||
- `true` for any other `interfaceID` this contract implements
|
||||
- `false` for any other `interfaceID`
|
||||
|
||||
This function must return a bool and use at most 30000 gas.
|
||||
|
||||
Implementation note, there are several logical ways to implement this function. Please see the example implementations and the discussion on gas usage.
|
||||
|
||||
### How to Detect if a Contract Implements ERC-165
|
||||
|
||||
1. The source contact makes a `CALL` to the destination address with input data: `0x01ffc9a701ffc9a7` value: 0 and gas 30000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`.
|
||||
2. If the call fails or return false, the destination contract does not implement ERC-165.
|
||||
3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff`.
|
||||
4. If the second call fails or returns true, the destination contract does not implement ERC-165.
|
||||
5. Otherwise it implements EIP165.
|
||||
|
||||
### How to Detect if a Contract Implements any Given Interface
|
||||
|
||||
1. If you are not sure if the contract implements ERC-165 Interface, use the previous procedure to confirm.
|
||||
2. If it does not implement ERC-165, then you will have to see what methods it uses the old fashioned way.
|
||||
3. If it implements ERC-165 then just call `supportsInterface(interfaceID)` to determine if it implements an interface you can use.
|
||||
|
||||
## Rationale
|
||||
|
||||
We tried to keep this specification as simple as possible. This implementation is also compatible with the current Solidity version.
|
||||
|
||||
## Backwards Compatibility
|
||||
|
||||
The mechanism described above (with `0xffffffff`) should work with most of the contracts previous to this standard to determine that they do not implement ERC-165.
|
||||
|
||||
Also [the ENS](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-137.md) already implements this EIP.
|
||||
|
||||
## Test Cases
|
||||
|
||||
XXXXXXXX HELP NEEDED XXXXXXXXX
|
||||
|
||||
## Implementation
|
||||
|
||||
XXXXXX IN PROGRES XXXXXX [https://github.com/jbaylina/EIP165Cache](https://github.com/jbaylina/EIP165Cache)
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
Loading…
x
Reference in New Issue
Block a user