错误 error
本章学习在 Solidity 中,错误 error 的定义和使用方法。
在 Solidity 中,可以使用 error 来自定义错误类型。当智能合约中发生错误或者异常时,能够输出 error 定义的描述性名称和数据。
我们知道,event 也可以用来输出信息,但它通常是在正常状态下输出信息,两者的使用场景并不相同。
error 是 solidity 0.8.4 版本新加的内容,它与 require 相比,不仅可以抛出操作失败的原因,同时还可以携带任意多个参数,来帮助开发者更好地调试合约。
另外,error 更省 gas,比较廉价。所以,error 完全可以用来替代断言语句 require 和 assert。
1. 定义语法
在 Solidity 代码中,使用 error 关键字来定义一个错误,语法如下:
error error-name(<parameter list>);
例如,在 ERC20 代币合约中,定义了一个转账金额不足的事件。
error NotEnoughFunds(uint requested, uint available);
其中,requested 是本次转账请求的金额,available 是账户目前可用金额。
2. 使用方法
在 Solidity 代码中,使用 revert 关键字来触发错误 error,语法如下:
revert error-name(<parameter list>);
使用 revert 触发 error,将会抛出错误信息,同时交易会被回滚 revert。
例如,触发 ERC20 代币合约中的 NotEnoughFunds 错误。
revert NotEnoughFunds(2000, 1000);
以下,我们使用一个完整的合约范例来展示 error 的定义和使用方法。
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; // 定义资金不足错误 error NotEnoughFunds(uint requested, uint available); // 代币合约 contract ErrorToken { mapping(address => uint) balances; // 内部账本 // 构造函数 constructor() { // 部署时,给合约部署者分配 1 wei代币 balances[msg.sender] = 1; } // 转账函数,to:接收者,amount:转账金额 function transfer(address to, uint amount) public { // 获取发送者账户余额 uint balance = balances[msg.sender]; // 如果余额小于转账金额,取消交易,并报错 if (balance < amount) revert NotEnoughFunds(amount, balance); // 更新发送者账户余额 balances[msg.sender] -= amount; // 更新接收者账户余额 balances[to] += amount; } }
我们把合约代码复制到 Remix,进行编译,并部署到区块链上:

输入一个转账地址,再输入转账数量 100,点击 transact 提交交易。
日志区就会输出错误信息,内容包括自定义的错误名称和两个参数。