simulateContract
Simulates/validates a contract interaction
This is useful for retrieving return data and revert reasons of contract write functions. This function does not require gas to execute and does not change the state of the blockchain. It is almost identical to ReadContract, but also supports contract write functions.
Import
Import the public actions package so you can call this action.
import "github.com/ChefBingbong/viem-go/actions/public"Usage
An example showing how to simulate a token transfer without sending a real transaction.
import ( "context" "log" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ChefBingbong/viem-go/actions/public" "github.com/ChefBingbong/viem-go/abi" "github.com/ChefBingbong/viem-go/client" "github.com/ChefBingbong/viem-go/client/transport" "github.com/ChefBingbong/viem-go/chain/definitions")
ctx := context.Background()
publicClient, err := client.CreatePublicClient(client.PublicClientConfig{ Chain: definitions.Mainnet, Transport: transport.HTTP("https://eth.llamarpc.com"),})if err != nil { log.Fatal(err)}defer func() { _ = publicClient.Close() }()
// Parse ERC20 ABIerc20ABI, err := abi.ParseABI(`[{"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"type":"bool"}],"type":"function"}]`)if err != nil { log.Fatal(err)}
tokenAddr := common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")senderAddr := common.HexToAddress("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266")recipientAddr := common.HexToAddress("0x70997970c51812dc3a010c7d01b50e0d17dc79c8")
result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Account: &senderAddr, Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)},})if err != nil { log.Fatal(err)}
if result.Result.(bool) { log.Println("Simulation successful!")}Returns
*SimulateContractReturnType
An object containing:
Result any- The decoded return value from the contract callRequest SimulateContractRequest- The request data that can be used for writeContract
Parameters
Configuration options accepted by this action.
Address
- Type:
common.Address - Required
The contract address.
import ( "github.com/ethereum/go-ethereum/common" "github.com/ChefBingbong/viem-go/actions/public")
tokenAddr := common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)},})ABI
- Type:
*abi.ABI - Required
The contract ABI.
import "github.com/ChefBingbong/viem-go/abi"
erc20ABI, err := abi.ParseABI(`[{"inputs":[...],"name":"transfer",...}]`)result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)},})FunctionName
- Type:
string - Required
The name of the function to call.
result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)},})Args
- Type:
[]any - Optional
The function arguments.
import "math/big"
result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)},})Account
- Type:
*common.Address - Optional
The account attached to the call (msg.sender).
senderAddr := common.HexToAddress("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266")result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Account: &senderAddr, Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)},})Value
- Type:
*big.Int - Optional
The amount of wei to send with the call.
import "math/big"
result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)}, Value: big.NewInt(1000000000000000000), // 1 ETH})BlockNumber
- Type:
*uint64 - Optional
The block number to simulate at.
blockNum := uint64(12345)result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)}, BlockNumber: &blockNum,})BlockTag
- Type:
BlockTag - Optional
The block tag to simulate at (e.g., "latest", "pending").
result, err := public.SimulateContract(ctx, publicClient, public.SimulateContractParameters{ Address: tokenAddr, ABI: erc20ABI, FunctionName: "transfer", Args: []any{recipientAddr, big.NewInt(1000000)}, BlockTag: public.BlockTagSafe,})StateOverride
- Type:
types.StateOverride - Optional
State overrides for the call.
BlockOverrides
- Type:
*types.BlockOverrides - Optional
Block-level overrides.
DataSuffix
- Type:
[]byte - Optional
Optional data to append to the calldata. Useful for adding a "domain" tag.
JSON-RPC Method
Underlying JSON-RPC method used by this action.
Uses eth_call with ABI-encoded data.