简体   繁体   English

跟踪 ERC721 智能合约上的所有铸造代币

[英]Keep track of all minted tokens on ERC721 Smart Contract

I have a Smart Contract that I'd like to build a web based marketplace app for.我有一个Smart Contract ,我想为它构建一个基于 web 的市场应用程序。 How can I list all available "Items" in the contract.如何在合同中列出所有可用的“项目”。 Seeing as there is no upper limit to the number of minted Items, how can I implement pagination and search?鉴于铸造项目的数量没有上限,如何实现分页和搜索?

What is a best practice and scalable solution:什么是最佳实践和可扩展的解决方案:

  • to simply return the Items[] array简单地返回 Items[] 数组

  • sync the array with my database on Transfer and other events在传输和其他事件上将阵列与我的数据库同步

  • other suggestions?其他建议?

     pragma solidity ^0.4.24; contract Item is ERC721{ struct Item{ string name; // Name of the Item uint level; // Item Level uint rarityLevel; // 1 = normal, 2 = rare, 3 = epic, 4 = legendary } Item[] public items; // First Item has Index 0 address public owner; function Item() public { owner = msg.sender; // The Sender is the Owner; Ethereum Address of the Owner } function createItem(string _name, address _to) public{ require(owner == msg.sender); // Only the Owner can create Items uint id = items.length; // Item ID = Length of the Array Items items.push(Item(_name,5,1)) // Item ("Sword",5,1) _mint(_to,id); // Assigns the Token to the Ethereum Address that is specified } }

You can create an itemsCount public property that holds the current amount of existing items, and increment it after each items.push() .您可以创建一个itemsCount公共属性来保存现有项目的当前数量,并在每个items.push()之后递增它。


Without pagination and search:没有分页和搜索:

Off-chain systems that want to read your data, can simply loop from items[0] to items[itemsCount] and since it's just a read operation, it doesn't require a transaction (ie it's free).想要读取您的数据的链下系统可以简单地从items[0]循环到items[itemsCount] ,并且由于它只是一个读取操作,它不需要事务(即它是免费的)。


With pagination and search:分页和搜索:

You can to create a view function that:您可以创建一个view function :

  1. Takes page and query as arguments以 arguments 作为pagequery
  2. Loops through existing items and if the item fits the criteria ( name contains query ), add it to the results array遍历现有items ,如果项目符合条件( name包含query ),则将其添加到结果数组
  3. Returns the results array返回结果数组

Note: Step 2 is actually going to be a bit more complicated in Solidity, because you can't push into an in-memory dynamic array.注意:在 Solidity 中,第 2 步实际上会稍微复杂一些,因为您不能将其push入内存中的动态数组。 So you need to:所以你需要:

  1. Loop through the items and find an amount that fit the criteria (up to the page limit)遍历项目并找到符合条件的数量(最多页面限制)
  2. Create a fix-length in-memory array results创建一个固定长度的内存数组results
  3. Now you can loop through the items again and fill the fix-length results array with values现在您可以再次循环遍历这些项目并用值填充固定长度的results数组

mapping are more efficient than arrays in solidity.映射在可靠性方面比 arrays 更有效。 You could have a uint in the smart contract that keeps the count of every Item and use a getter function to get each item from whatever number you want to paginate subtracted from the item count.您可以在智能合约中有一个 uint 来保存每个项目的计数,并使用吸气剂 function 从项目计数中减去您想要分页的任何数字获取每个项目。

contract Item is ERC721{

struct Item{
    string name; // Name of the Item
    uint level; // Item Level
    uint rarityLevel;  // 1 = normal, 2 = rare, 3 = epic, 4 = legendary
    uint id;
}

mapping(uint => Item) items; // First Item has Index 0
uint count;
address public owner;

function Item() public {
    owner = msg.sender; // The Sender is the Owner; Ethereum Address of the Owner
}

function createItem(string memory _name, address _to, uint level, uint rarityLevel
                    uint id) public{
    require(owner == msg.sender); // Only the Owner can create Items
        uint num = count++;
        items[num].name = _name;
        items[num].level = level;
        items[num].rarityLevel = rarityLevel;
        items[num].id = num;
        count++;
}

function getItem(uint item) public view returns(string memory _name, uint level, 
                 uint rarityLevel, uint id){
        uint level = items[item].level;
        uint rarityLevel = items[item].rarityLevel;
        uint id = items[item].id;
        string memory _name = items[item].name
        return(level, rarityLevel, id, _name)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM