Skip to main content
Version: 0.14

What is a Miden Smart Contract

This page describes Miden's execution model — accounts, notes, transactions, and lifecycle. The concepts apply regardless of whether you author contracts in MASM (the mainnet path) or the Rust SDK (in active development). Code examples on this page use Rust; for the MASM path, see MASM Smart Contracts.

Miden is a zero-knowledge layer 2 where transactions execute on the client and only a cryptographic proof is submitted to the network. Every entity — wallets, contracts, faucets — is an account with code, storage, a vault, and a nonce. Assets move between accounts through notes, which act as programmable UTXOs. This page describes the execution model, account structure, note system, and transaction lifecycle. For a hands-on walkthrough, see the Miden Bank Tutorial.

What makes Miden different

On Ethereum, smart contracts execute on every node. On Miden, transactions execute locally on the client — and only a cryptographic proof is submitted to the network.

This means:

  • Privacy by default — The network sees the proof, not the inputs
  • Parallel execution — Transactions don't compete for block space
  • Lower fees — No gas wars; proofs are cheap to verify
  • Client-side proving — Your machine generates the ZK proof

The compilation pipeline

Miden runs MASM (Miden Assembly) — the VM's native instruction set. There are two authoring paths that produce it:

MASM directly (the supported mainnet path):

MASM → ZK Circuit → Proof

You write MASM directly and build it into a .masp package (Miden Assembly Package). This is what mainnet supports for production today. See MASM Smart Contracts.

Rust (in active development):

Rust → Wasm → MASM → ZK Circuit → Proof

The Miden compiler (cargo-miden) compiles your #![no_std] Rust to WebAssembly, then translates it to MASM. The output is the same .masp package, so both paths share the same execution model and the same Miden Standards library.

When a transaction executes, the Miden VM runs the MASM and produces a zero-knowledge proof of correct execution. The output of cargo miden build (Rust) or the MASM build tooling is a .masp file containing the compiled MASM and metadata.

The account model

Every entity on Miden is an account. Accounts are smart contracts — even user wallets.

An account has four parts:

PartDescription
CodeOne or more components that define the account's behavior
StoragePersistent state — up to 255 slots of Value or StorageMap
VaultThe assets (fungible and non-fungible) the account holds
NonceA counter that increments with every state change (replay protection)

Components

Components are reusable code modules attached to accounts. Think of them as traits or mixins, not monolithic contracts. An account can have multiple components.

#[component]
struct MyWallet;

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

Each component defines its own storage layout and public methods. The #[component] macro generates the necessary WIT (WebAssembly Interface Type) definitions for cross-component interoperability.

See Components for full details.

Notes as UTXOs

Assets don't transfer directly between accounts. Instead, they move through notes — programmable messages that carry assets and logic.

Sender Account → creates Note (with assets + script) → Recipient Account consumes Note

Notes are similar to Bitcoin's UTXOs, but with arbitrary programmable logic. A note contains:

  • Assets: The tokens or NFTs being transferred
  • Script: Code that executes when the note is consumed (e.g., "only account X can claim this")
  • Inputs: Custom data the script can read

The most common pattern is P2ID (Pay to ID) — a note that can only be consumed by a specific account.

See Notes for implementation details.

Transaction flow

A transaction in Miden follows this flow:

  1. Build: The client assembles the transaction — which notes to consume, which account methods to call
  2. Execute: The Miden VM executes the transaction locally
  3. Prove: The VM produces a zero-knowledge proof of correct execution
  4. Submit: Only the proof (and state commitments) go to the network
  5. Verify: The network verifies the proof and updates state

Because execution happens locally, the network never sees your transaction inputs, the account's private state, or the logic that ran. It only sees that the proof is valid and the resulting state commitments.

What "proof generation fails" means

When you write assertions in Miden contracts:

assert!(amount > felt!(0));

If the assertion fails, the ZK circuit cannot produce a valid proof. This means:

  • The transaction is rejected before it ever reaches the network
  • No state changes occur — it's as if the transaction never happened
  • The client gets an error explaining which assertion failed

This is fundamentally different from Ethereum's revert — there's no onchain transaction that fails. The proof simply doesn't exist if the execution is invalid.

A separate failure mode is the empty transaction — a transaction that completes without mutating account state or consuming a note is also rejected, since Miden refuses to admit transactions with no observable effect.

Account types

Miden supports four account types, set at deployment time. The same types are used regardless of authoring language:

TypeDescription
RegularAccountUpdatableCodeStandard account — code can be updated after deployment
RegularAccountImmutableCodeAccount with fixed code — cannot be changed after deployment
FungibleFaucetToken minting account (fungible assets)
NonFungibleFaucetNFT minting account (non-fungible assets)

Where to go next

Authoring paths and libraries:

SectionWhen to use
MASM Smart ContractsProduction contracts for mainnet today
Rust SDKPrototyping today; long-term default once it ships v1
Miden StandardsReusable building blocks callable from either path

Topic guides (concepts apply regardless of authoring language):

TopicDescription
ComponentsReusable code modules with storage and exported interfaces
StorageUp to 255 slots of Value or StorageMap
Custom TypesExported structs/enums for public APIs
Account OperationsRead/write account state and vault
NotesProgrammable UTXOs for asset transfers
TransactionsTransaction context, scripts, and the advice provider
AuthenticationRPO-Falcon512 signatures and replay protection
Cross-Component CallsInter-component communication
TypesFelt, Word, Asset — the VM's native types
PatternsAccess control, rate limiting, spending limits, anti-patterns

Ready to start building? The Miden Bank Tutorial is a hands-on walkthrough (currently written against the Rust SDK; the concepts translate to MASM).