Skip to main content
Version: Devnet (v3.0.0-devnet.20251212)

Simulating Functions

This guide shows you how to use simulate to execute contract functions and read their return values without creating a transaction.

Prerequisites

Overview

The simulate method executes a contract function locally and returns its result. It works with private, public, and utility functions. No transaction is created and no gas is spent.

const result = await contract.methods.myFunction(arg1, arg2).simulate({ from: callerAddress });

The from option specifies which address context to use for the simulation. This is required for all simulations.

Basic simulation

const balance = await contract.methods
.balance_of_public(newAccountAddress)
.simulate({ from: newAccountAddress });

expect(balance).toEqual(1n);

Handling return values

For functions returning multiple values, destructure the result:

const [value1, value2] = await contract.methods
.get_multiple_values()
.simulate({ from: callerAddress });

Including metadata

Set includeMetadata: true to get additional information about the simulation:

const result = await contract.methods
.balance_of_public(address)
.simulate({ from: callerAddress, includeMetadata: true });

// Result includes:
// - result: the function return value
// - stats: execution statistics (timing, circuit sizes)
// - offchainEffects: any offchain effects emitted
// - estimatedGas: gas limit estimates
console.log("Balance:", result.result);
console.log("Estimated gas:", result.estimatedGas);

Private function considerations

When simulating private functions, the caller must have access to any private state being read. The PXE only has visibility into notes belonging to registered accounts.

// This works if callerAddress owns the notes
const balance = await contract.methods
.balance_of_private(callerAddress)
.simulate({ from: callerAddress });

// This fails if callerAddress doesn't have access to otherAddress's notes
const otherBalance = await contract.methods
.balance_of_private(otherAddress)
.simulate({ from: callerAddress }); // Error: cannot access private state
warning

Simulation runs locally without generating proofs. No correctness guarantees are provided on the result. See Call Types for more details.

Next steps