Abstract

The Multi-Asset Token standard, compatible with ERC-1155, facilitates the development of a new fundamental component: the context-dependent data output for each collection.

The context-dependent data output means that the asset is displayed in an appropriate format based on how the token is accessed. I.e., if the token is being opened in an e-book reader, the PDF asset is displayed; if the token is opened in the marketplace, the PNG or the SVG asset is displayed; if the token is accessed from within a game, the 3D model asset is accessed, and if the token is accessed by an Internet of Things (IoT) hub, the asset providing the necessary addressing and specification information is accessed.

A Token Collection can have multiple assets (outputs), which can be any file to order them by priority. They do not have to match in mime-type or tokenURI, nor do they depend on one another. Assets are not standalone entities but should be considered “namespaced tokenURIs”.

Motivation

With ERC-1155 compatible tokens being a widespread form of tokens in the Ethereum ecosystem and being used for various use cases, it is time to standardize additional utility for them. Having multiple assets associated with a single Token Collection allows for greater utility, usability, and forward compatibility. This EIP improves upon ERC-1155 in the following areas:

Cross-metaverse compatibility

The proposal can support any number of different implementations.

Cross-metaverse compatibility could also be referred to as cross-engine compatibility. An example is where a cosmetic item for game A is unavailable in game B because the frameworks are incompatible.

Such Tokens can be given further utility through new assets: more games, cosmetic items, and more.

The following is a more concrete example. One asset is a cosmetic item for game A, a file containing the cosmetic assets. Another is a cosmetic asset file for game B. A third is a generic asset intended to be shown in catalogs, marketplaces, portfolio trackers, or other generalized Token Collection viewers, containing a representation, stylized thumbnail, and animated demo/trailer of the cosmetic item.

This EIP adds a layer of abstraction, allowing game developers to pull asset data from a user’s Tokens directly instead of hard-coding it.

Multi-media output

Tokens of an eBook can be represented as a PDF, MP3, or some other format, depending on what software loads it. If loaded into an eBook reader, a PDF should be displayed, and if loaded into an audiobook application, the MP3 representation should be used. Other metadata could be present in the Tokens (perhaps the book’s cover image) for identification on various marketplaces, Search Engine Result Pages (SERPs), or portfolio trackers.

Media redundancy

Many Tokens are minted hastily without best practices in mind. Specifically, many Tokens are minted with metadata centralized on a server somewhere or, in some cases, a hardcoded IPFS gateway which can also go down, instead of just an IPFS hash.

By adding the same metadata file as different assets, e.g., one asset of metadata and its linked image on Arweave, one asset of this same combination on Sia, another of the same combination on IPFS, etc., the resilience of the metadata and its referenced information increases exponentially as the chances of all the protocols going down at once become less likely.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.

/// @title ERC-7603 Context-Dependent Multi-Asset Tokens, ERC-1155 Execution
/// @dev See https://eips.ethereum.org/EIPS/erc-7603

pragma solidity ^0.8.23;

interface IERC7603 /* is ERC165 */ {
    /**
     * @notice Used to notify listeners that an asset object is initialised at `assetId`.
     * @param assetId ID of the asset that was initialised
     */
    event AssetSet(uint64 assetId);

    /**
     * @notice Used to notify listeners that an asset object at `assetId` is added to token's asset
     *  array.
     * @param tokenId An ID of the token that received a new asset
     * @param assetId ID of the asset that has been added to the token's assets array
     * @param replacesId ID of the asset that would be replaced
     */
    event AssetAddedToToken(
        uint256[] tokenId,
        uint64 indexed assetId,
        uint64 indexed replacesId
    );

    /**
     * @notice Used to notify listeners that token's priority array is reordered.
     * @param tokenId ID of the token that had the asset priority array updated
     */
    event AssetPrioritySet(uint256 indexed tokenId);

    /**
     * @notice Sets a new priority array for a given token.
     * @dev The priority array is a non-sequential list of `uint16`s, where the lowest value is considered highest
     *  priority.
     * @dev Value `0` of a priority is a special case equivalent to uninitialised.
     * @dev Requirements:
     *
     *  - `tokenId` must exist.
     *  - The length of `priorities` must be equal the length of the assets array.
     * @dev Emits a {AssetPrioritySet} event.
     * @param tokenId ID of the token to set the priorities for
     * @param priorities An array of priorities of assets. The succession of items in the priorities array
     *  matches that of the succession of items in the array
     */
    function setPriority(uint256 tokenId, uint64[] calldata priorities)
        external;

    /**
     * @notice Used to retrieve IDs of assets of given token.
     * @dev Asset data is stored by reference, in order to access the data corresponding to the ID, call
     *  `getAssetMetadata(tokenId, assetId)`.
     * @dev You can safely get 10k
     * @param tokenId ID of the token to retrieve the IDs of the assets
     * @return uint64[] An array of the asset IDs of the given token
     */
    function getAssets(uint256 tokenId)
        external
        view
        returns (uint64[] memory);

    /**
     * @notice Used to retrieve the priorities of the assets of a given token.
     * @dev Asset priorities are a non-sequential array of uint16 values with an array size equal to asset
     *  priorites.
     * @param tokenId ID of the token for which to retrieve the priorities of the assets
     * @return uint16[] An array of priorities of the assets of the given token
     */
    function getAssetPriorities(uint256 tokenId)
        external
        view
        returns (uint64[] memory);

    /**
     * @notice Used to fetch the asset metadata of the specified token's asset with the given index.
     * @dev Can be overridden to implement enumerate, fallback or other custom logic.
     * @param tokenId ID of the token from which to retrieve the asset metadata
     * @param assetId Asset Id, must be in the assets array
     * @return string The metadata of the asset belonging to the specified index in the token's assets array
     */
    function getAssetMetadata(uint256 tokenId, uint64 assetId)
        external
        view
        returns (string memory);
}

Rationale

TBD

Backwards Compatibility

The MultiAsset token standard has been made compatible with ERC-1155 in order to take advantage of the robust tooling available for implementations of ERC-1155 and to ensure compatibility with existing ERC-1155 infrastructure.

Security Considerations

Needs discussion.

Copyright and related rights waived via CC0.