Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Launching a Transaction Simulation and Preview Feature

Implement a pre-execution engine to show users transaction outcomes, costs, and risks before signing. Covers integration with Tenderly, custom services, and result parsing.
Chainscore © 2026
introduction
INTRODUCTION

Launching a Transaction Simulation and Preview Feature

Transaction simulation allows developers to test and preview the outcome of a blockchain transaction before it is finalized, reducing risk and improving user experience.

A transaction simulation is a read-only execution of a smart contract call or transfer on a forked version of the blockchain state. It processes the transaction exactly as it would on-chain—including all state changes, event emissions, and gas usage—but without broadcasting it to the network. This is a critical tool for developers building wallets, dApps, and DeFi protocols, as it enables features like gas estimation, balance checks, and failure previews. Services like Tenderly, OpenZeppelin Defender, and the Hardhat network fork provide robust simulation environments.

Implementing a simulation typically involves using a JSON-RPC method such as eth_call for EVM chains. This method executes the transaction against a specified block (often the latest) and returns the result data without modifying the chain state. For a more detailed preview, including a full trace of internal calls and state diffs, providers offer enhanced APIs. For example, simulating a token swap on Uniswap V3 would reveal the exact output amount, the path taken through liquidity pools, and the total gas consumed by the transaction.

The primary benefit is risk mitigation. Users can see if a transaction will fail due to insufficient funds, slippage tolerance, or a reverted smart contract before signing and paying gas. For developers, it's indispensable for testing complex interactions in staging environments. A common implementation pattern is to intercept a user's transaction request in a wallet, simulate it via a backend service or RPC provider, and then display a clear preview of the outcome, including token balance changes and potential errors.

To build a preview feature, you need to parse the simulation result into a human-readable format. This involves decoding the transaction data to understand the called function, interpreting the returned data, and calculating the final state changes. For ERC-20 transfers, this means showing the sender's new balance. For swaps, it means displaying input/output amounts and price impact. Libraries like ethers.js and viem provide utilities for decoding ABI-encoded data, which is essential for this parsing step.

Advanced simulation can also assess MEV (Maximal Extractable Value) risks and sandwich attack vulnerability by analyzing the simulated mempool state. Security-focused previews might warn a user if their large DEX swap is likely to be front-run. As blockchain interactions grow more complex, transaction simulation and preview have evolved from a nice-to-have to a security necessity, forming the backbone of safer and more transparent Web3 applications.

prerequisites
GETTING STARTED

Prerequisites

Before you can launch a transaction simulation and preview feature, you'll need to set up the foundational tools and accounts. This section covers the essential requirements.

To begin, you need a blockchain development environment. This typically includes Node.js (version 18 or later) and a package manager like npm or Yarn. You'll also need a code editor such as Visual Studio Code. For interacting with blockchains, install a command-line tool like the Foundry toolkit (forge, cast, anvil) or Hardhat. These tools provide local test networks and utilities for compiling and deploying smart contracts, which are essential for testing your simulation logic.

Next, you must obtain API keys for simulation services. Most simulation features rely on external providers like Tenderly, Alchemy's simulate endpoint, or Blocknative. You will need to create free accounts on their respective platforms to generate API keys. For example, Tenderly offers a developer plan with a generous simulation quota. Store these keys securely using environment variables (e.g., in a .env file) and never commit them to version control.

You also need a basic understanding of Ethereum transaction structure. A simulation replays a transaction's logic, so you should be familiar with core fields: from (sender address), to (contract address), value (ETH amount), data (encoded function call), and gas. Understanding how these components interact with a smart contract's state is crucial for interpreting simulation results and debugging potential failures.

Finally, ensure you have access to blockchain data. Your application will need to fetch current state, such as token balances or contract storage, to create accurate simulations. You can use a node provider like Alchemy, Infura, or a public RPC endpoint. For mainnet-fork testing, tools like Foundry's anvil or Hardhat Network allow you to fork the Ethereum mainnet at a specific block, giving you a realistic environment with real contract states to test against.

key-concepts-text
DEVELOPER GUIDE

How Transaction Simulation Works

