> Feedback: If these docs are stale, missing, or confusing, post sanitized feedback to `https://docs.tempo.xyz/api/feedback` with `source: "mcp"`, a short `message`, and any relevant `toolName`, `relatedResource`, or `client`.
# EVM Differences

Tempo is fully compatible with the Ethereum Virtual Machine (EVM), targeting the **Osaka** EVM hard fork. Developers can deploy and interact with smart contracts using the same tools, languages, and frameworks they use on Ethereum, such as Solidity, Foundry, and Hardhat. All Ethereum JSON-RPC methods work out of the box.

While the execution environment mirrors Ethereum's, Tempo introduces some differences optimized for payments, described below.

<Cards>
  <Card description="How Tempo handles wallet compatibility and native token representation." to="#wallet-differences" icon="lucide:wallet" title="Wallet Differences" />

  <Card description="Key differences when sending transactions, including fee tokens and default preferences." to="#transaction-differences" icon="lucide:send" title="Transaction Differences" />

  <Card description="VM-level differences including balance opcodes and Solidity compatibility." to="#vm-layer-differences" icon="lucide:code" title="VM Layer Differences" />

  <Card description="How Tempo's consensus and finality differ from Ethereum's approach." to="#consensus--finality" icon="lucide:check-circle" title="Consensus & Finality" />
</Cards>

## Wallet Differences

By default, all existing functionality will work for EVM-compatible wallets, with only a few quirks. For developers of wallets, we strongly encourage you to implement support for Tempo Transactions over regular EVM transactions. See the [transaction differences](#transaction-differences) for more.

:::tip
If you are building a wallet, read our [guide for wallet developers](/docs/quickstart/wallet-developers).
:::

### Handling ETH (native token) Balance Checks

Remember that on Tempo, there is no native gas token.

Many wallets and applications check a user's "native account balance" before letting them complete some action. In this scenario, you might see an error message like "Insufficient balance".

This stems from the return value of the `eth_getBalance` RPC method. When a wallet calls this method, it expects a hex string representing the "native token balance", hard-coded to be represented as an 18-decimal place number.

On Tempo, the `eth_getBalance` method returns a hex string representing an extremely large number. Specifically it returns: `0x9612084f0316e0ebd5182f398e5195a51b5ca47667d4c9b26c9b26c9b26c9b2` which is represented in decimals as 4.242424242424242e+75.

Our recommendation to wallets and to applications using this method is to remove this balance check, and to not represent any "native balance" in your user's UI. This will allow users to complete actions without being blocked by balance checks.

We endorse [this proposed ERC](https://github.com/ethereum/ERCs/pull/1220) to standardize this behavior.

### Specifying a Native Token Currency Symbol

Sometimes wallets will need to specify the currency symbol for the native token. On Tempo, there is no native token, but fees are denominated in USD. So, we recommend using the currency symbol "USD".

## Transaction Differences

### Dealing with the fee token selection

Tempo does not have a native gas token. Instead, fees are denominated in USD and fees can be paid in an stablecoin. For Tempo Transactions, the `fee_token` field can be set to any TIP-20 token, and fees are paid in that token.

If your transactions are not using Tempo Transactions, there is a cascading fee token selection algorithm that determines the default fee token based on the user's preferences and the contract being called.

This preference system is specified [here](/docs/protocol/fees/spec-fee#fee-token-preferences) in detail.

#### Consideration 1: Setting a user default fee token

As specified in the preference system above, the simplest way to specify the fee token for a user is to set the user default fee token. Read about how to do that [here](/docs/protocol/fees/spec-fee#account-level) on behalf of an account.

#### Consideration 2: Paying fees in the TIP-20 contract being interacted with

If the user is calling a method on a TIP-20 token (e.g., `transfer`), the default fee token is that token itself. For example, if the user is calling the `transfer` method on a TIP-20 token with a symbol of "USDG", the default fee token would be "USDG".

Importantly, note that the `amount` field in this case is sent in full. So, if the user is calling the `transfer` method on a TIP-20 token with a symbol of "USDG" with the `amount` field set to 1000, the full amount of the token will be transferred **and** the sender's balance will be reduced by the amount spent in fees. So, the recipient will receive 1000 USDG.

#### Consideration 3: The fallback in the case of a non-TIP-20 contract

If the user is calling a contract that is not a TIP-20 token, the EVM transaction will default to the pathUSD token. Thus, in order to send transactions to non-TIP-20 contracts, the wallet must hold some balance of pathUSD.

On the Tempo Testnet, pathUSD is available from the [faucet](/docs/quickstart/faucet).

If a wallet wants to submit a non-TIP20 transaction without having to submit the above transaction, we recommend investing in using [Tempo Transactions](/docs/quickstart/integrate-tempo#tempo-transactions) instead.

## VM Layer Differences

At the VM layer, all opcodes are supported out of the box. Due to the lack of a native token, native token balance is always returning zero balances.

### State Creation Costs

Tempo uses higher gas costs for state-creating operations to prevent state growth attacks ([TIP-1000](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1000.md)):

| Operation | Tempo | Ethereum |
|-----------|-------|----------|
| New storage slot (SSTORE 0→non-zero) | 250,000 gas | 20,000 gas |
| Account creation | 250,000 gas | 0 gas |
| Contract creation per byte | 1,000 gas | 200 gas |
| Transaction gas cap | 30M gas | 30M gas |

This means transfers to new addresses cost ~300k gas, and contract deployments cost 5-10x more than on Ethereum. Update your `gas_limit` estimates accordingly.

### Balance Opcodes and RPC Methods

| Feature | Behavior on Tempo | Alternatives |
|---------|-------------------|--------------|
| **`BALANCE` and `SELFBALANCE`** | Will always return 0 | Use TIP-20 `balanceOf` instead |
| **`CALLVALUE`** | Will always return 0 | There is no alternative |

:::info
We are exploring transaction level introspection for Tempo Transactions, with an ability to declare things like `tx.fee_token` and `tx.fee_payer` in Solidity.
:::

## Consensus & Finality

Tempo uses **Simplex BFT consensus** with a permissioned validator set at launch, providing deterministic finality, unlike Ethereum's finality gadget which takes approximately 12 minutes.

Block times are targeted at ~0.5 seconds compared to Ethereum's ~12 second slots.
