Arrays

數組 .pop() 上的錯誤

  • October 27, 2021

我有一個修改數組的函式,如果我註釋掉 .pop() 行,它通過,如果沒有,我得到這個錯誤:

虛擬機錯誤.revert

程式碼:

function moveShipsToSpace(uint[] memory ships, uint16 fromSpace, uint16 toSpace) public{
    
    for(uint8 i= 0; i<ships.length; i++) { 
       require(containsInSpace(ships[i],fromSpace), "dont have that ship");            
       // Move the last element into the place to delete
       whichShipsAtSpace[msg.sender][fromSpace][i] = whichShipsAtSpace[msg.sender][fromSpace][whichShipsAtSpace[msg.sender][fromSpace].length - 1];
       // Delete
       whichShipsAtSpace[msg.sender][fromSpace].pop();
       // Insert in new location
       whichShipsAtSpace[msg.sender][toSpace].push(shipsArray(ships[i]));
       emit LogUint(ships[i]);
    }
}

另外,如果我傳遞一個數字,它會與 .pop() 一起傳遞,如果我傳遞 2 個或更多它會失敗,所以不確定是什麼問題,請停下來!

它實際上在這裡失敗了:

whichShipsAtSpace[msg.sender][fromSpace][i] = ...

因為您假設索引“i”是數組 ship 和 whichShipsAtSpace 的有效索引

$$ msg.sender $$$$ fromSpace $$. 但事實並非如此。 船舶將始終保持相同的長度,但 whichShipsAtSpace

$$ msg.sender $$$$ fromSpace $$當您從中彈出項目時,長度會減少。在某些時候,變數 i 是 whichShipsAtSpace 的超出範圍索引$$ msg.sender $$$$ fromSpace $$. 要解決此問題,您需要更換:

whichShipsAtSpace[msg.sender][fromSpace][i] = ...

經過 :

whichShipsAtSpace[msg.sender][fromSpace][shipIndexInFromSpace(ships[i])] = ...

其中 shipIndexInFromSpace 是返回船舶索引的函式

$$ i $$在 whichShipsAtSpace 裡面$$ msg.sender $$$$ fromSpace $$大批。 您的程式碼崩潰實際上是一件好事,因為它甚至沒有按照您希望它在目前狀態下執行的操作。由於索引 ‘i’ 指向一艘未知的船和 whichShipsAtSpace 的順序

$$ msg.sender $$$$ fromSpace $$$$ i $$元素正在被轉移,我相信您的程式碼可能會默默地刪除與您打算的不同的船。

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