Skip to main content
Version: 0.17 (unstable)

What are Accounts?

Accounts are the primary actors in Miden. Every entity on the network — wallets, smart contracts, token faucets — is an account. Unlike traditional blockchains where user wallets and smart contracts are fundamentally different, Miden treats them all as programmable accounts with the same structure.

Each account is an independent state machine. Most transactions execute locally on a client, while network accounts can instead be executed and proven by a network transaction builder. In both cases, correct execution is verified through a zero-knowledge proof. Accounts never share a global execution environment — they run in isolation, which enables parallel execution and privacy by default.

Anatomy of an account​

Every account has an immutable identifier and four state elements:

PartDescription
IDAn immutable identifier that uniquely identifies the account
CodeOne or more components that define the account's behavior — its public API and internal logic
StoragePersistent state — up to 255 typed slots of StorageValue or StorageMap
VaultThe fungible and non-fungible assets the account holds
NonceA counter that increments by one in every state-changing transaction, providing replay protection

For public accounts, the network stores the full account state. For private accounts, it stores only a commitment to the account state — computed from the ID, nonce, vault root, storage commitment, and code commitment — while the full state remains offchain and must be maintained by the user (see account design).

Components, not contracts​

On Ethereum, a smart contract is a single monolithic unit of code deployed to an address. On Miden, accounts are composed of components — reusable modules that each contribute their own storage layout and exported procedures.

use miden::{component, component_storage, Asset};

#[component_storage]
struct MyWalletStorage;

#[component]
trait MyWallet {
#[account_procedure]
fn receive_asset(&mut self, asset: Asset);
}

#[component]
impl MyWallet for MyWalletStorage {
fn receive_asset(&mut self, asset: Asset) {
self.add_asset(asset);
}
}

An account can have multiple components. For example, a DeFi account might combine a wallet component (for holding assets), an auth component (for signature verification), and custom application logic — all in a single account. Components communicate with each other through cross-component calls using WIT (WebAssembly Interface Types) bindings.

Account types​

Accounts are configured with AccountType, which controls state visibility:

TypeDescription
AccountType::PublicFull state is stored onchain and visible to everyone — suitable for shared protocols like DEXs and faucets
AccountType::PrivateOnly a state commitment is stored onchain — the actual data stays with the account owner

Wallet, contract, and faucet roles are determined by the account's components and options, not by separate account-type enum variants. For example, a fungible faucet is a public or private account that includes the FungibleFaucet component and token policy configuration.

How accounts differ from EVM contracts​

EVMMiden
ExecutionEvery validator re-executes every transactionA client or network transaction builder executes; the network verifies a ZK proof
State visibilityAll state variables are public onchainPrivate accounts expose commitments; public accounts store their full state onchain
Code structureMonolithic contract deployed to an addressMultiple reusable components composed into one account
IdentityWallets are EOAs, contracts are separateEverything is an account — wallets are smart contracts
Failurerevert consumes gas, leaves an onchain traceInvalid execution cannot produce a proof, so no failed transaction is submitted onchain