【Solidity】Gasestimationfailed-Gasestimationer。。。
今天在写完合约在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 failed的ERROR,根据字⾯意思看是因为计算不出来所需GAS的费⽤,即使强制执⾏transaction也会失败,博主也是⼩⽩,推测是GAS开销太⼤了导致的问题,期待有哪位⼤佬能出详细的原因解释。
后来博主改变了思路,引⼊了CET4List和CET6List来存储成绩列表,并使mapping (address=>CET4[]) public addrToCET4和mapping (address=>CET6[]) public addrToCET6变为mapping (uint=>address) internal CET4IndexToAddr和mapping (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{
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){
soliditytimeList[counter] = CET6List[i].time;
gradeList[counter] = CET6List[i].grade;
counter++;
}
}
return(timeList,gradeList);
}
}
问题解决~
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论