execution revertedとcustom errorをviemでデコードする方法
execution revertedで返るエラーデータをABIとviemでデコードし、Error(string)・Panic・custom errorを切り分ける方法を解説します。

execution revertedは、コントラクトの処理が条件を満たせず、途中までの変更も取り消されたという意味です。
たとえば、残高が足りない、利用許可額が足りない、期限を過ぎた、操作する権限がない、といった場合に発生します。ただし、この表示だけではどの条件に引っかかったかまでは分かりません。
そこで、返されたエラーの中身を表すデータ(revert data)をABIと照合します。
エラーデータは関数呼び出しと似た形で読める
custom errorのデータは、先頭4バイトの目印(selector)と、ABI形式で並べた引数で構成されます。
0x | 4-byte error selector | 32-byte word | 32-byte word | ...
これは、封筒の先頭に「どの種類の通知か」を示す番号があり、その後ろに詳細情報が続くイメージです。
エラー定義を含むABIがあれば、decodeErrorResultでエラー名と引数を復元できます。
import { decodeErrorResult } from 'viem'
const decoded = decodeErrorResult({
abi,
data: revertData,
})
console.log(decoded.errorName, decoded.args)
ABIにはfunctionだけでなくerror項目も必要です。 実装コントラクトがproxyの背後にある場合、proxy側のABIだけではcustom errorを解決できないことがあります。
3種類のエラーを分けて考える
Error(string)
revert("message")や文字列付きrequireで使われる形式です。selectorは0x08c379a0で、その後ろにABI形式の文字列が続きます。
人が読めるメッセージを返せますが、メッセージが短すぎる場合や、途中の外部呼び出しからそのまま返ってきた場合は、追加の確認が必要です。
Panic(uint256)
assertの失敗、ゼロ除算、配列の範囲外など、Solidityが定義する内部的な異常を番号で返す形式です。selectorは0x4e487b71です。
番号だけで判断せず、使用しているSolidityのバージョンに対応するpanic codeの表と、失敗した処理を照合します。
custom error
error InsufficientBalance(uint256 available, uint256 required);
custom errorは、開発者がエラー名と引数を定義する形式です。上の例なら、「利用できる残高」と「必要な残高」を数値で返せます。
文字列より少ないデータ量で詳しい情報を返せる一方、正しいABIがなければ元のエラー名へ戻せません。
simulateContractの例外から読む
viemでは、simulateContractでシミュレーションしたときの例外からContractFunctionRevertedErrorを探し、デコード済みの情報を参照できます。
import { BaseError, ContractFunctionRevertedError } from 'viem'
try {
await publicClient.simulateContract({
address,
abi,
functionName: 'transfer',
args: [to, amount],
account,
})
} catch (error) {
if (error instanceof BaseError) {
const reverted = error.walk(
(cause) => cause instanceof ContractFunctionRevertedError,
)
if (reverted instanceof ContractFunctionRevertedError) {
console.log(reverted.data?.errorName, reverted.data?.args)
}
}
}
シミュレーションは実際の取引を送信しないため、まず原因を調べる用途に向いています。送信元、送る数量、関数、引数、ブロック条件を元の取引と揃えることが重要です。
デコードできないときの確認順
dataが空ではないか0xを含む完全なエラーデータか- 呼び出し先がproxyなら、実装アドレスと実装側ABIを確認したか
- delegatecall先や外部呼び出し先のerrorもABIへ含めたか
- 同じ
account、value、ブロック条件でシミュレーションしたか - ノードやRPCがエラーデータを省略していないか
関数入力のABI確認はABI・function selector・calldata・event logsを手で読む方法、トランザクション全体の入口はviemで失敗トランザクションを調べるを参照してください。
エラー名だけを信用しない
エラーデータは外部呼び出しからそのまま返ってくることがあり、任意のコントラクトが同じ形のバイト列を返すこともできます。そのため、表示されたエラー名だけで送信元や安全性を証明することはできません。
次の情報も合わせて確認します。
- 実行結果に記録された送信先
- proxyの実装アドレス
- 検証済みソースコードとABI
- シミュレーションやtraceで実際に呼び出されたコントラクト
直コンの基本を使う場合も、署名画面だけで判断せず、対象アドレスと入力データを先に検証してください。
確認した一次情報
- viem decodeErrorResult確認日: 2026/8/28
- viem simulateContract確認日: 2026/8/28
- Solidity Contract ABI Specification確認日: 2026/8/28
- Solidity エラーハンドリング確認日: 2026/8/28



