A basic NFT modifiers and more…

So far in our ERC721 contract we’ve got one function ( mintOneNft ) that’s public (external) and anyone can mint. There is a difference between a public function and external but for our case at this time we just need to know it can be accessed by anyone in the outside world.

Let’s add a new function that’s only called by the owner of the token. The owner has been defined as the address that deployed the contract. Up until now we’ve been using the OZ contract Ownable . We can use our own modifier and introduce that concept. Take a little more control over our own contract and how we want to implement it.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

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

contract BasicERC721 is ERC721 {
    
    using Counters for Counters.Counter;

    Counters.Counter public _tokenIds;

    string private baseUri;
    address public _owner;

    constructor(
        string memory _name,
        string memory _symbol,
        string memory _uri) 
        ERC721(_name,_symbol) {
            baseUri = _uri;
            _owner = msg.sender;
        }

    function mintOneNftByOwner() external onlyTheOwner {
        _safeMint(msg.sender, _tokenIds.current());
        _tokenIds.increment();
    }

    function mintOneNft() external {
        _safeMint(msg.sender, _tokenIds.current());
        _tokenIds.increment();
    }

    /**
    *
    *
    * add our own modifier similar to 
    * OZ "onlyOwner" modifier
    *
    */
    modifier onlyTheOwner {
        require(
            msg.sender == _owner,
                "Only the Owner can call this function."
        );
        _;
    }
    
}
  

We’ve defined a new member variable _owner that is set to the address that calls the constructor (msg.sender). A function modifier let’s you change the behavior of functions of your Solidity contracts in a declarative way. The mintOneNftByOwner uses onlyTheOwner modifier to perform a security check. If the condition is true “_;” you can look at this like a placeholder for the body of the function calling the modifier.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

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

contract BasicERC721 is ERC721 {

    event UpdatedMintStatus( bool oldValue, bool newValue );
    
    using Counters for Counters.Counter;

    Counters.Counter public _tokenIds;

    string private baseUri;
    address public owner;
    bool public publicMintStatus;

    constructor(
        string memory _name,
        string memory _symbol,
        string memory _uri) 
        ERC721(_name,_symbol) {
            baseUri = _uri;
            owner = msg.sender;
        }

    function mintOneNftByOwner() external onlyTheOwner {
        _safeMint(msg.sender, _tokenIds.current());
        _tokenIds.increment();
    }

    function mintOneNft() external onlyIfPublicMintStatus {
        _safeMint(msg.sender, _tokenIds.current());
        _tokenIds.increment();
    }

    function setPublicMintStatus(bool _mintStatus) external onlyTheOwner {
        emit UpdatedMintStatus( publicMintStatus, _mintStatus );
        publicMintStatus = _mintStatus;
    }

    /**
    *
    *
    * add our own modifier similar to 
    * OZ "onlyOwner" modifier
    *
    */
    modifier onlyTheOwner {
        require(
            msg.sender == owner,
                "Only the Owner can call this function."
        );
        _;
    }


    /**
    *
    *
    *
    * another modifier to prevent public minting if
    * if not allowed
    */
    modifier onlyIfPublicMintStatus {
        require(
            publicMintStatus == true,
                "Public minting is not available at this time."
        );
        _;
    }
    
}

I Added an event when the public minting status is updated that lets the client know the member variable publicMintStatus has been updated and emits the old and newly updated status.

repo branch: https://github.com/bws9000/smart-contract-tests/tree/add-more-features-erc721

previous article

By Burt Snyder

Writing about interesting things and sharing ideas.

1 comment

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.