EVM系のdAppを初めて利用するとき、画面の見た目だけでは、接続先のネットワーク、コントラクトの実体、管理権限、既存のトークン承認を判断できません。
この記事では、ウォレットを接続せず、署名も送信せずに、公開されているオンチェーン情報をcastで確認する手順をまとめます。目的は安全性を断定することではなく、接続前に確認できる事実を増やすことです。
前提
-
Foundryの
castが利用できる - 対象チェーンのRPC URLが分かっている
- 公式資料から対象コントラクトの完全なアドレスを取得している
以下の例では、秘密鍵やシードフレーズは使用しません。シェル履歴や環境変数に秘密情報を保存しないでください。
export RPC_URL="https://your-rpc.example"
export TARGET="0xTargetContractAddress"
1. チェーンとデプロイ済みコードを確認する
最初に、RPCが接続しているチェーンを確認します。
cast chain-id --rpc-url "$RPC_URL"
次に、対象アドレスのランタイムバイトコードを取得します。
cast code "$TARGET" --rpc-url "$RPC_URL"
結果が0xの場合、そのネットワーク上のアドレスにはランタイムコードがありません。ネットワークの選択ミス、アドレスの転記ミス、EOAをコントラクトとして参照している可能性を確認します。
コードが存在しても、そのアドレスが公式のものだとは限りません。完全なアドレスを公式ドキュメントと照合する作業は別に必要です。
2. 検証済みソースコードとABIを確認する
対象チェーンのブロックエクスプローラーで、次の項目を確認します。
- アドレスが公式資料と一致しているか
- ソースコードが検証済みか
- コンパイラのバージョンと設定
- ABIが公開されているか
- Proxyとして表示されているか
「ソースコード検証済み」は、公開されたソースとデプロイ済みバイトコードの対応を調べやすくするものです。監査済み、脆弱性なし、運営者を信頼できる、という意味ではありません。
3. EIP-1967 Proxyの実装先と管理者を確認する
アップグレード可能なProxyでは、利用者が操作するアドレスと、ロジックを持つImplementationアドレスが異なる場合があります。
EIP-1967で定義されたImplementationスロットを読み取ります。
IMPLEMENTATION_SLOT="0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"
cast storage "$TARGET" "$IMPLEMENTATION_SLOT" \
--rpc-url "$RPC_URL"
32バイトの結果がゼロでなければ、末尾20バイトがImplementationアドレスです。エクスプローラー上の実装先と一致するか確認します。
管理者スロットも確認できます。
ADMIN_SLOT="0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"
cast storage "$TARGET" "$ADMIN_SLOT" \
--rpc-url "$RPC_URL"
ゼロだからProxyではない、と断定はできません。Beacon Proxy、独自実装、別方式のアップグレード機構もあります。エクスプローラーの表示、ABI、ソースコードを合わせて確認します。
4. 読み取り関数から権限と現在の状態を確認する
ABIにowner()やpaused()がある場合は、eth_callで現在値を読めます。
cast call "$TARGET" "owner()(address)" \
--rpc-url "$RPC_URL"
cast call "$TARGET" "paused()(bool)" \
--rpc-url "$RPC_URL"
対象の関数が存在しない場合、呼び出しは失敗します。そのときはABIを確認し、AccessControlのrole、ProxyAdmin、multisig、timelockなど、実際の権限モデルを調べます。
特に確認したいのは、次の操作が誰に許可されているかです。
- 実装コントラクトの変更
- 手数料や上限値の変更
- 一時停止と再開
- トークンのmintやburn
- コントラクト内資産の移動
- roleの付与と削除
管理権限があること自体は異常ではありません。重要なのは、その権限、保有者、変更履歴が利用者に説明されていることです。
5. ERC-20のallowanceを確認する
接続先がトークン操作を伴う場合は、ウォレットとspenderの組み合わせに対する既存のallowanceを確認します。
export TOKEN="0xTokenContractAddress"
export WALLET="0xPublicWalletAddress"
export SPENDER="0xSpenderContractAddress"
cast call "$TOKEN" \
"allowance(address,address)(uint256)" \
"$WALLET" "$SPENDER" \
--rpc-url "$RPC_URL"
allowanceは、ownerがspenderに使用を許可した残量です。非常に大きな値なら、無制限に近い承認かどうかを確認します。不要な承認は、対象チェーンに対応した信頼できるツールやトークンコントラクトのapproveを用いて取り消します。取り消し操作自体はトランザクションであり、内容と送信先を確認してから署名します。
変更履歴も確認する
現在値だけでなく、エクスプローラーのLogsやTransactionsで最近の管理操作を確認します。
UpgradedAdminChanged- ownership transfer
- roleの付与・削除
- pause / unpause
- 手数料や上限値の変更
1回の正常なトランザクションだけでは、コントラクト全体の挙動は判断できません。複数の実行例と管理操作の履歴を確認します。
接続前チェックリスト
- チェーンIDが想定と一致している
- 完全なコントラクトアドレスを公式資料と照合した
- デプロイ済みコードが存在する
- ソースコード、ABI、Proxyの有無を確認した
- Implementationと管理権限を確認した
- TOKEN、WALLET、SPENDERを分けてallowanceを確認した
- 最近のアップグレードと管理操作を確認した
- 不明点が残る場合は接続や署名を中止した
まとめ
オンチェーンデータは、コントラクトの安全性や将来の運用を保証しません。一方で、ネットワーク、コード、Proxy、権限、allowanceという基本情報は、ウォレットを接続する前に読み取り専用で確認できます。
画面に表示された説明と、公開されているコントラクトの状態が一致しているかを確認することが、実務的な第一歩です。
参考資料
- Foundry: cast call
- ERC-1967: Proxy Storage Slots
- OpenZeppelin: Proxy Upgrade Pattern
- OpenZeppelin Contracts: IERC20 allowance
この記事は、Atlas Systemが公開する教育目的の技術資料です。特定のプロジェクト、コントラクト、金融商品の安全性や収益性を保証するものではありません。