我正在开发一个使用solidity的NFT市场,特别是我正在OpenZeppelin的ERC-721智能合约上创建我自己的智能合约。我的NFT目前有5个属性(id,图像,描述,集合和图像),我保存了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);
}
} 如果有什么奇怪的地方,欢迎任何关于如何改进代码的建议。
我希望这不是一个荒谬的问题,我是从以太的世界开始的。
非常感谢。
发布于 2021-04-09 21:05:05
是的,图像地址等信息存储在从ERC721继承的约定中。ERC721主要跟踪令牌的所有权、铸币和转移。
您可能需要考虑的一件事是令牌的唯一性。在您的示例中,可以存在许多具有相同图像和描述的令牌。您可能希望通过存储_imgHash、_description、_collection的散列来防止这种情况,并要求它是唯一的,这样用户就无法创建现有令牌的“副本”。
类似于:
keccak256(abi.encodePacked(_imgHash, _description, _collection))另一个经常使用的标准是Opensea元数据标准,其中tokenURI存储在链上,元数据位于区块链之外。https://docs.opensea.io/docs/metadata-standards
https://stackoverflow.com/questions/67018238
复制相似问题