simulateContract
Simulates/validates a contract interaction
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 the public actions package so you can call this action.
import "github.com/ChefBingbong/viem-go/actions/public"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!")}*SimulateContractReturnType
An object containing:
Result any - The decoded return value from the contract callRequest SimulateContractRequest - The request data that can be used for writeContractConfiguration options accepted by this action.
common.AddressThe 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.ABIThe 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)},})stringThe 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)},})[]anyThe 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)},})*common.AddressThe 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)},})*big.IntThe 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})*uint64The 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,})BlockTagThe 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,})types.StateOverrideState overrides for the call.
*types.BlockOverridesBlock-level overrides.
[]byteOptional data to append to the calldata. Useful for adding a "domain" tag.
Underlying JSON-RPC method used by this action.
Uses eth_call with ABI-encoded data.