3分钟Solidity: 4.5 错误

34 阅读2分钟

如需获取本内容的最新版本,请参见 Cyfrin.io 上的Error(代码示例)

错误将撤销交易期间对状态所做的所有更改。 您可以通过调用requirerevertassert来抛出错误。

  • require用于在执行前验证输入和条件。
  • revertrequire类似。详情请参阅下面的代码。
  • assert用于检查永远不应为假的代码。断言失败可能意味着存在错误。

使用自定义错误以节省gas费用。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract Error {
    function testRequire(uint256 _i) public pure {
        // Require 应用于验证以下条件:
        // - 输入
        // - 执行前的条件
        // - 其他函数调用的返回值
        require(_i > 10, "Input must be greater than 10");
    }

    function testRevert(uint256 _i) public pure {
        // 当需要检查的条件很复杂时,Revert 非常有用。
        // 这段代码的功能与上面的示例完全相同
        if (_i <= 10) {
            revert("Input must be greater than 10");
        }
    }

    uint256 public num;

    function testAssert() public view {
        / /断言应仅用于检测内部错误和验证不变量。

        // 我们断言num始终等于0, 因为无法更新num的值
        assert(num == 0);
    }

    // 自定义 error
    error InsufficientBalance(uint256 balance, uint256 withdrawAmount);

    function testCustomError(uint256 _withdrawAmount) public view {
        uint256 bal = address(this).balance;
        if (bal < _withdrawAmount) {
            revert InsufficientBalance({
                balance: bal,
                withdrawAmount: _withdrawAmount
            });
        }
    }
}

Remix Lite 尝试一下 solidity-error

这是另一个例子

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract Account {
    uint256 public balance;
    uint256 public constant MAX_UINT = 2 ** 256 - 1;

    function deposit(uint256 _amount) public {
        uint256 oldBalance = balance;
        uint256 newBalance = balance + _amount;

        // balance + _amount 不会溢出,如果balance + _amount >= oldBalance
        require(newBalance >= oldBalance, "Overflow");

        balance = newBalance;

        assert(balance >= oldBalance);
    }

    function withdraw(uint256 _amount) public {
        uint256 oldBalance = balance;

        // balance - _amount 不会下溢,如果balance >= _amount
        require(balance >= _amount, "Underflow");

        if (balance < _amount) {
            revert("Underflow");
        }

        balance -= _amount;

        assert(balance <= oldBalance);
    }
}

Remix Lite 尝试一下

solidity-require_revert_assert

END