> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://v3.viem.sh/api/mcp` to find what you need.

# Simulate Contract \[contract.simulate]

Simulates a write function on a contract without broadcasting a transaction. Returns the decoded `result` and a `request` that can be passed to [write](/docs/actions/wallet/contract/write).

Unlike [write](/docs/actions/wallet/contract/write), this action validates the call against current state via `eth_call`. The response surfaces return data and revert reasons.

The call does not require gas or change chain state.

## Usage

This example simulates a write function on a contract without broadcasting a transaction.

:::code-group
```ts twoslash [example.ts]
import { Abi } from 'viem/utils'
import { client } from './viem.config'

const { request, result } = await client.contract.simulate({
  abi: Abi.from(['function mint(uint32 tokenId) returns (uint32)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
// @log: result: 69420

const hash = await client.contract.write(request)
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http, publicActions, walletActions } from 'viem'
import { mainnet } from 'viem/chains'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
})
  .extend(publicActions())
  .extend(walletActions())
```
:::

### Standalone Action

Call `Actions.contract.simulate` directly by passing the Client as the first argument.

:::code-group
```ts twoslash [example.ts]
import { Actions } from 'viem'
import { Abi } from 'viem/utils'
import { client } from './viem.config'

const { request, result } = await Actions.contract.simulate(client, {
  abi: Abi.from(['function mint(uint32 tokenId) returns (uint32)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
// @log: result: 69420

const hash = await Actions.contract.write(client, request)
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http } from 'viem'
import { mainnet } from 'viem/chains'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
})
```
:::

## Recipes

### Simulate a Payable Call

Pass `account` and `value` when the result depends on the sender or native currency amount.

```ts twoslash
import { Client, http, publicActions } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({
  chain: mainnet,
  transport: http(),
}).extend(publicActions())

const { request } = await client.contract.simulate({
  abi: Abi.from(['function deposit() payable']),
  account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus]
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'deposit',
  value: 1n, // [!code focus]
})
```

### Simulate Historical State Changes

Combine a block number with state overrides to simulate temporary changes on top of historical state.

```ts twoslash
import { Client, http, publicActions } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({
  chain: mainnet,
  transport: http(),
}).extend(publicActions())

const account = '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'
const { result } = await client.contract.simulate({
  abi: Abi.from(['function mint() returns (uint256)']),
  account,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blockNumber: 19_760_235n, // [!code focus]
  functionName: 'mint',
  stateOverride: { // [!code focus]
    [account]: { // [!code focus]
      balance: 1000000000000000000n, // [!code focus]
    }, // [!code focus]
  }, // [!code focus]
})
```

## Return Value

`{ request, result }`

* `result`: the decoded return value of the simulated function. The type is inferred from the `abi` and `functionName`.
* `request`: a write request (with the ABI minimized to the called function) that can be passed to [write](/docs/actions/wallet/contract/write).

## Parameters

### abi

* **Type:** `Abi`

The contract's ABI. The `functionName` and `args` are inferred from it.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi: Abi.from(['function mint(uint32 tokenId) returns (uint32)']), // [!code focus]
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
```

### account

* **Type:** `Account | Address`
* **Default:** `client.account`

The account to simulate the call from (`msg.sender`). Falls back to the account configured on the client.

```ts twoslash
import { Account, Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId) returns (uint32)'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  account: Account.fromPrivateKey('0x…'), // [!code focus]
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
```

### address

* **Type:** `Address`

The address of the contract.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId) returns (uint32)'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus]
  args: [69420],
  functionName: 'mint',
})
```

### args

* **Type:** Inferred from `abi` and `functionName`.

The arguments to pass to the contract function.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi: Abi.from(['function mint(uint32 tokenId) returns (uint32)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420], // [!code focus]
  functionName: 'mint',
})
```

### as

* **Type:** `'Object' | 'Array'`
* **Default:** `'Object'`

The shape to use when the function returns multiple named values.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi: Abi.from([
    'function mint() returns (uint256 tokenId, address owner)',
  ]),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  as: 'Array', // [!code focus]
  functionName: 'mint',
})
```

### authorizationList

* **Type:** `AuthorizationList`

