Solidity
為擁有的每個外部 ERC1155 和 ERC721 代幣允許免費鑄幣一次
我修改了一個鑄幣功能,允許使用者在擁有另一個合約的代幣時免費鑄幣。到目前為止,該功能執行良好,但我無法確定安全檢查以防止使用者免費鑄造相同的令牌。
例如,如果令牌 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); } } }