Skip to main content
Version: v3.0.0-nightly.20250919

Simulating Functions

This guide shows you how to simulate function calls to read contract state.

Prerequisites

  • Deployed contract address and ABI
  • Wallet or PXE connection
  • Understanding of contract functions

Connect to a contract

Let's say you've connected to a contract, for example:

import { Contract } from "@aztec/aztec.js";

const contract = await Contract.at(contractAddress, artifact, wallet);

or

import { MyContract } from './artifacts/MyContract';

const contract = await MyContract.at(contractAddress, wallet);

Simulate public functions

Step 1: Call a public view function

const result = await contract.methods.get_public_value(param1)
.simulate({ from: callerAddress }); // assuming callerAddress is already registered on the wallet, i.e. wallet.createSchnorrAccount(caller.secret, caller.salt)

console.log('Public value:', result);

Step 2: Handle return values

const result = await contract.methods
.get_multiple_values()
.simulate({ from: callerAddress });

// Destructure if returning multiple values
const [value1, value2] = result;

Simulate private functions

Step 1: Call a private view function

const privateResult = await contract.methods.get_private_balance(ownerAddress)
.simulate({ from: ownerAddress });

Step 2: Access private notes

// Private functions can access the caller's private state
const notes = await contract.methods.get_my_notes()
.simulate({ from: ownerAddress });
warning

Private simulations only work if the caller has access to the private state being queried.

Simulate utility functions

Step 1: Call utility function

const result = await contract.methods.compute_value(input1, input2)
.simulate({ from: account.address });

console.log('Computed value:', result);

Step 2: Use utility functions for complex queries

const aggregatedData = await contract.methods.get_aggregated_stats(
startBlock,
endBlock
).simulate({ from: account.address });

// Returns structured data based on function signature
console.log('Stats:', aggregatedData);

Simulate with different contexts

Simulate from different addresses

// Simulate as different users to test access control
const asOwner = await contract.methods.admin_function()
.simulate({ from: ownerAddress });

try {
const asUser = await contract.methods.admin_function()
.simulate({ from: userAddress });
} catch (error) {
console.log('User cannot access admin function');
}

Next steps