【Solidity】ERC165を読んでみる
ERC721で継承されているERC165とは何者か?と気になったのでコントラクトを読んでみました。
その結果を備忘録を兼ねて記事にまとめています。
ERC721
ERC165が継承されているのが確認できます。
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
ERC165
コードが短いので、全文を載せておきます。
まずはInterfaceを定義しているIERC165.sol
を見てみます。
以下はコメントをDeepLで翻訳したものです。
要は、コントラクトでサポートしているInterfaceを他者から問い合わせ可能にする規格のようです。
ERC165 規格のインターフェースで、以下のように定義されています。 https://eips.ethereum.org/EIPS/eip-165[EIP].
実装者はコントラクトインターフェースのサポートを宣言することができ、そのインターフェイスを他者({ERC165Checker})が照会することができる。
実装者はコントラクトインターフェースのサポートを宣言することができ、それを他者({ERC165Checker})が問い合わせることができる。
実装については、{ERC165}を参照。
このコントラクトが
interfaceId
で定義されたインターフェースを実装している場合、true を返します。
定義されたインターフェイスを実装しているかどうかを返します。
これらのIDがどのように作成されるかについては、対応する EIP セクション を参照してください。
この関数呼び出しは、30,000ガス未満でなければなりません。
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* 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[EIP 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);
}
次にERC165.sol
を見ていきます。
supportsInterface
関数はvirtual
のため、overrideして使用します。
自分で新たなInterfaceを作成して継承した場合は、overrideして追加していきます。
{IERC165} インターフェースの実装です。
ERC165 を実装したいコントラクトは、このコントラクトを継承して {supportsInterface} をオーバーライドし、サポートされる追加インターフェース ID をチェックする必要があります。
サポートされる追加インターフェース ID をチェックする。例えば...(コード省略)
あるいは、{ERC165Storage}はより使いやすいですが、より高価な実装を提供しています。
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 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);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
overrideする場合はこのように書きます。
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
}
Discussion