Solidity 中的断言与要求?

Cha*_*aag 1 ethereum

我的理解是,如果失败,“require”会退还剩余的gas,而“assert”则不会。

我有点困惑,尽管 b/c 剩余气体是什么意思?我经常指定一个非常大的 gas 限制,即使我调用的合同需要很少。

如果我指定 4,700,000 gas 限制,并且只需要 50,000 gas,但是在被调用的合约中“assert”失败,我会失去所有 4,700,000 gas 吗?

Ada*_*nis 5

是的,您会损失全部金额(或接近金额)。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 气体(哎哟)。

在此处输入图片说明