3MIKAN
仮想通貨直コン

estimateGasが失敗する理由|シミュレーションとエラーデータの確認方法

estimateGasの失敗を、入力、送信元、送金額、権限、利用許可額、期限、シミュレーション、エラーデータの順に切り分ける方法を解説します。

ガス見積もりの失敗を入力条件、コントラクトの状態、RPC差分へ分けて調べる流れ

estimateGasが失敗したとき、ガス上限を増やすだけでは直らないことがあります。

eth_estimateGasは、実際には取引を送信せず、「この処理を実行するにはどれくらいのガスが必要か」を試算する仕組みです。試算の途中でコントラクトが処理を拒否すると、必要量を計算する前に止まります。

たとえば、トークン残高や利用許可額が足りない場合です。このとき表示は「ガスを見積もれない」でも、本当の原因はガス不足ではありません。

ガス見積もりの失敗を送信内容、シミュレーション、コントラクトの状態、RPCの順に切り分ける図

ガス上限不足と処理の取り消しを分ける

  • ガス上限不足: 処理できる内容だが、許可したガス量が足りない
  • 処理の取り消し(revert): 権限、残高、利用許可額、期限、価格条件、停止状態などにより、コントラクトが処理を拒否する
  • RPCへの入力不備: 送信元、送信先、送金額、入力データ、チェーンが実際の送信条件と違う

エラー文にestimateGasと書かれていても、根本原因がコントラクトのcustom errorであることは珍しくありません。

1. 実際に送る条件を揃える

まず、次の値を確認します。

チェーンID(chainId)
送信元(account / from)
コントラクトアドレス(address / to)
関数名と引数(function name + args / data)
送るネイティブトークン量(value)
access list(利用時)
対象ブロックまたはblockTag

accountを省略すると、msg.senderに依存する権限や残高の確認結果が、実際の送信時と変わる可能性があります。ETHなどを同時に送るpayable関数ではvalueも必要です。

2. simulateContractで試運転する

simulateContractは、実際には取引を送らず、同じ条件でコントラクトを試運転する関数です。

const { request, result } = await publicClient.simulateContract({
  address,
  abi,
  functionName,
  args,
  account,
  value,
})

シミュレーションが成功した場合は、返されたrequestをWallet Clientへ渡すと、確認した条件と実際の送信条件のずれを減らせます。

失敗した場合は、返されたエラーデータを確認します。具体的な読み方はcustom errorのデコード手順で扱っています。

3. 時間や残高で変わる条件を確認する

同じコードでも、次の状態が変わると結果が変わります。

  • トークン残高とネイティブトークン残高
  • 利用許可額(allowance)と承認先
  • role、owner、allowlistなどの権限
  • 一時停止状態、販売の開始・終了
  • 期限とブロック時刻
  • DEXのreserveとminimum output
  • proxyの実装と更新後のABI

たとえば、昨日は十分な残高があったとしても、現在の残高が減っていれば同じ取引は失敗します。過去に成功した取引を比較するときは、入力値だけでなくブロック番号も一緒に残してください。

4. ガス量とガス単価を分ける

estimateGasが扱うのは、実行に必要なガスの量です。estimateFeesPerGasなどが扱うのは、ガス1単位あたりの手数料です。

コントラクトが処理を拒否している段階でpriority feeだけを上げても、残高不足や権限不足は解消しません。

保留中の取引や置換の問題はnonce too low・replacement underpricedの原因と直し方へ分けます。

よくある修正ミス

ガス上限を大きくすれば直ると思う

処理を取り消す条件は、ガス量を増やしても変わりません。まずエラーデータと入力条件を確認します。

送信元を省略した読み取りだけで判断する

権限、残高、利用許可額が送信者によって変わる場合は、本番と同じaccountを指定してシミュレーションします。

実装側ではなくproxy側のABIだけを使う

関数やcustom errorを復元できない場合があります。proxyの実装アドレスと検証済みソースコードを確認します。

mainnetで試し送信する

原因調査のために実資産を送る必要はありません。最初にシミュレーションを行い、必要ならtestnetを使います。直コンも同様に、読み取りとシミュレーションから始めてください。

最小チェックリスト

  1. チェーンとコントラクトアドレスは正しいか
  2. accountvalue、引数を実際の送信条件と揃えたか
  3. ABIは現在の実装と一致するか
  4. 残高、利用許可額、権限、期限を確認したか
  5. シミュレーションで返ったエラーデータを保存したか
  6. 別のRPCでも同じ結果か
  7. 対象ブロックと確認日時を記録したか

トランザクションハッシュがすでにある場合は、実行結果から始める解析フローへ戻ると、送信前のエラーと確定後の処理取り消しを分けて考えられます。

確認した一次情報