Arrays

將結構添加到數組 - 無效的操作碼 - Solidity 0.6

  • July 3, 2020

我已經為此絞盡腦汁了一段時間,可以使用一些幫助。底線,該newProposal函式引發VM Exception while processing transaction: invalid opcode錯誤。令人費解的是,這個函式在 Solidity 0.5 上執行良好,但在 0.6 上卻不行。這是我到目前為止所嘗試的,非常感謝任何進一步的見解。

  1. 根據 Solidity 0.6 中的重大更改,我懷疑問題是關於調整proposals數組大小以添加新Proposal結構,這在某種程度上得到了這個問題的支持。
  • 現在,對數組長度的成員訪問始終是只讀的,即使對於儲存數組也是如此。不再可能通過為其長度分配新值來調整儲存陣列的大小。改用 push()、push(value) 或 pop(),或者分配一個完整的數組,這當然會覆蓋現有的內容。其背後的原因是為了防止巨大儲存陣列的儲存衝突。

所以我在這裡嘗試了許多變體(即proposals.push(),硬編碼proposalID)。沒運氣。我不相信結構及其屬性是問題所在,但我也不能 100% 確定這一點。所以我覺得我在這裡遺漏了一些相對明顯的東西,我感謝你的幫助。

返回invalid opCode錯誤的函式

   /**
    * Add Proposal
    *
    * Propose to send `weiAmount / 1e18` ether to `beneficiary` for `jobDescription`. `transactionBytecode ? Contains : Does not contain` code.
    *
    * @param beneficiary who to send the ether to
    * @param weiAmount amount of ether to send, in wei
    * @param jobDescription Description of job
    * @param transactionBytecode bytecode of transaction
    */
   function newProposal(
       address beneficiary,
       uint weiAmount,
       string memory jobDescription,
       bytes memory transactionBytecode
   )
       public onlyShareholders
       returns (uint proposalID)
   {
       proposalID = proposals.length+1; //I suspect the problem is here...
       // I've tried proposals.push(); proposalID = proposals.length; instead, no luck
       Proposal storage p = proposals[proposalID]; //...or here
       p.recipient = beneficiary;
       p.amount = weiAmount;
       p.description = jobDescription;
       p.proposalHash = keccak256(abi.encodePacked(beneficiary, weiAmount, transactionBytecode));
       p.minExecutionDate = now + debatingPeriodInMinutes * 1 minutes;
       p.executed = false;
       p.proposalPassed = false;
       p.numberOfVotes = 0;
       emit ProposalAdded(proposalID, beneficiary, weiAmount, jobDescription);
       numProposals = proposalID+1;

       return proposalID;
   }

Proposal結構體和proposals數組

   Proposal[] public proposals;

   struct Proposal {
       address recipient;
       uint amount;
       string description;
       uint minExecutionDate;
       bool executed;
       bool proposalPassed;
       uint numberOfVotes;
       bytes32 proposalHash;
       Vote[] votes;
       mapping (address => bool) voted;
   }

編輯:這修復了它,請參閱下面@goodvibration 的評論

proposalID = proposals.length;
proposals.push();
Proposal storage p = proposals[proposalID];

您顯然是在嘗試訪問非法索引處的數組:

proposalID = proposals.length+1;
Proposal storage p = proposals[proposalID]; 

any 中的有效索引array介於0和之間array.length - 1

大多數人在嘗試訪問arrayat 時都會出錯array.length

您嘗試訪問arrayat時弄錯了array.length + 1


請注意,無論您預先推入多少元素,嘗試訪問arrayusing或更高版本都被定義array.length為失敗,因為在推入這些元素時,它會隨之增長。array``array.length

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