Skip to content

Comments

feat: adapt the layout of Assets to the double word representation#2437

Open
PhilippGackstatter wants to merge 39 commits intopgackst-user-asset-key-valuefrom
pgackst-asset-layout
Open

feat: adapt the layout of Assets to the double word representation#2437
PhilippGackstatter wants to merge 39 commits intopgackst-user-asset-key-valuefrom
pgackst-asset-layout

Conversation

@PhilippGackstatter
Copy link
Contributor

@PhilippGackstatter PhilippGackstatter commented Feb 12, 2026

Refactors the layout of fungible and non-fungible assets. The main benefit for now is that non-fungible assets include the full account ID. The other good news is that this PR removes the last unsafe code from miden base 😅.

Layout Changes

For direct comparison, the previous layout was:

  • Fungible asset value: [amount, 0, faucet_id_suffix, faucet_id_prefix].
  • Fungible asset key: [0, 0, faucet_id_suffix, faucet_id_prefix].
  • Non-fungible asset value: [hash0, hash1, hash2, faucet_id_prefix].
  • Non-fungible asset key: [faucet_id_prefix, hash1, hash2, hash0'].

The new layout is:

  • Fungible asset value: [amount, 0, 0, 0].
  • Fungible asset key: [0, 0, faucet_id_suffix, faucet_id_prefix].
  • Non-fungible asset value: [hash0, hash1, hash2, hash3].
  • Non-fungible asset key: [hash0, hash1, faucet_id_suffix, faucet_id_prefix].

The most notable change is that non-fungible assets now contain the full AccountId instead of just the AccountIdPrefix. I believe this removes the last reason we had that account ID prefixes needed to be unique in the account tree. So, we could now consider lifting this restriction.

Account Delta

The account delta is impacted by the layout change, namely that non-fungible asset's were previously committed to by hashing their value. Because the value doesn't contain the faucet ID anymore, the delta also doesn't commit to the asset's issuer anymore and so the delta format needed to be changed to commit to the faucet ID. This means the asset key of the non-fungible asset is now included.

For security, the faucet ID prefix (specifically the bit in the account ID that determines the faucet type) must be at the same position in the layout to avoid introducing an ambiguity in the delta format. So, the layout of the fungible asset's delta elements was adapted as well. Overall it is now:

Fungible Assets

  • [domain = 1, was_added, faucet_id_suffix, faucet_id_prefix]
  • [amount_delta, 0, 0, 0]

Non-Fungible Assets

  • [domain = 1, was_added, faucet_id_suffix, faucet_id_prefix]
  • [hash0, hash1, hash2, hash3] (= ASSET_VALUE)

See docs of AccountDelta::to_commitment for all the details.

This change included updates to the delta commitment computation as well as how non-fungible assets are tracked in the delta.

Note that the NonFungibleAssetDelta's internal representation is a bit ugly, but a larger refactors doesn't make sense at this point since this may change more fundamentally when generalizing assets.

Asset Key Ordering

AssetVaultKey implements Ord and PartialOrd based on LexicographicWord for use in the delta. Not strictly necessary, but convenient. I also added implementations for Asset that delegate to AssetVaultKey, but these are currently unused.

Asset Modules

This PR commits further to the fungible_asset and now non_fungible_asset module in the kernel for implementing their respective logic. If we move this logic elsewhere later, this should make this process easier.

Transaction Outputs

Since the fee asset is a fungible asset, and it is represented as a double word, the FEE_ASSET_VALUE tx output needed to be adapted, as it would now only contain the amount, but not the faucet ID. The new approach is to output the individual required elements from the fungible asset, i.e. its faucet ID limbs and the amount. This also happens to make room for a full word on the output stack.

Tests

Fixes a couple of tests where asset key and value were incorrectly ordered but the test didn't fail before, presumably due to the similar layout of key and value.

Migration

  • miden::protocol::active_account::has_non_fungible_asset now takes an ASSET_KEY as an input.
  • miden::protocol::asset::create_non_fungible_asset now takes the full account ID as an input.
  • The previous asset to/from word conversions were removed, since an asset is now represented as a double word. The replacements are the to_key_word and to_value_word methods, and from_key_value and from_key_value_words constructors.
  • NonFungibleAssetDelta::new's signature has changed.
  • FungibleAsset::new and Asset::is_(non_)fungible are no longer const (I'm not sure these can realistically be used in a const context and it restricts future non-breaking internal changes).
  • {Asset, NonFungibleAsset, FungibleAsset}::faucet_id_prefix was removed.
  • NonFungibleAsset's and NonFungibleAssetDetails' structure has changed. They both contain the full AccountId now.
  • AssetVaultKey::{new_unchecked, faucet_id_prefix, as_word} were removed. Use new, faucet_id and to_word instead.
  • AssetVaultKey::from_account_id renamed to new_fungible since non-fungible asset vault keys cannot be created from just a faucet ID.

Follow-Up

  • We should come up with a different name for "native asset ID" (= the faucet ID of the "fee asset"), since AssetId now is its own thing.
  • Fungible asset and non-fungible asset's display impl should be adapted at some point. It currently delegates to the Debug implementation which is not a stable representation (could change with non-breaking changes) and it also shouldn't be used for error messages.
  • The asset vault key must be hashed before using it as the key in the asset vault SMT (reason).

closes #2328

@PhilippGackstatter PhilippGackstatter linked an issue Feb 12, 2026 that may be closed by this pull request
@igamigo igamigo added the pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority label Feb 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-from-maintainers PRs that come from internal contributors or integration partners. They should be given priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expand asset layout from one to two words

2 participants