導入
ブロックチェーン上では、あるコントラクトが別のコントラクトを呼び出すことがよくあります。相手の中身を知らなくても「どんな関数があるか」の約束さえあれば呼べます。それが interface(インターフェース) です。
説明
interface は「関数の形(シグネチャ)」だけを宣言し、実装は持ちません。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// 相手のトークンが持つ関数の「約束」だけを宣言
interface IToken {
function transfer(address to, uint256 amount) external returns (bool);
function balanceOf(address who) external view returns (uint256);
}
contract Payer {
// 別のアドレスにあるトークンコントラクトを呼び出す
function pay(address token, address to, uint256 amount) public {
IToken(token).transfer(to, amount);
}
}
interface IToken { ... }… 関数の名前・引数・戻り値だけを定義。中身({ }の処理)は書かない。すべてexternal。IToken(token)… 「このアドレスにあるコントラクトをITokenとして扱う」というキャスト。- これで、相手コントラクトの完全なコードがなくても、約束された関数を呼び出せる。
graph LR
P["Payer コントラクト"] -- "IToken(token).transfer(...)" --> T["別のトークン<br/>コントラクト"]
I["interface IToken<br/>(呼び出しの約束)"] -.型として使う.-> P
interface は「コントラクト同士がつながる規格」の土台です。次のレッスンの ERC-20 も、実体は「みんなが従う共通の interface」だと考えると理解しやすくなります。
やってみよう
USB の規格が合えば、どのメーカーの機器でもつながるのと同じで、interface が合えば知らないコントラクトとも安全にやり取りできます。「実装より約束(インターフェース)に依存する」という設計思想を感じ取ってみましょう。