简体   繁体   中英

Why does the minting function of ERC721 have an access control?

Most of the ERC721 examples using Open Zeppelin I see require the mint function to have an access control where only the owner of the contract is allowed to call the function. For example ,

function mint(address to) public virtual {
    require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint");

    _mint(to, _tokenIdTracker.current());
    _tokenIdTracker.increment();
}

or the following using the Ownable library.

function mint(address receiver) external onlyOwner returns (uint256) {
    _tokenIds.increment();

    uint256 newTokenId = _tokenIds.current();
    _mint(receiver, newTokenId);

    return newTokenId;
}

Does this mean a new contract has to be deployed each time a new token is minted? This seems not only excessive in terms of the gas fee, but also the ERC721 contract has properties for mapping different owners and tokens:

// Mapping from token ID to owner address
mapping (uint256 => address) private _owners;

// Mapping owner address to token count
mapping (address => uint256) private _balances;

which wouldn't make sense if minting is restricted to the contract owner.

It makes more sense to me that you deploy a single ERC721 contract (and its dependencies) and have the users call the mint function. What is the best practice for the mint function of ERC721?

The ERC-721 standard does not define a "best" or "correct" way to mint new tokens (such as whether it should be open or restricted) and it's up to each contract developer to implement or omit the minting feature in a way that reflects their needs.

Creating of NFTs ("minting") and destruction NFTs ("burning") is not included in the specification. Your contract may implement these by other means. Please see the event documentation for your responsibilities when creating or destroying NFTs.

But having a whitelist of addresses that are authorized to mint new tokens (eg MINTER_ROLE or onlyOwner ) seems to be more common than allowing anyone to freely mint new tokens.


Even though it's theoretically possible to deploy new contract each time a new token is minted, it's not a standard approach (and I personally haven't seen any contract that does it). In most cases the minting process "just" creates a new ID, stores a new string/URL value associated with the ID, associates this new token with an owner address (of the token, not a contract owner), plus updates some metadata such as amount of tokens owned by an address (see example below).

The token owner can then transfer their tokens, give anyone control over their tokens, and do other stuff depending on the contract implementation.

The mappings that you point out in your question ( _owners and _balances ) suggest that they store token owner (not contract owner) addresses as well as amount of tokens held by each address.

Example:

  1. Contract owner mints token ID 1 to address 0x123 .

    • Value of _owners[1] is 0x123 (was 0, the default value)

    • Value of _balances[0x123] becomes 1 (was 0, the default value)

  2. Contract owner mints token ID 2 to address 0x123 .

    • Value of _owners[1] is still 0x123

    • Value of _owners[2] is now 0x123 (was 0, the default value)

    • Value of _balances[0x123] becomes 2 (because they now own 2 tokens)

Replying to comments: As stated in example contract owner (markeplace owner) will mint token then this owner has to bear gas fee. What if i want address 0x123 token owner to pay gas fees?..thanks.

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