Transaction simulation allows developers to test and preview the outcome of a blockchain transaction before it is finalized, preventing costly errors and improving user experience.

Transaction simulation is a deterministic execution of a smart contract call using a node's current state, but without broadcasting the transaction to the network. It answers the critical question: "What would happen if I sent this transaction right now?" This process is essential for building safe applications, as it allows you to preview potential state changes, gas costs, and even revert reasons without spending real gas or risking funds. Major RPC providers like Alchemy, Infura, and QuickNode offer simulation endpoints, such as eth_call on Ethereum or simulateTransaction on Solana.

To launch a simulation, you send a transaction object—including the from address, to (contract address), data (encoded function call), and value—to a node's simulation endpoint. The node executes the call against a virtual machine (EVM, SVM, etc.) using the latest block's state. It returns the result as if the transaction were included in that block. This result includes the return data, estimated gas used, and any logs emitted. Crucially, the simulation can also detect and report reverts, allowing you to see error messages like "Insufficient balance" or "Ownable: caller is not the owner" before the user signs anything.

Implementing a preview feature involves integrating this simulation call into your application's frontend or backend workflow. A common pattern is to simulate a transaction immediately after a user fills out a form in a dApp interface. For example, before a user approves a token spend or submits a swap, your code can call provider.call(transactionObject) to check for success and display an estimated outcome. This builds user trust by showing exact token amounts they will receive, potential slippage, or clear warnings about why an action would fail. Libraries like viem and ethers.js abstract these RPC calls into simple methods like simulateContract.

Advanced simulation techniques go beyond single-state checks. State overrides allow you to simulate "what-if" scenarios by modifying the blockchain state for the simulation only, such as testing with a different user balance. Block overrides let you simulate future conditions, like executing a transaction at a specific block number or with a different base fee. These tools are invaluable for developers building complex DeFi strategies or testing smart contract interactions under various market conditions without deploying to a testnet.

While powerful, simulations have limitations. They cannot predict outcomes that depend on future state, such as the result of a transaction that would be included in a later block where other interactions occur. They also rely on the accuracy of the node's state, which in rare cases of chain reorgs may be temporary. Therefore, simulation should be used as a robust pre-check, not an absolute guarantee. Always implement proper error handling for the live transaction broadcast, as network conditions can change between simulation and submission.

TECHNICAL SPECS

Transaction Simulation Provider Comparison

A comparison of leading providers for integrating transaction simulation and preview into wallets and dApps.

Feature / MetricTenderlyBlocknativeBlowfishOpenZeppelin Defender

Simulation Method

Full EVM fork

Mempool + local fork

Local EVM execution

Ganache fork via API

Supported Chains

Ethereum, Polygon, Arbitrum, 15+

Ethereum, Polygon, BSC

Ethereum, Solana, 10+ EVM L2s

Ethereum, Polygon, Arbitrum

Risk Detection

Gas Estimation

High accuracy with historical data

Real-time mempool based

Scenario-based projection

Basic estimation

Average API Latency

< 300 ms

< 500 ms

< 200 ms

< 800 ms

Cost Model

Tiered SaaS, free tier available

Pay-per-simulation

Freemium API calls

Bundled with Defender suite

State Overrides

Fraudulent Signature Detection

implement-tenderly-simulation
DEVELOPER TUTORIAL

Implementing Simulation with Tenderly API

A step-by-step guide to integrating Tenderly's simulation API for previewing and validating blockchain transactions before execution.

Transaction simulation is a critical tool for Web3 developers, allowing you to dry-run smart contract interactions and predict outcomes without spending gas or risking funds on mainnet. The Tenderly API provides a robust platform for this, enabling you to simulate any transaction on multiple EVM-compatible networks like Ethereum, Arbitrum, and Polygon. By using simulation, you can catch errors, estimate gas costs, and verify state changes, which is essential for building secure applications, testing complex DeFi strategies, or creating user-facing preview features.

To get started, you need a Tenderly account and a project. Navigate to the Tenderly Dashboard, create a project, and generate an Access Token with appropriate permissions. Your API requests will authenticate using this token in the header: X-Access-Key: YOUR_ACCESS_KEY. The core simulation endpoint is POST https://api.tenderly.co/api/v1/account/{account}/project/{project}/simulate. You must construct a JSON payload specifying the network ID, from and to addresses, input data, and optionally, the value and gas parameters.

