diff --git a/404.html b/404.html index 2c60df07..24bc2c8c 100644 --- a/404.html +++ b/404.html @@ -91,7 +91,7 @@ diff --git a/approved/0001-agile-coretime.html b/approved/0001-agile-coretime.html index 1bdf242d..e831f697 100644 --- a/approved/0001-agile-coretime.html +++ b/approved/0001-agile-coretime.html @@ -90,7 +90,7 @@ diff --git a/approved/0005-coretime-interface.html b/approved/0005-coretime-interface.html index 5051ab43..dec4ef8c 100644 --- a/approved/0005-coretime-interface.html +++ b/approved/0005-coretime-interface.html @@ -90,7 +90,7 @@ diff --git a/approved/0007-system-collator-selection.html b/approved/0007-system-collator-selection.html index 3fd92663..65255540 100644 --- a/approved/0007-system-collator-selection.html +++ b/approved/0007-system-collator-selection.html @@ -90,7 +90,7 @@ diff --git a/approved/0008-parachain-bootnodes-dht.html b/approved/0008-parachain-bootnodes-dht.html index 4a71e7c6..5f76aa8f 100644 --- a/approved/0008-parachain-bootnodes-dht.html +++ b/approved/0008-parachain-bootnodes-dht.html @@ -90,7 +90,7 @@ diff --git a/approved/0009-improved-net-light-client-requests.html b/approved/0009-improved-net-light-client-requests.html index 32283a4a..dbf1b22b 100644 --- a/approved/0009-improved-net-light-client-requests.html +++ b/approved/0009-improved-net-light-client-requests.html @@ -90,7 +90,7 @@ diff --git a/approved/0010-burn-coretime-revenue.html b/approved/0010-burn-coretime-revenue.html index 3068c598..cc030e88 100644 --- a/approved/0010-burn-coretime-revenue.html +++ b/approved/0010-burn-coretime-revenue.html @@ -90,7 +90,7 @@ diff --git a/approved/0012-process-for-adding-new-collectives.html b/approved/0012-process-for-adding-new-collectives.html index b648e1c8..dfb022ba 100644 --- a/approved/0012-process-for-adding-new-collectives.html +++ b/approved/0012-process-for-adding-new-collectives.html @@ -90,7 +90,7 @@ diff --git a/approved/0013-prepare-blockbuilder-and-core-runtime-apis-for-mbms.html b/approved/0013-prepare-blockbuilder-and-core-runtime-apis-for-mbms.html index 31a38a03..53b1ea23 100644 --- a/approved/0013-prepare-blockbuilder-and-core-runtime-apis-for-mbms.html +++ b/approved/0013-prepare-blockbuilder-and-core-runtime-apis-for-mbms.html @@ -90,7 +90,7 @@ diff --git a/approved/0014-improve-locking-mechanism-for-parachains.html b/approved/0014-improve-locking-mechanism-for-parachains.html index 0624ca1e..f49a077c 100644 --- a/approved/0014-improve-locking-mechanism-for-parachains.html +++ b/approved/0014-improve-locking-mechanism-for-parachains.html @@ -90,7 +90,7 @@ diff --git a/approved/0022-adopt-encointer-runtime.html b/approved/0022-adopt-encointer-runtime.html index d427a45b..2f1288c5 100644 --- a/approved/0022-adopt-encointer-runtime.html +++ b/approved/0022-adopt-encointer-runtime.html @@ -90,7 +90,7 @@ diff --git a/approved/0026-sassafras-consensus.html b/approved/0026-sassafras-consensus.html index d49546fa..c6550e08 100644 --- a/approved/0026-sassafras-consensus.html +++ b/approved/0026-sassafras-consensus.html @@ -90,7 +90,7 @@ diff --git a/approved/0032-minimal-relay.html b/approved/0032-minimal-relay.html index 099b3970..ddffea97 100644 --- a/approved/0032-minimal-relay.html +++ b/approved/0032-minimal-relay.html @@ -90,7 +90,7 @@ diff --git a/approved/0042-extrinsics-state-version.html b/approved/0042-extrinsics-state-version.html index 00ce4b01..1894821c 100644 --- a/approved/0042-extrinsics-state-version.html +++ b/approved/0042-extrinsics-state-version.html @@ -90,7 +90,7 @@ diff --git a/approved/0043-storage-proof-size-hostfunction.html b/approved/0043-storage-proof-size-hostfunction.html index 3cadfd26..f18b0f94 100644 --- a/approved/0043-storage-proof-size-hostfunction.html +++ b/approved/0043-storage-proof-size-hostfunction.html @@ -90,7 +90,7 @@ diff --git a/approved/0045-nft-deposits-asset-hub.html b/approved/0045-nft-deposits-asset-hub.html index 25be3bce..ede21662 100644 --- a/approved/0045-nft-deposits-asset-hub.html +++ b/approved/0045-nft-deposits-asset-hub.html @@ -90,7 +90,7 @@ diff --git a/approved/0047-assignment-of-availability-chunks.html b/approved/0047-assignment-of-availability-chunks.html index 3f987448..524cee3f 100644 --- a/approved/0047-assignment-of-availability-chunks.html +++ b/approved/0047-assignment-of-availability-chunks.html @@ -90,7 +90,7 @@ diff --git a/approved/0048-session-keys-runtime-api.html b/approved/0048-session-keys-runtime-api.html index c3312497..84312b58 100644 --- a/approved/0048-session-keys-runtime-api.html +++ b/approved/0048-session-keys-runtime-api.html @@ -90,7 +90,7 @@ diff --git a/approved/0050-fellowship-salaries.html b/approved/0050-fellowship-salaries.html index 8d870cb3..9d31e66d 100644 --- a/approved/0050-fellowship-salaries.html +++ b/approved/0050-fellowship-salaries.html @@ -90,7 +90,7 @@ diff --git a/approved/0056-one-transaction-per-notification.html b/approved/0056-one-transaction-per-notification.html index 068407b5..da536e48 100644 --- a/approved/0056-one-transaction-per-notification.html +++ b/approved/0056-one-transaction-per-notification.html @@ -90,7 +90,7 @@ diff --git a/approved/0059-nodes-capabilities-discovery.html b/approved/0059-nodes-capabilities-discovery.html index f69f76e9..7fca8e0e 100644 --- a/approved/0059-nodes-capabilities-discovery.html +++ b/approved/0059-nodes-capabilities-discovery.html @@ -90,7 +90,7 @@ diff --git a/approved/0078-merkleized-metadata.html b/approved/0078-merkleized-metadata.html index 6be221d6..7ad1034b 100644 --- a/approved/0078-merkleized-metadata.html +++ b/approved/0078-merkleized-metadata.html @@ -90,7 +90,7 @@ diff --git a/approved/0084-general-transaction-extrinsic-format.html b/approved/0084-general-transaction-extrinsic-format.html index 303ff559..be714c43 100644 --- a/approved/0084-general-transaction-extrinsic-format.html +++ b/approved/0084-general-transaction-extrinsic-format.html @@ -90,7 +90,7 @@ diff --git a/approved/0091-dht-record-creation-time.html b/approved/0091-dht-record-creation-time.html index 81325194..6b8b464a 100644 --- a/approved/0091-dht-record-creation-time.html +++ b/approved/0091-dht-record-creation-time.html @@ -90,7 +90,7 @@ diff --git a/approved/0097-unbonding_queue.html b/approved/0097-unbonding_queue.html index f431ef45..59406e68 100644 --- a/approved/0097-unbonding_queue.html +++ b/approved/0097-unbonding_queue.html @@ -90,7 +90,7 @@ diff --git a/approved/0099-transaction-extension-version.html b/approved/0099-transaction-extension-version.html index 5fd99dea..40dc2ff6 100644 --- a/approved/0099-transaction-extension-version.html +++ b/approved/0099-transaction-extension-version.html @@ -90,7 +90,7 @@ diff --git a/approved/0100-xcm-multi-type-asset-transfer.html b/approved/0100-xcm-multi-type-asset-transfer.html index 8c62c639..443a6a04 100644 --- a/approved/0100-xcm-multi-type-asset-transfer.html +++ b/approved/0100-xcm-multi-type-asset-transfer.html @@ -90,7 +90,7 @@ diff --git a/approved/0101-xcm-transact-remove-max-weight-param.html b/approved/0101-xcm-transact-remove-max-weight-param.html index 666ad615..d0b000c2 100644 --- a/approved/0101-xcm-transact-remove-max-weight-param.html +++ b/approved/0101-xcm-transact-remove-max-weight-param.html @@ -90,7 +90,7 @@ diff --git a/approved/0103-introduce-core-index-commitment.html b/approved/0103-introduce-core-index-commitment.html index fe18b6d0..29392568 100644 --- a/approved/0103-introduce-core-index-commitment.html +++ b/approved/0103-introduce-core-index-commitment.html @@ -90,7 +90,7 @@ diff --git a/approved/0105-xcm-improved-fee-mechanism.html b/approved/0105-xcm-improved-fee-mechanism.html index 1b896e3e..5e1b6657 100644 --- a/approved/0105-xcm-improved-fee-mechanism.html +++ b/approved/0105-xcm-improved-fee-mechanism.html @@ -90,7 +90,7 @@ diff --git a/approved/0107-xcm-execution-hints.html b/approved/0107-xcm-execution-hints.html index 54011059..5b8099e6 100644 --- a/approved/0107-xcm-execution-hints.html +++ b/approved/0107-xcm-execution-hints.html @@ -90,7 +90,7 @@ diff --git a/approved/0108-xcm-remove-testnet-ids.html b/approved/0108-xcm-remove-testnet-ids.html index 8c82db22..0ae9dc72 100644 --- a/approved/0108-xcm-remove-testnet-ids.html +++ b/approved/0108-xcm-remove-testnet-ids.html @@ -90,7 +90,7 @@ diff --git a/approved/0122-alias-origin-on-asset-transfers.html b/approved/0122-alias-origin-on-asset-transfers.html index 57aa00bc..aa97dfbf 100644 --- a/approved/0122-alias-origin-on-asset-transfers.html +++ b/approved/0122-alias-origin-on-asset-transfers.html @@ -90,7 +90,7 @@ diff --git a/index.html b/index.html index 928c0b63..33116079 100644 --- a/index.html +++ b/index.html @@ -90,7 +90,7 @@ diff --git a/introduction.html b/introduction.html index 928c0b63..33116079 100644 --- a/introduction.html +++ b/introduction.html @@ -90,7 +90,7 @@ diff --git a/print.html b/print.html index 8ee910ac..cdbf5214 100644 --- a/print.html +++ b/print.html @@ -91,7 +91,7 @@ @@ -571,6 +571,229 @@

