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);
    }
}

猜你喜欢

转载自blog.csdn.net/kongtaoxing/article/details/128273222