Back

blockchain - 判断某个contract的方法调用是否生效(trigger revert): 通过estimateGas 来判断!

发布时间: 2022-07-09 00:39:00

refer to: https://ethereum.stackexchange.com/questions/131401/my-call-to-contract-method-not-throw-error-but-stuck-why/131442#131442

contract源代码:

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract VeryGoodNftWithMaxSupply is ERC721URIStorage {

  uint256 private _currentId = 0;
  address public rootAddress = address(0);
  uint256 public _maxSupply = 3;

  event Minted(address to, uint256 nftId, address minter);

  modifier shouldLessThanMaxSupply(){
    require(
      _currentId < _maxSupply, "Reached max supply, no available nft left"
    );
    // 下划线表示被hook方法的内容。 会在编译、执行的时候做个替换
    _;
  }

  constructor() ERC721("VeryGoodNftWithMaxSupply", "VGNWM") {
    rootAddress = msg.sender;
  }

  function mint(address to) external shouldLessThanMaxSupply{
    uint256 nftId = _currentId + 1;
    _mint(to, nftId);
    _currentId = nftId;
    address from = msg.sender;
    emit Minted(to, nftId, from);
  }
}

调用方法:

(会一直卡住)

const CONTRACT_ADDRESS = "0x7eB6D07B6A69a2Be809dAed88d456C1460aA7C3e"
const contractJson = require('./build/contracts/VeryGoodNftWithMaxSupply.json')

module.exports = async function (callback) {
  const contract = new web3.eth.Contract( contractJson.abi, CONTRACT_ADDRESS );

  const network = await web3.eth.net.getNetworkType()

  // This method will meet the error ( rever : max nft supply reached ... ) 
  const tx = contract.methods.mint('0xc0dD5021e298dB57bEF361C735cd1C04cef2E48A')

  const receipt = await tx
  .send({
    from: (await web3.eth.getAccounts())[0], 
    gas: await tx.estimateGas(),
  })
  .once('sending', (payload) => {
    console.info("-- in sending..., payload: ", payload)
  })
  .once('sent', (payload) => {
    console.info("-- in sent..., payload: ", payload)
  })
  .once("transactionHash" , (txHash) => {
    console.log(`Mining transaction ... network: ${network}, tx: ${txhash}`)
    // console.log(`https://${network}.etherscan.io/tx/${txhash}`)
  })
  .once('receipt', (receipt) => {
    console.info("-- in receipt...", receipt)
    console.log('====== total: ')
    console.log(receipt)
    console.log('====== events.Minted: ', receipt.events.Minted)
    // Success, you've minted the NFT. The transaction is now on chain!
    console.log(
        `Success: The NFT has been minted and mined in block ${receipt.blockNumber}`)
    callback()
  })
  .on('confirmation', (confNumber, receipt, lastBlockHash) => {
    console.info("-- in confirm...", receipt)
  })
  .on('error', (error) => {
    console.error(`An error happened: ${error}`)
    callback()
  })

}

解决办法:

修改 estimateGas, 增加catch 部分(处理error)

  // 发送!
  console.info("== before estimateGas: ")
  let gas = await tx.estimateGas()
  .then(function(e){
    console.log(e)
  }).catch(function(e){
    console.error(e) 
    throw("=== we got an error , ", e)
  })
  console.info("== after estimateGas: ", gas)

灵感来源:

Back