哪些信息持有 NFT?

Posted

技术标签:

【中文标题】哪些信息持有 NFT?【英文标题】:Which information hold an NFT? 【发布时间】:2021-07-05 03:57:02 【问题描述】:

我正在使用 Solidity 开发 NFT 市场,特别是我正在 OpenZeppelin 的 ERC-721 智能合约之上创建自己的智能合约。目前我的 NFT 有 5 个图片属性(id、image、description、collection 和 image),我保存了 ipfs 在上传时开发的哈希。

我的问题是在哪里保存所有这些属性,因为我有具有上述属性的 Image 结构,我将它添加到一个数组中,并使用数组中 Image 对象的 id 和地址创建 NFT创作者。我的意思是,我将所有信息都保存在 ERC-721 合约之外,所以我不太了解 NFT 是什么,因为属性不是来自 NFT,但 NFT 是我的结构的属性。

我是否正确实施它并且 ERC-721 标准只是 NFT 的必要功能,还是我将信息保存在它不涉及的地方?

我的代码目前如下:

pragma solidity ^0.5.0;

import "./ERC721Full.sol";

contract NftShop is ERC721Full 
  string public name;
  Image[] public nft;
  uint public imageId = 0;
  mapping(uint => bool) public _nftExists;
  mapping(uint => Image) public images;

  struct Image 
    uint id;                  //id of the nft
    string hash;              //hash of the ipfs            
    string description;       //nft description
    string collection;        //what collection the nft bellongs
    address payable author;   //creator of the nft
  

  //Event used when new Token is created
  event TokenCreated(
    uint id,
    string hash,
    string description,
    string collection,
    address payable author
  );

  constructor() public payable ERC721Full("NftShop", "NFTSHOP") 
    name = "NftShop";
  

  //uploadImage to the blockchain and mint the nft.
  function uploadImage(string memory _imgHash, string memory _description, string memory _collection) public 
    // Make sure the image hash exists
    require(bytes(_imgHash).length > 0);
    // Make sure image description exists
    require(bytes(_description).length > 0);
    // Make sure collectionage exists
    require(bytes(_collection).length > 0);
    // Make sure uploader address exists
    require(msg.sender!=address(0));

    // Increment image id
    imageId ++;

    // Add Image to the contract
    images[imageId] = Image(imageId, _imgHash, _description, _collection, msg.sender);

    //Mint the token
    require(!_nftExists[imageId]);
    uint _id = nft.push(images[imageId]);
    _mint(msg.sender, _id);
    _nftExists[imageId] = true;

    // Trigger an event
    emit TokenCreated(imageId, _imgHash, _description, _collection, msg.sender);
  
 

如果有什么奇怪的地方,欢迎提出任何关于如何改进代码的建议。

我希望这不是一个荒谬的问题,我是从以太坊的世界开始的。

非常感谢。

【问题讨论】:

【参考方案1】:

是的,图像地址等信息存储在继承自 ERC721 的合约中。 ERC721 主要跟踪代币的所有权、铸造和转让。

您可能需要考虑的一件事是令牌的唯一性。在您的示例中,可以存在许多具有相同图像和描述的标记。 您可能希望通过存储 _imgHash、_description、_collection 的哈希并要求它是唯一的来防止这种情况发生,这样任何用户都无法创建现有令牌的“副本”。

类似:

keccak256(abi.encodePacked(_imgHash, _description, _collection))

另一个常用的标准是 Opensea 元数据标准,其中 tokenURI 存储在链上,元数据位于区块链之外。 https://docs.opensea.io/docs/metadata-standards

【讨论】:

感谢您的回答,我有一个类似的问题,在存储 _imgHash、_description 等的哈希的情况下...您认为这是否可以适应“版税”场景,其中每个后续销售会给创作者带来一些收入吗?谢谢! @DanielVieira ERC721 中的 NFT 有一个所有者。当它被出售时,它属于新的所有者。在版税场景中,您可能希望拥有多个所有者。每次销售都会向代币的创建者产生版税。这是可能的,但该功能还必须在继承自 NFT(例如 ERC721)的合约中实现(或已经在另一个标准中)。 非常感谢@ruff09,您是否涉足过 ERC-1155 标准,显然它实现了版税标准,看起来很有趣...

以上是关于哪些信息持有 NFT?的主要内容,如果未能解决你的问题,请参考以下文章

NFT推动全球加密艺术浪潮

NFT推动全球加密艺术浪潮

NFT推动全球加密艺术浪潮

NFT推动全球加密艺术浪潮

多对多持有关系信息

浅谈NFT的注意力经济