solidity-异常 error require assert

  1. solidity-异常
  2. error&revert
  3. require
  4. assert
  5. 部署测试
  6. 消耗gas对比

solidity-异常

写智能合约经常会出bug,solidity中的异常命令帮助我们debug,并且加强我们合约的健壮性

error&revert

error是solidity 0.8版本新加的内容,方便且高效(省gas)地向用户解释操作失败的原因。人们可以在contract之外定义异常。在执行当中,error必须搭配revert(回退)命令使用。

也可以直接使用 revert 抛出异常,而不用定义 error ,也可以 revert 自定义的error,同时可以进行传参

function testError(uint256 amount) public view {
    if (_balance[msg.sender] < amount) {
        revert("error Insufficient balance");
    }
}

error amountError(string errMsg, uint256 amount); // 也可以写在合约代码块外面

function testCustomError(uint256 amount) public view {
    if (_balance[msg.sender] < amount) {
        revert amountError("custom error", amount);
    }
}

require

require命令是solidity 0.8版本之前抛出异常的常用方法,目前很多主流合约仍然还在使用它。它很好用,唯一的缺点就是gas随着描述异常的字符串长度增加,比error命令要高。使用方法:require(检查条件,”异常的描述”),当检查条件不成立的时候,就会抛出异常。

function testReqiure(uint256 amount) public view {
require(_balance[msg.sender] > amount, "require: balance must more than amount"); // 当不满足前面的条件时,抛出异常,并显示自定义信息
}

assert

assert命令一般用于程序员写程序debug,因为它不能解释抛出异常的原因(比require少个字符串)。它的用法很简单,assert(检查条件),当检查条件不成立的时候,就会抛出异常。

function testAssert(uint256 amount) public view {
    assert(_balance[msg.sender] > amount); // 当不满足前面的条件时,抛出异常
}

部署测试

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

error amountError(string errMsg, uint256 amount);

contract errorTest {
    mapping(address => uint256) public _balance;

    constructor() {
        _balance[msg.sender] = 100;
    }

    function testError(uint256 amount) public view {
        if (_balance[msg.sender] < amount) {
            revert("error Insufficient balance");
        }
    }

    function testCustomError(uint256 amount) public view {
        if (_balance[msg.sender] < amount) {
            revert amountError("custom error", amount);
        }
    }

    function testReqiure(uint256 amount) public view {
        require(
            _balance[msg.sender] > amount,
            "require: balance must more than amount"
        ); // 当不满足前面的条件时,抛出异常,并显示自定义信息
    }

    function testAssert(uint256 amount) public view {
        assert(_balance[msg.sender] > amount); // 当不满足前面的条件时,抛出异常
    }
}

只要我们的余额小于amount,就会抛出异常

  • error
    d12656c8-899d-479b-9f9e-7401a3cf3dec-image.png
  • 自定义error
    4a098772-403f-476c-81b1-8d47c89be1bb-image.png
  • require
    f06b6b8f-20c4-4954-a0fc-cf016273a3ab-image.png
  • assert
    468fa0e9-9090-411a-a77a-01e8e5e3ab00-image.png

消耗gas对比

  • error 2886gas
  • 自定义error 3005gas
  • require 2945gas
  • assert 2645gas

gas的消费不是固定的,由于assert没有打印任何信息,消费的gas最少,但是如果error不打印任何信息,消耗的gas才是最少的。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 lyucan_1@163.com