异常处理的简单认识

  • nilliol
  • 更新于 2024-06-09 13:14
  • 阅读 216

在solidity中一旦出现异常,则当前交易将会回滚(即相当于没有发生过,除了你的gas被消耗了)。solidity里抛出异常的方法有三种:errorrequireassert对于可能出现异常抛出的地方,solidity也提供了try-catch方法进行异常捕获处理。

solidity中一旦出现异常,则当前交易将会回滚(即相当于没有发生过,除了你的gas被消耗了)。

`solidity`里抛出异常的方法有三种:
  • error
  • require
  • assert

    对于可能出现异常抛出的地方,solidity也提供了try-catch方法进行异常捕获处理。

1 error

errorsolidity 0.8.4新加的内容,方便且高效(省gas)地向用户解释操作失败的原因,同时还可以在抛出异常的同时携带参数,帮助开发者更好地调试。

使用error需要用户自己定义error类型和抛出的参数,同时需要搭配revert使用。例子如下:

 error TransferNotOwner(); // 自定义error

    function transferOwner1(uint256 tokenId, address newOwner) public {
        if(_owners[tokenId] != msg.sender){
            // revert 将会返回后面的一个数值,同时回滚交易
            // 在 0.8.4 后允许抛出 error 错误,帮助调试代码
            // revert 会剩余的 gas 返回调用者
            revert TransferNotOwner();
        }
        _owners[tokenId] = newOwner;
    }

2 require

require命令是solidity 0.8之前抛出异常的常用方法,根据条件判断是否抛出异常require(检查条件,"异常的描述")。优点是好用,缺点是随着require后返回的字符串的长度的增加,gas费用也在增加,比error高。例子如下:

    function transferOwner2(uint256 tokenId, address newOwner) public {
        require(_owners[tokenId] == msg.sender, "Transfer Not Owner");
        _owners[tokenId] = newOwner;
    }

3 assert

assert命令一般用于程序员写程序debug,因为它不能解释抛出异常的原因(比require少个字符串)assert(检查条件)。最大的缺点是条件不成立后,抛出异常且gas用回全部消耗掉。例子如下:

    function transferOwner3(uint256 tokenId, address newOwner) public {
        assert(_owners[tokenId] == msg.sender);
        _owners[tokenId] = newOwner;
    }

4 try-catch

solidity 0.6版本后,solidity也添加了异常处理方法,并且try-catch只能被用于external函数(只能由外部调用的函数)或创建合约时constructor(被视为external函数)的调用。基本语法如下:

        try externalContract.f() {
            // call成功的情况下 运行一些代码
        } catch Error(string memory reson){
            // 这里一般是 require/revert 的异常抛出,毕竟参数是 string
            // call 失败的情况下 运行一些代码
        } catch (bytes memory reason) {
            // assert 的异常抛出
            // catch 失败的 assert()
            emit CatchByte(reason);
        }

5 总结

现在真正使用的异常抛出方法有:error(新兴)、require,而assert由于其高费用而常常不予考虑。

对于异常捕获tyr-catch只能在调用外部函数(包括生成新合约)时使用。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
nilliol
nilliol
0xbe3e...29A9
新人一枚,正在向 web3 方向前进