ESDT Improvement Proposal - dynamic resources - MIP-5

ESDT improvement proposal

Problem statement: a set of functionalities are limited/we do not allow them when we speak about NFT metadata (creator, URIs, attributes). Builders made a few informal proposals wanting more features. Plus we can think about some of the attributes and properties of an NFT/SFT/MetaESDT as resources, which can be modified by the contract owner.

New built in functions:

  1. ESDTModifyRoyalties@tokenID@nonce@newRoyalty:
    a. Built in function which will rewrite the royalties on the given tokenID
    b. Only if the account has that tokenID and only for NFTs
    c. New Role to be added ESDTRoleNFTModifyRoyalties

  2. ESDTNFTSetNewURIs@tokenID@nonce@list(URI)
    a. Built in function which will rewrite URIs
    b. Only if the account has tokenID and only for NFTs
    c. New Role to be added ESDTRoleNFTSetNewURIs

  3. ESDTNFTModifyCreator@tokenID@nonce
    a. Change the creator to the current caller
    b. Only if it is allowed, new role to be checked

ESDTMetaData structure contains: URIs, Royalties, Attributes, Name, Creator, Hash, and when NFT is created it needs to have all the arguments in the ESDTNFTCreateFunction. We can improve the Rust framework with Macro Magic as to give the default inputs when the user does not provide it. But that can be discussed in another thread.

Another remark here: as of now, only NFTs can have attributes/URIs modified, as in case of SFTs/metaESDTs they can be on multiple shards and it would be somewhat of an inconsistency issue. But we can resolve those with this improvement proposal, and we can further enhance the customizability of Tokens with MetaData.

Now change the narrative and think about ESDTs as Resources and enable SC developer to do customized things on those: this tweet made us think that we could simply implement the listed features directly in the protocol.
Came with a response:

Right now you can do the following:
Launch a token and create tokens without actual attributes, keep resources under Nonce storage inside the smart contract. You send the token to the user (tokenID and nonce) as a representation of a resource which is managed at the SC level. The SC has a map of (tokenID, nonce) to attributes, internal structure, thus the SC can manage anything, while the user has only a representation. To enable interoperability, the SC could write in the attributes of the tokens a set of Query functions (as hooks) for other SCs/Microservices to interpret it.

But as needs evolve, builders build more complex projects, the underlying protocol should evolve as well. Thus we propose to improve the ESDT Metadata and its functions for all tokens, making those dynamic if the project wants.

First important point of enhancing customizability: enable change of attributes/URIs/royalties for SFTs/metaESDTs and add automatic versioning as well.

On the ESDTData structure we have an unused field - named Reserved. This is an open byte array. We can use this as a versioning mechanism for all the ESDTMetaData out there. ESDTMetaData structure contains: URIs, Royalties, Attributes, Name, Creator, Hash. All of which should be enabled to be changed using the existing and the new functions.

The paradigm change will be the following:

  1. We enable changing metaData for SFTs/metaESDTs and in case of transfers, we always rewrite the old versions with the new one.
    a. There is the chance of having an SFT at multiple users,
    b. The contract decides to update the attributes of an SFT, this update will be reflected on the contract shard, and if the contract sends to a user, it will be reflected on the shard of the user.
    c. In case there is a cross shard transfer, in which one systemAccount has one type of ESDTMetaData and on the transferData we have another type of ESDTMetaData, we will always write and use the one with the higher version.
    d. Handling of rewriting the data in case of transfer depending on the version of the ESDTMetadata is easy.

  2. This means on all the functions which can change the MetaData of a token we increase the version of the token.

  3. This also means that there can always be only ONE address which has the role of updating attributes.

This change does not affect any existing DeFi application, these updates/upgrades can be used for other types of financial services/dApps.

Second important point of enhancing customizability: enable the change of metaData even if the token is not in the balance of the SC. In case of ERC/other token based contract, the contract can change the attributes of the tokenMetadata as the SC dictates.

So, building from the previous point we can enable the function of ESDTMetaDataRecreate to be called even if the contract who calls this endpoint does not have the tokenID+nonce in his balance. We can add a special type of roles and identification on the ESDT system SC level, in which we can show that a token is built in such a way that the attributes can be rewritten by the smart contract with the rewrite role, even if it does not have that token in his balance.