RFC-0125: XCM Asset Metadata

+
+ + + +
Start Date22 Oct 2024
DescriptionXCM Asset Metadata definition and a way of communicating it via XCM
AuthorsDaniel Shiposha
+
+

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.

+

Motivation

+

Currently, there is no way to communicate metadata of an asset (or an asset instance) via XCM.

+

The ability to query and modify the metadata is useful for two kinds of entities:

+ +

Besides metadata modification, the ability to read it is also valuable. On-chain logic can interpret the NFT metadata, i.e., the metadata could have not only the media meaning but also a utility function within a consensus system. Currently, such a way of using NFT metadata is possible only within one consensus system. This RFC proposes making it possible between different systems via XCM so different chains can fetch and analyze the asset metadata from other chains.

+

Stakeholders

+

Runtime users, Runtime devs, Cross-chain dApps, Wallets.

+

Explanation

+

The Asset Metadata is information bound to an asset class (fungible or NFT collection) or an asset instance (an NFT). +The Asset Metadata could be represented differently on different chains (or in other consensus entities). +However, to communicate metadata between consensus entities via XCM, we need a general format so that any consensus entity can make sense of such information.

+

We can name this format "XCM Asset Metadata".

+

This RFC proposes:

+
    +
  1. +

    Using key-value pairs as XCM Asset Metadata since it is a general concept useful for both structured and unstructured data. Both key and value can be raw bytes with interpretation up to the communicating entities.

    +

    The XCM Asset Metadata should be represented as a map SCALE-encoded equivalent to the BTreeMap<Vec<u8>, Vec<u8>>.

    +

    As such, the XCM Asset Metadata types are defined as follows:

    +
    #![allow(unused)]
    +fn main() {
    +type MetadataKey = Vec<u8>;
    +type MetadataValue = Vec<u8>;
    +type MetadataMap = BTreeMap<MetadataKey, MetadataValue>;
    +}
    +
  2. +
  3. +

    Communicating only the demanded part of the metadata, not the whole metadata.

    + +
  4. +
  5. +

    New XCM instructions to communicate the metadata.

    +
  6. +
