solidity中使用try catch语句处理异常


try-catch是现代编程语言几乎都有的处理异常的一种标准方式,solidity 0.6之后的版本也添加了这一功能。相比于solidity中经典的 assertrequirereverttry-catch在处理函数调用中发生的失败之后,并不需要回滚整个交易。接下来就介绍一下这一语句。

try-catch

在solidity中,try-catch只能被用于external函数或创建合约时constructor(被视为external函数)的调用。例如:

try externalContract.f() returns(returnType val) {
        // call成功的情况下 运行一些代码
    } catch {
        // call失败的情况下 运行一些代码
    }

其中externalContract.f()代表外部函数,return表示该外部函数的返回值(没有可以省略),如果调用成功的话则执行try{}里面的语句,失败的话则执行catch{}里面的语句

如果想要将其用于合约内部的函数,则需要使用this方法来指向本合约(不能在构造函数中使用),例如:

try this.f() {
    // call成功的情况下 运行一些代码
	} catch {
	// call失败的情况下 运行一些代码
	}

另外,try-catch还支持捕获错误原因,例如:

try externalContract.f() returns(returnType){
            // call成功的情况下 运行一些代码
        } catch Error(string memory err) {
            console.log(err);
        }
          

实例

在下面的例子中,我们想要找到tokenId在 0 − 100 0-100 0100范围内,哪些NFT没有被铸造:

代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

interface NFTContract {
    function ownerOf(uint256 _tokenId) external view returns (address);
}

contract tryCatch {
    uint256[] a;
    function m(address con) public returns (uint256[] memory){
        for (uint256 i = 0; i < 10; i++) {
            try NFTContract(con).ownerOf(i) {
                console.log(i);
            }
            catch  {
                a.push(i);
            }
        }
        return a;
    }
}

其中address con代表所观察NFT的合约地址,ownerOf函数功能是找到给定tokenId的持有者,如果tokenId不存在,则报错。

测试

将上述代码复制到remix中,并部署合约
在这里插入图片描述
事先部署一个简单的NFT合约,并mint了三个NFT,然后调用上述合约中的m函数,可以看到,当函数执行到已经mint了的tokenId 的时候,就会执行console.log,执行到未mint的tokenId的时候,就会向数组a中push该tokenId,最终输出。

上述NFT代码

//SPDX-License-Identifier:MIT
pragma solidity ^0.8.17;

import '@openzeppelin/contracts/token/ERC721/ERC721.sol';

// 继承ERC721, Ownable
contract Simple721Contract is ERC721 {
    uint256 public totalSupply;

    constructor() ERC721('Simple Erc-721 NFT', 'SMPL721') {
    }
    
    function mint() external payable {
        totalSupply++;
        uint256 tokenId = totalSupply;
        _safeMint(msg.sender, tokenId);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涛行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值