Thus we create new tokenTypes only on ESDTSystemSmartContract level appending to the existing token type versions the name “dynamic”. In the case of “dynamic” tokenType (NFTDynamic, SFTDynamic, metaESDTDynamic), we create a new set of roles by appending the dynamic name to the ESDTRoleNFTRecreate. ESDTRoleNFTRecreateDynamic.

In the built in functions mentioned in the first page, we check for the balance of the contract only if the dynamic role is missing. If the dynamic role is in this contract, there is no need to check for balance. Dynamic role can be given to only one SC per tokenID.

As you can see, this will greatly enhance all dynamicNFT usecases, or all game useCases. One can level up my character, SC will rewrite the attributes of the new character, and I do not have to call the SC to upgrade my NFT every time. One can do it when one wants, on the first interaction. It makes building games/dynamic NFTs easier.

We propose a new set of functions for upgrade/recreate:

  1. ESDTMetaDataRecreate@ATTR@newAttr@URI@newURIs@CREATOR@address@ROYALTIES@newRoyalties:
    a. This recreates all the attributes from zero. If an argument is not received, that field is set to zero.

  2. ESDTMetadataUpdate@ATTR@newAttr@URI@newURIs@CREATOR@address@ROYALTIES@newRoyalties:
    a. If nothing is received for a given attribute we keep the old version of that.


This proposal is something that has been highly awaited, allowing NFT and SFTs to evolve through time and making it as attractive to create NFT assets for games on MvX as elsewhere.

Should the NFT/SFT have a property called “dynamic” that is by default false? This ensures clarity to both users and marketplaces if the token can change, even remotely.
canUpgrade would allow an already existing collection to become dynamic or disabling it down the line.

Why should the dynamic role only be given to a SC? I think it’s with a logic that everything is happening onchain, but I can see a few use cases where a dedicated wallet is linked to a game server to update attributes without needing a SC.

I’m looking forward to seeing this MIP being implemented and bring a new wave of utility on MultiversX.


The dynamic role can be. given to any account. But it will be most probable that these will be handled by SCs. “dynamic” is set to false by default.

1 Like

@robert any specific reason why not allowing setting the creator as another wallet not exclusive to the caller ?
It would be helpful for improving launchpads contracts + other contracts as a service.

I see a point where scammers/random people will abuse it and set other wallets as creator without the end wallet wanting to be a creator, but still I can not find what can go wrong even if a wallet that don’t want to be creator is actually one ? Worst case will receive royalties right ?

1 Like

I think the worst case would be showing that Beni, Luci, Core members, MultiversX Foundation is launching an NFT. Maybe this could be done in two steps, like accept to be a creator, thus the address has to accept this.


I would suggest also adding the possibility of updating the NFT’s Name.

As we know, the Ticker & Nonce are the unique identifier of an NFT, similar to Contract + Nonce on EVM chains.

Following this logic, all other values of the NFT should be changeable, creating a new playground for projects to innovate.

Added Function


a) Buil in function which will rewrite the name of the given tokenID + Nonce

b) New Role to be added ESDTRoleNFTModifyName

In the past, projects have burned + minted an NFT to create a new version of it.

We could imagine a scenario similar to Pokemon, where a gaming NFT evolves, from “Squirtle” to “Wartortle”.

The unique identifier of the NFT (tokenID) remains the same, but the attributes, URI and name should change.

In addition, the latest version of the NFT should always be easily accessible through API endpoints, ensuring marketplaces and projects can show it.

Those new features will facilitate building web3 games on MultiversX and give the right tools for keeping the game asset’s data on-chain, and not dependent on off-chain endpoints.

We have chosen to use upgrade/recreate endpoints through which everything can be rewritten.

  1. ESDTNFTCreate: all params have to be given.
    a. Rust Macro Magic will abstract this and developers will be able to set only what they want.

  2. ESDTNFTRecreate:
    a. This recreates all the attributes from zero. If an argument is not received, that field is set to zero.

  3. ESDTNFTUpdate:
    a. If nothing is received for a given attribute we keep the old version of that.

1 Like