DEV Community

AI x Crypto Systems
AI x Crypto Systems

Posted on

Transaction Simulation Story: The Dry Run Is Not the Signed Result

Transaction Simulation Story

Disclosure: AI tools were used for source collection and editorial review. The article was written by a human author, who checked the facts, code, and conclusions.

Crypto risk disclosure: This article is a technical explanation, not investment advice. It is not a recommendation to buy, sell or hold any cryptoasset.

Transaction Simulation Story is useful before a signature only when the preview says exactly what it simulated. A dry run can show a result against selected state, but the preview should not pretend that result is the future block, the final ordering, or the user's full intent.

The mistake is easy to make in AI wallets and agent wallets. A transaction preview sounds like a single safety layer, while the actual evidence comes from different layers: Ethereum execution APIs, client debug methods, provider simulation APIs, ABI decoding, and wallet warning UX.

Simulation Receipt

The dry run needs a receipt before it needs a promise. The receipt below is deliberately provider-scoped: it separates a standard call result from trace, logs, and asset changes that only exist when a client or provider supplies them.

{
  "request": {
    "from": "0xUser",
    "to": "0xContract",
    "value": "0x0",
    "input": "0xa9059cbb...",
    "gas": "0x186a0"
  },
  "blockContext": "latest",
  "providerMethod": "eth_call",
  "standardResult": {
    "eth_callReturnData": "0x..."
  },
  "providerResult": {
    "status": "success",
    "revertReason": null,
    "gasUsed": "provider_specific",
    "calls": "provider_specific",
    "logs": "provider_specific",
    "assetChanges": "provider_specific"
  },
  "warnings": [
    "state may change before inclusion",
    "trace fields are not universal Ethereum JSON-RPC",
    "decoded asset changes depend on provider coverage and ABI"
  ]
}
Enter fullscreen mode Exit fullscreen mode

That receipt is the article's core artifact. Transaction Simulation Story becomes safer when each field has a source and a limit, because the wallet can show "this is a provider estimate" instead of "this will happen."

Standard Call

The standard call layer is narrower than many previews imply. The Ethereum Execution APIs for eth_call support executing a call against selected state without creating an onchain transaction.

That is valuable, but it is not a full trace. The pre-signature preview should treat eth_call output as return data or an error for a selected block context, not as proof of future asset changes, call tree, or logs.

Simulation State

The most direct official simulation language comes from Ethereum Execution APIs eth_simulateV1. The method can simulate calls, accumulate state between simulated calls, and use block or state overrides.

That power is also the warning. The receipt has to name the state it used: latest, safe, finalized, pending, a specific block number, or a provider override. A successful result on one state is not a guarantee that a signed transaction will see the same state later.

Provider Trace

The trace layer is provider or client specific. Geth debug_traceCall belongs to the Geth debug namespace, while Tenderly simulations and Alchemy simulation APIs expose richer trace, asset, and balance views through provider APIs.

That difference should be visible to the user or agent. A wallet should not label a Tenderly asset-change object or an Alchemy internal-call list as "Ethereum said this." Ethereum supplied the call/state primitive; the provider supplied the decoded preview.

Boundary Table

The next engineer needs a short boundary table so one field does not carry five meanings.

Layer What it can say What it cannot say
eth_call Return data or error against selected state Future inclusion, asset diff, full trace
eth_simulateV1 Simulated calls and state changes under chosen options Guaranteed future block result
Geth debug_traceCall Client debug trace under tracer configuration Universal provider output
Tenderly/Alchemy simulation Provider-decoded calls, logs, balances, or asset changes Protocol-native guarantee
Wallet warning User-facing caution before signature Complete threat detection or signature block

This table keeps the preview out of the "dry run equals safety" trap. A preview is useful when it says which layer produced each claim.

Fee Preview

Gas and fee previews have their own boundary. Ethereum eth_estimateGas estimates gas for completion, while EIP-1559 defines fee fields such as max fee and max priority fee for type 0x02 transactions.

That does not make the displayed cost final. The wallet should say "estimated under this state and fee context," because base fee, priority fee, pending block constraints, and state changes can move before inclusion.

Signature Context

Structured signing helps the display layer but does not prove user understanding. EIP-712 defines typed structured data hashing and signing with domain separation, which can make a request easier to inspect than opaque bytes.

That display layer still needs the simulation receipt. A nicely typed signature is not proof that the user saw the eventual asset movement, provider trace, or MEV/order risk.

Wallet Warning

Wallet warnings are a user interface layer, not a consensus layer. MetaMask transaction insights let a Snap inspect an unsigned transaction request, while MetaMask security alerts document warning behavior and limits for MetaMask's own system.

That makes the pattern useful for AI x crypto systems: an agent can prepare the receipt, but the wallet should still show the method, state, provider, decoded change, warning, and uncertainty before signature.

Ordering Risk

The final boundary is ordering. Flash Boys 2.0 is not a wallet simulation manual, but it is strong evidence that transaction ordering and priority dynamics matter in Ethereum-style systems.

That is why the dry-run story should end with a refusal to overpromise. A dry run can catch many mistakes before a signature, but it cannot freeze the mempool, future state, block builder behavior, or every provider decoding assumption.

Final Receipt

The pattern works when the wallet or agent says: "This is what the dry run saw, using this state, this provider method, and these decoded fields." The signature decision is better because the uncertainty is visible.

That is the developer habit worth keeping. A simulation trace is not a prophecy; it is a labeled piece of evidence before a user or agent signs.

Top comments (0)