0

I have an ERC721 contract that mints an NFT. I added a function that mints multiple NFTs in one call. I tried returning the token ids from that function, but I cannot write the test code to get them.

Code:

//@dev mint token for user
  function mintToken() public payable returns(uint256) {
    require(_deactivated == false, "Token sale is deactivated");
    uint256 price = calculatePrice(msg.sender);
    require(msg.value >= price, "Insufficient ETH sent");

    //get token id
    _tokenIds.increment();
    uint256 tokenId = _tokenIds.current();

    //get uri
    string memory uri = randomUri();

    //mint and set uri
    _safeMint(msg.sender, tokenId);
    _setTokenURI(tokenId, uri);

    return tokenId;
  }

  //@dev mint multiple tokens for user
  function mintMultipleTokens(uint numberOfTokens) public payable returns(uint256[] memory) {
    require(_deactivated == false, "Token sale is deactivated");
    uint256 price = calculatePrice(msg.sender).mul(numberOfTokens);
    require(msg.value >= price, "Insufficient ETH sent");

    uint256[] memory tokenIds = new uint256[](numberOfTokens);
    for(uint index = 0; index < numberOfTokens; index++) {
      tokenIds[index] = mintToken();
    }
    return tokenIds;
  }

In my test, when I execute: const tokenIds = await token.connect(user3).mintMultipleTokens(numberOfTokens, {value: price}); I receive the following in tokenIds:

{
  hash: '0x8eab2571a37a17c481e9ede9c4d5eb99b410a743d9459dc1017e393500e67d72',
  type: 2,
  accessList: [],
  blockHash: '0xbbbda0142bbea68b403dc8bfc910cc037260dce00725aa1b8f6cd53c52f1c8b7',
  blockNumber: 42,
  transactionIndex: 0,
  confirmations: 1,
  from: '0x90F79bf6EB2c4f870365E785982E1f101E93b906',
  gasPrice: BigNumber { _hex: '0x3c1214ea', _isBigNumber: true },
  maxPriorityFeePerGas: BigNumber { _hex: '0x3b9aca00', _isBigNumber: true },
  maxFeePerGas: BigNumber { _hex: '0x3c895fd4', _isBigNumber: true },
  gasLimit: BigNumber { _hex: '0x01bad518', _isBigNumber: true },
  to: '0x09635F643e140090A9A8Dcd712eD6285858ceBef',
  value: BigNumber { _hex: '0x06f05b59d3b20000', _isBigNumber: true },
  nonce: 1,
  data: '0xe1dffcb90000000000000000000000000000000000000000000000000000000000000005',
  r: '0x6f8717d164eebdd6578218c4d8c5cce95e2244f7b6f218e15e846d32688bddb7',
  s: '0x616dc1810a7dcf4574e5254df4f144c0a6d1f30b3f9398637e28e0c899cfc768',
  v: 1,
  creates: null,
  chainId: 31337,
  wait: [Function (anonymous)]
}

How can I receive the ids array properly, so I can conclude my test?

I'm using Hardhat 2.6.8, Solidity 0.8.4, Node 17.0.1.

2

1 Answer 1

0

There is no way to get the return value of a transaction, directly. How this is usually done, is with one of two ways (or both):

  1. Emit events with the required data, and catch those events

  2. Get the required data through a view function. So the main function stores the result in a state variable(s) and that data is read in a separate view function. view functions can return data directly, since those are called with a local call, instead of a real transaction.

You can read more about this for example here: return function value instead of transaction receipt with web3

5
  • I suspected it has something to do with view. But then, why can I get the value of mintToken (which is uint256) properly? it's not a view either? Nov 15, 2021 at 21:51
  • My guess is that you're accidentally calling it as a local call, instead of a real transaction Nov 15, 2021 at 21:52
  • So far, I've only been calling it in a Hardhat test. But it is a standard NFT mint function, and those always return the id? Nov 15, 2021 at 21:53
  • Something else came to mind: each time an NFT gets minted, a Transfer event is fired. Is there a way to capture multiple Transfer events? That way, I won't need to return an array, as each even would include an id. Nov 15, 2021 at 21:55
  • The ERC721 standard doesn't specify anything about minting, so its signature can be anything. If you have further questions, please post a new question or search for existing answers Nov 15, 2021 at 21:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.