检索多维余额

时间:2018-05-27 20:29:39

标签: ethereum solidity web3

我正在开发一款基于以太坊的纸牌游戏。用户可以收集n量的个人/唯一卡。一切正常,我正在使用以下余额映射:

mapping (address => mapping (uint256 => uint256)) balances;

第一个uint是卡ID,第二个uint是卡计数。我将拥有多达1000张卡片,现在我正在测试700张卡片。

我通过调用:

来检索DApp Start上的余额
function balanceOf(address _owner, uint256 _id) view external returns(uint256) {
    return balances[_owner][_id];
}
每个ID都

。在余额变化方面,我做了部分余额更新。这通常有效。它是免费的,但它也非常慢,因为初始检索调用必须完成640次。我已经研究了很多,并尝试了各种实现,但主要问题是我需要检索一个包含Card ID和Count信息的地址映射数组。目前,您无法轻松检索动态大小的阵列或结构。

解决问题的建议是什么?我是否坚持在DApp Start上进行多达1000次balanceOf调用,直到Solidity引入简单的数组调用?

我考虑过在我的WebServer上缓存数据,但为了实现这一点,我需要在WebServer上运行一个我想避免的节点。 由于区块链的异步性,客户端将余额发布到WebServer的基于客户端的缓存也可能会遇到不一致状态。

3 个答案:

答案 0 :(得分:0)

您还可以使用struct更轻松地管理数据。我也使用struct和保留数据签订了一份合同。如果这种方法不适合你,请告诉我。

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);
}


}

答案 1 :(得分:0)

您最好的机会是使用辅助映射来存储某些用户拥有的卡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];
    }

}

答案 2 :(得分:0)

我一直在尝试各种不同的解决方案但是找不到任何好办法来解决这个问题。我找到了一个现在适用于我的设置,直到Solidity更新为在数组处理方面更具功能性,特别是动态大小的变量。

满足我要求的最快解决方案:

mapping (address => uint256[1000]) public balances;

映射现在将地址分配给固定大小的数组。我现在可以使用:

检索DApp Start上的完整列表
function balancesOf(address _owner) view external returns (uint256[1000]) {
  return balances[_owner];
}

与其他任何解决方案相比,它的主要优点是速度极快。主要缺点是,我丢失了动态大小的阵列,我必须提前知道最大卡数 - 我不知道。我现在使用安全缓冲区,但如果我达到1000卡标记,我将不得不更新合同。希望将来有更好的解决方案。