本文へ移動

ウォレットでの Calldata デコード

トランザクションのコールデータ、ABI ワードとオフセット、セレクター衝突、プロキシ、バッチ、承認、型付きデータの permit、シミュレーション、取引後照合を検証優先で解説します。

更新日

教育目的の参考情報であり、投資、法律、セキュリティ上の助言ではありません。デコードとシミュレーションは曖昧さを減らしますが、承認、実行、資産の安全性、ファイナリティを保証するものではありません。

端的な答え

Calldata は、Ethereum の最上位トランザクションまたは内部メッセージ呼び出しに入力として渡される不変のバイト列です。通常の Solidity 関数呼び出しは 4-byte のセレクターで始まり、その後に ABI エンコードされた引数が続きます。ただし、calldata は自己記述形式ではありません。同じバイト列でも、実行時コード、プロキシの実装、スキーマが異なれば意味が変わることがあります。フォールバック関数、低水準アセンブリ、Solidity 以外のプロトコルは、通常の関数 ABI に従う必要さえありません。

したがって、ウォレットは候補となる関数名だけを表示すべきではありません。安全な確認では、バイト列を chainId、特定のブロック、fromto、ネイティブ資産の value、実行時 codeHash、有効な実装コントラクト、信頼できる ABI に結び付けます。その上で、すべてのネストされた呼び出しを厳密にデコードし、オンチェーンの calldata と EIP-712 署名を区別し、明示した状態でシミュレーションし、ブロック収録後に実際のレシートと状態変化を照合します。

Calldata デコード
0 / 5
0 項目確認済み; 5 項目が未解決

すべて確認しても、資産・取引・システムの安全性が証明されるわけではありません。

仕組み

  1. 署名対象のエンベロープと観測時点を固定します。chainId、ブロック番号とハッシュ、fromto、ネイティブ資産の value、入力バイト、nonce、手数料フィールドを記録します。ウォレットまたは RPC の取得元も保存します。別のチェーンやブロックから得たデコード結果は、同じ判断材料ではありません。
  2. デコード前に対象の種類を分類します。トランザクション、EIP-712 型付きデータ要求、ERC-2612 permit、ERC-4337 UserOperation、生の personal-sign メッセージでは、ドメインとスキーマが異なります。すべてをトランザクション ABI として扱ってはいけません。
  3. 固定したブロックで宛先を解決します。実行時バイトコードと codeHash を読み、該当する場合はプロキシ、ビーコン、実装を特定し、実装と管理者のストレージスロットを記録します。その正確なコード版に一致する ABI を取得します。セレクターレジストリが示すのは候補であり、権威ある根拠ではありません。
  4. 厳密にデコードします。セレクターは、戻り値の型を除く正規関数シグネチャを Keccak-256 でハッシュした先頭 4 bytes です。静的な値は 32-byte ワードを占め、動的引数のヘッドにはセレクター後の引数ブロック先頭を基準とするオフセットが入ります。切り詰められたデータ、範囲外のオフセット、成立しない長さ、不正なパディング、説明できない末尾バイトは拒否します。
  5. multicall、ネストされた calldata、委任実行を再帰的に展開します。子呼び出しごとに、宛先、ネイティブ資産額、セレクター、引数、呼び出し種別、allowFailure フラグの有無を列挙します。delegatecall では、実装コードが呼び出し元のアドレス、残高、ストレージのコンテキストで動作し、msg.sendermsg.value は保持されます。
  6. 権限台帳と価値台帳を分けて作成してからシミュレーションします。受取人、spender、NFT オペレーター、トークンの生の単位、decimals、期限、スリッページ境界、ネイティブ資産額を記録します。正確なブロック、送信者、value でシミュレーションしますが、状態、価格、時刻、コード、トランザクション順序は変化し得るため、結果は条件付きのスナップショットとして扱います。
  7. 署名前に重要なフィールドをすべて確認します。ブロック収録後は、レシートのステータス、ログ、利用可能なトレース、残高、allowance、オペレーター状態の差分を確認します。捕捉された子呼び出しの失敗と最上位呼び出しの成功を区別し、リバート時にも gas を計上し、必要なファイナリティを待ちます。説明できない失敗があれば、無条件に再署名せず中止します。

