Skip to content

Commit

Permalink
deploy: 8991489
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominik1999 committed Jan 24, 2024
1 parent 4f24ef6 commit 10ccff2
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 12 deletions.
88 changes: 83 additions & 5 deletions architecture/accounts.html
Original file line number Diff line number Diff line change
Expand Up @@ -213,24 +213,102 @@ <h3 id="vault"><a class="header" href="#vault">Vault</a></h3>
</ul>
<p>An account vault can be reduced to a single hash which is the root of the sparse Merkle tree.</p>
<h3 id="code"><a class="header" href="#code">Code</a></h3>
<p>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. Functions exposed by the account have the following properties:</p>
<p>Interface for accounts. In Miden every account is a smart contract. It has an interface that exposes functions that can be called by <a href="https://0xpolygonmiden.github.io/miden-base/architecture/notes.html#note-scripts">note scripts</a> and <a href="https://0xpolygonmiden.github.io/miden-base/transactions/transaction-kernel.html#the-transaction-script-processing">transaction scripts</a>. Users cannot call those functions directly. </p>
<p>Functions exposed by the account have the following properties:</p>
<ul>
<li>Functions are actually roots of <a href="https://0xpolygonmiden.github.io/miden-vm/user_docs/assembly/main.html">Miden program MASTs</a> (i.e., a 32-byte hash). Thus, function identifier is a commitment to the code which is executed when a function is invoked.</li>
<li>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.</li>
<li>Account functions can take parameters and can create new notes.</li>
</ul>
<p><em>Note: Since code in Miden is expresed 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 <code>256</code> functions</em></p>
<p><em>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 <code>256</code> functions</em></p>
<h4 id="example-account-code"><a class="header" href="#example-account-code">Example Account Code</a></h4>
<p>Currently, Miden provides two standard implementations for account code. </p>
<h5 id="basic-user-account-regular-updatable-account"><a class="header" href="#basic-user-account-regular-updatable-account">Basic user account (Regular updatable account)</a></h5>
<p>There is a standard for a basic user account. It exposes three functions via its interface.</p>
<details>
<summary>What to see the code?</summary>
<pre><code> use.miden::contracts::wallets::basic-&gt;basic_wallet
use.miden::contracts::auth::basic

export.basic_wallet::receive_asset
export.basic_wallet::send_asset
export.basic::auth_tx_rpo_falcon512
</code></pre>
</details>
<p><a href="https://0xpolygonmiden.github.io/miden-base/architecture/notes.html#note-scripts">Note scripts</a> or <a href="https://0xpolygonmiden.github.io/miden-base/transactions/transaction-kernel.html#the-transaction-script-processing">transaction scripts</a> can call <code>receive_asset</code> and <code>send_asset</code> and in doing so, the account can receive and send assets. Transaction scripts can also call <code>auth_tx_rpo_falcon512</code> 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.</p>
<h5 id="basic-fungible-faucet-faucet-for-fungible-assets"><a class="header" href="#basic-fungible-faucet-faucet-for-fungible-assets">Basic fungible faucet (Faucet for fungible assets)</a></h5>
<p>There is also a standard for a <a href="https://github.com/0xPolygonMiden/miden-base/blob/main/miden-lib/asm/miden/contracts/faucets/basic_fungible.masm">basic fungible faucet</a>.</p>
<details>
<summary>What to see the code?</summary>
<pre><code>#! Distributes freshly minted fungible assets to the provided recipient.
#!
#! ...
export.distribute
# get max supply of this faucet. We assume it is stored at pos 3 of slot 1
push.METADATA_SLOT exec.account::get_item drop drop drop
# =&gt; [max_supply, amount, tag, RECIPIENT, ...]

# get total issuance of this faucet so far and add amount to be minted
exec.faucet::get_total_issuance
# =&gt; [total_issuance, max_supply, amount, tag, RECIPIENT, ...]

# compute maximum amount that can be minted, max_mint_amount = max_supply - total_issuance
sub
# =&gt; [max_supply - total_issuance, amount, tag, RECIPIENT, ...]

# check that amount =&lt; max_supply - total_issuance, fails if otherwise
dup.1 gte assert
# =&gt; [asset, tag, RECIPIENT, ...]

# creating the asset
exec.asset::create_fungible_asset
# =&gt; [ASSET, tag, RECIPIENT, ...]

# mint the asset; this is needed to satisfy asset preservation logic.
exec.faucet::mint
# =&gt; [ASSET, tag, RECIPIENT, ...]

