From 26e8c1a930b63c0ca04d574c966a6e3de43380d1 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz Date: Wed, 11 Dec 2024 08:39:16 +0000 Subject: [PATCH 01/13] Update accounts --- docs/architecture/accounts.md | 40 +++++++++++++++++------------------ docs/index.md | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/architecture/accounts.md b/docs/architecture/accounts.md index e8b68cd9d..c76ca45e1 100644 --- a/docs/architecture/accounts.md +++ b/docs/architecture/accounts.md @@ -1,29 +1,27 @@ -Accounts are basic building blocks representing a user or an autonomous smart contract. +# Accounts -For smart contracts, the go-to solution is account-based state. Miden supports expressive smart contracts via a Turing-complete language and the use of accounts. +In Miden, every account is a smart contract. -In Miden, an account is an entity that holds assets and defines rules about how to transfer these assets. - -## Account design - -In Miden, every account is a smart contract. The diagram below illustrates the basic components of an account. +The diagram below illustrates the basic components of an account:

Account diagram

-> **Tip: Key to diagram** -> - **Account ID**: A unique identifier for an account. This does not change throughout its lifetime. -> - **Storage**: User-defined data which can be stored in an account. -> - **Nonce**: A counter which increments whenever the account state changes. -> - **Vault**: A collection of assets stored in an account. -> - **Code**: A collection of functions which define the external interface for an account. +> **Info:** +> - **ID**: Immutable unique identifier for an account. +> - **Storage**: User-defined data stored in an account. +> - **Nonce**: Counter incrementing on each state change. +> - **Vault**: Collection of assets stored in the account. +> - **Code**: Collection of functions defining the account interface. ### Account ID -A `~63` bits long identifier for the account ID (one field element `felt`). +A `~63` bits long identifier (one field element `felt`). -The four most significant bits specify the [account type](#account-types) - regular or faucet - and the account-storage-modes - public or private. +The four most significant bits specify both: +* [account type](#account-types): regular or faucet +* [account-storage-mode](#account-storage-mode): public or private ### Account storage @@ -38,13 +36,13 @@ As described below, accounts can be stored off-chain (private) and on-chain (pub ### Nonce -A counter which increments whenever the account state changes. +A Counter incrementing on each state change. Nonce values must be strictly monotonically increasing and increment by any value smaller than `2^32` for every account update. ### Vault -An asset container for an account. +A collection of [assets](assets.md) stored in the account. An account vault can contain an unlimited number of [assets](assets.md). The assets are stored in a sparse Merkle tree as follows: @@ -55,11 +53,13 @@ An account vault can be reduced to a single hash which is the root of the sparse ### Code -The interface for accounts. In Miden, every account is a smart contract. It has an interface that exposes functions that can be called by [note scripts](notes.md#the-note-script) and transaction scripts. Users cannot call those functions directly. +A collection of functions defining the account interface. + +In Miden, every account is a smart contract. It has an interface that exposes functions that can be called by [note scripts](notes.md#the-note-script) and transaction scripts. Functions exposed by the account have the following properties: -* Functions are actually roots of [Miden program MASTs](https://0xpolygonmiden.github.io/miden-vm/user_docs/assembly/main.html) (i.e., a `32`-byte hash). Thus, the function identifier is a commitment to the code which is executed when a function is invoked. +* Functions are roots of [Miden program MASTs](https://0xpolygonmiden.github.io/miden-vm/user_docs/assembly/main.html) (i.e., a `32`-byte hash). Thus, the function identifier is a commitment to the code which is executed when a function is invoked. * Only account functions have [mutable access](transactions/contexts.md) to an account's storage and vault. Therefore, the only way to modify an account's internal state is through one of the account's functions. * Account functions can take parameters and can create new notes. @@ -203,7 +203,7 @@ Type and mutability are encoded in the most significant bits of the account's ID | **Code updatability** | Yes | No | No | No | | **Most significant bits** | `00` | `01` | `10` | `11` | -## Public and private accounts +## Account storage mode Users can decide whether to keep their accounts private or public at account creation. The account ID encodes this preference in the third and fourth most significant bits. diff --git a/docs/index.md b/docs/index.md index 5705bc82c..68f0488bc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,7 +8,7 @@ If you want to join the technical discussion, please check out the following: * [Discord](https://discord.gg/0xpolygonRnD) * [Miden repo](https://github.com/0xPolygonMiden) -* [Roadmap](introduction/roadmap.md) +* [Roadmap](roadmap.md) > **Info** > - These docs are still work-in-progress. From 13a153b78df5dcdbfe25a39e86f6d0c8f985c3e0 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz Date: Wed, 11 Dec 2024 13:27:29 +0000 Subject: [PATCH 02/13] Update notes to more explanative stance --- docs/architecture/notes.md | 326 +++++++++++++------------------------ 1 file changed, 109 insertions(+), 217 deletions(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 712dd5ae3..8bcc28a56 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -1,261 +1,102 @@ -Two of Miden's key goals are parallel transaction execution and privacy. +# Notes -Polygon Miden implements a hybrid UTXO and account-based [state model](state.md) which enforces these goals with notes. Notes interact with, and transfer assets between, accounts. They can be consumed and produced asynchronously and privately. +> The medium through which [Accounts](accounts.md) communicate in the Miden protocol -The concept of notes is a key divergence from Ethereum’s account-based model. +## What is a Note? -## Note design +A note in Miden is an object containing both assets and the logic that governs how these assets can be consumed. By blending concepts from both UTXO and account-based models, notes allow for asynchronous and privacy-preserving asset transfers between accounts. This approach enables parallel transaction execution and strong privacy guarantees. + +## The Notes Core Components + +A `Note` is composed of several core components, illustrated below:

Note diagram

