我的理解是,如果失败,“require”会退还剩余的gas,而“assert”则不会。
我有点困惑,尽管 b/c 剩余气体是什么意思?我经常指定一个非常大的 gas 限制,即使我调用的合同需要很少。
如果我指定 4,700,000 gas 限制,并且只需要 50,000 gas,但是在被调用的合约中“assert”失败,我会失去所有 4,700,000 gas 吗?
是的,您会损失全部金额(或接近金额)。assert实际上是由于完全出乎意料的事情而导致交易的灾难性救助。它应该用于检查诸如确保您的合约没有以无效状态结束、避免除以 0、上溢/下溢等。
require,另一方面,只会消耗使用到故障点的气体。剩余的gas将被退还。
您指定的 gas 限制不应太高。当您发起交易时,您指定的全部 gas 将被发送,并且执行结束时剩余的任何金额都将退还给您。你不仅asserts在自己的合约中暴露自己,而且如果你从你自己的合约中调用其他合约,你会给这个合约很多带宽,让你用传递给它的气体做任何它想做的事情。
显示气体消耗的示例:
pragma solidity ^0.4.16;
contract Test {
function run(uint8 i) public pure {
uint8 total = 0;
for (uint8 j = 0; j < 10; j++)
total += j;
assert (i < 20);
require (i < 10);
for (j = 0; j < 10; j++)
total += j;
}
}
Run Code Online (Sandbox Code Playgroud)
所有测试都以 gas limit = 5000000 运行
测试 #1 - run(8):函数成功运行 - 消耗了 1860 gas。
测试 #2 - run(15):函数通过断言,在需要时失败。仅运行第一个循环 - 消耗了 1049 个气体。
测试 #3 - run(25):函数在断言时失败。同样,只运行第一个循环 - 消耗了 4978536 气体(哎哟)。