# create a note containing the asset
exec.tx::create_note
# =&gt; [note_ptr, ZERO, ZERO, ...]
end

#! Burns fungible assets.
#!
#! ...
export.burn
# burning the asset
exec.faucet::burn
# =&gt; [ASSET]

# increments the nonce (anyone should be able to call that function)
push.1 exec.account::incr_nonce

# clear the stack
padw swapw dropw
# =&gt; [...]
end
</code></pre>
</details>
<p>The contract exposes two functions <code>distribute</code> and <code>burn</code>. The first function <code>distribute</code> 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, <a href="https://0xpolygonmiden.github.io/miden-base/architecture/notes.html#note-metadata">tag</a>, <a href="https://0xpolygonmiden.github.io/miden-base/architecture/notes.html#note-recipient">RECIPIENT</a>.</p>
<p>The second function <code>burn</code> can be called by anyone to burn the tokens that are contained in a note.</p>
<p><em>Info: The difference is that the <code>burn</code> procedure exposes <code>exec.account::incr_nonce</code>, so by calling <code>burn</code> the nonce of the executing account gets increased by 1 and the transaction will pass the epilogue check. The <code>distribute</code> procedure does not expose that. That means the executing user needs to call <code>basic::auth_tx_rpo_falcon512</code> which requires the private key.</em></p>
<h2 id="account-creation"><a class="header" href="#account-creation">Account creation</a></h2>
<p>For an account to exist it must be present in the <a href="https://0xpolygonmiden.github.io/miden-base/architecture/state.html#account-database">Account DB</a> kept by the Miden Node(s). However, new accounts can be created locally by users using a wallet.</p>
<p>For an account to exist it must be present in the <a href="https://0xpolygonmiden.github.io/miden-base/architecture/state.html#account-database">Account DB</a> kept by the Miden node(s). However, new accounts can be created locally by users using a wallet.</p>
<p>The process is as follows:</p>
<ul>
<li>Alice grinds a new Account ID (according to the account types) using a wallet</li>
<li>Alice's Miden Client requests the Miden Node to check if new Account ID already exists</li>
<li>Alice's Miden client requests the Miden node to check if new Account ID already exists</li>
<li>Alice shares the new Account ID to Bob (eg. when Alice wants to receive funds)</li>
<li>Bob executes a transaction and creates a note that contains an asset for Alice</li>
<li>Alice consumes Bob's note to receive the asset in a transaction</li>
<li>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</li>
</ul>
<p>For a user to create an account we have 2 solutions at the moment:</p>
<ol>
<li>Use the <a href="https://github.com/0xPolygonMiden/miden-client/tree/main">Miden client</a> as a wallet</li>
<li>Use the Miden Base builtin functions for wallet creation: <a href="https://github.com/0xPolygonMiden/miden-base/blob/4e6909bbaf65e77d7fa0333e4664be81a2f65eda/miden-lib/src/accounts/wallets/mod.rs#L15">Basic wallet</a>, <a href="https://github.com/0xPolygonMiden/miden-base/blob/4e6909bbaf65e77d7fa0333e4664be81a2f65eda/miden-lib/src/accounts/faucets/mod.rs#L11">Fungible faucet</a></li>
</ol>
<h2 id="account-types"><a class="header" href="#account-types">Account types</a></h2>
<p>There are four types of accounts in Miden:</p>
<div class="table-wrapper"><table><thead><tr><th></th><th>Regular updatable account</th><th>Regular immutable account</th><th>Faucet for fungible assets</th><th>Faucet for non-fungible assets</th></tr></thead><tbody>
Expand All @@ -240,7 +318,7 @@ <h2 id="account-types"><a class="header" href="#account-types">Account types</a>
</tbody></table>
</div>
<h2 id="account-storage-modes"><a class="header" href="#account-storage-modes">Account storage modes</a></h2>
<p>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 <code>00</code>, encrypted <code>01</code>, or private <code>11</code>.</p>
<p>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 <code>00</code>, encrypted <code>01</code>, or private <code>11</code>.</p>
<ul>
<li>Accounts with <strong>public state</strong>, 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.</li>
<li>Accounts with <strong>private state</strong>, 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: <code>hash([account ID, 0, 0, nonce], [vault root], [storage root], [code root])</code>.</li>
Expand Down
Loading

0 comments on commit 10ccff2

Please sign in to comment.