Solidity - 合约结构 - 错误(error)- ^0.8.4版本新增

我们知道,合约结构包含 状态变量、函数、函数修改器(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一样,可以写在合约里,也可以写在合约外面,只要作用域不同,同一个error可以在多个地方定义,以上代码写在了合约外面(可以被其它合约使用),同时使用了natspec注释形式。 

在应用二进制接囗(ABI)的JSON描述中,同事件、函数、合约中方法一样,同样包含了error,如下所示:

	{
		"inputs": [
			{
				"internalType": "uint256",
				"name": "_balance",
				"type": "uint256"
			},
			{
				"internalType": "uint256",
				"name": "_amount",
				"type": "uint256"
			}
		],
		"name": "NotEnoughFunds",
		"type": "error"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": false,
				"internalType": "address",
				"name": "_from",
				"type": "address"
			},
			{
				"indexed": false,
				"internalType": "address",
				"name": "_to",
				"type": "address"
			},
			{
				"indexed": false,
				"internalType": "uint256",
				"name": "_amount",
				"type": "uint256"
			}
		],
		"name": "Tansfer",
		"type": "event"
	},
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "_to",
				"type": "address"
			},
			{
				"internalType": "uint256",
				"name": "_amount",
				"type": "uint256"
			}
		],
		"name": "transfer",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "_to",
				"type": "address"
			},
			{
				"internalType": "uint256",
				"name": "_amount",
				"type": "uint256"
			}
		],
		"name": "transferWithError",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	}

error可以继承,但不能被重写。重写条件为父合约标记为virtual函数可以在继承合约里重写,error不能标记为virtual。

测试

使用Remix中JavaScript VM部署合约,执行合约中两个函数(一个使用error结构,另一个使用错误字符串),验证失败时花费的gas:

(1)执行transfer函数(使用错误字符串)

执行后可以看到错误信息提示“no enough funds”,花费的gas为22513

(2)执行transferWithError函数(使用error结构)

执行后可以看到错误中输出的参数值,感觉与前端的console.log一样,可以当作调试信息,花费的gas为22497,比上面少了16个gas

若部署到测试网,如 Popsten,执行函数会直接先提示(如下图所示),若强制进行交易,则与上面结果相同。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值