> For the complete documentation index, see [llms.txt](https://docs.lumia.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lumia.org/build-on-lumia/smart-contracts/evm-differences-on-lumia.md).

# EVM differences on Lumia

You're porting a contract written for Ethereum (or another EVM chain) to Lumia and need to know where the zkEVM's behavior diverges from what you're used to.

**Who this is for:** developers deploying existing Solidity contracts on Lumia, especially anything using low-level opcodes, `SELFDESTRUCT`, or a hash/pairing precompile. **Prerequisites:** [Smart Contracts on Lumia](broken://pages/bd2011a6ce1159bafc4ce4edc5f80b3b699f6bc7). **Time:** 5 minutes to read; longer if you need to rewrite affected code.

## The short version

Lumia's zkEVM supports the EVM instruction set with a small number of modified opcodes and three unsupported ones, plus a reduced precompile set. The full, current table lives at [`/reference/evm-opcodes`](file:///reference/EVM-opcode-support.md). This page explains why it matters and doesn't repeat the table.

## What to check before you deploy

**Modified opcodes**: these still work, but don't behave the way they do on Ethereum L1:

* `SELFDESTRUCT` is removed and replaced by `SENDALL`. If your contract (or an inherited library) relies on `SELFDESTRUCT` to reclaim funds or as an upgrade/kill-switch mechanism, that code path needs rewriting, not just redeploying.
* `EXTCODEHASH` reads from the zkEVM state tree, not raw bytecode the way you may be assuming.
* `DIFFICULTY` always returns `0`. If any code branches on difficulty (rare, but seen in old randomness hacks), it will behave differently.
* `BLOCKHASH` returns all previous block hashes, not just the last 256. Do not assume the Ethereum L1 256-block window applies.
* `NUMBER` returns the number of processable transactions, not a conventional block number in the way some contracts assume. Check any logic that does arithmetic on `block.number`.

{% hint style="warning" %}
**Unsupported opcodes**: using these will fail, full stop. `SHA256`, `BLAKE`, `PAIRINGS` are not supported. A contract or an imported library (some ZK/aggregate-signature libraries call these) that touches any of the three will not deploy or will revert at call time.
{% endhint %}

{% hint style="warning" %}
**Precompiles**: only `ecRecover` and `identity` are supported; every other precompile address reverts. This affects anything relying on `modexp`, the `bn256`/`alt_bn128` pairing precompiles (common in some ZK-verifier and BLS-signature libraries), or `ripemd160`.
{% endhint %}

## Verify it worked

Compile and deploy on Beam testnet first (see [`/build/smart-contracts/deploy-with-hardhat`](broken://pages/f176929e0032d6e7897dd25c5f662a1adae28160)). If deployment or a specific call reverts with no clear reason, check whether the reverting code path touches one of the opcodes/precompiles above before assuming it's a logic bug.

## Troubleshooting

<details>

<summary>Deployment reverts with no revert reason</summary>

Search your contract and its imports for `selfdestruct`, `sha256(`, or a pairing-precompile call; these are the most common cause on a straight L1 port.

</details>

<details>

<summary>A library you didn't write yourself fails</summary>

Some audited libraries (older BLS/ZK-verification code) call `bn256Pairing`/`modexp` internally. Check the library's source, not just your own contract.

</details>
