XCM Asset Metadata#125
Conversation
Co-authored-by: Adrian Catangiu <adrian@parity.io>
xlc
left a comment
There was a problem hiding this comment.
Maybe explicit define MetadataMap and MetadataKeys
type MetadataKey = Vec<u8>;
type MetadataValue = Vec<u8>;
type MetadataMap = BTreeMap<MetadataKey, MetadataValue>;
type MetadataKeys = BTreeSet<MetadataKey>; // or call it MetadataKeySet?|
Let me know if you want me to put this for onchain voting |
|
|
||
| The `ReportMetadata` can be used without origin (i.e., following the `ClearOrigin` instruction) since it only reads state. | ||
|
|
||
| Safety: The reporter origin should be trusted to hold the true metadata. If the reserve-based model is considered, the asset's reserve location must be viewed as the only source of truth about the metadata. |
There was a problem hiding this comment.
You're envisioning this metadata to be useful for fungible assets as well? In that case, would it be something small like name, decimals, symbol?
If that's the case, I guess we only need to have this security measure for NFTs. Runtimes should identify foreign NFTs and not report the metadata for them since they don't hold the source of truth.
There was a problem hiding this comment.
You're envisioning this metadata to be useful for fungible assets as well? In that case, would it be something small like name, decimals, symbol?
Yes, since Asset { id: ASSET_ID, fun: NonFungible(AssetInstance::Undefined) } now means a collection.
However, we'd need some standards so different fungible implementations could report something universally applicable.
If that's the case, I guess we only need to have this security measure for NFTs.
What about the derivative fungible collections? They might also have a symbol, decimals, etc. However, other chains shouldn't use derivative collections' information as true information (though maybe they might want to inspect such information?).
Runtimes should identify foreign NFTs and not report the metadata for them since they don't hold the source of truth.
True. Yet, a counterparty might act maliciously. I wrote this safety note just to highlight that it is our decision on whom to trust.
|
|
||
| Regarding ergonomics, no drawbacks were noticed. | ||
|
|
||
| As for the user experience, it could discover new cross-chain use cases involving asset collections and NFTs, indicating a positive impact. |
There was a problem hiding this comment.
I'm wondering if there are any metadata keys that we can make known and standard instead of leaving everything as a Vec<u8>. But I think this is a good start and cross-chain NFT standards can start to emerge from this.
There was a problem hiding this comment.
Yes, metadata standards should exist. This is one of the tasks of the NFT Collective (a project launched by Unique Network).
However, this RFC outlines the technical possibility of interchanging data in a universal way via XCM.
|
@xlc Could you please put this RFC for on-chain voting? |
|
/rfc propose |
|
Hey @xlc, here is a link you can use to create the referendum aiming to approve this RFC number 0125. Instructions
It is based on commit hash d16c0f71119a168e1be0cc4845902658c9ccaad2. The proposed remark text is: |
|
Voting for this referenda is ongoing. Vote for it here |
|
The referendum has been executed. However, the bot didn't react to this for some reason. |
|
/rfc process |
|
Please provider a block hash where the referendum confirmation event is to be found. |
|
/rfc process 0x06151e3d6507c12dcfa4644062f678b9f9b433d1477ec8b028a9cc8ad70a96c9 |
|
The on-chain referendum has approved the RFC. |
## Overview This PR provides new XCM types and tools for building NFT Asset Transactors. The new types use general and granular NFT traits from #5620. The new XCM adapters and utility types to work with NFTs can be considered the main deliverable of the **[XCM NFT proposal](https://polkadot.polkassembly.io/referenda/379)**. The new types use a more general approach, making integration into any chain with various NFT implementations easier. For instance, different implementations could use: * different ID assignment approaches * predefined NFT IDs - pallet-uniques, pallet-nfts * derived NFT IDs (NFT IDs are automatically derived from collection IDs) - Unique Network, ORML/Acala, Aventus * classless (collection-less) tokens - CoreTime NFTs, Aventus NFT Manager NFTs * in-class (in-collection) tokens - Unique Network, pallet-uniques, pallet-nfts, ORML/Acala * different approaches to storing associated data on-chain: * data is stored entirely separately from tokens - pallet-uniques * data is stored partially or entirely within tokens (i.e., burning a token means destroying it with its data) - pallet-nfts ([partially](https://github.com/paritytech/polkadot-sdk/blob/8b4cfda7589325d1a34f70b3770ab494a9d4052c/substrate/frame/nfts/src/features/create_delete_item.rs#L240-L241)), Unique Network, ORML/Acala With new types, these differences can be abstracted away. Moreover, the new types provide greater flexibility for supporting derivative NFTs, allowing several possible approaches depending on the given chain's team's goals or restrictions (see the `pallet-derivatives` crate docs and mock docs). Also, this is the PR I mentioned in the #4073 issue, as it can be viewed as the solution. In particular, the new adapter (`UniqueInstancesAdapter`) requires the `Update` operation with the `ChangeOwnerFrom` strategy. This brings the attention of both a developer and a reviewer to the `ChangeOwnerFrom` strategy (meaning that the transfer checks if the asset can be transferred from a given account to another account), both at trait bound and at the call site, without sacrificing the flexibility of the NFT traits. ## New types for xcm-builder and xcm-executor This PR introduces several XCM types. The `UniqueInstancesAdapter` is a new `TransactAsset` adapter that supersedes both `NonFungibleAdapter` and `NonFungiblesAdapter` (for reserve-based transfers only, as teleports can't be implemented appropriately without transferring the NFT metadata alongside it; no standard solution exists for that yet. Hopefully, the Felloweship RFC 125 ([PR](polkadot-fellows/RFCs#125), [text](https://github.com/polkadot-fellows/RFCs/blob/3a24444278f22dac414fbd2b5c4b205f73d78af7/text/0125-xcm-asset-metadata.md)) will help with that). Thanks to the new Matcher types, the new adapter can be used instead of both `NonFungibleAdapter` and `NonFungiblesAdapter`: * `MatchesInstance` (a trait) * `MatchInClassInstances` * `MatchClasslessInstances` The `UniqueInstancesAdapter` works with existing tokens only. To create new tokens (derivative ones), there is the `UniqueInstancesDepositAdapter`. See the `pallet-derivatives` mock and tests for the usage example. ### Superseding the old adapters for pallet-uniques Here is how the new `UniqueInstancesAdapter` in Westend Asset Hub replaces the `NonFungiblesAdapter`: ```rust /// Means for transacting unique assets. pub type UniquesTransactor = UniqueInstancesAdapter< AccountId, LocationToAccountId, MatchInClassInstances<UniquesConvertedConcreteId>, pallet_uniques::asset_ops::Item<Uniques>, >; ``` `MatchInClassInstances` allows us to reuse the already existing `UniquesConvertedConcreteId` matcher. The `pallet_uniques::asset_ops::Item<Uniques>` already implements the needed traits. So, migrating from the old adapter to the new one regarding runtime config changes is easy. >NOTE: `pallet_uniques::asset_ops::Item` grants access to the asset operations of NFT items of a given pallet-uniques instance, whereas `pallet_uniques::asset_ops::Collection` grants access to the collection operations. ### Declarative modification of an NFT engine If an NFT-hosting pallet only implements a transfer operation but not the `Stash` and `Restore`, one could declaratively add them using the `UniqueInstancesWithStashAccount` adapter. So, you can use it with the `UniqueInstancesAdapter` as follows: ```rust parameter_types! { pub StashAccountId: AccountId = /* Some Stash Account ID */; } type Transactor = UniqueInstancesAdapter< AccountId, LocationToAccountId, Matcher, UniqueInstancesWithStashAccount<StashAccountId, NftEngine>, >; ``` ### Supporting derivative NFTs (reserve-based model) There are several possible scenarios of supporting derivative NFTs (and their collections, if applicable). A separate NFT-hosting pallet instance could be configured to use XCM `AssetId` as collection ID and `AssetInstance` token ID. In that case, the asset transaction doesn't need any special treatment. However, registering NFT collections might require a special API. Also, if the NFT-hosting pallet can't be configured to use XCM ID types, we would need to store a mapping between the XCM ID of the original token and the derivative ID. See the `pallet-derivatives` crate docs for details. The example of its usage can be found in its mock and tests. #### TODO No benchmarks were run for `pallet-derivatives`, so there is no `weights.rs` for it yet. --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
|
NOTE on implementation: this can't be implemented before introducing a basic structure of XCM v6 (effectively, this issue must be resolved first) |
## Overview This PR provides new XCM types and tools for building NFT Asset Transactors. The new types use general and granular NFT traits from #5620. The new XCM adapters and utility types to work with NFTs can be considered the main deliverable of the **[XCM NFT proposal](https://polkadot.polkassembly.io/referenda/379)**. The new types use a more general approach, making integration into any chain with various NFT implementations easier. For instance, different implementations could use: * different ID assignment approaches * predefined NFT IDs - pallet-uniques, pallet-nfts * derived NFT IDs (NFT IDs are automatically derived from collection IDs) - Unique Network, ORML/Acala, Aventus * classless (collection-less) tokens - CoreTime NFTs, Aventus NFT Manager NFTs * in-class (in-collection) tokens - Unique Network, pallet-uniques, pallet-nfts, ORML/Acala * different approaches to storing associated data on-chain: * data is stored entirely separately from tokens - pallet-uniques * data is stored partially or entirely within tokens (i.e., burning a token means destroying it with its data) - pallet-nfts ([partially](https://github.com/paritytech/polkadot-sdk/blob/8b4cfda7589325d1a34f70b3770ab494a9d4052c/substrate/frame/nfts/src/features/create_delete_item.rs#L240-L241)), Unique Network, ORML/Acala With new types, these differences can be abstracted away. Moreover, the new types provide greater flexibility for supporting derivative NFTs, allowing several possible approaches depending on the given chain's team's goals or restrictions (see the `pallet-derivatives` crate docs and mock docs). Also, this is the PR I mentioned in the #4073 issue, as it can be viewed as the solution. In particular, the new adapter (`UniqueInstancesAdapter`) requires the `Update` operation with the `ChangeOwnerFrom` strategy. This brings the attention of both a developer and a reviewer to the `ChangeOwnerFrom` strategy (meaning that the transfer checks if the asset can be transferred from a given account to another account), both at trait bound and at the call site, without sacrificing the flexibility of the NFT traits. ## New types for xcm-builder and xcm-executor This PR introduces several XCM types. The `UniqueInstancesAdapter` is a new `TransactAsset` adapter that supersedes both `NonFungibleAdapter` and `NonFungiblesAdapter` (for reserve-based transfers only, as teleports can't be implemented appropriately without transferring the NFT metadata alongside it; no standard solution exists for that yet. Hopefully, the Felloweship RFC 125 ([PR](polkadot-fellows/RFCs#125), [text](https://github.com/polkadot-fellows/RFCs/blob/3a24444278f22dac414fbd2b5c4b205f73d78af7/text/0125-xcm-asset-metadata.md)) will help with that). Thanks to the new Matcher types, the new adapter can be used instead of both `NonFungibleAdapter` and `NonFungiblesAdapter`: * `MatchesInstance` (a trait) * `MatchInClassInstances` * `MatchClasslessInstances` The `UniqueInstancesAdapter` works with existing tokens only. To create new tokens (derivative ones), there is the `UniqueInstancesDepositAdapter`. See the `pallet-derivatives` mock and tests for the usage example. ### Superseding the old adapters for pallet-uniques Here is how the new `UniqueInstancesAdapter` in Westend Asset Hub replaces the `NonFungiblesAdapter`: ```rust /// Means for transacting unique assets. pub type UniquesTransactor = UniqueInstancesAdapter< AccountId, LocationToAccountId, MatchInClassInstances<UniquesConvertedConcreteId>, pallet_uniques::asset_ops::Item<Uniques>, >; ``` `MatchInClassInstances` allows us to reuse the already existing `UniquesConvertedConcreteId` matcher. The `pallet_uniques::asset_ops::Item<Uniques>` already implements the needed traits. So, migrating from the old adapter to the new one regarding runtime config changes is easy. >NOTE: `pallet_uniques::asset_ops::Item` grants access to the asset operations of NFT items of a given pallet-uniques instance, whereas `pallet_uniques::asset_ops::Collection` grants access to the collection operations. ### Declarative modification of an NFT engine If an NFT-hosting pallet only implements a transfer operation but not the `Stash` and `Restore`, one could declaratively add them using the `UniqueInstancesWithStashAccount` adapter. So, you can use it with the `UniqueInstancesAdapter` as follows: ```rust parameter_types! { pub StashAccountId: AccountId = /* Some Stash Account ID */; } type Transactor = UniqueInstancesAdapter< AccountId, LocationToAccountId, Matcher, UniqueInstancesWithStashAccount<StashAccountId, NftEngine>, >; ``` ### Supporting derivative NFTs (reserve-based model) There are several possible scenarios of supporting derivative NFTs (and their collections, if applicable). A separate NFT-hosting pallet instance could be configured to use XCM `AssetId` as collection ID and `AssetInstance` token ID. In that case, the asset transaction doesn't need any special treatment. However, registering NFT collections might require a special API. Also, if the NFT-hosting pallet can't be configured to use XCM ID types, we would need to store a mapping between the XCM ID of the original token and the derivative ID. See the `pallet-derivatives` crate docs for details. The example of its usage can be found in its mock and tests. #### TODO No benchmarks were run for `pallet-derivatives`, so there is no `weights.rs` for it yet. --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>





This is a refined version of the XCM Asset Metadata RFC.
This PR supersedes the PR opened in the xcm-format repository following the migration of XCM RFCs to the Fellowship RFCs.
Summary
This RFC proposes a metadata format for XCM-identifiable assets (i.e., for fungible/non-fungible collections and non-fungible tokens) and a set of instructions to communicate it across chains.