Solidity

Solidity 返回結構錯誤的數組

  • July 15, 2022

我想返回一個結構數組,因為我想輸出我的所有數據。

//SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;

contract MyContract
{
   mapping(uint256 => People) dataList;
   uint256[] countArr;
   struct People{
       string name;
       uint256 favNum;
   }

在這個函式中,我設置了我的結構對象的數據,然後將它包含在我的映射中。

   function setPerson(string memory _name,uint256 _id, uint256 _favNum) public {
       dataList[_id]= People(_name,_favNum);
       countArr.push(_id);
   }

這個函式在這裡獲取我指定的結構對象的數據。

   function getPerson(uint _id) public view returns(string memory,uint256){
       return (dataList[_id].name, dataList[_id].favNum);
   }

現在這是我認為給我帶來麻煩的函式,因為在這個函式中我想返回的不是單個 People 對象的數據,而是我的所有數據,每當我在我的 REMIX IDE 控制台上執行這個函式時,它都會向我顯示錯誤:呼叫 MyContract.getAllData 出錯:VM 錯誤:還原。revert 事務已恢復到初始狀態。注意:如果您發送值並且您發送的值應該小於您目前的餘額,則呼叫的函式應該是應付的。

   function getAllData()public view returns(People[] memory){
       uint256 count = (countArr.length);
       uint256 i = 0;
       People[] memory outputL= new People[](count);
       while(count >= 0){
           (string memory nam,uint256 num) = getPerson(count-1);
           People memory temp = People(nam,num);
           outputL[i]=temp;
           count--;
           i++;
       }
       return outputL;
   }                
}

任何人都可以幫助解釋什麼是錯的,我怎樣才能讓它執行?

您的問題在於while()條件和數組長度的邏輯。在您最初的智能合約中,您可以使用count變數來跟踪數組長度減 1,但最後一個操作是錯誤的。因為數組的長度不是從 0 開始的。範例:如果我有這個數組:

$$ 0 $$= 元素 $$ 1 $$= 元素 $$ 2 $$= 元素 array_length 為 3

由於這個問題,如果 people 數組中有 3 個元素,則 count 變數的值為:2 並且當您初始化 outputL 數組時,最後一個對象的動態長度為 2,這是錯誤的!因此,您會收到該錯誤。

我調整了您的智能合約,您可以在以下幾行中看到它:

//SPDX-License-Identifier:MIT
pragma solidity ^0.8.0;

contract MyContract
{
   mapping(uint256 => People) dataList;
   uint256[] countArr;
   
   struct People{
       string name;
       uint256 favNum;
   }

   function setPerson(string memory _name,uint256 _id, uint256 _favNum) public {
       dataList[_id]= People(_name,_favNum);
       countArr.push(_id);
   }

   function getPerson(uint _id) public view returns(string memory,uint256){
       return (dataList[_id].name, dataList[_id].favNum);
   }

   function getAllData()public view returns(People[] memory){
       uint256 count = countArr.length;
       uint256 i = 0;
       People[] memory outputL = new People[](count);
       while(count > 0){
           (string memory nam,uint256 num) = getPerson(i);
           People memory temp = People(nam,num);
           outputL[i]=temp;
           count--;
           i++;
       }
       return outputL;
   }                
}

@Kerry99 提到的更改是正確的。我對其進行了測試並可以確認。似乎您尚未部署帶有更改的契約。

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