0

How can I add some additional vaidation to my mint function to check if the person minting the nft owns an item from a specific NFT collection.

In other words, I own 2 collections. I want a user to only be able to mint from collection A in they already own an item in collection B.

function _mint(address to, uint256 tokenId) internal virtual {
    require(to != address(0), "ERC721: mint to the zero address");
    require(!_exists(tokenId), "ERC721: token already minted");

    // some additional check here? 
    // psuedocode: _hasItemInCollection(to);

    _beforeTokenTransfer(address(0), to, tokenId);

    _balances[to] += 1;
    _owners[tokenId] = to;

    emit Transfer(address(0), to, tokenId);
}

Edited: I moved this logic to live in the mint function, not the internal _mint function. Here is the updated code:

function mint(uint256 _mintAmount) public payable mintCompliance(_mintAmount) {
    require(!paused, "The contract is paused!");

    // not A *REAL* contract address, your contract address HERE. 
    address patronAccessToken = 0x000000001234567890ABCDEF0001112022222222;

    bool isPatron = (IToken(patronAccessToken).balanceOf(msg.sender) > 0);
    if (isPatron == true) {
        setCost(0.015 ether);
    }
    require(msg.value >= cost * _mintAmount, "Insufficient funds!");

    _mintLoop(msg.sender, _mintAmount);
}

Thank you for your wisdom!

2
  • 1
    So if a user has minted in collection A, will the _balances value of the user in A be >0 ? If it is, that can be used a way to detect if the user has minted in A.
    – pbsh
    Jan 25, 2022 at 18:47
  • @pbsh Yes, but I think that I need to check the _balances or _owners of collection B. if we are trying to mint in collection A then _balances in this function are correlated with the current collection (user may have zero or more). I though i'd need to perform a lookup to etherscan or something to check. - sorry I am a newbie Jan 25, 2022 at 18:53

1 Answer 1

2

I'm assuming that both the contracts are created using this template based on the code you posted.

Let's say contract A is deployed at ADDRESS_A. We'll need to add an interface to interact with contract A.

interface IToken {
    function balanceOf(address) external view returns (uint256);
}

Now in our _mint function, we can check if the msg.sender has previously minted in contract A. To do that, we will create an instance of the contract using our interface.

function _mint(address to, uint256 tokenId) internal virtual {
    require(to != address(0), "ERC721: mint to the zero address");
    require(!_exists(tokenId), "ERC721: token already minted");

    require(IToken(ADDRESS_A).balanceOf(msg.sender),"HAVE NOT MINTED A TOKENS")

    _beforeTokenTransfer(address(0), to, tokenId);

    _balances[to] += 1;
    _owners[tokenId] = to;

    emit Transfer(address(0), to, tokenId);
}

Now the mint function will only proceed if the msg.sender balance is non-zero in contract A.

6
  • I will for sure. I am going to test it first. thank you again! Jan 25, 2022 at 20:38
  • 2
    This is very nice. I don't know why I didn't "get it" that you can reference any other contract from your contract. So you can do interesting, yet ethical or moral questionable things here. e.g. I can check for Bored Ape or CryptoPunk owners and ban them from minting or even buying my NFT if I wanted using the opposite of this code. Jan 25, 2022 at 21:22
  • 1
    You sure can. Smart contracts are unstoppable that way, almost all data is public and accessible, thus interactable.
    – pbsh
    Jan 25, 2022 at 21:42
  • I was planning to allow owners of my first collection to mint future collections for a lower minting cost. Jan 26, 2022 at 14:11
  • @pbsh should I be handling this in the mint function or is there a place earlier in the process? can we perform this detection before the mint step, so the person minting can see the adjusted mint price before they attempt to mint? thank you for all your help. Jan 26, 2022 at 14:20

Your Answer

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

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