Solidity

每個錢包的功能 Max mint 不起作用

  • August 2, 2022

學習穩固性和好奇我如何將我的 NFT 鑄造限制在每個錢包地址僅 2 個。試圖阻止人們在免費鑄造階段使用“映射”鑄造超過 2 個代幣,但不起作用。

pragma solidity >=0.8.9 <0.9.0;

import 'erc721a/contracts/extensions/ERC721AQueryable.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/utils/cryptography/MerkleProof.sol';
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';

contract DD is ERC721AQueryable, Ownable, ReentrancyGuard {

 using Strings for uint256;

 string public baseURI = '';
 string public uriSuffix = '.json';
 
 uint256 public cost;
 uint256 public maxSupply;
 uint256 public maxFreeMint = 4;
 uint256 public maxMintAmountPerWallet = 2;

 mapping(address => uint256) private _freeWalletMints;

 bool public paused = true;

 constructor(
   string memory _tokenName,
   string memory _tokenSymbol,
   uint256 _cost,
   uint256 _maxSupply
 ) ERC721A(_tokenName, _tokenSymbol) {
   setCost(_cost);
   maxSupply = _maxSupply;
 }

 modifier mintCompliance(uint256 _mintAmount) {

   require(_mintAmount > 0, 'Invalid mint amount!');
   require(totalSupply() + _mintAmount <= maxSupply, 'Max supply exceeded!');

   _;
 }


 function mint(uint256 _mintAmount) public payable mintCompliance(_mintAmount){
   if(msg.sender != owner()){
     require(!paused, 'The contract is paused!');
     require(_freeWalletMints[_msgSender()] + _mintAmount <= 2, 'You have already minted');
     if (totalSupply()+_mintAmount > maxFreeMint){
         require(msg.value >= cost * _mintAmount, "Insufficient funds!");
       }
     }
     _safeMint(_msgSender(), _mintAmount);
   }

 function _startTokenId() internal view virtual override returns (uint256) {
   return 1;
 }

 function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
   require(_exists(_tokenId), 'ERC721Metadata: URI query for nonexistent token');

   string memory currentBaseURI = _baseURI();
   return bytes(currentBaseURI).length > 0
       ? string(abi.encodePacked(currentBaseURI, _tokenId.toString(), uriSuffix))
       : '';
 }

 function setCost(uint256 _cost) public onlyOwner {
   cost = _cost;
 }
 function setBaseURI(string memory _url) public onlyOwner {
   baseURI = _url;
 }

 function setUriSuffix(string memory _uriSuffix) public onlyOwner {
   uriSuffix = _uriSuffix;
 }

 function setPaused(bool _state) public onlyOwner {
   paused = _state;
 }

 function withdraw() public onlyOwner nonReentrant {
   (bool os, ) = payable(owner()).call{value: address(this).balance}('');
   require(os);
 }

 function _baseURI() internal view virtual override returns (string memory) {
   return baseURI;
 }
}

我認為您沒有增加地圖內的儲存值。

 function mint(uint256 _mintAmount) public payable mintCompliance(_mintAmount){
   if(msg.sender != owner()){
     require(!paused, 'The contract is paused!');
     require(_freeWalletMints[_msgSender()] + _mintAmount <= 2, 'You have already minted');
     // increase the value to prevent new mints in the future
     _freeWalletMints[_msgSender()] += _mintAmount;
     if (totalSupply()+_mintAmount > maxFreeMint){
         require(msg.value >= cost * _mintAmount, "Insufficient funds!");
       }
     }
     _safeMint(_msgSender(), _mintAmount);
   }

好的,我知道你在這裡做了什麼。你這樣做是為了讓使用者不能用你的“mintCompliance 修飾符”通過 1 筆交易,鑄造 2 個令牌。

你真正想要的是一個錢包地址可能永遠不會鑄造超過 2 個代幣,無論交易數量如何。

您需要做的是: 向使用者的錢包添加一個映射,以跟踪鑄造的代幣數量。然後在鑄幣功能上,首先檢查地圖,看看地址是否已經鑄幣 2。如果是,他們可能不再鑄幣了。如果沒有,那麼他們可以鑄造並且映射是“增量的”。

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