错误 error

本章学习在 Solidity 中,错误 error 的定义和使用方法。

视频Bilibili  |  Youtube
官网binschool.app
推特@BinSchool    DiscordBinDAO   微信:bkra50 

Solidity 中,可以使用 error 来自定义错误类型。当智能合约中发生错误或者异常时,能够输出 error 定义的描述性名称和数据。

我们知道,event 也可以用来输出信息,但它通常是在正常状态下输出信息,两者的使用场景并不相同。

errorsolidity 0.8.4 版本新加的内容,它与 require 相比,不仅可以抛出操作失败的原因,同时还可以携带任意多个参数,来帮助开发者更好地调试合约。

另外,error 更省 gas,比较廉价。所以,error 完全可以用来替代断言语句 requireassert

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 提交交易。

日志区就会输出错误信息,内容包括自定义的错误名称和两个参数。