Arrays

映射結構數組、氣體或性能問題?

  • May 30, 2018

我有一個關於使用結構數組迭代映射的問題。有一個 for 循環迭代了數千次,試圖在結構中找到匹配的屬性。

前任:

struct MatchBettingInfo {    
   address better;
   uint matchId;
   uint homeScore;
   uint awayScore; 
}

mapping(uint => MatchBettingInfo[]) public matchBettingInfo;  

function claimPrizes(uint _matchId, uint _homeScore, uint _awayScore) public returns (bool) {
   uint totalNumBetters = matchBettingInfo[_matchId].length;  

   // Find matching scores among betters who betted for this match
   for (uint i = 0; i < totalNumBetters; i++) {
       if (matchBettingInfo[_matchId][i].homeScore == _homeScore && 
           matchBettingInfo[_matchId][i].awayScore == _awayScore) {          
           numOfWinners++;
       }  
   }  

   ... more codes
}

此迭代不在viewnorconstant函式內。所以它在呼叫它時會消耗一些氣體。我只是擔心如果循環迭代大量(超過一萬個?)

在優化方面有什麼建議嗎?

此解決方案將允許您避免循環,這在您的應用程序中可能是災難性的,因為如果有很多使用者並且循環所需的氣體超出了允許的限制,契約可能會卡住。我試圖使其盡可能接近您的原始實現:

struct MatchBettingInfo {    
   mapping(bytes32 => address[]) bets;
   mapping(address => uint) homeScore;
   mapping(address => uint) awayScore; 
}

mapping(uint => MatchBettingInfo) public matchBettingInfo;  

現在,設置一個賭注將由這個函式實現:

function makeBet(uint _matchId, uint _homeScore, uint _awayScore) public {
   bytes32 mybet = keccak256(_homeScore,_awayScore);
   matchBettingInfo[_matchId].bets[mybet].push(msg.sender);
   matchBettingInfo[_matchId].homeScore[msg.sender] = _homeScore;
   matchBettingInfo[_matchId].homeScore[msg.sender] = _awayScore;
}

現在您可以一口氣獲得獲獎者名單:

function claimPrizes(uint _matchId, uint _homeScore, uint _awayScore) public returns (bool) {
   bytes32 winnerScore = keccak256(_homeScore,_awayScore);
   uint numOfWinners = matchBettingInfo[_matchId].bets[winnerScore].length;

   // rest of your code

}

這是如何工作的?

首先,請注意映射現在是結構的映射,而不是結構數組的映射。

獲勝者需要猜測主客場比分,那麼這是一個獨特的組合,我將兩個數字的雜湊值保存為下注。該結構還為每個地址保存這些數字,以防您需要它們,如果您不這樣做,可以安全地刪除這兩個稱為awayScore和的映射homeScore

現在,要獲取獲勝者的數量就像獲取儲存在密鑰中的地址數量一樣簡單,該密鑰是通過獲取 and 的雜湊形成homeScoreawayScore

uint numOfWinners = matchBettingInfo[_matchId].bets[winnerScore].length;

給你獲勝者的數量和:

matchBettingInfo[_matchId].bets[winnerScore]

一口氣給你中獎名單!!!

希望這可以幫助

引用自:https://ethereum.stackexchange.com/questions/50019