Remix

分配結構的無限氣體

  • August 9, 2021

我有這個程式碼,它給了我無限的氣體。請幫我改進它。

pragma solidity ^0.4.23;
// v6
contract owned {

   constructor() public { owner = msg.sender; }
   address owner;

   modifier onlyOwner {
       require(msg.sender == owner);
       _;
   }

}

contract mortal is owned {
   function kill() public onlyOwner {
       selfdestruct(owner);
   }
}

contract StudentCertificate is owned, mortal {

   struct Certificate {
       bytes32 title;
       bytes32 courseName;
       bytes32 issuedBy;
       bool _isRekoved;
   }

   struct Student {
       uint16 id;
       bytes32 name;
       uint certificateCount;
       mapping(uint => Certificate) certificates;
   }

   mapping(address => Student) public students;

   function addStudent(bytes32 _name, address _studentAddress, uint16 _userUId) public onlyOwner {
       require(students[_studentAddress].id==0);
       students[_studentAddress] = Student({
           id: _userUId,
           name: _name,
           certificateCount: 0
       });        
   }

   function removeStudent(address _studentAddress) public onlyOwner {
       require(students[_studentAddress].id!=0); // save gas
       // first delete certs if any
       for(uint i = 0; i < students[_studentAddress].certificateCount; i++){
           delete(students[_studentAddress].certificates[i]);
       }
       delete(students[_studentAddress]);  // will save gas. gas refund 
   }


   function addStudentCertificate(address _studentAddress, bytes32 _title, bytes32 _courseName, bytes32 _issuedBy) public onlyOwner {
       require(students[_studentAddress].id!=0);
       students[_studentAddress].certificates[students[_studentAddress].certificateCount] = Certificate({
           title: _title,
           courseName: _courseName,
           issuedBy: _issuedBy,
           _isRekoved: false
           });

       students[_studentAddress].certificateCount++;
   }


   function getStudentCertificateCount(address _studentAddress) public view returns (uint256){
       return students[_studentAddress].certificateCount;
   }

   function getStudentCertificateData(address _studentAddress, uint256 _certArrayIndex) public view returns (bytes32, bytes32, bytes32, bool){
       return (
           students[_studentAddress].certificates[_certArrayIndex].title,
           students[_studentAddress].certificates[_certArrayIndex].courseName,
           students[_studentAddress].certificates[_certArrayIndex].issuedBy,
           students[_studentAddress].certificates[_certArrayIndex]._isRekoved
           );
   }



}

Remix 的錯誤/警告消息:

Gas requirement of function StudentCertificate.addStudent(bytes32,address,uint16) high: infinite. If the gas requirement of a function is higher than the block gas limit, it cannot be executed. Please avoid loops in your functions or actions that modify large areas of storage (this includes clearing or copying arrays in storage)

這個錯誤通常是一個誤導性的紅鯡魚。

您是onlyOwner修飾符(未顯示),並且您require(student[....id==0);是條件語句,它們在執行其工作時可能會消耗所有氣體,以防止函式在不可接受的情況下執行。

您可以在靜態分析選項卡上禁用此特定類型的警告。

希望能幫助到你。

事實上,這個警告(是的:“警告”)在 Remix 中很大程度上是不可信的。

使用它的正確方法是詳細檢查(可能)無限循環的程式碼,可能的無限儲存使用(例如綁定到一些動態數組或字元串,理論上可以無限制地推送以進行增長,以及另一種檢查的可能性是函式可以呼叫一些在使用的氣體方面不容易預測的外部服務的情況。

如果一切正常並且沒有出現任何異常,只需按照 Rob 的建議將其關閉即可。

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