我有一个 Smart Contract
,我想为其构建一个基于网络的市场应用程序。如何在合同中列出所有可用的“项目”。既然铸造的Item数量没有上限,我该如何实现分页和搜索?
什么是最佳实践和可扩展的解决方案:
简单地返回 Items[] 数组
在 Transfer 和其他事件上将数组与我的数据库同步
其他建议?
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
}
}
答案 0 :(得分:2)
您可以创建一个 itemsCount
公共属性来保存现有项目的当前数量,并在每个 items.push()
之后增加它。
没有分页和搜索:
想要读取您的数据的链下系统可以简单地从 items[0]
循环到 items[itemsCount]
,并且由于它只是一个读取操作,因此不需要交易(即它是免费的)。
分页和搜索:
您可以创建一个 view
函数:
page
和 query
作为参数items
,如果项目符合条件(name
包含 query
),则将其添加到结果数组中注意:在 Solidity 中,第 2 步实际上会稍微复杂一些,因为您无法将 push
放入内存中的动态数组。所以你需要:
results
results
数组答案 1 :(得分:1)
映射比数组更有效。您可以在智能合约中使用一个 uint 来保存每个项目的计数,并使用 getter 函数从您想要分页的任何数字中获取每个项目,并从项目计数中减去。
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)
}