Here is a basic Node.js example using the axios library to simulate a simple ETH transfer. This code sends a request to Tenderly's API and logs the transaction's status and gas used.

javascript
const axios = require('axios');
const SIM_URL = 'https://api.tenderly.co/api/v1/account/myTeam/project/myProject/simulate';
const headers = { 'X-Access-Key': process.env.TENDERLY_ACCESS_KEY };

const simulationConfig = {
  "network_id": "1", // Mainnet
  "from": "0x742d35Cc6634C0532925a3b844Bc9e...",
  "to": "0x742d35Cc6634C0532925a3b844Bc9e...",
  "input": "0x", // Empty data for simple transfer
  "value": "1000000000000000000", // 1 ETH in wei
  "gas": 21000,
  "save": true // Persists simulation in dashboard
};

axios.post(SIM_URL, simulationConfig, { headers })
  .then(res => {
    console.log('Status:', res.data.transaction.status);
    console.log('Gas Used:', res.data.transaction.gas_used);
  })
  .catch(console.error);

For more complex interactions, such as calling a specific function on a smart contract, you must provide the correct input data. This is the encoded function selector and arguments. You can generate this using ethers.js or web3.js. For instance, to simulate a call to the transfer function of an ERC-20 token, you would encode the function call transfer(address,uint256). The simulation response is rich with data, including the final state diff (showing storage changes), emitted events, logs, and a detailed trace. This allows you to programmatically verify that a swap on Uniswap would succeed or that a mint operation would not revert.

A powerful application is building a transaction preview for end-users. Before a user signs a transaction in your dApp's wallet, you can simulate it in the background using Tenderly's API and display a predicted outcome. For example, you could show: "This swap will give you approximately 1.5 ETH" or "Warning: This transaction is expected to revert due to insufficient liquidity." This enhances user experience and safety. Remember to handle simulation failures gracefully and consider using Tenderly's forking feature for simulations that depend on a specific historical or future blockchain state.

When implementing at scale, consider rate limits, error handling, and caching strategies. Tenderly offers different pricing tiers with varying request quotas. For production use, simulate transactions in a non-blocking manner to avoid UI delays. Always use environment variables for your access keys and consider setting the save flag to false for high-volume simulations to manage your project's storage. By integrating simulation, you move from reactive debugging to proactive validation, significantly improving the reliability and user trust in your blockchain application.

building-custom-simulator
DEVELOPER GUIDE

Launching a Transaction Simulation and Preview Feature

Implement a service that allows users to preview transaction outcomes before signing, reducing errors and improving security.

Transaction simulation is a critical tool for user safety in Web3. It involves executing a transaction in a controlled, sandboxed environment—typically a forked version of the blockchain—to determine its outcome without broadcasting it to the main network. This allows users to see exactly what will happen: token transfers, contract state changes, and most importantly, potential failures or unexpected side effects. Services like Tenderly, OpenZeppelin Defender, and the Chainscore API provide this functionality, which is essential for building secure wallets, dApp dashboards, and developer tooling.

To build a custom simulation service, you need three core components: an RPC provider to access blockchain data, an execution environment to run the simulation, and a result parser to present the data. Start by forking the state of the target chain at a specific block using a node provider like Alchemy or Infura. Then, use the eth_call RPC method or a dedicated simulation SDK to execute the transaction against this forked state. The simulation will return a detailed trace, showing every opcode executed, gas used, and state changes, which you can then analyze for the user.

Handling complex transactions requires careful state management. For simulations involving DeFi interactions like swaps on Uniswap V3 or loans on Aave, you must ensure the forked state includes the latest contract data and price oracles. You should also simulate common failure modes: slippage tolerance breaches, insufficient liquidity, or insufficient approval allowances. Implementing a pre-flight check that validates user balances and contract approvals before the main simulation can save computational resources and provide faster feedback.

Here's a basic code example using the Ethers.js library and a simulation endpoint. This snippet simulates a simple ETH transfer.

javascript
const { ethers } = require('ethers');

