pragma solidity >=0.7.0 <0.9.0;
abstract contract IParent {
function ownerOf(uint256 tokenId) external view virtual returns (address);
function walletOfOwner(address _owner) external view virtual returns (uint256[] memory);
function totalSupply() external view virtual returns (uint256);
function balanceOf(address owner) external view virtual returns (uint256);
}
Since ownerOf,
walletOfOwner
, totalSupply
, and balanceOf
have been declared but no implementation was provided, the contract uses the keyword abstract
. These four functions are used in the parent contract (e.g. Balloontown).
mapping(address=>uint256) public _parentsClaimedPerAddress;
uint256 public parentClaims;
address public v2Address =0x3b8e3C1a29C5cA73Dd47Dc57781d3E7551c0A2aB;
IParent public v2;
_parentsClaimedPerAddress
mapping is used to track addresses that have claimed the NFT, which are holders of the parent NFT.
parentClaims
variable keeps track of the total minted NFTs from holders of the parent NFT.
v2Address
is the hardcoded address of the parent contract.
The v2
variable gets initialized as the IParent
interface.
constructor() ERC721(_collectionName, _collectionSymbol)
{
setNotRevealedURI("ipfs://QmdC8LcRr5Xxzqdx3YCgs5uCEQBCApaCFXGRK7tdTwAp9P/HiddenMetadata.json");
v2= IParent(v2Address);
}
When deploying the child contract, the parent’s contract is passed to v2
.
function claimForParentNFT(uint256 numberOfTokens) external payable {
uint256 balance= v2.balanceOf(msg.sender);
uint256 currentSupplyGlobal = totalSupply();
uint256 currentClaimed =_parentsClaimedPerAddress[msg.sender];
require(parentClaimActive, "Claim is not active");
require(numberOfTokens+currentClaimed <=balance, "Exceeded max available to purchase");
require(currentSupplyGlobal + numberOfTokens <= maxSupply, "Purchase would exceed max supply");
for (uint256 i = 1; i <= (numberOfTokens); i++) {
_safeMint(msg.sender, currentSupplyGlobal + i);
}
parentClaims+=numberOfTokens;
_parentsClaimedPerAddress[msg.sender]+=numberOfTokens;
amountMinted+=numberOfTokens;
}
Holder passes in numberOfTokens
, also known as, the number of parent NFTs owned.
The balance
variable is set by calling the parent’s contract balanceOf
function, which passes the caller’s (holder’s) address and returns the number of NFTs owned.
The currentSupplyGlobal
variable is set by calling the child’s totalSupply
function and returning the total number of minted NFTs.
The currentClaimed
variable is set by using the mapping _parentsClaimedPerAddress
and keeping count of the total amount of NFTs claimed by the caller (holder).
Three require statements are used to check if the claim function is active, verify the caller is not able to mint more NFTs than they hold on the parent’s contract, and lastly, the transaction does not exceed the max supply.
The for-loop iterates the number of “tokens” or NFTs the caller owns from the parent contract, each time calling the _safeMint
function. Each call to the _safeMint
function increments currentSupplyGlobal
by 1. Once the for-loop has finished, the numberOfTokens
is added to parentClaims
, _parentsClaimedPerAddress
mapping is passed the numberOfTokens
, and numberOfTokens
is added to amountMinted
.