Skip to content

Commit e950f1c

Browse files
add clarification re directory
1 parent 049df84 commit e950f1c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1776
-1
lines changed

docs/cdk/how-to/use-native-token.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ You have previously deployed a CDK using previous versions.
1212

1313
## Use a custom native token
1414

15-
Open the deploy_parameters.json file and add a new entry:
15+
Go to the `...contracts/deployment` folder and find the `deploy_parameters.json` file.
16+
17+
!!! warning
18+
The directory naming is dependent on your build type (rollup or validium).
19+
20+
Open the `deploy_parameters.json` file and add a new entry:
1621

1722
```json
1823
{
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Miden base documentation
2+
3+
Welcome to the Miden base repo docs.
4+
5+
## Running locally
6+
7+
### Prerequisites
8+
9+
1. [Python 3.12](https://www.python.org/downloads/).
10+
2. [`virtualenv`](https://pypi.org/project/virtualenv/): Install using `pip3 install virtualenv`.
11+
12+
### Setup
13+
14+
1. Clone the repository.
15+
2. `cd` to the root.
16+
3. Run the `run.sh` script. You may need to make the script executable: `chmod +x run.sh`
17+
18+
```sh
19+
./run.sh
20+
```
21+
22+
The site comes up at http://127.0.0.1:8000/
23+
24+
## Style guide
25+
26+
We are using the [Microsoft Style Guide](https://learn.microsoft.com/en-us/style-guide/welcome/).
27+
28+
## Contributing
29+
30+
1. Fork the `main` branch into your own GitHub account and create a feature branch for your changes.
31+
2. Commit changes and create a PR.
32+
33+
## Contact
34+
35+
- For docs issues (technical or language) open an issue here.
36+
- For anything else, join our [Discord](https://discord.gg/0xpolygondevs).
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# Accounts
2+
Miden aims to support expressive smart contracts via a Turing-complete language. For smart contracts the go-to solution is account-based state. In Miden, an account is an entity which holds assets and defines rules of how these assets can be transferred. They are basic building blocks representing a user or an autonomous smart contract.
3+
4+
## Account Design
5+
The diagram below illustrates basic components of an account. In Miden every account is a smart contract.
6+
7+
<center>
8+
![Architecture core concepts](../img/architecture/account/account-definition.png){ width="25%" }
9+
</center>
10+
11+
In the above picture, you can see:
12+
13+
* **Account ID &rarr;** a unique identifier of an account which does not change throughout its lifetime
14+
* **Storage &rarr;** user-defined data which can be stored in an account
15+
* **Nonce &rarr;** a counter which must be incremented whenever the account state changes
16+
* **Vault &rarr;** a collection of assets stored in an account
17+
* **Code &rarr;** a collection of functions which define the external interface for an account
18+
19+
### Account ID
20+
~63 bits (1 field element) long identifier for the account. The four most significant bits specify its [account type](https://0xpolygonmiden.github.io/miden-base/architecture/accounts.html#account-types) - regular, immutable, faucet - and the [storage mode](https://0xpolygonmiden.github.io/miden-base/architecture/accounts.html#account-storage-modes) - public or private.
21+
22+
### Account Storage
23+
Storage for user-defined data. `AccountStorage` is composed of two components.
24+
25+
The first component is a simple Sparse Merkle Tree of depth `8` which is index addressable. This provides the user with `256` `Word` slots.
26+
27+
Users requiring additional storage can use the second component a `MerkleStore`. It allows users to store any Merkle structures they need. The root of the Merkle structure can be stored as a leaf in a simple Sparse Merkle Tree. When `AccountStorage` is serialized it will check if any of the leafs in the simple Sparse Merkle Tree are Merkle roots of other Merkle structures. If any Merkle roots are found then the Merkle structures will be persisted in the `AccountStorage` `MerkleStore`.
28+
29+
### Nonce
30+
Counter which must be incremented whenever the account state changes. Nonce values must be strictly monotonically increasing and can be incremented by any value smaller than 2^{32} for every account update.
31+
32+
### Vault
33+
Asset container for an account.
34+
35+
An account vault can contain an unlimited number of [assets](https://0xpolygonmiden.github.io/miden-base/architecture/assets.html). The assets are stored in a sparse
36+
Merkle tree as follows:
37+
38+
* For fungible assets, the index of a node is defined by the issuing faucet ID, and the value
39+
of the node is the asset itself. Thus, for any fungible asset there will be only one node
40+
in the tree.
41+
* For non-fungible assets, the index is defined by the asset itself, and the asset is also
42+
the value of the node.
43+
44+
An account vault can be reduced to a single hash which is the root of the Sparse Merkle Tree.
45+
46+
### Code
47+
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](https://0xpolygonmiden.github.io/miden-base/architecture/notes.html#note-scripts) and [transaction scripts](https://0xpolygonmiden.github.io/miden-base/transactions/transaction-kernel.html#the-transaction-script-processing). Users cannot call those functions directly.
48+
49+
Functions exposed by the account have the following properties:
50+
51+
* 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, function identifier is a commitment to the code which is executed when a function is invoked.
52+
* Only account functions have mutable access 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.
53+
* Account functions can take parameters and can create new notes.
54+
55+
*Note: Since code in Miden is expressed as MAST, every function is a commitment to the underlying code. The code cannot change unnoticed to the user because its hash would change. Behind any MAST root there can only be `256` functions*
56+
57+
#### Example Account Code
58+
Currently, Miden provides two standard implementations for account code.
59+
60+
##### Basic user account (Regular updatable account)
61+
There is a standard for a basic user account. It exposes three functions via its interface.
62+
<details>
63+
<summary>Want to see the code?</summary>
64+
65+
```
66+
use.miden::contracts::wallets::basic->basic_wallet
67+
use.miden::contracts::auth::basic
68+
69+
export.basic_wallet::receive_asset
70+
export.basic_wallet::send_asset
71+
export.basic::auth_tx_rpo_falcon512
72+
```
73+
</details>
74+
75+
[Note scripts](https://0xpolygonmiden.github.io/miden-base/architecture/notes.html#note-scripts) or [transaction scripts](https://0xpolygonmiden.github.io/miden-base/transactions/transaction-kernel.html#the-transaction-script-processing) can call `receive_asset` and `send_asset` and in doing so, the account can receive and send assets. Transaction scripts can also call `auth_tx_rpo_falcon512` and authenticate the transaction. It is important to know, that without correct authentication, i.e. knowing the correct private key, a note cannot successfully invoke receive and send asset.
76+
77+
##### Basic fungible faucet (Faucet for fungible assets)
78+
There is also a standard for a [basic fungible faucet](https://github.com/0xPolygonMiden/miden-base/blob/main/miden-lib/asm/miden/contracts/faucets/basic_fungible.masm).
79+
80+
<details>
81+
<summary>Want to see the code?</summary>
82+
83+
```
84+
#! Distributes freshly minted fungible assets to the provided recipient.
85+
#!
86+
#! ...
87+
export.distribute
88+
# get max supply of this faucet. We assume it is stored at pos 3 of slot 1
89+
push.METADATA_SLOT exec.account::get_item drop drop drop
90+
# => [max_supply, amount, tag, RECIPIENT, ...]
91+
92+
# get total issuance of this faucet so far and add amount to be minted
93+
exec.faucet::get_total_issuance
94+
# => [total_issuance, max_supply, amount, tag, RECIPIENT, ...]
95+
96+
# compute maximum amount that can be minted, max_mint_amount = max_supply - total_issuance
97+
sub
98+
# => [max_supply - total_issuance, amount, tag, RECIPIENT, ...]
99+
100+
# check that amount =< max_supply - total_issuance, fails if otherwise
101+
dup.1 gte assert
102+
# => [asset, tag, RECIPIENT, ...]
103+
104+
# creating the asset
105+
exec.asset::create_fungible_asset
106+
# => [ASSET, tag, RECIPIENT, ...]
107+
108+
# mint the asset; this is needed to satisfy asset preservation logic.
109+
exec.faucet::mint
110+
# => [ASSET, tag, RECIPIENT, ...]
111+
112+
# create a note containing the asset
113+
exec.tx::create_note
114+
# => [note_ptr, ZERO, ZERO, ...]
115+
end
116+
117+
#! Burns fungible assets.
118+
#!
119+
#! ...
120+
export.burn
121+
# burning the asset
122+
exec.faucet::burn
123+
# => [ASSET]
124+
125+
# increments the nonce (anyone should be able to call that function)
126+
push.1 exec.account::incr_nonce
127+
128+
# clear the stack
129+
padw swapw dropw
130+
# => [...]
131+
end
132+
```
133+
</details>
134+
135+
The contract exposes two functions `distribute` and `burn`. The first function `distribute` can only be called by the faucet owner, otherwise it fails. As inputs, the function expects everything that is needed to create a note containing the freshly minted asset, i.e., amount, [tag](https://0xpolygonmiden.github.io/miden-base/architecture/notes.html#note-metadata), [RECIPIENT](https://0xpolygonmiden.github.io/miden-base/architecture/notes.html#note-recipient).
136+
137+
The second function `burn` can be called by anyone to burn the tokens that are contained in a note.
138+
139+
*Info: The difference is that the `burn` procedure exposes `exec.account::incr_nonce`, so by calling `burn` the nonce of the executing account gets increased by 1 and the transaction will pass the epilogue check. The `distribute` procedure does not expose that. That means the executing user needs to call `basic::auth_tx_rpo_falcon512` which requires the private key.*
140+
141+
## Account creation
142+
For an account to exist it must be present in the [Account DB](https://0xpolygonmiden.github.io/miden-base/architecture/state.html#account-database) kept by the Miden node(s). However, new accounts can be created locally by users using a wallet.
143+
144+
The process is as follows:
145+
146+
* Alice grinds a new Account ID (according to the account types) using a wallet
147+
* Alice's Miden client requests the Miden node to check if new Account ID already exists
148+
* Alice shares the new Account ID to Bob (eg. when Alice wants to receive funds)
149+
* Bob executes a transaction and creates a note that contains an asset for Alice
150+
* Alice consumes Bob's note to receive the asset in a transaction
151+
* Depending on the account storage mode (private vs. public) and transaction type (local vs. network) the Operator receives the new Account ID eventually and - if the transaction is correct - adds the ID to the Account DB
152+
153+
For a user to create an account we have 2 solutions at the moment:
154+
155+
1. Use the [Miden client](https://github.com/0xPolygonMiden/miden-client/tree/main) as a wallet
156+
2. Use the Miden Base builtin functions for wallet creation: [Basic wallet](https://github.com/0xPolygonMiden/miden-base/blob/4e6909bbaf65e77d7fa0333e4664be81a2f65eda/miden-lib/src/accounts/wallets/mod.rs#L15), [Fungible faucet](https://github.com/0xPolygonMiden/miden-base/blob/4e6909bbaf65e77d7fa0333e4664be81a2f65eda/miden-lib/src/accounts/faucets/mod.rs#L11)
157+
158+
## Account types
159+
There are four types of accounts in Miden:
160+
161+
| | Regular updatable account | Regular immutable account | Faucet for fungible assets | Faucet for non-fungible assets |
162+
|---|---|---|---|---|
163+
| **Description** | For most users, e.g. a wallet. Code changes allowed, including public API. | For most smart contracts. Once deployed code is immutable. | Users can issue fungible assets and customize them. | Users can issue non-fungible assets and customize them. |
164+
| **Code updatability** | yes | no | no | no |
165+
| **Most significant bits** | `00` | `01` | `10` | `11` |
166+
167+
## Account storage modes
168+
Account data - stored by the Miden node - can be public, private, or encrypted. The third and fourth most significant bits of the account ID specifies whether the account data is public `00`, encrypted `01`, or private `11`.
169+
170+
* Accounts with **public state**, where the actual state is stored onchain. These would be similar to how accounts work in public blockchains. Smart contracts that depend on public shared state should be stored public on Miden, e.g., DEX contract.
171+
* Accounts with **private state**, where only the hash of the account is stored onchain. Users who want stay private and take care of their own data should choose this mode. The hash is defined as: `hash([account ID, 0, 0, nonce], [vault root], [storage root], [code root])`.
172+
173+
In the future we will also support **encrypted state** which will be onchain but encrypted. * Depending on the account storage mode (private vs. encrypted vs. public) and transaction type (local vs. network) the operator receives the new Account ID eventually and - if the transaction is correct - adds the ID to the Account DB
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Assets
2+
In Miden, users can create and trade arbitrary fungible and non-fungible assets.
3+
4+
We differentiate between native and non-native assets in Miden. Native assets follow the Miden asset model. Non-native assets are all other data structures of value that can be exchanged.
5+
6+
Recording of native assets in Polygon Miden suffices four goals:
7+
8+
* Asset exchange should be parallelizable
9+
* Asset ownership should be private
10+
* Asset usage should be indeed censorship resistant
11+
* Fees can be paid using any asset
12+
13+
All native assets in Miden are stored directly in accounts, like Ether in Ethereum. Miden does not track ownership of assets using global hashmaps, e.g., ERC20 contracts. Storage of assets locally in accounts provides privacy and the ability for client-side proofs. That is because ownership changes always involve only one account and not the change of a global hashmap. Thus, they can happen in parallel. Additionally, asset exchange is censorship resistant at this level because there is no global contract the transfer must pass through. Finally, users can pay fees in any asset.
14+
15+
## Native assets
16+
Native assets are data structures that follow the Miden asset model (encoding, issuance, storing). All native assets are encoded using a single `Word` (4 field elements). The asset encodes both the ID of the issuing account and the asset details. Having the issuer's ID encoded in the asset makes it cost-efficient to determine the type of an asset inside and outside Miden VM. And, representing the asset in a `Word` means the representation is always a commitment to the asset data itself. That is particularly interesting for non-fungible assets.
17+
18+
### Issuance
19+
Only specialized accounts called faucets can issue assets. Just like with regular accounts, anyone can create a faucet account. Faucets can issue only either fungible or non-fungible assets - but not both. The `faucet_id` identifies the faucet and is starts with a different sequence depending on the asset type, see [here](https://0xpolygonmiden.github.io/miden-base/architecture/accounts.html#account-id). The faucet's code defines rules for how assets can be minted, who can mint them etc. Conceptually, faucet accounts on Miden are similar to ERC20 contracts on Ethereum. But, there is no ownership tracking in Miden faucets.
20+
21+
Faucets can create assets and immediately distribute them by producing notes. However, assets can also stay in the faucet after creation to be sent later, e.g., in a bundle. That way, one can mint a million NFTs locally in a single transaction and then send them out as needed in separate transactions in the future.
22+
23+
<center>
24+
![Architecture core concepts](../img/architecture/asset/asset-issuance.png)
25+
</center>
26+
27+
### Fungible assets
28+
A fungible asset is encoded using the amount and the `faucet_id` of the faucet which issued the asset. The amount is guaranteed to be $2^{63} - 1$ or smaller, the maximum supply for any fungible asset. Examples of fungible assets are ETH and stablecoins, e.g., DAI, USDT, and USDC.
29+
30+
If the `faucet_id` of MATIC were to be `2`, 100 MATIC are encoded as `[100, 0, 0, 2]` - whereas the `0`s in the middle help to quickly distinguish between fungible and non-fungible assets.
31+
32+
### Non-fungible assets
33+
A non-fungible asset is encoded by hashing the asset data into a `Word` and then replacing the second element with the `faucet_id` of the issuing account. It looks like `[e0, faucet_id, e2, e3]`. Note that the second element is guaranteed to be non-Zero.
34+
35+
Examples of non-fungible assets are all NFTs, e.g., a DevCon ticket. The ticket's data might be represented in a JSON string - which DevCon, the date, the initial price, etc. . Now, users can create a faucet for non-fungible DevCon tickets. This DevCon faucet would hash the JSON string into a `Word` to transform the ticket into an asset.
36+
37+
### Storage
38+
[Accounts](https://0xpolygonmiden.github.io/miden-base/architecture/accounts.html) and [notes](https://0xpolygonmiden.github.io/miden-base/architecture/notes.html) contain asset vaults that are used to store assets. Accounts can keep unlimited assets in a Sparse Merkle Tree called `account vault`. Notes can only store up to `255` distinct assets.
39+
40+
<center>
41+
![Architecture core concepts](../img/architecture/asset/asset-storage.png)
42+
</center>
43+
44+
The information on which and how many assets are owned can be private depending on the account's or note's storage mode. This is true for any native asset in Miden.
45+
46+
## Non-native assets
47+
Miden is flexible enough to create other types of assets as well.
48+
49+
For example, developers can fully replicate Ethereum's ERC20 model, where ownership of fungible assets is recorded in a single account. To transact, users must send a note to that account to change the global hashmap.
50+
51+
Furthermore, a complete account can be treated as a programmable asset because ownership of accounts is transferrable. An account could be a "crypto kitty" with specific attributes and rules, and people can trade these "crypto kitties" by transferring accounts between each other.
52+
53+
We can also think of an account representing a car. The owner of the car can change so the car account - granting access to the physical car - can be treated as an asset. In this car account, there could be rules defining who is allowed to drive the car and when.

0 commit comments

Comments
 (0)