ABI Decoding
Decode function calldata, return data, event logs, and errors for contract calls in viem-go
Decode function calldata (with selector), function return data, event logs, and revert errors using a parsed ABI. For standalone parameter decoding without a contract ABI, see Decode Parameters.
Import
import ("encoding/hex""github.com/ethereum/go-ethereum/common""github.com/ChefBingbong/viem-go/abi")
DecodeFunctionData
Decode full calldata (selector + args) using a parsed ABI. Identifies the function by selector and returns name and arguments.
import "github.com/ChefBingbong/viem-go/abi"// parsed is *abi.ABI from abi.Parse(...)// calldata is tx input data (selector + ABI-encoded args)decoded, err := parsed.DecodeFunctionData(calldata)if err != nil {log.Fatal(err)}fmt.Println(decoded.FunctionName) // e.g. "transfer"fmt.Println(decoded.Args...) // decoded argumentsfmt.Println(decoded.Selector) // [4]byte
- Signature:
(a *ABI) DecodeFunctionData(data []byte) (*DecodedFunctionData, error) - DecodedFunctionData has FunctionName, Args (
[]any), Selector ([4]byte). - Returns an error if the selector does not match any function on the ABI.
DecodeFunctionDataByName
Decode calldata when you already know the function name (still expects selector + args):
args, err := parsed.DecodeFunctionDataByName("transfer", calldata)
// args is []any
DecodeFunctionArgsFromData
Decode only the arguments (no selector). Use when data is only the ABI-encoded arguments (e.g. constructor args):
args, err := parsed.DecodeFunctionArgsFromData("transfer", dataWithoutSelector)
DecodeFunctionResult
Decode return data from a contract call using the function’s output definition. Use a parsed ABI and the function name.
import ("math/big""github.com/ChefBingbong/viem-go/abi")// returnData is the raw bytes from eth_callvalues, err := parsed.DecodeFunctionResult("balanceOf", returnData)if err != nil {log.Fatal(err)}// For balanceOf(address) returns (uint256): values[0] is *big.Int or int64
- Signature:
(a *ABI) DecodeFunctionResult(functionName string, data []byte) ([]any, error) - Returns a slice of values in the order of the function’s outputs.
DecodeFunctionResultInto
Decode return data into a struct (or slice of pointers). Field names are matched case-insensitively to ABI output names, or by position.
type ReservesResult struct {
Reserve0 *big.Int
Reserve1 *big.Int
BlockTimestamp uint32
}
var result ReservesResult
err := parsed.DecodeFunctionResultInto("getReserves", returnData, &result)
- Signature:
(a *ABI) DecodeFunctionResultInto(functionName string, data []byte, output any) error
DecodeEventLog
Decode event log topics and data using a parsed ABI. Identifies the event by the first topic (event signature hash) and decodes indexed and non-indexed parameters.
import ("github.com/ethereum/go-ethereum/common""github.com/ChefBingbong/viem-go/abi")// log.Topics and log.Data from eth_getLogs / FilterLogsdecoded, err := parsed.DecodeEventLog(log.Topics, log.Data)if err != nil {log.Fatal(err)}fmt.Println(decoded.EventName) // e.g. "Transfer"fmt.Println(decoded.Args) // map[string]any: "from", "to", "value"fmt.Println(decoded.Topics) // []common.Hashfmt.Println(decoded.Data) // raw data bytes
- Signature:
(a *ABI) DecodeEventLog(topics []common.Hash, data []byte) (*DecodedEventLog, error) - DecodedEventLog has EventName, Args (
map[string]any), Topics, Data. - topics[0] must be the event signature (for non-anonymous events).
DecodeEventLogByName
Decode when you already know the event name:
decoded, err := parsed.DecodeEventLogByName("Transfer", log.Topics, log.Data)
DecodeErrorResult
Decode revert data: standard Error(string) and Panic(uint256) plus custom errors defined on the ABI.
import "github.com/ChefBingbong/viem-go/abi"// errorData is the revert payload from a failed calldecoded, err := parsed.DecodeErrorResult(errorData)if err != nil {log.Fatal(err)}fmt.Println(decoded.ErrorName) // e.g. "InsufficientBalance" or "Error" or "Panic"fmt.Println(decoded.Args) // []anyfmt.Println(decoded.Selector) // [4]byte// decoded.AbiItem is *Error for custom errors, nil for Error(string)/Panic(uint256)
- Signature:
(a *ABI) DecodeErrorResult(data []byte) (*DecodedErrorResult, error) - DecodedErrorResult has ErrorName, Args (
[]any), Selector ([4]byte), AbiItem (*Erroror nil). - DecodeErrorResultWithoutABI(data []byte) decodes only Error(string) and Panic(uint256) without a parsed ABI.
Error handling
Always check decoding errors. Invalid data, wrong length, or mismatched ABI will return descriptive errors (e.g. "function with selector ... not found", "data too short").
decoded, err := parsed.DecodeFunctionData(calldata)
if err != nil {
log.Printf("decode error: %v", err)
return
}
Go notes
- DecodeFunctionData and DecodeEventLog require the ABI to contain the function/event; otherwise they return "not found" errors.
- Event topics are []common.Hash; convert from RPC hex strings if needed (e.g. common.HexToHash).
- Decoded integers may be int64 or *big.Int depending on size; see ABI Types.
See also
- Encoding — EncodeFunctionData, EncodeEventTopics
- Decode Parameters — standalone DecodeAbiParameters
- Types — AbiParam and type mapping
- Selectors — ParseEventLogs for batch decoding