Solidity

為擁有的每個外部 ERC1155 和 ERC721 代幣允許免費鑄幣一次

  • February 20, 2022

我修改了一個鑄幣功能,允許使用者在擁有另一個合約的代幣時免費鑄幣。到目前為止,該功能執行良好,但我無法確定安全檢查以防止使用者免費鑄造相同的令牌。

例如,如果令牌 1 用於免費鑄幣廠,則它不能再次使用。

這是我到目前為止所擁有的 -

....
modifier mintCompliance(uint256 _mintAmount) {
   // REMOVED TO PUT IN OTHER FUNCTIONS 
       _;
     }
   
     function totalSupply() public view returns (uint256) {
       return supply.current();
     }
   
   // START MINT FUNCTION
     function mint(uint256 _mintAmount) public payable mintCompliance(_mintAmount) {
       require(!paused, "The contract is paused!");
   
   
   // DETERMINE MINT LOGIC HERE
        if (msg.sender != owner()) { // IF NOT THE OWNER
   
           // MAKE SURE USER OWNS AT LEAST 1 TOKEN
           require(IERC721(0x00...).balanceOf(msg.sender) >= 1, "No tokens owned!");
   
           // CHECK USER TOKEN BALANCE
           uint256 count = IERC721(0x00...).balanceOf(msg.sender);
   
           if (count > 0) { // OWNS AT LEAST 1
           uint256 FreeMints = count * 4; // MULTIPLY AMOUNT OWNED BY 4
           maxMintAmount = FreeMints; // TAKE THAT AND SET AMOUNT FREE FOR THIS ADDRESS
           maxSupply = 100; // MINT FROM A POOL OF RANDOM TOKENS SET ASIDE FOR FREE MINTS ONLY 
           cost = 0 ether; // SET COST TO FREE FOR TOKEN OWNERS
   
           // !NEED SECURITY CHECK SO SYSTEM IS NOT ABSUED/ONLY CLAIM ONCE PER TOKEN. KEEP TRACK SOMEHOW
           // TO DO
   
           // MINT COMPLIANCE REQUIREMENTS
           require(count > 0, "Not Allowed!"); // DONT ALLOW MINT IF NO TOKENS OWNED
           uint256 ownerTokenCount = addressMintedBalance[msg.sender];
           require(ownerTokenCount + _mintAmount <= FreeMints, "max per free mint exceeded");
           require(_mintAmount > 0 && _mintAmount <= maxMintAmount, "Invalid mint amount!");
           require(supply.current() + _mintAmount <= maxSupply, "Max supply exceeded!");
           require(_mintAmount <= maxMintAmount, "max mint amount per session exceeded");
           }
        
       require(msg.value >= cost * _mintAmount, "Insufficient funds!");
   
       _mintLoop(msg.sender, _mintAmount);
     }
     } // END MINT FUNCTION

此外,我試圖在同一個 mint 函式中使用 erc1155 合約做同樣的事情,但它給了我這個錯誤 -Undeclared identifier. Did you mean "IERC165"?.

require(IERC1155(0x00...).balanceOf(msg.sender) >= 1, "No tokens owned!");

編輯: 目前契約使用 ERC721 -

contract NFT is ERC721, Ownable {
 using Strings for uint256;
 using Counters for Counters.Counter;

 Counters.Counter private supply;

但是,我要查詢的契約是-

contract NFT is ERC721Enumerable, Ownable {

如果你的 NFT 合約是 ERC721Enumerable 合約,那麼你可以使用這個系統。

將此映射添加到您的狀態:

mapping(address => bool) usedTokens;

並修改您的程式碼(我知道這不是產品程式碼,但您可以了解基礎知識):

modifier mintCompliance(uint256 _mintAmount) {
// REMOVED TO PUT IN OTHER FUNCTIONS 
   _;
}

function totalSupply() public view returns (uint256) {
   return supply.current();
}

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

   // DETERMINE MINT LOGIC HERE
   if (msg.sender != owner()) { // IF NOT THE OWNER
       uint _userBalance = IERC721(0x00...).balanceOf(msg.sender);

       if(_userBalance > 0) {
           for(uint i; i < _userBalance; i++) {
               uint _tokenId = IERC721(0x00...).tokenOfOwnerByIndex(msg.sender, i);
               if(!usedTokens[_tokenId]) { // IF TOKEN NOT USED
                   usedTokens[_tokenId] = true;

                   uint256 ownerTokenCount = addressMintedBalance[msg.sender];
                   require(ownerTokenCount + _mintAmount <= FreeMints, "max per free mint exceeded");
                   require(_mintAmount > 0 && _mintAmount <= maxMintAmount, "Invalid mint amount!");
                   require(supply.current() + _mintAmount <= maxSupply, "Max supply exceeded!");
                   require(_mintAmount <= maxMintAmount, "max mint amount per session exceeded");
               }
           }
       } else {
           require(msg.value >= cost * _userBalance, "Insufficient funds!");
           _mintLoop(msg.sender, _mintAmount);
       }
   }
}

引用自:https://ethereum.stackexchange.com/questions/121703