ABI Decoding
Decode function calldata, return data, event logs, and errors for contract calls in viem-go
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 ( "encoding/hex" "github.com/ethereum/go-ethereum/common" "github.com/ChefBingbong/viem-go/abi")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(a *ABI) DecodeFunctionData(data []byte) (*DecodedFunctionData, error)[]any), Selector ([4]byte).Decode calldata when you already know the function name (still expects selector + args):
args, err := parsed.DecodeFunctionDataByName("transfer", calldata)
// args is []any
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)
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(a *ABI) DecodeFunctionResult(functionName string, data []byte) ([]any, error)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)
(a *ABI) DecodeFunctionResultInto(functionName string, data []byte, output any) errorDecode 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(a *ABI) DecodeEventLog(topics []common.Hash, data []byte) (*DecodedEventLog, error)map[string]any), Topics, Data.Decode when you already know the event name:
decoded, err := parsed.DecodeEventLogByName("Transfer", log.Topics, log.Data)
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)(a *ABI) DecodeErrorResult(data []byte) (*DecodedErrorResult, error)[]any), Selector ([4]byte), AbiItem (*Error or nil).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
}