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

- 自定义error

- require

- assert

消耗gas对比
- error
2886gas - 自定义error
3005gas - require
2945gas - assert
2645gas
gas的消费不是固定的,由于assert没有打印任何信息,消费的gas最少,但是如果error不打印任何信息,消耗的gas才是最少的。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 lyucan_1@163.com