Solidity

在映射中添加數組

  • August 20, 2018

這段程式碼的主要目的是在映射中添加一個使用者數組。有某些玩影片遊戲的使用者現在處於某個級別,級別將被視為映射索引,在這些級別上,將有一系列使用者。現在獲取使用者數組的主要目的是因為同一級別可以有多個使用者。我剛開始學習solidity,所以程式碼中可能存在一些邏輯錯誤,任何人都可以幫助我並用這段程式碼向我解釋嗎?

pragma solidity ^0.4.24; 

contract game
{

    struct users
    {
        string name;
        uint level;
        uint score;
    }

    mapping(uint => users[]) mulusers;

    function addusers (string _name, uint _level, uint _score) public {

        users memory use= users(_name,_level,_score); 
    }

    function getusers (uint _level) public view returns (string)
    {
       uint index= mulusers[_level].length;
        for(uint i=0; i<index; i++)
        {       
          return mulusers[_level].users[i].name;    //remix is showing an error   
        }   
    }   
}

因此,我將您的程式碼更改為您認為需要的程式碼。還可以使用 PascalCase 來表示Structandevent名稱,使用 camelCase 來表示function,modifier和變數名。哦,如果你Struct只定義了一個對象(一個玩家,一個項目,一本書等),不要在其中使用複數名稱:)

PSstringToBytes32功能不是我的。我在某處找到它並在我的程式碼中使用了一段時間,不確定它是否是最有效的轉換方法。

pragma solidity ^0.4.24;

contract game {

   struct User
   {
       string name;
       // If your array to level, 
       // i don't think you really need 
       // it to be stored here since
       // you will already know the level
       // when you call mapping, so save some gas
       uint level;
       uint score;
   }

   mapping(uint => User[]) mulUsers;

   function addUsers (string _name, uint _level, uint _score) public {
       User memory user = User(_name,_level,_score); 
       mulUsers[_level].push(user);
   }

   // Return array of bytes32 as solidity doesn't support returning string arrays yet
   function getUsers (uint _level) public view returns (bytes32[] users)
   {
       uint length = mulUsers[_level].length;
       users = new bytes32[](length);

       for(uint i = 0; i < length; i++)
       {
           users[i] = stringToBytes32(mulUsers[_level][i].name);
       }   
   }

   // Make sure that string is not longer than 32 bytes or result will be cut
   function stringToBytes32(string memory source) private pure returns (bytes32 result) {
       bytes memory tempEmptyStringTest = bytes(source);
       if (tempEmptyStringTest.length == 0) {
           return 0x0;
       }

       assembly {
           result := mload(add(source, 32))
       }
   }
}

我只是重構了你的合約程式碼,只做了很少的改動。在獲取數據之前,您必須添加到狀態變數。在這裡,您在映射中使用了動態數組,因此您需要將使用者結構數據推送到特定索引上。

contract game {

struct users{
    string name;
    uint level;
    uint score;
}

mapping(uint => users[]) mulusers;

function addusers (uint id, string _name, uint _level, uint _score) public {
    users memory user= users(_name,_level,_score); 
    mulusers[id].push(user);
}

function getusers (uint _id) public view returns (string){

   uint index= mulusers[_id].length;

    for(uint i=0; i<index; i++){       
      return mulusers[_id][i].name; 
    }   
 }   
}

這份契約應該有效!

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