找回多维平衡
Retrieving multidimensional balance
我正在开发基于以太坊的纸牌游戏。一个用户可以收集 n 张 individual/unique 张卡片。一切正常,运行ning,我正在使用以下余额映射:
mapping (address => mapping (uint256 => uint256)) balances;
第一个单位是卡片ID,第二个单位是卡片数量。我将拥有多达 1000 张卡片,现在我正在测试 700 张卡片。
我通过调用以下方式检索 DApp 上的余额:
function balanceOf(address _owner, uint256 _id) view external returns(uint256) {
return balances[_owner][_id];
}
对于每个 ID。在平衡变化方面,我进行部分平衡更新。这通常有效。它是免费的,但它也非常慢,因为初始检索调用必须执行 640 次。我研究了很多并尝试了各种实现,但主要问题是我需要检索一个包含卡 ID 和计数信息的地址映射数组。目前,您无法轻松检索动态大小的数组或结构。
解决该问题的建议是什么?在 Solidity 引入简单的 Array 调用之前,我是否在 DApp Start 上坚持了多达 1000 个 balanceOf 调用?
我考虑过在我的 WebServer 上缓存数据,但要实现这一点,我需要 运行WebServer 上的一个节点,我想避免这样做。
基于客户端的缓存,其中客户端将余额发布到 WebServer 也可能 运行 由于区块链的异步性质而进入不一致状态。
您还可以使用结构来更轻松地管理数据。我也使用结构和保留数据签订了一份合同。如果此方法对您不起作用,请告诉我。
pragma solidity ^0.4.18;
contract Test{
struct User{
uint cardId;
uint cardCount;
}
address user_address;
mapping (address => User) public Users;
function add_user() public {
user_address = msg.sender ;
var new_user = Users[user_address];
new_user.cardId =2;
new_user.cardCount = 50;
}
function get() public returns(uint,uint)
{
return(Users[user_address].cardId,Users[user_address].cardCount);
}
}
最好的办法是使用辅助映射来存储某些用户拥有的卡 ID,首先对其进行查询,然后针对每个 ID 检查该用户和该卡 ID 的计数。
这是在 Remix 上测试的代码:
pragma solidity 0.4.24;
contract Test {
mapping (address => uint[]) cardsOwned;
mapping (address => mapping (uint => uint)) cardsCounter;
function cardsOwnedBy(address _owner) view public returns (uint[]) {
return (cardsOwned[_owner]);
}
function cardsCounterFor(address _owner, uint _id) view public returns (uint) {
return cardsCounter[_owner][_id];
}
}
我一直在尝试各种不同的解决方案,但找不到任何好的方法来处理这个问题。我找到了一个目前适合我的设置,直到 Solidity 更新为在数组处理和特别是动态大小的变量方面更具功能性。
满足我要求的最快解决方案:
mapping (address => uint256[1000]) public balances;
映射现在将地址分配给固定大小的数组。我现在可以通过以下方式在 DApp Start 上检索完整列表:
function balancesOf(address _owner) view external returns (uint256[1000]) {
return balances[_owner];
}
主要优点是与任何其他解决方案相比,它的速度极快。主要缺点是,我丢失了动态大小的数组,而且我必须提前知道最大卡片数——我不知道。我现在使用了一个安全缓冲区,但如果我达到 1000 张卡片标记,我将不得不更新合约。希望以后会有更好的解决方案。
我正在开发基于以太坊的纸牌游戏。一个用户可以收集 n 张 individual/unique 张卡片。一切正常,运行ning,我正在使用以下余额映射:
mapping (address => mapping (uint256 => uint256)) balances;
第一个单位是卡片ID,第二个单位是卡片数量。我将拥有多达 1000 张卡片,现在我正在测试 700 张卡片。
我通过调用以下方式检索 DApp 上的余额:
function balanceOf(address _owner, uint256 _id) view external returns(uint256) {
return balances[_owner][_id];
}
对于每个 ID。在平衡变化方面,我进行部分平衡更新。这通常有效。它是免费的,但它也非常慢,因为初始检索调用必须执行 640 次。我研究了很多并尝试了各种实现,但主要问题是我需要检索一个包含卡 ID 和计数信息的地址映射数组。目前,您无法轻松检索动态大小的数组或结构。
解决该问题的建议是什么?在 Solidity 引入简单的 Array 调用之前,我是否在 DApp Start 上坚持了多达 1000 个 balanceOf 调用?
我考虑过在我的 WebServer 上缓存数据,但要实现这一点,我需要 运行WebServer 上的一个节点,我想避免这样做。 基于客户端的缓存,其中客户端将余额发布到 WebServer 也可能 运行 由于区块链的异步性质而进入不一致状态。
您还可以使用结构来更轻松地管理数据。我也使用结构和保留数据签订了一份合同。如果此方法对您不起作用,请告诉我。
pragma solidity ^0.4.18;
contract Test{
struct User{
uint cardId;
uint cardCount;
}
address user_address;
mapping (address => User) public Users;
function add_user() public {
user_address = msg.sender ;
var new_user = Users[user_address];
new_user.cardId =2;
new_user.cardCount = 50;
}
function get() public returns(uint,uint)
{
return(Users[user_address].cardId,Users[user_address].cardCount);
}
}
最好的办法是使用辅助映射来存储某些用户拥有的卡 ID,首先对其进行查询,然后针对每个 ID 检查该用户和该卡 ID 的计数。
这是在 Remix 上测试的代码:
pragma solidity 0.4.24;
contract Test {
mapping (address => uint[]) cardsOwned;
mapping (address => mapping (uint => uint)) cardsCounter;
function cardsOwnedBy(address _owner) view public returns (uint[]) {
return (cardsOwned[_owner]);
}
function cardsCounterFor(address _owner, uint _id) view public returns (uint) {
return cardsCounter[_owner][_id];
}
}
我一直在尝试各种不同的解决方案,但找不到任何好的方法来处理这个问题。我找到了一个目前适合我的设置,直到 Solidity 更新为在数组处理和特别是动态大小的变量方面更具功能性。
满足我要求的最快解决方案:
mapping (address => uint256[1000]) public balances;
映射现在将地址分配给固定大小的数组。我现在可以通过以下方式在 DApp Start 上检索完整列表:
function balancesOf(address _owner) view external returns (uint256[1000]) {
return balances[_owner];
}
主要优点是与任何其他解决方案相比,它的速度极快。主要缺点是,我丢失了动态大小的数组,而且我必须提前知道最大卡片数——我不知道。我现在使用了一个安全缓冲区,但如果我达到 1000 张卡片标记,我将不得不更新合约。希望以后会有更好的解决方案。