I'm creating a solidity contract for an NFT and in my mint function I'm not sure if a call to totalSupply() vs using a token counter and incrementing it is better practice. Does either variation cost more gas? Is one the more standard practice? I've seen examples of both being used.
Variation 1:
contract MyNFT is ERC721Enumerable, PaymentSplitter, Ownable {
using Counters for Counters.Counter;
Counters.Counter private currentTokenId;
...
function mint(uint256 _count)
public payable
{
uint256 tokenId = currentTokenId.current();
require(tokenId < MAX_SUPPLY, "Max supply reached");
for(uint i = 0; i < _count; ++i){
currentTokenId.increment();
uint256 newItemId = currentTokenId.current();
_safeMint(msg.sender, newItemId);
}
}
}
Variation 2:
function mint(uint256 _count)
public payable
{
uint supply = totalSupply();
require( supply + _count <= MAX_SUPPLY, "Exceeds max supply." );
for(uint i = 0; i < _count; ++i){
_safeMint(msg.sender, supply + i);
}
}
Both versions seem to work. I just want to be sure I'm using the most efficient / secure. Thanks for any advice!
First off all, you need to show us the underlying implementations. However, I can speculate that these are unmodified openzeppelin implementations for ERC721Enumerable and Counters.
For your case only, using Counter seems a little bit pointless to me.
I am not guaranteeing correctness of the following analysis
Calling totalSupply (looking from opcode point of view) will:
However, while using Counter, you sstore (>= 5000 gas) each time you decrement and sload (200 gas) each time you read.
As long as i am not mistaken about Counter using storage, and therefore sstore and sload opcodes, second variant will use much less gas.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With