Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions docs/builder/get-started/evm-developers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
sidebar_position: 6
title: Coming from Ethereum
description: A mental-model map for developers familiar with Ethereum, the EVM, and Solidity — how accounts, tokens, transfers, storage, and execution translate to Miden.
---

# Coming from Ethereum

If you already know Ethereum and Solidity, this page maps the concepts you know to their Miden equivalents so the rest of the documentation reads faster.

## The three big shifts

Almost every difference between Ethereum and Miden follows from three architectural decisions:

1. **Local execution instead of global execution.** On Ethereum, every node re-executes every transaction to agree on a single global state. On Miden, the user executes a transaction locally and produces a zero-knowledge proof; the network only verifies the proof and records the resulting commitments.
2. **Notes instead of direct balance updates.** Ethereum is account-based: a transfer mutates two balances in one global state transition. Miden transfers are note-based (UTXO-like) and span two transactions: the sender creates a note carrying the assets, and the recipient consumes it in a separate transaction. A Miden transaction is always the state transition of a _single_ account.
3. **Privacy by default.** On Ethereum, all state and calldata is public. On Miden, accounts, notes, and transactions can be public or private — private state is held by its owner, with only commitments onchain.

## Concept mapping

| Ethereum / Solidity | Miden |
| ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| Smart contract (code + storage at an address) | Account — every account is a smart contract with code, storage, and an asset vault |
| Externally owned account (EOA) | Account composed of a wallet component and an authentication component |
| State variables / `mapping` | Account storage slots and storage maps (up to 255 slots per account) |
| ERC-20 token contract | Fungible faucet account issuing a fungible asset |
| `transfer(to, amount)` | Creating a P2ID (pay-to-ID) note; the recipient consumes it in a second transaction |
| Token minting / issuance | A faucet mints assets into a note addressed to the recipient |
| `msg.sender` | The account's authentication component (e.g. a signature scheme) authorizes its transactions |
| Events / logs | Notes — the primary communication primitive between accounts |
| `eth_call` (read-only call) | `executeProgram` — runs a script locally against account state, without submitting or proving |
| Public mempool, all data public | Public and private notes; private note data is exchanged offchain via a note transport layer |
| One transaction can touch many contracts atomically | One transaction transitions one account; cross-account interaction happens via notes and foreign procedure calls |

## Assets and transfers

In Solidity, moving tokens is a single call that updates two balances atomically:

```solidity title="ERC-20 transfer (Solidity)"
// balances[msg.sender] -= amount; balances[to] += amount;
token.transfer(bob, 100);
```

In Miden, the same transfer is two transactions connected by a note:

```typescript title="Tx 1 — Alice sends (creates the note)"
import { MidenClient } from "@miden-sdk/miden-sdk";

const client = await MidenClient.createTestnet();

// Create a pay-to-ID note carrying 100 tokens, addressed to Bob.
const { txId, note } = await client.transactions.send({
account: aliceWallet,
to: bobWallet,
token: faucet,
amount: 100n,
type: "private", // note data is not posted onchain
returnNote: true,
});
console.log("Created note:", note.id().toString());
```

```typescript title="Tx 2 — Bob consumes (in his own client)"
// Private notes are delivered via the note transport network; Bob's
// client fetches the ones addressed to him (endpoint is preconfigured
// by createTestnet).
await client.notes.fetchPrivate();

// Consuming the note moves the tokens into Bob's vault.
const [received] = await client.notes.listAvailable({ account: bobWallet });
await client.transactions.consume({ account: bobWallet, notes: received });
```

Two things are worth noticing:

- **Alice's transaction is final on its own.** Bob does not need to be online; the note waits until he consumes it. A `reclaimAfter` option also lets Alice reclaim the assets if Bob never consumes the note.
- **The two transactions are unlinkable onchain** when the note is private — there is no global transfer event connecting sender and recipient.

The "sealed envelope" intuition and the full mint → consume flow are covered in [Notes & Transactions](./notes).

## Smart contracts

- **Language**: contracts are written in Rust and compiled to Miden assembly (MASM), or written directly in MASM — see [Smart Contracts](../smart-contracts/).
- **Storage**: instead of Solidity's flat storage layout, each account has up to 255 storage slots plus storage maps — see [Read Storage Values](./read-storage).
- **Authorization**: there is no implicit `msg.sender`; an account's authentication component defines how its transactions are authorized (e.g. a Falcon512 signature).
- **Read-only queries**: instead of `eth_call`, run a transaction script locally with `executeProgram`, which returns the resulting VM stack without submitting or proving anything.

## What stays familiar

- Wallets, token faucets, fungible and non-fungible assets, and DeFi-style flows all exist — they are just composed from accounts and notes.
- TypeScript tooling is first-class: the web client runs in the browser via WebAssembly, so dApp frontends look like any other web3 app.

## Where to go next

- [Accounts](./accounts) — create wallets and faucets programmatically
- [Notes & Transactions](./notes) — the two-transaction transfer model in depth
- [Read Storage Values](./read-storage) — query contract state
- [Smart Contracts](../smart-contracts/) — write contracts in Rust/MASM

---