先日EthereumのERC-165を読んでいたので, 備忘録として日本語でまとめを記しておきます.
ERC-165: Standard Interface Detection
このERCでは, スマートコントラクトがどのようなInterfaceを実装しているのかを公開・検出する方法を定義しています.
これによって, 目の前のスマコンがERC-20準拠なのかとか, あのInterfaceを実装しているのかとかを調べることができるという嬉しいポイントがあります.
Interfaceとは?
これこれ. プログラミング言語によってはInterfaceの概念がないものもあったりして馴染みのない方ももしかしたらいるかもしれません.
このコントラクトは, こういうメソッドを持つよ! というお約束を書くアレです.
標準化した内容
以下の4つを標準化しました.
- Interfaceの識別方法
- コントラクトが実装しているInterfaceを公開する方法
- コントラクトがERC-165を実装しているかを検出する方法
- コントラクトが, 任意のInterfaceを実装しているかを検出する方法
1. Interfaceの識別方法
Interface識別子というものを導入します.
Interface識別子というのは, 全てのFunction Selectorのxorを取ることで計算されます.
Function Selector自体は
bytes4(keccak256("関数名(引数の型)"))
で計算されます.Function Selectorってなんやねんという方は, こちらの記事を読むとスッキリすると思います.
なのでざっくり言うと, 目の前のコントラクトがERC-20に準拠しているか知りたかったら, ERC-20が備えているべきInterfaceの識別子を計算し, それをコントラクトに渡してお前はこのInterface持っとるかと聞けばいいわけですね.
2. コントラクトが実装しているInterfaceを公開する方法
目の前のコントラクトに, 「(少なくとも)このInterfaceをサポートしてますか?」と聞いたら, はい or いいえのbool値を返してほしいですね.
それを標準化しました.
ERC165準拠のコントラクトは, 上記のsupportsInterfaceメソッドを備える必要があります.
このsupportsInterfaceメソッドは, 以下の挙動をします.
- interfaceIDが, 0x01ffc9a7 → trueを返す
0x01ffc9a7は, ERC165自体のInterface識別子です.
bytes4(keccak256(“supportsInterface(bytes4)”)) == 0x01ffc9a7なので. - interfaceIDが, 0xffffffff → falseを返す
- interfaceIDが, 実装しているInterfaceの識別子 → trueを返す
- interfaceIDが, 実装していないInterfaceの識別子 → falseを返す
3. コントラクトがERC-165を実装しているかを検出する方法
そもそも, 目の前のコントラクトがsupportsInterfaceメソッドを持っているか知らないと, 問い合わせようもないですよね.
ということで, その確認方法も標準化しました. 以下の順序で行います.
- 相手のコントラクトの, supportsInterface関数を呼び出してみるチャレンジ
contract.supportsInterface(0x01ffc9a7)をやる.
ここで呼び出しが失敗したり, falseが返ってきたりしたらERC-165を実装していないとわかる - もし1でtrueが返ってきたら, contract.supportsInterface(0xffffffff)を呼び出す
1でtrueが返ってきたからといって, 安心するべからず. もしかしたらそのsupportsInterface関数は, たまたま同じ名前・引数なだけで, たまたまtrueを返したのかもしれない…中身は, なにか別の目的のためにオレオレ実装されているものかもしれない… ということで, 0xffffffffでも呼び出してみるというわけ.
ここで呼び出しに失敗したり, falseが返ってこなかったらERC-165を実装していないとわかる. - ここまできたら, ERC-165を実装しているということになる.
4. コントラクトが, 任意のInterfaceを実装しているか検出する方法
ERC-165を実装していることをさきほどの手順で確認した上で, supportsInterfaceメソッドの引数に調べたいInterface識別子を突っ込み, その戻り値で判断します.
おわりに
ERC-165完全理解太郎になった!
参考文献
- Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken, “EIP-165: Standard Interface Detection,” Ethereum Improvement Proposals, no. 165, January 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-165.
- Solidity Assembly入門 ~ Function Selector ~ – アルゴリズムとかオーダーとか