The signed EIP-7702 authorization list to attach to the call.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  authorizationList: [ // [!code focus]
    { // [!code focus]
      address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus]
      chainId: 1, // [!code focus]
      nonce: 0n, // [!code focus]
      r: '0x...', // [!code focus]
      s: '0x...', // [!code focus]
      yParity: 0, // [!code focus]
    }, // [!code focus]
  ], // [!code focus]
  functionName: 'mint',
})
```

### blockHash

* **Type:** `Hex`

The hash of the block whose state to use for the simulation.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blockHash: '0x89644bbd5c8d682a2e9611170e6c1f02573d866d286f006cbf517eec7254ec2d', // [!code focus]
  functionName: 'mint',
})
```

### blockNumber

* **Type:** `bigint`

The number of the block whose state to use for the simulation.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blockNumber: 42069n, // [!code focus]
  functionName: 'mint',
})
```

### blockOverrides

* **Type:** `BlockOverrides`

The block fields to override for the simulation.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blockOverrides: { // [!code focus]
    baseFeePerGas: 1_000_000_000n, // [!code focus]
  }, // [!code focus]
  functionName: 'mint',
})
```

### blockTag

* **Type:** `'latest' | 'earliest' | 'pending' | 'safe' | 'finalized'`
* **Default:** `client.blockTag ?? 'latest'`

The block tag whose state to use for the simulation.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blockTag: 'pending', // [!code focus]
  functionName: 'mint',
})
```

### code

* **Type:** `Hex`

The bytecode to execute without deploying it. Pass `code` instead of `address`.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi: Abi.from(['function mint()']),
  code: '0x6080604052...', // [!code focus]
  functionName: 'mint',
})
```

### dataSuffix

* **Type:** `Hex`
* **Default:** `client.dataSuffix`

The data to append to the encoded calldata.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  dataSuffix: '0xdeadbeef', // [!code focus]
  functionName: 'mint',
})
```

### factory

* **Type:** `Address`

The factory address for a deployless simulation. Pass [`factoryData`](#factorydata) and the counterfactual contract `address`.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  factory: '0xE8Df82fA4E10e6A12a9Dab552bceA2acd26De9bb', // [!code focus]
  factoryData: '0x...',
  functionName: 'mint',
})
```

### factoryData

* **Type:** `Hex`

The calldata that the factory uses to deploy the counterfactual contract.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  factory: '0xE8Df82fA4E10e6A12a9Dab552bceA2acd26De9bb',
  factoryData: '0x...', // [!code focus]
  functionName: 'mint',
})
```

### functionName

* **Type:** Inferred from `abi`.

The name of the function to call on the contract.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId) returns (uint32)'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint', // [!code focus]
})
```

### requestOptions

* **Type:** `{ dedupe?: boolean; signal?: AbortSignal; ... }`

The options to pass to the underlying transport request.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
const controller = new AbortController()
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  requestOptions: { signal: controller.signal }, // [!code focus]
})
```

### requireCanonical

* **Type:** `boolean`
* **Default:** `false`

Whether the block selected by [`blockHash`](#blockhash) must be in the canonical chain.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blockHash: '0x89644bbd5c8d682a2e9611170e6c1f02573d866d286f006cbf517eec7254ec2d',
  functionName: 'mint',
  requireCanonical: true, // [!code focus]
})
```

### stateOverride

* **Type:** `StateOverrides`

The [state overrides](/docs/actions/public/call#stateoverride) to apply for the simulation.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId) returns (uint32)'])
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
  stateOverride: { // [!code focus]
    '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2': { balance: 1n }, // [!code focus]
  }, // [!code focus]
})
```

### value

* **Type:** `bigint | number | Hex`

The value (in wei) to send with the call. Only available on `payable` functions.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi, Value } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const { result } = await Actions.contract.simulate(client, {
  abi: Abi.from(['function mint(uint32 tokenId) payable returns (uint32)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
  value: Value.fromEther('0.01'), // [!code focus]
})
```

## Errors

| Error | Description |
| --- | --- |
| `ContractError.ContractFunctionExecutionError` | The contract function could not be executed. Its `cause` is `ContractError.ContractFunctionRevertedError` for a revert or `ContractError.ContractFunctionZeroDataError` when the call returns no data. |
