public-awesome / cw-nfts

Examples and helpers to build NFT contracts on CosmWasm
Apache License 2.0
185 stars 181 forks source link

cw721: extension (compared to ERC721 metadata extension and enumeration extension) #105

Closed taitruong closed 1 year ago

taitruong commented 1 year ago

Quick question what extension means and is suppose to be: the purpose of cw721 extension is solely for metadata?

Check here: https://github.com/CosmWasm/cw-nfts/blob/main/packages/cw721/src/query.rs#L120

But reading the ERC721 spec there are 2 types of extensions: metadata and enumeration metadata: https://eips.ethereum.org/EIPS/eip-721

Check here: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md

The metadata extension is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your smart contract to be interrogated for its name and for details about the assets which your NFTs represent.

/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
///  Note: the ERC-165 identifier for this interface is 0x5b5e139f.
interface ERC721Metadata /* is ERC721 */ {
    /// @notice A descriptive name for a collection of NFTs in this contract
    function name() external view returns (string _name);

    /// @notice An abbreviated name for NFTs in this contract
    function symbol() external view returns (string _symbol);

    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
    ///  3986. The URI may point to a JSON file that conforms to the "ERC721
    ///  Metadata JSON Schema".
    function tokenURI(uint256 _tokenId) external view returns (string);
}

The enumeration extension is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to publish its full list of NFTs and make them discoverable.

/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://eips.ethereum.org/EIPS/eip-721
///  Note: the ERC-165 identifier for this interface is 0x780e9d63.
interface ERC721Enumerable /* is ERC721 */ {
    /// @notice Count NFTs tracked by this contract
    /// @return A count of valid NFTs tracked by this contract, where each one of
    ///  them has an assigned and queryable owner not equal to the zero address
    function totalSupply() external view returns (uint256);

    /// @notice Enumerate valid NFTs
    /// @dev Throws if `_index` >= `totalSupply()`.
    /// @param _index A counter less than `totalSupply()`
    /// @return The token identifier for the `_index`th NFT,
    ///  (sort order not specified)
    function tokenByIndex(uint256 _index) external view returns (uint256);

    /// @notice Enumerate NFTs assigned to an owner
    /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
    ///  `_owner` is the zero address, representing invalid NFTs.
    /// @param _owner An address where we are interested in NFTs owned by them
    /// @param _index A counter less than `balanceOf(_owner)`
    /// @return The token identifier for the `_index`th NFT assigned to `_owner`,
    ///   (sort order not specified)
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
}
LeTurt333 commented 1 year ago

Extension

extension can be used if you want to have some metadata stored on chain

(imo) since your contract should have a universal Metadata Extension type for all NFTs, you can customize your extension however you want. Anytime someone wants to get information about an NFTs metadata, they should be able to query your contract and expect the metadata returned will follow the format you have defined in your extension

Having your Metadata stored on chain also allows other contracts to interact with it, which otherwise would not be possible if you had your metadata stored off chain (or at least would not be nearly as easy)

URI

token_uri can be used if you want to point to some metadata stored off chain

From cw721-base/state.rs

    /// Universal resource identifier for this NFT
    /// Should point to a JSON file that conforms to the ERC721
    /// Metadata JSON Schema
    pub token_uri: Option<String>,

From OpenSea metadata standards

...the uri function in your ERC1155 contract should return an HTTP or IPFS URL.
When queried, this URL should in turn return a JSON blob of data with the metadata for your token.

Since this is expected to just be JSON (and not a strongly typed Rust struct), there can't really be any guarantee of what the structure of that JSON will be. But, making a simple GET request is likely much more ergonomic than setting up a client and querying a node directly


Enumeration

Everything within the ERC-721 Enumeration Extension you posted is available by default with cw721-base (or has a comparable alternative)

ERC: totalSupply | CW721: num_tokens

ERC: tokenByIndex | CW721: nft_info

ERC: tokenOfOwnerByIndex | CW721: tokens

Examples

cw721-metadata-onchain - Core example of extending cw721-base with on-chain metadata

EnvoyLabs WhoamI - Example of a customized on-chain metadata extension

JakeHartnell commented 1 year ago

Closing for now, re-open if you have additional questions.