async function simulateTransaction(tx) {
  // Connect to a provider with simulation support (e.g., Tenderly)
  const provider = new ethers.providers.JsonRpcProvider('YOUR_SIMULATION_RPC_URL');
  
  // Perform the call
  try {
    const result = await provider.call(tx);
    console.log('Simulation successful. Result:', result);
    // Parse the result to determine token balances, etc.
  } catch (error) {
    console.error('Simulation failed:', error.reason);
    // Extract revert reason for user feedback
  }
}

// Example transaction object
const tx = {
  to: '0xRecipientAddress',
  value: ethers.utils.parseEther('1.0'),
  from: '0xSenderAddress'
};

simulateTransaction(tx);

This provides the raw output, which you'll need to decode based on the target contract's ABI.

After obtaining the raw simulation data, the final step is result interpretation and user presentation. Transform the low-level call traces into a human-readable preview. This should clearly show: net balance changes for all affected tokens (using the token's decimals), estimated gas cost in USD and native currency, and a risk assessment highlighting any approvals to untrusted contracts or large slippage. Integrating this feature directly into a wallet's confirmation dialog or a dApp's interface significantly reduces user error and builds trust, as seen in popular wallets like Rabby and Rainbow.

parsing-displaying-results
TUTORIAL

Parsing and Displaying Simulation Results

Learn how to interpret the output of a transaction simulation and build a user-friendly preview interface for your dApp.

A transaction simulation returns a detailed object containing the projected state changes of a transaction before it is broadcast. This object, often called a SimulationResult, includes key data points like the final account balances, token transfers, executed instructions, and the overall success or failure status. Parsing this data correctly is essential for providing users with a clear, accurate preview of what their transaction will do. The structure of this result varies by provider (e.g., Helius, Jito, Blink), but core concepts remain consistent across platforms.

The most critical component to parse is the list of balance changes. This shows the net difference in SOL or SPL token balances for all accounts involved. For example, a swap simulation might show a decrease in USDC and an increase in SOL for the user's wallet. You should extract the preBalance and postBalance for each account, calculate the delta, and filter to show only the changes relevant to the user. This forms the basis of a transaction summary.

Beyond balances, inspect the logs and instructions arrays. The logs provide a human-readable trace of program execution, which is invaluable for debugging failed simulations. The instructions detail the exact program calls made, including the program ID, accounts involved, and data passed. Parsing these helps verify the transaction's intent—confirming it calls the expected smart contract with the correct parameters.

To display this data, design a preview component that highlights the outcome. A common pattern includes: a status badge (Success/Failure/Error), a summary of net asset changes (e.g., '-5.2 USDC, +0.01 SOL'), and a detailed, expandable view showing logs and account interactions. For security, always display the simulated compute units (CU) and prioritization fee; this shows users the expected network cost and helps prevent unexpected failures.

Implementing this requires handling the simulation provider's specific API response. Here's a simplified TypeScript example for parsing a generic result:

typescript
interface BalanceChange {
  account: string;
  mint: string;
  preBalance: number;
  postBalance: number;
}

function parseSimulation(result: any): {
  success: boolean;
  balanceChanges: BalanceChange[];
  logs: string[];
} {
  return {
    success: result.value.err === null,
    balanceChanges: result.value.accounts?.map((acc: any) => ({
      account: acc.pubkey,
      mint: acc.mint,
      preBalance: acc.preBalance,
      postBalance: acc.postBalance,
    })) || [],
    logs: result.value.logs || [],
  };
}

Finally, integrate error handling for simulation failures. Common reasons include insufficient balance, slippage tolerance exceeded, or an invalid program instruction. Parse the error object from the simulation result and present a clear, actionable message to the user. This transforms a cryptic blockchain error into guidance, such as 'Increase your SOL balance by 0.05 to cover fees' or 'The swap price moved; try again.' Effective parsing and display build user trust and reduce failed transaction submissions.

TRANSACTION SIMULATION

Handling Edge Cases and Reverts

Transaction simulation helps developers predict outcomes before broadcasting. This guide covers common failure modes and how to interpret simulation results to handle reverts, gas issues, and state changes.

This discrepancy is often caused by state changes between simulation and broadcast. A simulation uses a specific block state. If another transaction alters that state (e.g., drains a liquidity pool, changes an approval), your real transaction may revert.

Common causes:

  • Front-running: A bot executes a similar transaction with higher gas.
  • Slippage: Price impact differs due to pool reserves changing.
  • Time-dependent logic: Contracts using block.timestamp or block.number.
  • Missing approvals: Simulating from an EOA that hasn't granted token approval.

Mitigation: Use recent block hashes for simulation, implement deadline checks, and consider simulating with a slight buffer for slippage.

DATA FIELDS

Simulation Output Data Structure

Key data points returned by a transaction simulation, used for previewing outcomes and assessing risk.

FieldTypeDescriptionExample Value

status

string

Final execution status of the simulated transaction.

"success" or "reverted"

gasUsed

number

Total gas units consumed during the simulation.

21000

gasCost

string

Estimated cost of gas in the native token (e.g., ETH).

0.0015 ETH

balanceChanges

array

List of token balance changes for the sender and involved addresses.

[{address: "0x...", delta: "-1.5 ETH"}]

stateChanges

array

Detailed changes to smart contract storage and event logs.

[{contract: "0x...", key: "balance", value: "100"}]

revertReason

string

Error message if the transaction reverted, null on success.

"Insufficient funds for transfer"

simulationId

string

Unique identifier for this simulation run for debugging.

"sim_abc123xyz"

TRANSACTION SIMULATION

Frequently Asked Questions

Common questions and solutions for developers implementing transaction simulation and preview features in their Web3 applications.

Transaction simulation is the process of executing a transaction in a virtual, isolated environment before it is broadcast to the live network. It uses a fork of the target blockchain's state to predict the outcome without spending real gas or altering the mainnet.

This is critical for:

  • User Experience: Showing users exactly what will happen (e.g., token amounts received, approvals granted) before they sign.
  • Security: Detecting potential failures, unexpected reverts, or malicious interactions.
  • Cost Estimation: Providing accurate gas estimates and total cost breakdowns.

Tools like Tenderly, OpenZeppelin Defender, and Blocknative offer simulation APIs that have become a standard for safe dApp interaction.

conclusion
IMPLEMENTATION GUIDE

Conclusion and Next Steps

You have successfully implemented a transaction simulation and preview feature. This guide summarizes the key benefits and outlines practical next steps to enhance your application's security and user experience.

Integrating a transaction simulation API like Chainscore's provides a critical safety layer for your users. By previewing outcomes—including token transfers, approvals, and potential failures—you prevent costly mistakes and build trust. This feature is essential for any application handling user funds, from DeFi protocols to NFT marketplaces. It transforms the user experience from a leap of faith into an informed interaction.

To maximize the value of this feature, consider these next steps:

1. Enhance UI/UX Feedback

Go beyond simple success/failure messages. Display a detailed breakdown of simulated state changes: token balances before/after, new approvals granted, and estimated gas costs. Visual diff indicators can make changes instantly understandable.

2. Implement Risk Scoring

Leverage the simulation data to flag high-risk actions automatically. This includes detecting interactions with newly deployed or unaudited contracts, unexpectedly large approvals, or transactions that would drain a wallet's balance.

For advanced use cases, you can build upon the simulation foundation. Develop a "dry-run" mode for power users to test complex transaction sequences. Use historical simulation data to train a model that predicts transaction failure rates for common patterns. Furthermore, integrate simulation checks into backend services to screen transactions before they are broadcast to the public mempool, adding a security filter for your application's own bots or automation.

The simulation response is a rich data source. Log and analyze it to gain insights into common user errors, which can inform better error messages or UI design. Monitor for patterns of malicious transaction attempts targeting your app. This data is invaluable for iteratively improving both security and usability.

Finally, stay updated with the evolving landscape. As new transaction types (like EIP-4337 account abstraction) and chains emerge, ensure your simulation provider supports them. Regularly review and test your integration. Resources like the Chainscore Documentation and community forums are excellent places to track best practices and new features.

How to Add Transaction Simulation and Preview to Your Dapp | ChainScore Guides