+

Note: the maximum lengths of MetadataKey, MetadataValue, MetadataMap, and MetadataKeySet are implementation-defined.

+

New instructions

+

ReportMetadata

+

The ReportMetadata is a new instruction to query metadata information. +It can be used to query metadata key list or to query values of interested keys.

+

This instruction allows querying the metadata of:

+ +

If an asset (or an asset instance) for which the query is made doesn't exist, the Response::Null should be reported via the existing QueryResponse instruction.

+

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.

+

The use case for this instruction is when the metadata information of a foreign asset (or asset instance) is used in the logic of a consensus entity that requested it.

+
#![allow(unused)]
+fn main() {
+/// An instruction to query metadata of an asset or an asset instance.
+ReportMetadata {
+    /// The ID of an asset (a collection, fungible or nonfungible).
+    asset_id: AssetId,
+
+    /// The ID of an asset instance.
+    ///
+    /// If the value is `Undefined`, the metadata of the collection is reported.
+    instance: AssetInstance,
+
+    /// See `MetadataQueryKind` below.
+    query_kind: MetadataQueryKind,
+
+    /// The usual field for Report<something> XCM instructions.
+    ///
+    /// Information regarding the query response.
+    /// The `QueryResponseInfo` type is already defined in the XCM spec.
+    response_info: QueryResponseInfo,
+}
+}
+

