関数セレクタとは
関数セレクタは、関数の正規シグネチャ(関数名の後に、スペースやパラメータ名なしでパラメータ型を括弧で囲んだもの)の Keccak-256 ハッシュの先頭 4 バイトです。例: transfer(address,uint256) → 0xa9059cbb。すべてのコントラクト呼び出しの calldata の先頭 4 バイトを構成し、どの関数を実行するかをコントラクトに伝えます。残りのバイトは ABI エンコードされた引数です。
よく使われるセレクタ
この表はツールと同じ Keccak 実装によってページ上で計算されているため、セルフテストも兼ねています。上の入力欄に任意のセレクタを貼り付けると逆引きできます。
具体例
function approve(address spender, uint256 amount) external returns (bool) を例にします。キーワード、パラメータ名、可視性、戻り値の型を取り除くと approve(address,uint256) になります。この ASCII 文字列の Keccak-256 は 0x095ea7b3… で始まるので、セレクタは 0x095ea7b3 です。1 USDT(6 桁)を approve する calldata は、セレクタ、32 バイトに左パディングした spender アドレス、32 バイトワードとしての 1000000 で構成され、4 + 32 + 32 = 68 バイトになります。
最もよく目にする ERC-20 セレクタ
| シグネチャ | セレクタ |
|---|---|
totalSupply() | 0x18160ddd |
balanceOf(address) | 0x70a08231 |
transfer(address,uint256) | 0xa9059cbb |
transferFrom(address,address,uint256) | 0x23b872dd |
approve(address,uint256) | 0x095ea7b3 |
allowance(address,address) | 0xdd62ed3e |
よくある間違い
uint256ではなくuintをハッシュする。transfer(address,uint)は別の値にハッシュされます。正規形では常にビット幅を明記します。- パラメータ名やスペースを含める。
transfer(address to, uint256 amount)は正規シグネチャではありません。 - タプルに構造体名を使う。 構造体はフィールドの型を括弧で囲んで書き、
MyStructのようには書きません。 - セレクタとトピックを混同する。 関数は 4 バイト、イベントは 32 バイトの完全なハッシュを使います。
対応している入力形式
transfer(address,uint256): 正規形。function transfer(address to, uint256 amount) external returns (bool): Solidity の宣言。名前、可視性、returns は除去されます。event Transfer(address indexed from, address indexed to, uint256 value): トピックハッシュの計算ではindexedキーワードは無視されます。0xa9059cbbまたは 32 バイトのトピック: 内蔵リストに対する逆引き。
完全な calldata を組み立てたり読み解いたりするには、ABI エンコーダー / デコーダーに進んでください。