Solidity语言中定义了以下三种错误处理方式:
require
:用于在执行前验证输入和条件;revert
:用于直接触发回退,可自定义异常处理;assert
:用于检查不应该为假的代码,失败的断言可能意味着代码层面存在错误。
异常处理将撤消当前调用对状态所做的所有更改,并且还可以向调用者抛出错误。
错误处理函数-
Require()
require(condition, description)
require
首先检查condition
,如果条件为真则继续执行,否则提供一个消息字符串description
用于标记错误(可选)。 -
revert()
if (!condition) revert(); if (!condition) revert(description); if (!condition) revert CustomError(arg1, arg2, ...);
revert
可以直接触发回退,也可以抛出一个消息字符串用于标记错误,也可以自定义错误处理。 -
assert()
assert(condition);
assert
用于检查condition
是否为真,检查失败时抛出异常。
以下三个语句的功能完全相同:
if (msg.sender != owner) { revert(); }
assert(msg.sender == owner);
require(msg.sender == owner);
这三个语句都用于检查当前调用者是否为合约的所有者,如果检查结果不为真则抛出异常。
函数差异化 Gas开销assert()
将消耗所有剩余的Gas,并恢复所有的操作。
require()
和 revert()
将退还所有剩余的Gas,同时可以返回一个值(自定义的报错信息)。
require()
的适用场景
-
验证用户输入,如:
require(input > 10);
-
验证外部合约响应(返回值),如:
require(external.send(amount));
-
执行合约前验证状态条件,如:
require(block.number > SOME_BLOCK_NUMBER); // 或者 require(balance[msg.sender] >= amount);
合约中应该尽量使用 require
来处理错误,且放在函数最开始的地方使用。
revert()
的适用场景
revert
函数与 require
函数类似,但是适用更复杂处理逻辑的场景。如果代码中需要复杂的 if/else
逻辑流,那么应该考虑适用 revert
函数而不是 require
函数。
assert()
的适用场景
-
检查整数溢出(overflow/underflow),如:
c = a + b; assert(c > b);
-
检查不变量(invariants),如:
assert(this.balance >= totalSupply);
-
验证改变后的状态,如:
assert(state);
合约中应该尽量少用 assert
调用,如果要适用 assert
应该在函数结尾处使用。
assert
与 require
函数均被用来检查条件并在条件不满足时抛出异常,它们的主要区别是 require
应该被用于函数中检查条件,assert
用于预防不应该发生的情况,即不应该使条件错误。
例子1:下面是一个合约例子,用来演示错误处理函数的用法。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
// 错误处理及异常
contract Errors {
// Require测试
function testRequire(uint i) public pure {
require(i > 10, "Input must be greater than 10");
}
// Revert测试
function testRevert(uint i) public pure {
if (i = oldBalance, "Overflow");
balance = newBalance;
assert(balance >= oldBalance);
}
// 从合约提取以太币
function withdraw(uint _amount) public payable {
uint oldBalance = balance;
// 检查溢出
require(balance >= _amount, "Underflow");
if (balance < _amount) {
revert("Underflow");
}
balance -= _amount;
assert(balance
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?