Skip to content

Latest commit

 

History

History
49 lines (41 loc) · 2.05 KB

File metadata and controls

49 lines (41 loc) · 2.05 KB

101-15 异常

写智能合约经常会出bug,Solidity中的异常命令帮助我们debug

error

error是solidity 0.8.4版本新加的内容,方便高效(省gas)地向用户解释操作失败的原因,同时还可以在抛出异常的同时携带参数,帮助开发者更好地调试。人们可以在contract之外定义异常。

下面定义一个TxNotOwner异常, 当用户不是tonken owner时尝试转账会抛出错误

error TxNotOwner();

也可以定义一个携带参数的异常,来替时尝试转账的账户地址

error TxNotOwner(address sender); 

在执行中,error必须搭配revert(回退)命令使用

function TxOwner1(uint256 tokenId, address newOwner) public {
    if(_owners[tokenId] != msg.sender){
        revert TxNotOwner();
        // revert TransferNotOwner(msg.sender);
    }
    _owners[tokenId] = newOwner;
}

我们定义了一个transferOwner1()函数,它会检查代币的owner是不是发起人,如果不是,就会抛出TransferNotOwner异常;如果是的话,就会转账。

Require

require命令是solidity 0.8版本之前抛出异常的常用方法,目前很多主流合约仍然还在使用它。它很好用,唯一的缺点就是gas随着描述异常的字符串长度增加,比error命令要高。使用方法:require(检查条件,"异常的描述"),当检查条件不成立的时候,就会抛出异常。

使用require重写上面的TxOwner1函数如下:

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

Assert

assert命令一般用于程序员debug,因为它不能解释抛出异常的原因(比require少个字符串)。它的用法很简单,assert(检查条件),当检查条件不成立的时候,就会抛出异常。

用assert重写TxOwner1函数如下:

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