Gas estimation failed-Gas estimation errored with the following message (see below)

匿名 (未验证) 提交于 2019-12-03 00:22:01

今天在写完合约在remix部署测试的时候遇到了这么一个问题,一旦向合约里写数据就出现如下错误:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
如下图所示:

网上一直搜索不到解决方法,最后经过自己的一番折腾后,还是解决了!
先说一下想实现的功能,尝试用合约存储四六级成绩,因为可以多次参加考试,所以每个人可以有多次四六级成绩记录。
原先合约代码:

pragma solidity ^0.4.23; import "./Ownable.sol"; contract StudentFactory is Ownable{     struct CET4{         uint32 time;          uint32 grade;     }      struct CET6{         uint32 time;          uint32 grade;     }     mapping (address=>CET4[]) public addrToCET4;      mapping (address=>CET6[]) public addrToCET6;     mapping (address=>uint) public addrCET4Count;      mapping (address=>uint) public addrCET6Count;  }  contract StudentHelper is StudentFactory{     function addCET4To(address _addr,uint32 _time,uint32 _grade) public onlyOwner{         CET4[] storage CET4List = addrToCET4[_addr];          CET4List[CET4List.length] = CET4(_time,_grade);         addrCET4Count[_addr]++;     }      function addCET6To(address _addr,uint32 _time,uint32 _grade) public onlyOwner{         CET6[] storage CET6List = addrToCET6[_addr];          CET6List[CET6List.length] = CET6(_time,_grade);         addrCET6Count[_addr]++;     } }

虽然编译没问题,但是一旦调用addCET4To来写入成绩的时候就会出现Gas estimation failedERROR,根据字面意思看是因为计算不出来所需GAS的费用,即使强制执行transaction也会失败,博主也是小白,推测是GAS开销太大了导致的问题,期待有哪位大佬能出详细的原因解释。

后来博主改变了思路,引入了CET4ListCET6List来存储成绩列表,并使mapping (address=>CET4[]) public addrToCET4mapping (address=>CET6[]) public addrToCET6变为mapping (uint=>address) internal CET4IndexToAddrmapping (uint=>address) internal CET6IndexToAddr
先通过for循环找出符合地址的CET4[]CET6[]的索引,再用索引去访问数组中具体的成绩。合约代码如下所示:

pragma solidity ^0.4.23; import "./Ownable.sol"; contract StudentFactory is Ownable{     struct CET4{         uint32 time;          uint32 grade;     }      struct CET6{         uint32 time;          uint32 grade;     }     CET4[] CET4List; // 四级成绩列表     CET6[] CET6List; // 六级成绩列表     mapping (uint=>address) internal CET4IndexToAddr; // 四级成绩序号到地址的映射     mapping (uint=>address) internal CET6IndexToAddr; // 六级成绩序号到地址的映射     mapping (address=>uint) public addrCET4Count;      mapping (address=>uint) public addrCET6Count;  }  contract StudentHelper is StudentFactory{     // 给某个地址添加四级成绩记录     function addCET4To(address _addr,uint32 _time,uint32 _grade) public onlyOwner{         uint index = CET4List.push(CET4(_time,_grade))-1;         CET4IndexToAddr[index] = _addr;         addrCET4Count[_addr]++;     }      // 给某个地址添加六级成绩记录     function addCET6To(address _addr,uint32 _time,uint32 _grade) public onlyOwner{         uint index = CET6List.push(CET6(_time,_grade))-1;         CET6IndexToAddr[index] = _addr;         addrCET6Count[_addr]++;     }      // 获得某个地址的四级成绩     function getCET4ByAddr(address _addr) view public returns (uint32[],uint32[]) {         uint32[] memory timeList = new uint32[](addrCET4Count[_addr]);          uint32[] memory gradeList = new uint32[](addrCET4Count[_addr]);         uint counter = 0;             for (uint i = 0; i < CET4List.length; i++) {             if(CET4IndexToAddr[i]==_addr){                 timeList[counter] = CET4List[i].time;                 gradeList[counter] = CET4List[i].grade;                 counter++;             }         }         return(timeList,gradeList);     }      // 获得某个地址的六级成绩     function getCET6ByAddr(address _addr) view public returns (uint32[],uint32[]) {         uint32[] memory timeList = new uint32[](addrCET6Count[_addr]);          uint32[] memory gradeList = new uint32[](addrCET6Count[_addr]);         uint counter = 0;             for (uint i = 0; i < CET6List.length; i++) {             if(CET6IndexToAddr[i]==_addr){                 timeList[counter] = CET6List[i].time;                 gradeList[counter] = CET6List[i].grade;                 counter++;             }         }         return(timeList,gradeList);     } }

问题解决~

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!