Changelog
- 2021-05-01: Initial Draft
- 2021-07-02: Review updates
- 2022-06-15: Add batch operation
- 2022-11-11: Remove strict validation of classID and tokenID
Status
PROPOSEDAbstract
This ADR defines thex/nft module which is a generic implementation of NFTs, roughly “compatible” with ERC721. Applications using the x/nft module must implement the following functions:
MsgNewClass- Receive the user’s request to create a class, and call theNewClassof thex/nftmodule.MsgUpdateClass- Receive the user’s request to update a class, and call theUpdateClassof thex/nftmodule.MsgMintNFT- Receive the user’s request to mint a nft, and call theMintNFTof thex/nftmodule.BurnNFT- Receive the user’s request to burn a nft, and call theBurnNFTof thex/nftmodule.UpdateNFT- Receive the user’s request to update a nft, and call theUpdateNFTof thex/nftmodule.
Context
NFTs are more than just crypto art, which is very helpful for accruing value to the Cosmos ecosystem. As a result, Cosmos Hub should implement NFT functions and enable a unified mechanism for storing and sending the ownership representative of NFTs as discussed in Link. As discussed in #9065, several potential solutions can be considered:- irismod/nft and modules/incubator/nft
- CW721
- DID NFTs
- interNFT
Decision
We create ax/nft module, which contains the following functionality:
- Store NFTs and track their ownership.
- Expose
Keeperinterface for composing modules to transfer, mint and burn NFTs. - Expose external
Messageinterface for users to transfer ownership of their NFTs. - Query NFTs and their supply information.
NFT or Class type described below. The app specific NFT data should be encoded in NFT.data for cross-chain integrity. Other objects related to NFT, which are not important for integrity can be part of the app specific module.
Types
We propose two main types:Class— describes NFT class. We can think about it as a smart contract address.NFT— object representing unique, non fungible asset. Each NFT is associated with a Class.
Class
NFT Class is comparable to an ERC-721 smart contract (provides description of a smart contract), under which a collection of NFTs can be created and managed.idis used as the primary index for storing the class; requirednameis a descriptive name of the NFT class; optionalsymbolis the symbol usually shown on exchanges for the NFT class; optionaldescriptionis a detailed description of the NFT class; optionaluriis a URI for the class metadata stored off chain. It should be a JSON file that contains metadata about the NFT class and NFT data schema (OpenSea example); optionaluri_hashis a hash of the document pointed by uri; optionaldatais app specific metadata of the class; optional
NFT
We define a general model forNFT as follows.
-
class_idis the identifier of the NFT class where the NFT belongs; required -
idis an identifier of the NFT, unique within the scope of its class. It is specified by the creator of the NFT and may be expanded to use DID in the future.class_idcombined withiduniquely identifies an NFT and is used as the primary index for storing the NFT; required -
uriis a URI for the NFT metadata stored off chain. Should point to a JSON file that contains metadata about this NFT (Ref: ERC721 standard and OpenSea extension); required -
uri_hashis a hash of the document pointed by uri; optional -
datais an app specific data of the NFT. CAN be used by composing modules to specify additional properties of the NFT; optional
data can take; however, best practices recommend upper-level NFT modules clearly specify their contents. Although the value of this field doesn’t provide the additional context required to manage NFT records, which means that the field can technically be removed from the specification, the field’s existence allows basic informational/UI functionality.
Keeper Interface
x/nft and use its Keeper.
Msg Service
MsgSend can be used to transfer the ownership of an NFT to another address.
The implementation outline of the server is as follows:
x/nft module are:
Interoperability
Interoperability is all about reusing assets between modules and chains. The former one is achieved by ADR-33: Protobuf client - server communication. At the time of writing ADR-33 is not finalized. The latter is achieved by IBC. Here we will focus on the IBC side. IBC is implemented per module. Here, we aligned that NFTs will be recorded and managed in the x/nft. This requires creation of a new IBC standard and implementation of it. For IBC interoperability, NFT custom modules MUST use the NFT object type understood by the IBC client. So, for x/nft interoperability, custom NFT implementations (example: x/cryptokitty) should use the canonical x/nft module and proxy all NFT balance keeping functionality to x/nft or else re-implement all functionality using the NFT object type understood by the IBC client. In other words: x/nft becomes the standard NFT registry for all Cosmos NFTs (example: x/cryptokitty will register a kitty NFT in x/nft and use x/nft for book keeping). This was discussed in the context of using x/bank as a general asset balance book. Not using x/nft will require implementing another module for IBC.Consequences
Backward Compatibility
No backward incompatibilities.Forward Compatibility
This specification conforms to the ERC-721 smart contract specification for NFT identifiers. Note that ERC-721 defines uniqueness based on (contract address, uint256 tokenId), and we conform to this implicitly because a single module is currently aimed to track NFT identifiers. Note: use of the (mutable) data field to determine uniqueness is not safe.sPositive
- NFT identifiers available on Cosmos Hub.
- Ability to build different NFT modules for the Cosmos Hub, e.g., ERC-721.
- NFT module which supports interoperability with IBC and other cross-chain infrastructures like Gravity Bridge
Negative
- New IBC app is required for x/nft
- CW721 adapter is required
Neutral
- Other functions need more modules. For example, a custody module is needed for NFT trading function, a collectible module is needed for defining NFT properties.
Further Discussions
For other kinds of applications on the Hub, more app-specific modules can be developed in the future:x/nft/custody: custody of NFTs to support trading functionality.x/nft/marketplace: selling and buying NFTs using sdk.Coins.x/fractional: a module to split an ownership of an asset (NFT or other assets) for multiple stakeholder.x/groupshould work for most of the cases.