Skip to main content
Version: 0.13

What are Notes?

Notes are Miden's primary mechanism for cross-account communication — they carry assets, execute programmable logic, and trigger state changes on the consuming account. Like UTXOs, notes are created and consumed atomically. Unlike Bitcoin's UTXOs, each Miden note carries an arbitrary executable script — written in Rust — that runs when the note is consumed, enabling programmable conditions far beyond simple locking scripts.

While asset transfers are the most common use of notes, notes are how accounts communicate with one another in general: a note can trigger a counter increment, initiate a swap, delegate an operation, or carry arbitrary data to be acted on by the recipient's logic.

Assets never transfer directly between accounts. Instead, they always move through notes. This indirection is what makes Miden private: the network sees notes being created and consumed, but it can't link sender and recipient accounts because those operations happen in separate transactions.

Anatomy of a note

Every note has four parts:

PartDescription
AssetsThe fungible or non-fungible tokens the note carries
ScriptCode that executes when the note is consumed — determines who can claim it and what side effects occur
InputsCustom data the script can read at consumption time (e.g., a target account ID, an expiration block)
MetadataSender ID, note tag (for discovery routing), and auxiliary data

The recipient is a cryptographic hash that encodes who can consume the note. When creating notes programmatically (via output_note::create), you compute a Recipient from the note's serial number, script hash, and inputs:

recipient = hash(hash(hash(serial_num, [0;4]), script_root), inputs_commitment)

Only someone who knows these values can construct a valid consumption proof. See Computing a Recipient for the SDK API.

The two-transaction model

Unlike Ethereum where a transfer is a single atomic call, Miden transfers happen across two separate transactions:

Transaction 1 (Sender)                Transaction 2 (Recipient)
┌─────────────────────────┐ ┌─────────────────────────┐
│ 1. Create note │ │ 1. Discover note │
│ 2. Attach assets │ │ 2. Consume note │
│ 3. Note published │──────────▶│ 3. Script runs │
│ (on-chain or private) │ │ 4. Assets move to vault │
│ │ │ 5. Note nullified │
└─────────────────────────┘ └─────────────────────────┘

Transaction 1: The sender's account creates an output note, attaches assets to it, and the note is published (either on-chain or kept private).

Transaction 2: The recipient discovers the note, consumes it in their own transaction, the note script runs and verifies the consumer is authorized, and assets transfer into the recipient's vault. A nullifier is recorded to prevent the same note from being consumed again (see note design).

This separation is what enables privacy and parallelism — the two transactions are independent and unlinkable from the network's perspective.

Public vs. private notes

Notes come in two visibility modes:

ModeDescription
PublicThe note's full data (assets, script, inputs) is stored by the Miden network and visible on-chain. Anyone can discover and attempt to consume it.
PrivateOnly a commitment (hash) is stored on-chain. The actual note data must be communicated off-chain between sender and recipient.

Private notes provide stronger privacy guarantees — the network can't even see what assets a note carries — but they require the sender and recipient to have a communication channel outside the protocol.

Miden provides built-in note patterns (P2ID, P2IDE, SWAP) for common transfer scenarios — see Note Types. You can also write fully custom note scripts for arbitrary consumption logic.

How notes differ from EVM transfers

EVMMiden
Transfer modelSingle transfer() call on a token contractTwo transactions: create note, then consume note
PrivacySender, recipient, and amount are publicTransactions are unlinkable; private notes hide all data
ProgrammabilityToken contracts control transfer logicEach note carries its own script with custom conditions
FailureRevert on-chain, gas consumedProof can't be generated — no on-chain trace
ParallelismTransfers contend for contract stateNotes are independent — unlimited parallel creation