👨‍💻

EIP165について読む

2024/08/15に公開

はじめに

ERC721とかDAOとかのコントラクトでも多用されているEIP165とは何者なのかについて調べて、その内容をまとめてみました。

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (governance/IGovernor.sol)

pragma solidity ^0.8.0;

import "../interfaces/IERC165.sol";
import "../interfaces/IERC6372.sol";

/**
 * @dev Interface of the {Governor} core.
 *
 * _Available since v4.3._
 */
abstract contract IGovernor is IERC165, IERC6372 {
    enum ProposalState {
        Pending,
        Active,
        Canceled,
        Defeated,
        Succeeded,
        Queued,
        Expired,
        Executed
    }

これはDAO関連のコントラクトです。その中で、EIP165が筆頭に継承されています。

その正体とは何者なのか、説明したいと思います。

IEIP165.solEIP165.solについて

まず、EIP165のインターフェースについて説明します。
いろいろ英語のコメントが書かれていますが、何をいっているかというと、
コントラクトがサポートしているインターフェースを定義して、外部から呼べるようにするということです。
この関数はsupportInterfaces()となります。

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

続いて、このIEIP165実際の実装(implementation)を見てみます。

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

import {IERC165} from "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

まとめ

どこかでみた「対象のスマートコントラクトが特定のインターフェイスを満たしているかどうか、を確認するインターフェイスがあると便利」という一言がこのEIPのまとめとしては、非常にわかりやすいと思いました。

Discussion