計算例

  • 静的な ERC-20 送付。 transfer(address,uint256) では一般にセレクター 0xa9059cbb が使われます。セレクター1個と ABI ワード2個で 4 + 2 * 32 = 68 bytes です。生の数量 1,500,000 は、独立に検証した対象トークンが 6 decimals を使う場合、1.5 tokens と表示されます。decimals は外部のコントラクトメタデータであり、これらの引数にはエンコードされていません。セレクターだけでコントラクトや関数を一意に特定することもできません。
  • 動的 bytes のオフセット。 f(address,bytes) でペイロードが 3-byte の場合、2ワードのヘッドが 64 bytes を占めます。動的オフセットは 0x40 で、セレクターを除いた引数ブロックの先頭から測ります。テールには 32-byte の長さワード1個と 32-byte にパディングされたデータワード1個が入るため、calldata 全体は 4 + 64 + 32 + 32 = 132 bytes です。オフセットをバイト0からの絶対位置と解釈すると、4バイト後ろにずれます。
  • バッチの value 処理は実装固有です。 外側の呼び出しが 1.00 ETH を伴い、デコードした3つの子呼び出しがそれぞれ 0.20 ETH0.30 ETH0.10 ETH、合計 0.60 ETH を明示的に要求するとします。残る 0.40 ETH は、バッチコード次第で返金、保持、転送、またはリバートの原因になり得ます。3番目の子呼び出しが allowFailure=true で失敗した場合、それ以前の呼び出しが確定する実装もあります。原子的な実装なら、すべてがリバートすることがあります。
  • permit は署名時点におけるリレイヤーの calldata ではありません。 1,000 USDC を保有する所有者が、300 USDC、nonce 41 の ERC-2612 permit に署名します。署名だけでは残高も allowance も変わりません。リレイヤーが正常に送信すると、nonce は 42、allowance は 300 になります。その後 spender が 180 を使用すると、残高は 820、残りの allowance は 120 です。サイトとの接続を解除しても、この権限は取り消されません。

リスク

  • 誤ったチェーン、フォーク、ブロックタグ、トランザクションエンベロープに対してデコードする。
  • 偽装されたドメイン、宛先アドレス、受取人に署名する。
  • 衝突があり得るにもかかわらず、4-byte セレクターを一意とみなす。
  • 推測した ABI、古い ABI、または正しく検証されていない ABI を使う。
  • 検証済みソースという表示を信頼し、現在の実行時 codeHash と照合しない。
  • 確認から実行までの間に行われた実装、ビーコン、管理者の変更を見落とす。
  • プロキシ関数と実装関数のセレクター衝突を見落とす。
  • delegatecall が呼び出し元のストレージコンテキストへ書き込むことを忘れる。
  • 不正な動的オフセット、長さ、パディング、末尾バイトを受け入れる。
  • 宛先、value、権限を隠すネストされたバッチを展開しない。
  • 実装が子呼び出しの失敗を捕捉または許容するのに、原子性を前提とする。
  • トークン引数が無害に見えるため、最上位のネイティブ value を見落とす。
  • decimals を誤る、または転送手数料型やリベース型トークンを標準 ERC-20 とみなす。
  • ERC-20 の無制限 allowance を与える、または allowance 更新競合を誤って扱う。
  • NFT の setApprovalForAll がコレクション全体に及ぼす権限を見落とす。
  • EIP-712 型付きデータまたは ERC-2612 permit をトランザクション calldata と誤認する。
  • nonce、期限、検証コントラクト、チェーンドメイン、リプレイ境界を見落とす。
  • オラクル、時刻、保留状態、MEV、コードが変化し得るのにシミュレーションを不変とみなす。
  • レシートのステータス、ログ、事業者のトレースを完全な経済状態の証明とみなす。
  • 侵害された UI から無条件に再署名する、または収録、リオーグ、ファイナリティのリスクを無視する。

よくある誤解

  • 関数セレクターだけで、コントラクトが実行する内容を一意に特定できる。
  • 検証済みのフロントエンド要約は、署名対象のバイト列と現在の実装に完全に一致する。
  • value=0 のトランザクションでは、トークン、NFT、委任済み資産を移動できない。
  • シミュレーション成功またはレシート成功は、安全性と意図した経済結果を証明する。
  • dapp との接続を解除すれば、承認、permit、NFT オペレーター権限も取り消される。

関連トピック

出典

ナビゲーション

Wiki を検索...