Testing and simulating Michelson contracts is not a best practice on Tezos—it is a deployment prerequisite. Because Michelson contracts are immutable once originated, any logic error, incorrect entrypoint guard, or gas inefficiency becomes a permanent liability. The Tezos protocol provides two primary pre-deployment validation surfaces: the run_script RPC for dry-running contract execution against a block context, and the simulate_operation RPC for pre-flighting full operations including gas consumption, storage updates, and balance effects. Development teams that skip simulation or rely solely on unit tests without protocol-level validation risk originating contracts that fail under live network conditions, lock user funds, or exhibit gas behavior that makes them economically unusable.

Testing and Simulating Michelson Contracts
Introduction
Why testing and simulating Michelson contracts is a hard requirement for Tezos development teams before mainnet origination.
The operational workflow for high-assurance contract development combines off-chain testing frameworks with protocol-native simulation. Frameworks such as Octez's built-in interpreter, the pytezos testing toolkit, and mock environments built on Flextesa sandboxes allow developers to validate Michelson logic against controlled ledger states. These tools catch entrypoint dispatch errors, type mismatches, and arithmetic bugs before the contract reaches a testnet. However, sandbox testing alone cannot replicate mainnet mempool dynamics, baker behavior, or gas cost variability. The simulate_operation RPC fills this gap by executing the signed operation against the actual protocol state, returning the exact storage diff, balance changes, internal operation results, and consumed gas—all without requiring a baker to include the operation in a block.
For high-value contracts—DeFi protocols, custody solutions, FA2 token implementations, and smart rollup kernels—the gap between simulation and formal verification is where material risk accumulates. Simulation validates behavior against a specific block state; it does not prove correctness across all possible inputs or adversarial conditions. Chainscore Labs provides pre-deployment review that combines simulation trace analysis with manual inspection of Michelson control flow, storage layout, and gas consumption patterns. Teams originating contracts that manage significant user funds or enforce complex permission logic should treat simulation as a necessary but insufficient step, and pair it with independent review before mainnet origination.
Validation Tooling Quick Facts
Operational facts for development teams evaluating Michelson contract logic before mainnet deployment using testing frameworks, mock environments, and Tezos client RPCs.
| Area | What changes | Who is affected | Action |
|---|---|---|---|
Simulation RPCs | Use of /chains/main/blocks/head/helpers/scripts/run_script and simulate_operation to pre-flight contract calls and originations. | Smart contract developers, exchange engineers, custody teams | Integrate simulation into CI/CD pipelines to predict gas costs and storage updates before signing. |
Mock Environments | Local sandboxes (e.g., Flextesa) and ephemeral testnets for stateful integration testing without spending tez. | dApp developers, QA engineers | Validate multi-contract interactions and entrypoint behavior in isolated environments before testnet deployment. |
Testing Frameworks | Frameworks like PyTezos and Taquito provide high-level APIs for unit testing Michelson entrypoints and on-chain views. | Application developers, protocol architects | Adopt a framework that supports property-based testing to catch edge cases in contract logic. |
Gas Estimation | Simulation provides gas consumption estimates, but complex dependent operations may cause out-of-gas failures on mainnet. | DeFi protocol teams, wallet providers | Apply a safety margin to simulated gas limits and monitor mainnet gas trends for dynamic operation costs. |
Storage Validation | Simulating originations reveals final storage layout, including big_map IDs, but does not guarantee indexer compatibility. | Indexer operators, data teams | Verify that simulated storage schemas match indexer parsing logic and TZIP-16 metadata expectations. |
Failure Mode Analysis | Simulation can miss failures caused by chain state changes between simulation and inclusion (e.g., spent tickets, updated big_maps). | High-value contract deployers, auditors | Treat simulation as a necessary but insufficient check; combine with formal review for liveness and state-dependency risks. |
Pre-Deployment Review | Simulation does not validate business logic correctness, authorization flaws, or compliance with FA standards. | Protocol architects, governance multisig signers | Engage Chainscore Labs for a comprehensive review of contract logic, upgradeability patterns, and integration risks before mainnet activation. |
The Validation Surface
Understanding the scope and limits of testing and simulation for Michelson contracts is the first step toward a reliable deployment.
Testing and simulating Michelson contracts on Tezos is not a single-step activity but a layered validation surface that spans local unit tests, integration tests against sandboxed nodes, and pre-flight simulation of operations against a live or testnet node. Each layer validates a different property: unit tests verify logical correctness of entrypoints in isolation, sandboxed environments test contract interactions and gas consumption under controlled conditions, and the simulate_operation RPC validates a specific operation's effects—including balance changes, storage updates, and internal operation emissions—without requiring a signature or on-chain inclusion. Teams that treat these layers as complementary rather than interchangeable catch more failure modes before mainnet risk is introduced.
The run_script and simulate_operation RPCs are the most operationally critical tools for pre-deployment validation. run_script executes a Michelson script against a given parameter and storage, returning the resulting storage and operations, but it does so without any chain context—no balance checks, no block level, no sender address. This makes it ideal for pure logic testing but insufficient for catching failures that depend on runtime context. simulate_operation, by contrast, executes the operation in the context of a specific block, validating the sender's balance, the contract's current state, and the effects of any internal operations. The simulation returns the exact storage diff, balance updates, and gas consumption that would occur if the operation were applied, making it the closest approximation to a real execution. However, simulation is not immune to state divergence: if the node's view of the chain is stale or if a prior operation in the same block alters the contract state, the simulation result may not match the final on-chain outcome.
For high-value contracts—those managing significant assets, implementing complex governance, or serving as infrastructure for other protocols—the validation surface must extend beyond automated testing and simulation. Formal verification of Michelson contracts using tools like Mi-Cho-Coq can prove the absence of entire classes of bugs, while manual review by security engineers can identify logic errors, access control gaps, and economic attack vectors that testing frameworks miss. Chainscore Labs provides protocol impact assessments and smart contract reviews that examine the full validation surface: from unit test coverage and simulation fidelity to formal correctness arguments and integration risk with wallets, indexers, and bridges. Teams preparing for a mainnet deployment should treat pre-deployment review not as a final checkbox but as the last layer of validation before real value is exposed.
Who Needs This Workflow
Pre-Deployment Validation
Michelson developers must validate contract logic before mainnet origination to prevent immutable bugs and fund loss. This workflow is critical for catching errors in entrypoint dispatch, storage updates, and gas consumption that unit tests alone may miss.
Key actions:
- Use
run_scriptto test individual entrypoints against expected storage and parameter inputs. - Use
simulate_operationto validate full transaction lifecycles including gas costs, balance effects, and internal operation generation. - Integrate simulation into CI/CD pipelines to catch regressions when contract logic changes.
For high-value contracts, simulation should be paired with formal review. Chainscore Labs can assess simulation coverage, identify untested edge cases, and verify that test scenarios match the contract's intended security model.
Validation Workflow Components
A structured validation pipeline for Michelson contracts that combines local testing, RPC-based simulation, and formal review to catch logic errors, state corruption, and gas anomalies before mainnet origination.
Risk Matrix: Simulation Gaps
Identifies failure modes where local simulation or the simulate_operation RPC may produce results that differ from mainnet execution, leading to undetected bugs, gas miscalculations, or state corruption.
| Risk | Failure mode | Severity | Mitigation |
|---|---|---|---|
Gas cost divergence | Simulated gas consumption differs from actual on-chain consumption due to differing block context or protocol parameters. | High | Always apply a safety margin to simulated gas limits. Validate against a testnet with identical protocol parameters before mainnet deployment. |
Big_map key omission | Simulation succeeds but on-chain execution fails with 'bad map key' because a required big_map key is missing in the current context. | High | Ensure all required big_map keys are pre-populated in the test environment. Use a dedicated test suite that mirrors mainnet big_map state. |
NOW instruction drift | Time-dependent logic using the NOW instruction passes simulation but fails or behaves unexpectedly on-chain due to block timestamp differences. | Medium | Parameterize tests with multiple timestamps, including edge cases. Avoid strict equality checks against NOW; use relative comparisons. |
Balance-dependent logic | Simulation uses a mock balance that does not reflect the contract's actual on-chain balance, masking transfer failures. | High | Explicitly set and vary the contract's balance in the simulation context. Test boundary conditions where the balance is zero or insufficient. |
Sender identity mismatch | The simulated SENDER or SOURCE is not the expected originator, hiding authorization bypass vulnerabilities. | Critical | Test with multiple sender identities, including unauthorized ones. Ensure access control logic is exercised against a matrix of callers. |
Internal operation ordering | The order of internal operations generated by the contract differs between simulation and mainnet, causing unexpected state transitions. | Medium | Verify the exact sequence of emitted operations using a block explorer on a testnet. Review the contract's operation emission logic for determinism. |
Sapling state unavailability | Simulation of Sapling shielded transactions does not have access to the full on-chain commitment tree, masking proof verification failures. | High | Conduct integration tests on a testnet with a populated Sapling state. Do not rely solely on local simulation for shielded contract validation. |
Ticket ownership mismatch | Simulation does not correctly reflect ticket ownership or the global ticket table, leading to incorrect assumptions about transferability. | High | Use a testnet to perform end-to-end ticket lifecycle tests. Verify ticket ownership and balances using a dedicated indexer before mainnet operations. |
Pre-Deployment Validation Checklist
A systematic checklist for development teams to complete before submitting a Michelson contract for mainnet origination. This process ensures logical correctness, gas efficiency, and integration compatibility, reducing the risk of post-deployment failures.
What to check: All entrypoints must be covered by unit tests that validate state transitions against expected storage and big_map mutations. Use property-based testing to verify invariants such as 'total supply remains constant after a transfer' or 'only the administrator can pause the contract'.
Why it matters: Michelson's stack-based execution and strict typing make logical errors easy to introduce. A missing FAILWITH or an incorrect COMPARE can lock funds or corrupt state.
Readiness signal: Test suites pass in a CI environment using a framework like PyTezos or SmartPy, with coverage reports showing no untested execution paths.
Canonical Resources
Use these primary resources to validate Michelson behavior before origination, compare local simulation against node RPC behavior, and confirm that off-chain integrations observe the same contract effects that the chain will apply.
Looking to build on a specific blockchain?
We build smart contracts, DeFi applications, wallets, tokenization platforms, and blockchain infrastructure across the major ecosystems teams choose today. That includes Ethereum, Arbitrum, Optimism, Polygon, Avalanche, Solana, Sui, Aptos, Hedera, Stellar, and NEAR, with support for additional EVM and non-EVM networks based on your product requirements.
EVM ecosystems
- Ethereum
- Arbitrum
- Optimism
- Polygon
- Avalanche
- Cronos