Where the MetadataQueryKind is:

+
#![allow(unused)]
+fn main() {
+enum MetadataQueryKind {
+    /// Query metadata key set.
+    KeySet,
+
+    /// Query values of the specified keys.
+    Values(MetadataKeySet),
+}
+}
+

The ReportMetadata works in conjunction with the existing QueryResponse instruction. The Response type should be modified accordingly: we need to add a new AssetMetadata variant to it.

+
#![allow(unused)]
+fn main() {
+/// The struct used in the existing `QueryResponse` instruction.
+pub enum Response {
+    // ... snip, existing variants ...
+
+    /// The metadata info.
+    AssetMetadata {
+        /// The ID of an asset (a collection, fungible or nonfungible).
+        asset_id: AssetId,
+
+        /// The ID of an asset instance.
+        ///
+        /// If the value is `Undefined`, the reported metadata is related to the collection, not a token.
+        instance: AssetInstance,
+
+        /// See `MetadataResponseData` below.
+        data: MetadataResponseData,
+    }
+}
+
+pub enum MetadataResponseData {
+    /// The metadata key list to be reported
+    /// in response to the `KeySet` metadata query kind.
+    KeySet(MetadataKeySet),
+
+    /// The values of the keys that were specified in the
+    /// `Values` variant of the metadata query kind.
+    Values(MetadataMap),
+}
+}
+

ModifyMetadata

+

