Research · Cross-chain
Ethereum and ICP: two ways to run a program on a chain
Where the program's state actually lives
An Ethereum contract is an account. It has an address, a balance, a code field and a storage field, and the storage is a key-value map that lives inside the same global state trie as every other account. The Ethereum documentation describes the world state as a mapping from addresses to accounts, and a transaction as a state transition that the whole network applies in the same order. A contract's variables are therefore not private to the contract in any structural sense: they are entries in a shared database that every node maintains a copy of, addressed by a hash of the contract address and the slot.
A canister is a different shape. The Internet Computer's documentation describes a canister as a WebAssembly module together with a memory that persists across calls, deployed to one subnet and replicated across that subnet's nodes. The canister's state is not an entry in a network-wide trie; it is the canister's own linear memory, and the subnet's consensus protocol decides which calls mutate it and in what order. Two canisters on two different subnets do not share a state space at all, and a call between them is an asynchronous message rather than a synchronous function call.
That single structural difference propagates. Because Ethereum's state is global, a contract can read another contract's public storage synchronously within one transaction, and composability across contracts is a property of the execution environment rather than something the developer arranges. Because a canister's state is local, cross-canister interaction is explicit, asynchronous and subject to the message-passing rules of the platform. The Internet Computer's documentation is direct about the consequence: an update call that calls another canister cannot return a value to its caller in the same round, and the developer has to design around that.
Upgrading a program without losing its state
On Ethereum, a deployed contract's code is immutable. The EVM has no instruction that rewrites the code stored at an address, so changing a contract's behaviour means deploying a new contract and moving users to it. The pattern the ecosystem settled on is the proxy: a small, permanent contract holds the storage and delegates every call to an implementation address that an administrator can change. The storage layout of the implementation must match the proxy's expectations, which is why upgradeable contracts are written against storage-layout conventions and why a mistake in that layout can corrupt live data. The immutability is real, but the upgrade path exists and it carries an administrative key.
The Internet Computer takes the opposite approach at the platform level. A canister can be upgraded in place: the documentation describes an upgrade as replacing the WebAssembly module while preserving the canister's memory, with an optional pre-upgrade and post-upgrade hook that let the developer migrate state between layouts. The canister keeps its address, its cycles balance and its memory across the upgrade, so users do not have to be moved and no proxy is required. The trade is that the upgrade is a first-class platform operation, which means the platform's own rules about who may upgrade a canister — its controllers — are the security boundary rather than a contract's own access control.
Neither arrangement removes the hard part. Both require the developer to reason about how old state maps onto new code, and both make that reasoning the place where upgrades go wrong. The difference is where the mechanism sits: Ethereum's upgradeability is a pattern built on top of an immutable execution layer, and the Internet Computer's is a feature of the execution layer itself.
Two cost models, and what each one charges for
Ethereum charges for execution in gas, and the fee for a transaction is the gas used multiplied by a price that the market sets. Since EIP-1559 the price has two parts: a base fee that the protocol adjusts block by block and burns, and a priority fee that goes to the validator. The important property for a developer is that the cost is paid by the transaction's sender, at the moment of the transaction, and is proportional to the work the EVM performs. A contract that is never called costs nothing to keep alive, because there is no such thing as keeping it alive: its storage is simply part of the state that every node already holds.
The Internet Computer charges in cycles, and the model is closer to hosting than to a per-transaction fee. The documentation describes cycles as the unit that pays for computation, memory and network usage, with a fixed conversion from ICP that the network's governance adjusts to keep the cost of computation stable. A canister holds a cycles balance and is charged continuously for the resources it occupies, which means an idle canister still consumes cycles and will eventually be frozen and then removed if its balance runs out. The developer, not the end user, is typically the party topping that balance up.
The two models therefore price different things. Ethereum prices work performed and makes the caller pay for it; the Internet Computer prices resources held and makes the operator fund them. Neither is a rounding error of the other, and a developer moving between the two has to re-learn what "cost" means: a contract that is expensive to call but cheap to keep, against a canister that is cheap to call but must be kept funded.
The two models side by side
The table states the structural differences that follow from where state lives and who pays for it. Each row is drawn from the two platforms' own documentation rather than from a benchmark.
| Dimension | Ethereum contract | ICP canister |
|---|---|---|
| Where state lives | Entries in one global state trie shared by every account | The canister's own persistent memory, replicated across one subnet |
| Scope of state | Network-wide; any contract can read another's public storage | Canister-local; other canisters are reached by message |
| Changing the code | Code is immutable; upgrades use a proxy and a storage layout | The module is replaced in place, with pre- and post-upgrade hooks |
| Unit of cost | Gas, priced per unit of work the EVM performs | Cycles, priced per unit of compute, memory and network used |
| Who pays | The sender of each transaction, at the time it is sent | The canister's cycles balance, funded by its controller |
| Cost of an idle program | Nothing; its storage is part of the state every node holds | Continuous; an unfunded canister is frozen and then removed |
| Calling another program | Synchronous within one transaction | Asynchronous message; no same-round return value |
Last reviewed 2026-09-21Source: Ethereum and ICP developer documentationStructural comparison; no throughput or price figures are asserted.
What the comparison does not settle
The table describes mechanisms, not outcomes. It does not say which model is cheaper to operate, because that depends on the workload: a program called once a year and a program called a thousand times a second are priced very differently by a per-work model and a per-resource model, and the crossover point moves with the market price of gas and the governance-set price of cycles. It also does not say which is easier to build on, because that depends on what the developer already knows and on the libraries available.
The comparison is also deliberately narrow. It sets the two execution models against each other and leaves out the questions that the rest of this cluster covers: how each network reaches finality, how each one represents a transaction, and how each one scales. A reader who wants the wider picture should start from the cross-chain research hub, which places this page alongside the execution, scaling, finality and data-model comparisons.
Finally, the page describes the platforms as their documentation describes them at the review date. Both are evolving: Ethereum's roadmap includes changes to how state and execution are organised, and the Internet Computer's subnet and canister model continues to develop. Where a mechanism is proposed rather than deployed, the documentation says so, and this page does not treat a proposal as a capability.
Sources and references
Each platform's execution model is described from its own documentation. No capability, figure or benchmark is asserted that the cited source does not state.
- Ethereum's accounts and world state. ethereum.org, Ethereum accounts and Ethereum Virtual Machine: a contract account carries code and a storage map inside the global state.
- Ethereum's fee market. EIP-1559, Fee market change for ETH 1.0 chain: the base fee is burned and a priority fee is paid to the validator.
- Canisters, subnets and upgrades. ICP Developer Docs, Canisters and code and Network overview: a canister holds persistent memory, is replicated across a subnet, and is upgraded in place.
- Cycles and resource accounting. ICP Developer Docs, Tokens and cycles: cycles pay for computation, memory and network usage, and a canister is charged for the resources it holds.
Related reading
- Research HubEvery dataset on the site, with methodology and provenance.
- Altcoin ResearchAltcoins measured against Bitcoin: design intent, consensus, execution, scaling and market structure.
- The ETH-BTC Correlation RecordHow the correlation is measured, how it behaves across windows, and where it breaks down.
- The ETH/BTC RatioWhat the ratio measures, how to read its trend, and why it is not a forecast.
- ETH During Bitcoin Bull PhasesAssociation within a common market factor, and what co-movement cannot establish.
- ETH During Bitcoin Bear PhasesDrawdown depth and duration compared over identical windows, and the limits of the comparison.