-> **Tip: Key to diagram** -> - **Assets**: An [asset](assets.md) container for a note. It can contain up to `256` assets stored in an array which can be reduced to a single hash. -> - **Script**: To be executed in the [transaction](https://0xpolygonmiden.github.io/miden-base/architecture/transactions.html) in which the note is consumed. The script defines the conditions for the consumption. If the script fails, the note cannot be consumed. -> - **Inputs**: Used to execute the note script. They can be accessed by the note script via [transaction kernel procedures](./transactions/kernel.md). A note can be associated with up to `128` input values. Each value is represented by a single field element. Thus, note input values can contain up to `~1` KB of data. -> - **Serial number**: A note's unique identifier to break link-ability between note hash and [nullifier](#note-nullifier-to-ensure-private-consumption). Should be a random `word` chosen by the user - if revealed, the nullifier might be computed easily. -> - In addition, a note has metadata including the sender and the note tag. Those values are always public regardless of the [note storage mode](#note-storage-mode). +These components are: -## Note lifecycle +1. [Assets](#assets) +2. [Script](#script) +3. [Inputs](#inputs) +4. [Serial number](#serial-number) +5. [Metadata](#metadata) -New notes are created by executing transactions. +### Assets -After verifying the transaction proof the operator adds either only the note hash (private notes) or the full note data (public notes) to the note database. +> An [asset](assets.md) container for a note. -Notes can be produced and consumed locally by users in local transactions or by the operator in a network transaction. +A note can contain up to `256` assets arranged in an array, which can be cryptographically reduced to a single hash. These assets represent fungible or non-fungible tokens, enabling flexible asset transfers. -Note consumption requires the transacting party to know the note data to compute the nullifier. After successful verification, the operator sets the corresponding entry in the nullifier database to "consumed". +### Script -![Architecture core concepts](../img/architecture/note/note-life-cycle.png) +> The code executed during the [transaction](https://0xpolygonmiden.github.io/miden-base/architecture/transactions.html) in which the note is consumed. -### Note creation - -Notes are created as the outputs (`OutputNotes`) of Miden transactions. Operators record the notes to the [note database](state.md#note-database). After successful verification of the underlying transactions, those notes can be consumed. - -### The note script - -Every note has a script which gets executed at note consumption. It is always executed in the context of a single account, and thus, may invoke zero or more of the [account's functions](accounts.md#code). The script allows for more than just asset transfers; actions which could be of arbitrary complexity thanks to the Turing completeness of the Miden VM. - -By design, every note script can be defined as a unique hash or the root of a [Miden program MAST](https://0xpolygonmiden.github.io/miden-vm/user_docs/assembly/main.html). That also means every function is a commitment to the underlying code. That code cannot change unnoticed to the user because its hash changes. That way it is easy to recognize standardized notes and those which deviate. - -Note scripts are created together with their inputs, i.e., the creator of the note defines which inputs are used at note execution by the executor. However, the executor or prover can pass optional note args. Note args are data put onto the stack right before a note script is executed. These are different from note inputs, as the executing account can specify arbitrary note args. - -There are [standard note scripts](https://github.com/0xPolygonMiden/miden-base/tree/main/miden-lib/asm/note_scripts) (P2ID, P2IDR, SWAP) that users can create and add to their notes using the Miden client or by calling internal [Rust code](https://github.com/0xPolygonMiden/miden-base/blob/fa63b26d845f910d12bd5744f34a6e55c08d5cde/miden-lib/src/notes/mod.rs#L15-L66). - -- P2ID and P2IDR scripts are used to send assets to a specific account ID. The scripts check at note consumption if the executing account ID equals the account ID that was set by the note creator as note inputs. The P2IDR script is reclaimable and thus after a certain block height can also be consumed by the sender itself. -- SWAP script is a simple way to swap assets. It adds an asset from the note into the consumer's vault and creates a new note consumable by the first note's issuer containing the requested asset. - -> **Example note script pay to ID (P2ID)** -> -> #### Goal of the P2ID script -> -> The P2ID script defines a specific target account ID as the only account that can consume the note. Such notes ensure a targeted asset transfer. -> -> #### Imports and context -> -> The P2ID script uses procedures from the account, note and wallet API. -> -> ```arduino -> use.miden::account -> use.miden::note -> use.miden::contracts::wallets::basic->wallet -> ``` -> -> As discussed in detail in [transaction kernel procedures](transactions/procedures.md) certain procedures can only be invoked in certain contexts. The note script is being executed in the note context of the [transaction kernel](transactions/kernel.md). -> -> #### Main script -> -> The main part of the P2ID script checks if the executing account is the same as the account defined in the `NoteInputs`. The creator of the note defines the note script and the note inputs separately to ensure usage of the same standardized P2ID script regardless of the target account ID. That way, it is enough to check the script root (see above). -> -> ```arduino -> # Pay-to-ID script: adds all assets from the note to the account, assuming ID of the account -> # matches target account ID specified by the note inputs. -> # -> # Requires that the account exposes: miden::contracts::wallets::basic::receive_asset procedure. -> # -> # Inputs: [SCRIPT_ROOT] -> # Outputs: [] -> # -> # Note inputs are assumed to be as follows: -> # - target_account_id is the ID of the account for which the note is intended. -> # -> # FAILS if: -> # - Account does not expose miden::contracts::wallets::basic::receive_asset procedure. -> # - Account ID of executing account is not equal to the Account ID specified via note inputs. -> # - The same non-fungible asset already exists in the account. -> # - Adding a fungible asset would result in amount overflow, i.e., the total amount would be -> # greater than 2^63. -> begin -> # drop the transaction script root -> dropw -> # => [] -> -> # load the note inputs to memory starting at address 0 -> push.0 exec.note::get_inputs -> # => [inputs_ptr] -> -> # read the target account id from the note inputs -> mem_load -> # => [target_account_id] -> -> exec.account::get_id -> # => [account_id, target_account_id, ...] -> -> # ensure account_id = target_account_id, fails otherwise -> assert_eq -> # => [...] -> -> exec.add_note_assets_to_account -> # => [...] -> end -> ``` -> -> 1. Every note script starts with the note script root on top of the stack. -> 2. After the `dropw`, the stack is cleared. -> 3. Next, the script stored the note inputs at pos 0 in the [relative note context memory](https://0xpolygonmiden.github.io/miden-base/transactions/transaction-procedures.html#transaction-contexts) by `push.0 exec.note::get_inputs`. -> 4. Then, `mem_load` loads a `Felt` from the specified memory address and puts it on top of the stack, in that cases the `target_account_id` defined by the creator of the note. -> 5. Now, the note invokes `get_id` from the account API using `exec.account::get_id` - which is possible even in the note context. -> -> Because, there are two account IDs on top of the stack now, `assert_eq` fails if the two account IDs (target_account_id and executing_account_id) are not the same. That means, the script cannot be successfully executed if executed by any other account than the account specified by the note creator using the note inputs. -> -> If execution hasn't failed, the script invokes a helper procedure `exec.add_note_assets_to_account` to add the note's assets into the executing account's vault. -> -> #### Add assets -> -> This procedure adds the assets held by the note into the account's vault. -> -> ```arduino -> #! Helper procedure to add all assets of a note to an account. -> #! -> #! Inputs: [] -> #! Outputs: [] -> #! -> proc.add_note_assets_to_account -> push.0 exec.note::get_assets -> # => [num_of_assets, 0 = ptr, ...] -> -> # compute the pointer at which we should stop iterating -> dup.1 add -> # => [ - -end_ptr, ptr, ...] -> -> # pad the stack and move the pointer to the top -> padw movup.5 -> # => [ptr, 0, 0, 0, 0, end_ptr, ...] -> -> # compute the loop latch -> dup dup.6 neq -> # => [latch, ptr, 0, 0, 0, 0, end_ptr, ...] -> -> while.true -> # => [ptr, 0, 0, 0, 0, end_ptr, ...] -> -> # save the pointer so that we can use it later -> dup movdn.5 -> # => [ptr, 0, 0, 0, 0, ptr, end_ptr, ...] -> -> # load the asset and add it to the account -> mem_loadw call.wallet::receive_asset -> # => [ASSET, ptr, end_ptr, ...] -> -> # increment the pointer and compare it to the end_ptr -> movup.4 add.1 dup dup.6 neq -> # => [latch, ptr+1, ASSET, end_ptr, ...] -> end -> -> # clear the stack -> drop dropw drop -> end -> ``` -> -> The procedure starts by calling `exec.note::get_assets`. As with the note's inputs before, this writes the assets of the note into memory starting at the specified address. Assets are stored in consecutive memory slots, so `dup.1 add` provides the last memory slot. -> -> In Miden, [assets](assets.md) are represented by `Words`, so we need to pad the stack with four `0`s to make room for an asset. Now, if there is at least one asset (checked by `dup dup.6 neq`), the loop starts. It first saves the pointer for later use (`dup movdn.5`), then loads the first asset `mem_loadw` on top of the stack. -> -> Now, the procedure calls the a function of the account interface `call.wallet::receive_asset` to put the asset into the account's vault. Due to different [contexts](https://0xpolygonmiden.github.io/miden-base/transactions/transaction-procedures.html#transaction-contexts), a note script cannot directly call an account function to add the asset. The account must expose this function in its [interface](https://0xpolygonmiden.github.io/miden-base/architecture/accounts.html#example-account-code). -> -> Lastly, the pointer gets incremented, and if there is a second asset, the loop continues (`movup.4 add.1 dup dup.6 neq`). Finally, when all assets were put into the account's vault, the stack is cleared (`drop dropw drop`). - -### Note storage mode - -Similar to accounts, there are two storage modes for notes in Miden - private and public. Notes can be stored publicly in the [note database](https://0xpolygonmiden.github.io/miden-base/architecture/state.html#notes-database) with all data publicly visible for everyone. Alternatively, notes can be stored privately by committing only the note hash to the note database. - -Every note has a unique note hash. It is defined as follows: +Each note has an associated script that defines the conditions under which it can be consumed. Because the script is executed in the context of a specific account, it may invoke that account’s functions, enabling complex operations beyond simple asset transfers. The Miden VM’s Turing completeness allows for arbitrary logic, making note scripts highly versatile. -```arduino -hash(hash(hash(hash(serial_num, [0; 4]), script_hash), input_hash), vault_hash) -``` +Every note script is represented as a commitment to underlying code—via a unique hash or a Miden program MAST root. This ensures that any changes to the script are detectable, preserving trust. Scripts are accompanied by inputs defined at note creation. Additionally, executors can provide optional “note args” before execution, granting flexibility in how the script is run. -> **Info** -> To compute a note's hash, we do not need to know the note's `serial_num`. Knowing the hash of the `serial_num` (as well as `script_hash`, `input_hash` and `note_vault`) is also sufficient. We compute the hash of `serial_num` as `hash(serial_num, [0; 4])` to simplify processing within the VM._ +### Inputs -### Note discovery (note tags) +> Arguments passed to the note script during execution. -Note discovery describes the process by which Miden clients find notes they want to consume. Miden clients can query the Miden node for notes carrying a certain note tag in their metadata. Note tags are best-effort filters for notes registered on the network. They are lightweight values (32-bit) used to speed up queries. Clients can follow tags for specific use cases, such as swap scripts, or user-created custom tags. Tags are also used by the operator to identify notes intended for network execution and include the corresponding information on how to execute them. +A note can have up to `128` input values, each stored as a single field element. These inputs can be accessed by the note script via [transaction kernel procedures](./transactions/kernel.md). With the ability to carry up to ~1 KB of data, these inputs can convey arbitrary parameters for note consumption. -The two most signification bits of the note tag have the following interpretation: +### Serial number -| Prefix | Execution hint | Target | Allowed note type | -| ------ | :------------: | :------: | :----------------:| -| `0b00` | Network | Specific | NoteType::Public | -| `0b01` | Network | Use case | NoteType::Public | -| `0b10` | Local | Any | NoteType::Public | -| `0b11` | Local | Any | Any | +> A unique and immutable identifier for the note. -- Execution hint: Set to `Network` for network transactions. These notes are validated and, if possible, consumed in a network transaction. -- Target: Describes how to interpret the bits in the note tag. For tags with a specific target, the rest of the tag is interpreted as an `account_id`. For use case values, the meaning of the rest of the tag is not specified by the protocol and can be used by applications built on top of the rollup. -- Allowed note type: Describes the note's storage mode, either `public` or `private`. +The serial number helps prevent linkability between the note’s hash and its nullifier. It should be a random `word` chosen by the user. If leaked, the note’s nullifier can be easily computed, potentially compromising privacy. -The following 30 bits can represent anything. In the above example note tag, it represents an account Id of a public account. As designed the first bit of a public account is always `0` which overlaps with the second most significant bit of the note tag. +### Metadata -``` -0b00000100_11111010_01010160_11100020 -``` +> Additional note information. + +Notes include metadata such as the sender’s account ID and a [tag](#note-discovery) that aids in discovery. Regardless of [storage mode](#note-storage-mode), these metadata fields remain public. + +## Note Lifecycle + +![Architecture core concepts](../img/architecture/note/note-life-cycle.png) -This example note tag indicates that the network operator (Miden node) executes the note against a specific account - `0x09f4adc47857e2f6`. Only the 30 most significant bits of the account id are represented in the note tag, since account Ids are 64-bit values but note tags only have 32-bits. Knowing a 30-bit prefix already narrows the set of potential target accounts down enough. +The note lifecycle proceeds through four primary phases: **creation**, **validation**, **discovery**, and **consumption**. Throughout this process, notes function as secure, privacy-preserving vehicles for asset transfers and logic execution. -Using note tags is a compromise between privacy and latency. If a user queries the operator using the note ID, the operator learns which note a specific user is interested in. Alternatively, if a user always downloads all registered notes and filters locally, it is quite inefficient. By using tags, users can customize privacy parameters by narrowing or broadening their note tag schemes. +### Note Creation -> **Example note tag for P2ID** -> P2ID scripts can only be consumed by the specified account ID (target ID). In the standard schema, the target ID is encoded into the note tag. -> -> For network execution of a P2ID note, the note tag is encoded as follows: 0b00000100_11111010_01010160_11100020. This encoding allows the Miden operator to quickly identify the account against which the transaction must be executed. -> -> For local execution of a P2ID note, the recipient needs to be able to discover the note. The recipient can query the Miden node for a specific tag to see if there are new P2ID notes to be consumed. In this case, the two most significant bits are set to 0b11, allowing any note type (private or public) to be used. The next 14 bits represent the 14 most significant bits of the account ID, and the remaining 16 bits are set to 0. -> -> Example for local execution: -> ``` -> 0b11000100_11111010_00000000_00000000 -> ``` -> This "fuzzy matching" approach balances privacy and efficiency. A note with this tag could be intended for any account sharing the same 16-bit prefix. +One or more notes can be generated as `OutputNotes` when Miden transactions complete successfully. These transactions may be initiated by: -### Note consumption +- **Users:** Executing local or network transactions. +- **Miden operators:** Facilitating on-chain actions, e.g. such as executing user notes against a DEX or other contracts. -As with creation, notes can only be consumed in Miden transactions. If a valid transaction consuming an `InputNote` gets verified by the Miden node, the note's unique nullifier gets added to the [nullifier database](https://0xpolygonmiden.github.io/miden-base/architecture/state.html#nullifier-database) and is therefore consumed. +#### Note Storage Mode -Notes can only be consumed if the note data is known to the consumer. The note data must be provided as input to the [transaction kernel](transactions/kernel.md). That means, for privately stored notes, there must be some off-chain communication to transmit the note's data from the sender to the target. +As with [accounts](accounts.md), notes can be stored either publicly or privately: -### Note recipient to restrict note consumption +- **Public mode:** The note data is stored in the [note database](https://0xpolygonmiden.github.io/miden-base/architecture/state.html#notes-database), making it fully visible on-chain. +- **Private mode:** Only the note’s hash (a cryptographic commitment) is stored. The note’s actual data remains off-chain, enhancing privacy. -There are several ways to restrict the set of accounts that can consume a specific note. One way is to specifically define the target account ID as done in the P2ID and P2IDR note scripts. Another way is by using the concept of a `RECIPIENT`. Miden defines a `RECIPIENT` (represented as `Word`) as: +The note’s hash can be computed as: ```arduino -hash(hash(hash(serial_num, [0; 4]), script_hash), input_hash) +hash(hash(hash(hash(serial_num, [0; 4]), script_hash), input_hash), vault_hash) ``` -This concept restricts note consumption to those users who know the pre-image data of `RECIPIENT` - which might be a bigger set than a single account. +#### Note Recipient - Restricting Consumption + +Consumption of a note can be restricted to certain accounts or entities. For instance, the P2ID and P2IDR note scripts target a specific account ID. Alternatively, Miden defines a `RECIPIENT` (represented as a `Word`) computed as: + +```arduino +hash(hash(hash(serial_num, [0; 4]), script_hash), input_hash) +``` -During the [transaction prologue](transactions/kernel.md) the users needs to provide all the data to compute the note hash. That means, one can create notes that can only be consumed if the `serial_num` and other data is known. This information can be passed off-chain from the sender to the consumer. This is only useful with private notes. For public notes, +Only those who know the `RECIPIENT`’s pre-image can consume the note. For private notes, this ensures an additional layer of control and privacy, as only parties with the correct data can claim the note. - all note data is known, and anyone can compute the `RECIPIENT`. +The [transaction prologue](transactions/kernel.md) requires all necessary data to compute the note hash. This setup allows scenario-specific restrictions on who may consume a note. -You can see in the standard [SWAP note script](https://github.com/0xPolygonMiden/miden-base/blob/main/miden-lib/asm/note_scripts/SWAP.masm) how `RECIPIENT` is used. Here, using a single hash, is sufficient to ensure that the swapped asset and its note can only be consumed by the defined target. +For a practical example, refer to the [SWAP note script](https://github.com/0xPolygonMiden/miden-base/blob/main/miden-lib/asm/note_scripts/SWAP.masm), where the `RECIPIENT` ensures that only a defined target can consume the swapped asset. -### Note nullifier to ensure private consumption +#### Note Nullifier - Ensuring Private Consumption -The note's nullifier is computed as: +The note nullifier, computed as: ```arduino hash(serial_num, script_hash, input_hash, vault_hash) @@ -270,3 +111,54 @@ This achieves the following properties: That means if a note is private and the operator stores only the note's hash, only those with the note details know if this note has been consumed already. Zcash first [introduced](https://zcash.github.io/orchard/design/nullifiers.html#nullifiers) this approach. ![Architecture core concepts](../img/architecture/note/nullifier.png) + +### Note Validation + +Once created, a note must be validated by a Miden operator. Validation involves checking the transaction proof that produced the note to ensure it meets all protocol requirements. + +- **Private Notes:** Only the note’s hash is recorded on-chain, keeping the data confidential. +- **Public Notes:** The full note data is stored, providing transparency for applications requiring public state visibility. + +After validation, notes become “live” and eligible for discovery and eventual consumption. + +### Note Discovery + +Clients often need to find specific notes of interest. Miden allows clients to query the note database using note tags. These lightweight, 32-bit tags serve as best-effort filters, enabling quick lookups for notes related to particular use cases, scripts, or account prefixes. + +The two most significant bits of the note tag guide its interpretation: + +| Prefix | Execution hint | Target | Allowed note type | +| ------ | :------------: | :------: | :----------------:| +| `0b00` | Network | Specific | NoteType::Public | +| `0b01` | Network | Use case | NoteType::Public | +| `0b10` | Local | Any | NoteType::Public | +| `0b11` | Local | Any | Any | + +- **Execution hint:** Indicates whether the note is meant for network or local transactions. +- **Target:** Describes how to interpret the bits in the note tag. For tags with a specific target, the rest of the tag is interpreted as an account_id. For use case values, the meaning of the rest of the tag is not specified by the protocol and can be used by applications built on top of the rollup. +- **Allowed note type:** Specifies the note's storage mode, either `public` or `private` + +> Example: +> +> The following 30 bits can represent anything. In the above example note tag, it represents an account Id of a public account. As designed the first bit of a public account is always `0` which overlaps with the second most significant bit of the note tag. +> +>``` +>0b00000100_11111010_01010160_11100020 +>``` +> +>This example note tag indicates that the network operator (Miden node) executes the note against a specific account - `0x09f4adc47857e2f6`. Only the 30 most significant bits of the account id are represented in the note tag, since account Ids are 64-bit values but note tags only have 32-bits. Knowing a 30-bit prefix already narrows the set of potential target accounts down enough. + +Using note tags strikes a balance between privacy and efficiency. Without tags, querying a specific note ID reveals a user’s interest to the operator. Conversely, downloading and filtering all registered notes locally is highly inefficient. Tags allow users to adjust their level of privacy by choosing how broadly or narrowly they define their search criteria, letting them find the right balance between revealing too much information and incurring excessive computational overhead. + +### Note Consumption + +To consume a note, the consumer must know its data, including the inputs needed to compute the nullifier. Consumption occurs as part of a transaction. Upon successful consumption a nullifier is generated for the consumed notes. + +Upon successful verification of the transaction: + +1. The Miden operator records the note’s nullifier as “consumed” in the nullifier database. +2. The note’s one-time claim is thus extinguished, preventing reuse. + +## Conclusion + +Miden’s notes introduce a powerful mechanism for secure, flexible, and private state management. By enabling asynchronous asset transfers, parallel execution, and privacy at scale, they transcend the limitations of strictly account-based models. As a result, developers and users alike enjoy enhanced scalability, confidentiality, and control. With these capabilities, Miden is paving the way for true **programmable money** where assets, logic, and trust converge seamlessly. From 59fa1e7f629996b9c26a6e1d63de0adbb9cc345f Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz Date: Wed, 11 Dec 2024 13:31:38 +0000 Subject: [PATCH 03/13] Reset accounts.md --- docs/architecture/accounts.md | 40 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/architecture/accounts.md b/docs/architecture/accounts.md index c76ca45e1..e8b68cd9d 100644 --- a/docs/architecture/accounts.md +++ b/docs/architecture/accounts.md @@ -1,27 +1,29 @@ -# Accounts +Accounts are basic building blocks representing a user or an autonomous smart contract. -In Miden, every account is a smart contract. +For smart contracts, the go-to solution is account-based state. Miden supports expressive smart contracts via a Turing-complete language and the use of accounts. -The diagram below illustrates the basic components of an account: +In Miden, an account is an entity that holds assets and defines rules about how to transfer these assets. + +## Account design + +In Miden, every account is a smart contract. The diagram below illustrates the basic components of an account.

Account diagram

-> **Info:** -> - **ID**: Immutable unique identifier for an account. -> - **Storage**: User-defined data stored in an account. -> - **Nonce**: Counter incrementing on each state change. -> - **Vault**: Collection of assets stored in the account. -> - **Code**: Collection of functions defining the account interface. +> **Tip: Key to diagram** +> - **Account ID**: A unique identifier for an account. This does not change throughout its lifetime. +> - **Storage**: User-defined data which can be stored in an account. +> - **Nonce**: A counter which increments whenever the account state changes. +> - **Vault**: A collection of assets stored in an account. +> - **Code**: A collection of functions which define the external interface for an account. ### Account ID -A `~63` bits long identifier (one field element `felt`). +A `~63` bits long identifier for the account ID (one field element `felt`). -The four most significant bits specify both: -* [account type](#account-types): regular or faucet -* [account-storage-mode](#account-storage-mode): public or private +The four most significant bits specify the [account type](#account-types) - regular or faucet - and the account-storage-modes - public or private. ### Account storage @@ -36,13 +38,13 @@ As described below, accounts can be stored off-chain (private) and on-chain (pub ### Nonce -A Counter incrementing on each state change. +A counter which increments whenever the account state changes. Nonce values must be strictly monotonically increasing and increment by any value smaller than `2^32` for every account update. ### Vault -A collection of [assets](assets.md) stored in the account. +An asset container for an account. An account vault can contain an unlimited number of [assets](assets.md). The assets are stored in a sparse Merkle tree as follows: @@ -53,13 +55,11 @@ An account vault can be reduced to a single hash which is the root of the sparse ### Code -A collection of functions defining the account interface. - -In Miden, every account is a smart contract. It has an interface that exposes functions that can be called by [note scripts](notes.md#the-note-script) and transaction scripts. +The interface for accounts. In Miden, every account is a smart contract. It has an interface that exposes functions that can be called by [note scripts](notes.md#the-note-script) and transaction scripts. Users cannot call those functions directly. Functions exposed by the account have the following properties: -* Functions are roots of [Miden program MASTs](https://0xpolygonmiden.github.io/miden-vm/user_docs/assembly/main.html) (i.e., a `32`-byte hash). Thus, the function identifier is a commitment to the code which is executed when a function is invoked. +* Functions are actually roots of [Miden program MASTs](https://0xpolygonmiden.github.io/miden-vm/user_docs/assembly/main.html) (i.e., a `32`-byte hash). Thus, the function identifier is a commitment to the code which is executed when a function is invoked. * Only account functions have [mutable access](transactions/contexts.md) to an account's storage and vault. Therefore, the only way to modify an account's internal state is through one of the account's functions. * Account functions can take parameters and can create new notes. @@ -203,7 +203,7 @@ Type and mutability are encoded in the most significant bits of the account's ID | **Code updatability** | Yes | No | No | No | | **Most significant bits** | `00` | `01` | `10` | `11` | -## Account storage mode +## Public and private accounts Users can decide whether to keep their accounts private or public at account creation. The account ID encodes this preference in the third and fourth most significant bits. From a99999636412f1ca1cf5c47be101a4a519ccab55 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz <42912740+phklive@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:50:15 +0000 Subject: [PATCH 04/13] Update docs/architecture/notes.md Co-authored-by: Dominik Schmid <35031754+Dominik1999@users.noreply.github.com> --- docs/architecture/notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 8bcc28a56..10854df5e 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -4,7 +4,7 @@ ## What is a Note? -A note in Miden is an object containing both assets and the logic that governs how these assets can be consumed. By blending concepts from both UTXO and account-based models, notes allow for asynchronous and privacy-preserving asset transfers between accounts. This approach enables parallel transaction execution and strong privacy guarantees. +A note in Miden holds assets and defines how these assets can be consumed. The note model in Miden enables parallel transaction execution and privacy. ## The Notes Core Components From 6de609658c5892f267f453f4b8b7ef275fd220e1 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz <42912740+phklive@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:50:33 +0000 Subject: [PATCH 05/13] Update docs/architecture/notes.md Co-authored-by: Dominik Schmid <35031754+Dominik1999@users.noreply.github.com> --- docs/architecture/notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 10854df5e..08a38cec4 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -26,7 +26,7 @@ These components are: > An [asset](assets.md) container for a note. -A note can contain up to `256` assets arranged in an array, which can be cryptographically reduced to a single hash. These assets represent fungible or non-fungible tokens, enabling flexible asset transfers. +A note can contain up to `256` different assets. These assets represent fungible or non-fungible tokens, enabling flexible asset transfers. ### Script From 5e1cee2ee3e12e76744ab5c7ae4af9e554476452 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz <42912740+phklive@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:50:54 +0000 Subject: [PATCH 06/13] Update docs/architecture/notes.md Co-authored-by: Dominik Schmid <35031754+Dominik1999@users.noreply.github.com> --- docs/architecture/notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 08a38cec4..87d8af046 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -30,7 +30,7 @@ A note can contain up to `256` different assets. These assets represent fungible ### Script -> The code executed during the [transaction](https://0xpolygonmiden.github.io/miden-base/architecture/transactions.html) in which the note is consumed. +> The code executed when the note is consumed. Each note has an associated script that defines the conditions under which it can be consumed. Because the script is executed in the context of a specific account, it may invoke that account’s functions, enabling complex operations beyond simple asset transfers. The Miden VM’s Turing completeness allows for arbitrary logic, making note scripts highly versatile. From 77048eb8deac95cab3d68e9aaefa769b15c786a8 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz <42912740+phklive@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:51:23 +0000 Subject: [PATCH 07/13] Update docs/architecture/notes.md Co-authored-by: Dominik Schmid <35031754+Dominik1999@users.noreply.github.com> --- docs/architecture/notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 87d8af046..9675008df 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -34,7 +34,7 @@ A note can contain up to `256` different assets. These assets represent fungible Each note has an associated script that defines the conditions under which it can be consumed. Because the script is executed in the context of a specific account, it may invoke that account’s functions, enabling complex operations beyond simple asset transfers. The Miden VM’s Turing completeness allows for arbitrary logic, making note scripts highly versatile. -Every note script is represented as a commitment to underlying code—via a unique hash or a Miden program MAST root. This ensures that any changes to the script are detectable, preserving trust. Scripts are accompanied by inputs defined at note creation. Additionally, executors can provide optional “note args” before execution, granting flexibility in how the script is run. +The code in note scripts, more specifically each procedure, can be expressed as a unique MAST root. Like account code functions. This ensures that any changes to the script are detectable, preserving trust. ### Inputs From 65f25a7f59d2191236c9c5a9ecf26016d287f48f Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz <42912740+phklive@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:51:55 +0000 Subject: [PATCH 08/13] Update docs/architecture/notes.md Co-authored-by: Dominik Schmid <35031754+Dominik1999@users.noreply.github.com> --- docs/architecture/notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 9675008df..70f26d3b9 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -40,7 +40,7 @@ The code in note scripts, more specifically each procedure, can be expressed as > Arguments passed to the note script during execution. -A note can have up to `128` input values, each stored as a single field element. These inputs can be accessed by the note script via [transaction kernel procedures](./transactions/kernel.md). With the ability to carry up to ~1 KB of data, these inputs can convey arbitrary parameters for note consumption. +A note can have up to `128` input values, which adds up to a maximum of 1 KB of data. The note script can access these inputs. They can convey arbitrary parameters for note consumption. ### Serial number From fc7e58636ee75ab59f44350bca299dd2965ebbc2 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz <42912740+phklive@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:52:34 +0000 Subject: [PATCH 09/13] Update docs/architecture/notes.md Co-authored-by: Dominik Schmid <35031754+Dominik1999@users.noreply.github.com> --- docs/architecture/notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 70f26d3b9..a6a74fe12 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -62,7 +62,7 @@ The note lifecycle proceeds through four primary phases: **creation**, **validat ### Note Creation -One or more notes can be generated as `OutputNotes` when Miden transactions complete successfully. These transactions may be initiated by: +Accounts can create notes in a transaction. The note exists if it is included in the global Notes DB. - **Users:** Executing local or network transactions. - **Miden operators:** Facilitating on-chain actions, e.g. such as executing user notes against a DEX or other contracts. From 411d5941b468433a0cdbcb1fceaaf372078046e0 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz Date: Fri, 13 Dec 2024 10:35:36 +0000 Subject: [PATCH 10/13] Made updates --- docs/architecture/notes.md | 85 +++++++++++++------------------------- 1 file changed, 29 insertions(+), 56 deletions(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index a6a74fe12..222a39ef5 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -32,9 +32,7 @@ A note can contain up to `256` different assets. These assets represent fungible > The code executed when the note is consumed. -Each note has an associated script that defines the conditions under which it can be consumed. Because the script is executed in the context of a specific account, it may invoke that account’s functions, enabling complex operations beyond simple asset transfers. The Miden VM’s Turing completeness allows for arbitrary logic, making note scripts highly versatile. - -The code in note scripts, more specifically each procedure, can be expressed as a unique MAST root. Like account code functions. This ensures that any changes to the script are detectable, preserving trust. +Each note has a script that defines the conditions under which it can be consumed. When accounts consume notes in transactions, note scripts call the account’s interface functions. This enables all sorts of operations beyond simple asset transfers. The Miden VM’s Turing completeness allows for arbitrary logic, making note scripts highly versatile. ### Inputs @@ -46,7 +44,7 @@ A note can have up to `128` input values, which adds up to a maximum of 1 KB of > A unique and immutable identifier for the note. -The serial number helps prevent linkability between the note’s hash and its nullifier. It should be a random `word` chosen by the user. If leaked, the note’s nullifier can be easily computed, potentially compromising privacy. +The serial number helps prevent linkability between the note’s hash and its nullifier. It should be a random `Word` chosen by the user. If leaked, the note’s nullifier can be easily computed, potentially compromising privacy. ### Metadata @@ -72,13 +70,35 @@ Accounts can create notes in a transaction. The note exists if it is included in As with [accounts](accounts.md), notes can be stored either publicly or privately: - **Public mode:** The note data is stored in the [note database](https://0xpolygonmiden.github.io/miden-base/architecture/state.html#notes-database), making it fully visible on-chain. -- **Private mode:** Only the note’s hash (a cryptographic commitment) is stored. The note’s actual data remains off-chain, enhancing privacy. +- **Private mode:** Only the note’s hash is stored. The note’s actual data remains off-chain, enhancing privacy. -The note’s hash can be computed as: +#### Ephemeral notes -```arduino -hash(hash(hash(hash(serial_num, [0; 4]), script_hash), input_hash), vault_hash) -``` +These use-case specific notes can be consumed even if not yet validated by being chained together into one final proof. This can allow for example sub second communication below blocktimes by adding additional trust assumptions. + +### Note Validation + +Once created, a note must be validated by a Miden operator. Validation involves checking the transaction proof that produced the note to ensure it meets all protocol requirements. + +- **Private Notes:** Only the note’s hash is recorded on-chain, keeping the data confidential. +- **Public Notes:** The full note data is stored, providing transparency for applications requiring public state visibility. + +After validation, notes become “live” and eligible for discovery and eventual consumption. + +### Note Discovery + +Clients often need to find specific notes of interest. Miden allows clients to query the note database using note tags. These lightweight, 32-bit tags serve as best-effort filters, enabling quick lookups for notes related to particular use cases, scripts, or account prefixes. + +Using note tags strikes a balance between privacy and efficiency. Without tags, querying a specific note ID reveals a user’s interest to the operator. Conversely, downloading and filtering all registered notes locally is highly inefficient. Tags allow users to adjust their level of privacy by choosing how broadly or narrowly they define their search criteria, letting them find the right balance between revealing too much information and incurring excessive computational overhead. + +### Note Consumption + +To consume a note, the consumer must know its data, including the inputs needed to compute the nullifier. Consumption occurs as part of a transaction. Upon successful consumption a nullifier is generated for the consumed notes. + +Upon successful verification of the transaction: + +1. The Miden operator records the note’s nullifier as “consumed” in the nullifier database. +2. The note’s one-time claim is thus extinguished, preventing reuse. #### Note Recipient - Restricting Consumption @@ -112,53 +132,6 @@ That means if a note is private and the operator stores only the note's hash, on ![Architecture core concepts](../img/architecture/note/nullifier.png) -### Note Validation - -Once created, a note must be validated by a Miden operator. Validation involves checking the transaction proof that produced the note to ensure it meets all protocol requirements. - -- **Private Notes:** Only the note’s hash is recorded on-chain, keeping the data confidential. -- **Public Notes:** The full note data is stored, providing transparency for applications requiring public state visibility. - -After validation, notes become “live” and eligible for discovery and eventual consumption. - -### Note Discovery - -Clients often need to find specific notes of interest. Miden allows clients to query the note database using note tags. These lightweight, 32-bit tags serve as best-effort filters, enabling quick lookups for notes related to particular use cases, scripts, or account prefixes. - -The two most significant bits of the note tag guide its interpretation: - -| Prefix | Execution hint | Target | Allowed note type | -| ------ | :------------: | :------: | :----------------:| -| `0b00` | Network | Specific | NoteType::Public | -| `0b01` | Network | Use case | NoteType::Public | -| `0b10` | Local | Any | NoteType::Public | -| `0b11` | Local | Any | Any | - -- **Execution hint:** Indicates whether the note is meant for network or local transactions. -- **Target:** Describes how to interpret the bits in the note tag. For tags with a specific target, the rest of the tag is interpreted as an account_id. For use case values, the meaning of the rest of the tag is not specified by the protocol and can be used by applications built on top of the rollup. -- **Allowed note type:** Specifies the note's storage mode, either `public` or `private` - -> Example: -> -> The following 30 bits can represent anything. In the above example note tag, it represents an account Id of a public account. As designed the first bit of a public account is always `0` which overlaps with the second most significant bit of the note tag. -> ->``` ->0b00000100_11111010_01010160_11100020 ->``` -> ->This example note tag indicates that the network operator (Miden node) executes the note against a specific account - `0x09f4adc47857e2f6`. Only the 30 most significant bits of the account id are represented in the note tag, since account Ids are 64-bit values but note tags only have 32-bits. Knowing a 30-bit prefix already narrows the set of potential target accounts down enough. - -Using note tags strikes a balance between privacy and efficiency. Without tags, querying a specific note ID reveals a user’s interest to the operator. Conversely, downloading and filtering all registered notes locally is highly inefficient. Tags allow users to adjust their level of privacy by choosing how broadly or narrowly they define their search criteria, letting them find the right balance between revealing too much information and incurring excessive computational overhead. - -### Note Consumption - -To consume a note, the consumer must know its data, including the inputs needed to compute the nullifier. Consumption occurs as part of a transaction. Upon successful consumption a nullifier is generated for the consumed notes. - -Upon successful verification of the transaction: - -1. The Miden operator records the note’s nullifier as “consumed” in the nullifier database. -2. The note’s one-time claim is thus extinguished, preventing reuse. - ## Conclusion Miden’s notes introduce a powerful mechanism for secure, flexible, and private state management. By enabling asynchronous asset transfers, parallel execution, and privacy at scale, they transcend the limitations of strictly account-based models. As a result, developers and users alike enjoy enhanced scalability, confidentiality, and control. With these capabilities, Miden is paving the way for true **programmable money** where assets, logic, and trust converge seamlessly. From df9479afb686350d5a313339d1923c57944af875 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz Date: Fri, 13 Dec 2024 10:41:08 +0000 Subject: [PATCH 11/13] Remove The --- docs/architecture/notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 222a39ef5..2751a4bc3 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -6,7 +6,7 @@ A note in Miden holds assets and defines how these assets can be consumed. The note model in Miden enables parallel transaction execution and privacy. -## The Notes Core Components +## Note Core Components A `Note` is composed of several core components, illustrated below: From c2090f9ee10135b51213652e2057397dacb34d6f Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz Date: Fri, 13 Dec 2024 10:43:46 +0000 Subject: [PATCH 12/13] Lowercase headers --- docs/architecture/notes.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 2751a4bc3..47ed9ce28 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -2,11 +2,11 @@ > The medium through which [Accounts](accounts.md) communicate in the Miden protocol -## What is a Note? +## What is a note? A note in Miden holds assets and defines how these assets can be consumed. The note model in Miden enables parallel transaction execution and privacy. -## Note Core Components +## Note core components A `Note` is composed of several core components, illustrated below: @@ -58,25 +58,25 @@ Notes include metadata such as the sender’s account ID and a [tag](#note-disco The note lifecycle proceeds through four primary phases: **creation**, **validation**, **discovery**, and **consumption**. Throughout this process, notes function as secure, privacy-preserving vehicles for asset transfers and logic execution. -### Note Creation +### Note creation Accounts can create notes in a transaction. The note exists if it is included in the global Notes DB. - **Users:** Executing local or network transactions. - **Miden operators:** Facilitating on-chain actions, e.g. such as executing user notes against a DEX or other contracts. -#### Note Storage Mode +#### Note storage mode As with [accounts](accounts.md), notes can be stored either publicly or privately: - **Public mode:** The note data is stored in the [note database](https://0xpolygonmiden.github.io/miden-base/architecture/state.html#notes-database), making it fully visible on-chain. - **Private mode:** Only the note’s hash is stored. The note’s actual data remains off-chain, enhancing privacy. -#### Ephemeral notes +#### Ephemeral note These use-case specific notes can be consumed even if not yet validated by being chained together into one final proof. This can allow for example sub second communication below blocktimes by adding additional trust assumptions. -### Note Validation +### Note validation Once created, a note must be validated by a Miden operator. Validation involves checking the transaction proof that produced the note to ensure it meets all protocol requirements. @@ -85,13 +85,13 @@ Once created, a note must be validated by a Miden operator. Validation involves After validation, notes become “live” and eligible for discovery and eventual consumption. -### Note Discovery +### Note discovery Clients often need to find specific notes of interest. Miden allows clients to query the note database using note tags. These lightweight, 32-bit tags serve as best-effort filters, enabling quick lookups for notes related to particular use cases, scripts, or account prefixes. Using note tags strikes a balance between privacy and efficiency. Without tags, querying a specific note ID reveals a user’s interest to the operator. Conversely, downloading and filtering all registered notes locally is highly inefficient. Tags allow users to adjust their level of privacy by choosing how broadly or narrowly they define their search criteria, letting them find the right balance between revealing too much information and incurring excessive computational overhead. -### Note Consumption +### Note consumption To consume a note, the consumer must know its data, including the inputs needed to compute the nullifier. Consumption occurs as part of a transaction. Upon successful consumption a nullifier is generated for the consumed notes. @@ -100,7 +100,7 @@ Upon successful verification of the transaction: 1. The Miden operator records the note’s nullifier as “consumed” in the nullifier database. 2. The note’s one-time claim is thus extinguished, preventing reuse. -#### Note Recipient - Restricting Consumption +#### Note recipient - restricting consumption Consumption of a note can be restricted to certain accounts or entities. For instance, the P2ID and P2IDR note scripts target a specific account ID. Alternatively, Miden defines a `RECIPIENT` (represented as a `Word`) computed as: @@ -114,7 +114,7 @@ The [transaction prologue](transactions/kernel.md) requires all necessary data t For a practical example, refer to the [SWAP note script](https://github.com/0xPolygonMiden/miden-base/blob/main/miden-lib/asm/note_scripts/SWAP.masm), where the `RECIPIENT` ensures that only a defined target can consume the swapped asset. -#### Note Nullifier - Ensuring Private Consumption +#### Note nullifier - ensuring private consumption The note nullifier, computed as: From 9e5727f926288dcf3c4f3a65e9888ecbaa8c6a04 Mon Sep 17 00:00:00 2001 From: Paul-Henry Kajfasz Date: Mon, 16 Dec 2024 21:21:44 +0000 Subject: [PATCH 13/13] Added the purpose of a Note --- docs/architecture/notes.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/architecture/notes.md b/docs/architecture/notes.md index 47ed9ce28..3c76f1640 100644 --- a/docs/architecture/notes.md +++ b/docs/architecture/notes.md @@ -2,9 +2,13 @@ > The medium through which [Accounts](accounts.md) communicate in the Miden protocol +## What is the purpose of a note? + +In Miden's hybrid UTXO and account-based model notes represent UTXO's which enable parallel transaction execution and privacy through asynchronous local note production and consumption. + ## What is a note? -A note in Miden holds assets and defines how these assets can be consumed. The note model in Miden enables parallel transaction execution and privacy. +A note in Miden holds assets and defines how these assets can be consumed. ## Note core components