The ModifyMetadata is a new instruction to request a remote chain to modify the values of the specified keys.

+

This instruction can be used to update the metadata of a collection (fungible or nonfungible) or of an NFT.

+

The remote chain handles the modification request and may reject it based on its internal rules. +The request can only be executed or rejected in its entirety. It must not be executed partially.

+

To execute the ModifyMetadata, an origin is required so that the handling logic can authorize the metadata modification request from a known source. Since this instruction requires an origin, the assets used to cover the execution fees must be transferred in a way that preserves the origin. For instance, one can use the approach described in RFC #122 if the handling chain configured aliasing rules accordingly.

+

The example use case of this instruction is to ask the reserve location of the asset to modify the metadata. So that, the original asset's metadata is updated according to the reserve location's rules.

+
#![allow(unused)]
+fn main() {
+ModifyMetadata {
+    /// The ID of an asset (a collection, fungible or nonfungible).
+    asset_id: AssetId,
+
+    /// The ID of an asset instance.
+    ///
+    /// If the value is `Undefined`, the modification request targets the collection, not a token.
+    instance: AssetInstance,
+
+    /// The map contains the keys mapped to the requested new values.
+    modification: MetadataMap,
+}
+}
+

Repurposing AssetInstance::Undefined

+

As the new instructions show, this RFC reframes the purpose of the Undefined variant of the AssetInstance enum. +This RFC proposes to use the Undefined variant of a collection identified by an AssetId as a synonym of the collection itself. I.e., an asset Asset { id: <AssetId>, fun: NonFungible(AssetInstance::Undefined) } is considered an NFT representing the collection itself.

+

As a singleton non-fungible instance is barely distinguishable from its collection, this convention shouldn't cause any problems.

+

Thus, the AssetInstance docs must be updated accordingly in the implementations.

+

Drawbacks

+

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 are no security concerns except for the ReportMetadata instruction, which implies that the source of the information must be trusted.

+

In terms of performance and privacy, there will be no changes.

+

Testing, Security, and Privacy

+

The implementations must honor the contract for the new instructions. Namely, if the instance field has the value of AssetInstance::Undefined, the metadata must relate to the asset collection but not to a non-fungible token inside it.

+

Performance, Ergonomics, and Compatibility

+

Performance

+

No significant impact.

+

Ergonomics

+

Introducing a standard metadata format and a way of communicating it is a valuable addition to the XCM format that potentially increases cross-chain interoperability without the need to form ad-hoc chain-to-chain integrations via Transact.

+

Compatibility

+

This RFC proposes new functionality, so there are no compatibility issues.

+

Prior Art and References

+

RFC: XCM Asset Metadata

+ +

The original RFC draft contained additional metadata instructions. Though they could be useful, they're clearly outside the basic logic. So, this RFC version omits them to make the metadata discussion more focused on the core things. Nonetheless, there is hope that metadata approval instructions might be useful in the future, so they are mentioned here.

+

You can read about the details in the original draft.

(source)

Table of Contents

-

Motivation

+

Motivation

In Substrate, runtime APIs facilitate off-chain clients in reading the state of the consensus system. However, different chains may expose different APIs for a similar query or have varying data types, such as doing custom transformations on direct data, or differing AccountId types. This diversity also extends to client-side, which may require custom computations over runtime APIs in various use cases. Therefore, tools and UI developers often access storage directly and reimplement custom computations to convert data into user-friendly representations, leading to duplicated code between Rust runtime logic and UI JS/TS logic. This duplication increases workload and potential for bugs.

Therefore, a system is needed to serve as an intermediary layer between concrete chain runtime implementations and tools/UIs, to provide a unified interface for cross-chain queries.

-

Stakeholders

+

Stakeholders

-

Explanation

+

Explanation

The overall query pattern of XCQ consists of three components:

Errors

-

Drawbacks

+

Drawbacks

Performance issues

-

Testing, Security, and Privacy

+

Testing, Security, and Privacy