我们知道,合约结构包含 状态变量、函数、函数修改器(modifier)、事件(event)、结构体(struct)和枚举类型(enum)。
在^0.8.4版本,合约结构增加了错误(error),为应对失败时,错误可以在revert 中使用。与错误字符串相比,error花费更少的gas(即更便宜),并且允许编码额外的数据,还可以使用natspec注释形式。
举个栗子,代码如下:
- // SPDX-License-Identifier: MIT
- pragma solidity ^0.8.4;
-
- /// @dev 没有足够的金额
- /// @param _balance表示当前合约账户余额
- /// @param _amount 转账金额
- error NotEnoughFunds(uint _balance,uint _amount);
-
- contract TestError {
- /// @dev 事件 - 记录转账信息
- event Tansfer(address _from, address _to, uint _amount);
-
- /// @dev 当合约账户余额小于转账金额时,使用字符串 revert
- function transfer(address _to, uint _amount) external {
- if (address(this).balance < _amount) {
- revert("no enough funds");
- }
- emit Tansfer(msg.sender, _to, _amount);
- }
-
- /// @dev 当合约账户余额小于转账金额时,使用error revert
- function transferWithError(address _to, uint _amount) external {
- if (address(this).balance < _amount) {
- revert NotEnoughFunds(address(this).balance, _amount);
- }
- emit Tansfer(msg.sender, _to, _amount);
- }
- }
error同struct一样,可以写在合约里,也可以写在合约外面,以上代码写在了合约外面。同时使用了natspec注释形式。
使用Remix中JavaScript VM部署合约,执行合约中两个函数(一个使用error结构,另一个使用错误字符串),验证失败时花费的gas:
执行后可以看到错误信息提示“no enough funds”,花费的gas为22513
执行后可以看到错误中输出的参数值,感觉与前端的console.log一样,可以当作调试信息,花费的gas为22497,比上面少了16个gas
若部署到测试网,如 Popsten,执行函数会直接先提示(如下图所示),若强制进行交易,则与上面结果相同。