Non-EVM ecosystems
- Solana
- Sui
- Aptos
- Hedera
- Stellar
- NEAR
Additional ecosystems
- Polkadot
- Cosmos
- TON
- Cardano
- Algorand
- Tempo
Also available for Base, appchains, custom EVM networks, and cross-chain product architecture.
Frequently Asked Questions
Common questions from development teams about validating Michelson contract logic before mainnet deployment, covering simulation accuracy, framework selection, and when formal review is warranted.
run_script executes a contract's entrypoint against provided parameters and storage in a fully local, stateless context. It does not interact with on-chain state, other contracts, or the broader protocol environment. Use it for fast unit-level logic validation during development.
simulate_operation (via the /chains/main/blocks/head/helpers/simulate_operation RPC) executes an operation as if it were included in a block, returning the resulting state diff, gas consumption, and balance changes. It accounts for the current chain context, including big_map values and other contract states.
When to use each:
- Use
run_scriptfor rapid iteration on pure Michelson logic, such as verifying a new entrypoint's arithmetic or storage transformation. - Use
simulate_operationfor integration-level testing: verifying token balance changes, gas cost estimation, and interaction effects with other contracts. - Why it matters: Relying solely on
run_scriptcan miss failures caused by chain context, such as abig_mapkey not existing or a balance check failing against the live ledger. Teams should integrate both into their CI pipeline.
Delivering blockchain solutions for 5+ years.
We have partnered with 50+ leading DeFi protocols, NFT ecosystems, and fintech innovators to build secure, scalable, and capital-efficient blockchain products.
Selected Partners & Clients
“I've been working with Chainscore Labs for last 3+ years, they've consistently delivered with strong ownership across multiple projects. The team is reliable and detail-oriented.”
How to get started?
If you're looking for blockchain integration, ChainScore Labs has 5+ years of experience helping teams build and integrate exchanges, wallets, smart contracts, tokenization solutions, and protocol-connected products, we can help you choose the right path, integrate securely, and get to production faster. Our team consists of experienced blockchain developers and architects who can help you with your blockchain integration needs.
Exploration & Strategy
Define your product goals and choose the right blockchain architecture for your use case.
Architecture & Design
Design the smart contracts, tokenomics, and security parameters of your system.
Development & Integration
Build and integrate with wallets, oracles, and front-end dApps for a seamless experience.
Security & Launch
Comprehensive audits followed by a risk-managed mainnet deployment to protect your users.
Discover our
blockchain development services.
We build production-grade blockchain solutions for top-tier projects across DeFi and Web3.
Need a blockchain engineering team?
Send the project context and we will respond with next steps, scope questions, and a practical path to delivery.


