简体   繁体   中英

Gas efficiency of totalSupply() vs. a tokenID counter | ERC-721

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.

  1. It increases your deployment costs(just a little bit) because of redundant code coming from Counter library
  2. You already know the length of your tokens array, why keep it twice? Counters is created for situations where you don't know the number of elements, like a mapping.

I am not guaranteeing correctness of the following analysis

Calling totalSupply (looking from opcode point of view) will:

  • jump to totalsupply (8 gas)
  • sload tokens.slot (200) gas

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM