最近有用户在提现PNUT时会碰到如图所示的“合约调用超时”的失败交易,而且一下就耗光了帐户中的trx!
查看具体原因,主要是两点:
合约调用超时通常是以下两个原因导致:
1.智能合约复杂度过高,执行时间超过50ms
2.全节点性能较差
看这原因,在合约中最好是不要有for循环,因为很快就会导致执行超时!在PNUT的矿池合约中有个实时计算所有人的收益的方法,要用到for循环。现在Nutbox已有约77人代理,难道循环计算77次就会出现超时?!!
可以极限测试下波场网络能做多少次的for循环,以下是小小地测试:
unit256 num = 2;
function test1000()
public
{
for (uint i = 0; i < 1000; i++) {
num = num.add(i+2);
}
}
function test2000()
public
{
for (uint i = 0; i < 2000; i++) {
num = num.add(i+2);
}
}
以上是简单循环地对num做加法,测试之下是大约只能完成1000~2000次的循环! 大家也可以看看合约执行的详情, https://shasta.tronscan.org/#/contract/TV1depurRkcELVztY5g9Bjxx3sVTYnpdBy
因为各方面的原因,波场不能做相对复杂的运算,特别是循环。另外,最近波场的节点不稳定,这也导致有时提现成功,而有时提现却失败。
在等波场修复它的bug前我们也只能将损失限制下:在前端调用时加上一个参数feeLimit以减少损失。方法倒也简单,就是在send方法上加上一行参数,instance.withdrawPeanuts().send({feeLimit:20_000_000})
有了这个限制,就算再出错,也只会最多花费20个trx,而不会乱收费了!