Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miden blockexplorer - next iteration #205

Open
Dominik1999 opened this issue Sep 25, 2024 · 3 comments
Open

Miden blockexplorer - next iteration #205

Dominik1999 opened this issue Sep 25, 2024 · 3 comments

Comments

@Dominik1999
Copy link
Contributor

Dominik1999 commented Sep 25, 2024

Goal: next iteration of the block explorer

On our explorer (https://explorer.miden.io), we want to have a couple of updates and fixes.

General

Can you open-source the code and provide instructions on how to run it?

Main page (2 changes)

  1. Let's remove the "account updates" box - this should always be the same as the number of transactions
  2. It would be really nice to get some of these numbers to update dynamically (i.e., the block count, the transaction count etc.)
    This could include a "dynamic row" in the block/transaction tables to say something "10 new blocks since refresh".

Blocks

Overview tab (2 changes)

  1. We need "Consumed notes" tab which would show note nullifiers created in this block.
  2. We need to change the on-hover descriptions. We will provide new texts

Accounts

Assets tab (2 changes)

  1. The assets in the explorer should show the token symbol, three letters, e.g., POL. However, we do not know the token symbol for every asset. The miden client has a token mapping.
  2. We should also show the token's decimals. The token symbol and the decimals are stored in the account in slot 1 (for public accounts).

Code tab (2 changes)

  1. We currently show the code digests for public accounts (see here). We need to show the MAST code (once there is pprint merged into the Miden VM)
  2. For known digests (code snippets from the Miden Standard Library), we can show the MASM code. For that, we need to store a mapping from digest to MASM code. If the account code only consists of known digests, we can add a green hook symbol that this account is "verified".

Maybe @PhilippGackstatter can provide a mapping of the current MASM procedures.

Storage - new (1 change)

We want to show the account's storage. There are two ways to store something in the account.

  1. There are 255 Storage slots, each a Word.
  2. There are StorageMaps, which are SparseMerkleTrees of depth 64. We need to show the leaves and the root of the tree.

Upload accounts - new

We want to be able to upload an account to the explorer. Accounts are serialized as *.mac files. So when I click on a private account, there needs to be an upload button; I then upload my account, and if the account hash matches, all data should be shown as if the account were a public account.

Notes issued - new

We should also add "Notes" tab. This would show all notes sent out from the account (i.e., where note.sender == account_id).

Transactions tab

Instead of "Transactions" tab, it may make sense to show "Updates" tab. This tab could have a table with the following fields:

  1. Block number ("The block in which the update was committed")
  2. State hash ("Hash of the new account state after this block")
  3. Transaction ID ("Transactions executed against the account in this block") - a list of one or more transactions.

Created Notes

Note Tags (1 change)

We want to be able to search notes by TAG. The TAG is in the note metadata. There should be a separate "Note tags" page where we list all tags and then when we click on a specific tag, we can see all notes which have this tag.

Consumed notes

Right now, this shows the same data as the "Notes" page. Instead, it should show a table of nullifiers. Specifically, this table would have two columns: "Note nullifier" and "Committed block number."

@bobbinth
Copy link
Contributor

bobbinth commented Sep 25, 2024

A few small comments from me:

It would be really nice to get some of these numbers to update dynamically (i.e., the block count, the transaction count etc.)

I think this may already be done. But the "dynamic row" is not there yet.

The token symbol and the decimals are stored in the account in slot 1 (for public accounts).

We'll need to define a strategy for how to reconcile data from the mapping file and the one stored in accounts.

Code tab (2 changes)

  1. We currently show the code digests for public accounts (see here). We need to show the MAST code (once there is pprint merged into the Miden VM)
  2. For known digests (code snippets from the Miden Standard Library), we can show the MASM code. For that, we need to store a mapping from digest to MASM code. If the account code only consists of known digests, we can add a green hoom symbol that this account is "verified".

In addition to this, we'll also need to show a couple of attributes for each procedure. Specifically, storage offset and storage size.

  • There are 255 Storage slots, each a Word.
  • There are StorageMaps, which are SparseMerkleTrees of depth 64. We need to show the leaves and the root of the tree.

There are could be up to 255 storage slot (but usually will be much fewer - e.g., a basic wallet has only 1 storage slot).

For key-value maps, we should probably show a table (e.g., with 2 columns) with currently populated key-value pairs.

Upload accounts - new

We want to be able to upload an account to the explorer. Accounts are serialized as *.mac files. So when I click on a private account, there needs to be an upload button; I then upload my account, and if the account hash matches, all data should be shown as if the account were a public account.

This is really a "nice-to-have" - I would tackle it only after everything else is done.

Also, another nice to have would be to be able to download NoteFile for public notes.

@PhilippGackstatter

This comment was marked as off-topic.

@PhilippGackstatter
Copy link
Contributor

I just realized I misunderstood what was needed, so I hid my above comment.

  1. For known digests (code snippets from the Miden Standard Library), we can show the MASM code. For that, we need to store a mapping from digest to MASM code. If the account code only consists of known digests, we can add a green hoom symbol that this account is "verified".

Contrary to note scripts, account code is a library, so it doesn't have a single, well-defined entrypoint, hence we cannot compute a single identifying MAST root for it (afaict).

I think what can be done instead to identify standard account contracts is first gather all of its exported procedure's MAST roots (hashes). If this set of roots matches one of the following sets exactly (no more or less elements) then we can show a verified contract symbol and display the name of the contract:

Contract: asm/miden/contracts/faucets/basic_fungible.masm
0xb8ab9250552340f85a7fae48b91bcdb66b9e03e6d7aa690ea20a161df45846b9 -> auth_tx_rpo_falcon512
0xc20293f0369767effe117526998e405f8745504ac280aa6052357f7f7779c017 -> burn
0x5975eac536b66c718e0aedb43b77c6cf7f7b1479f087e670bb9438baeee0f79a -> distribute

Contract: asm/miden/contracts/auth/basic.masm
0xb8ab9250552340f85a7fae48b91bcdb66b9e03e6d7aa690ea20a161df45846b9 -> auth_tx_rpo_falcon512

Contract: asm/miden/contracts/wallets/basic.masm
0x8500b731b95c38cc663dd823d18becc928ab99a8ddd8e5e589ef719ad609a4f5 -> create_note
0x7517eb7731fbfe883d6ab1bc8c66c95728f321e7c3538436e9ef9105d61637c1 -> move_asset_to_note
0xe048a235aba9e9806f8598fdfd8e76c21e3cc72955ca2e858b3a06020096bbc4 -> receive_asset

As far as I can tell, the auth/basic.masm is not a useful account contract by itself since it only does authentication, so I guess only the other two are relevant for the explorer.

For display purposes, I think some proper names for these contracts would be desirable, e.g. "Basic Wallet" and "Fungible Faucet".

The code for this is here.

Note: This requires the walkdir crate.

use std::{self};

use miden_lib::transaction::TransactionKernel;
use walkdir::WalkDir;

fn main() {
    let contracts_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/asm/miden/contracts/");

    for entry in WalkDir::new(contracts_dir) {
        let entry = entry.unwrap();
        if entry.file_type().is_dir() {
            continue;
        }

        let contract_bytes = std::fs::read(entry.path()).unwrap();
        let contract_name = entry.path().strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap();

        let assembler = TransactionKernel::assembler();
        let lib = assembler.assemble_library([contract_bytes]).unwrap();

        println!("Contract: {}", contract_name.display());
        for module_info in lib.module_infos() {
            for (_, proc_info) in module_info.procedures() {
                println!("{} -> {}", proc_info.digest, proc_info.name);
            }
        }
        println!("");
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants