什麼是NFT盲盒?NFT盲盒挖礦生態遊戲開發功能介紹

nice1022發表於2023-03-01

說起盲盒,顧名思義,就是看不到裡面是什麼,現實中的盲盒大部分都是一些周邊、手辦、生活用品、電子產品等等,現在就連NFT專案也與盲盒結合了起來,推出了NFT盲盒,這二者的結合保證了專案的穩定發展和社群的持續活力。


NFT盲盒是什麼意思?

正如玩家所說,專案開發I34-合約I633-部署53I9,你永遠猜不到盒子裡面是什麼。這就是魅力所在。迎合了大眾的心理,追求未知的刺激。現在盲盒也開始轉移到線上,再次掀起浪潮。


就拿現在的NFT專案與盲盒結合舉例來說,盲盒與挖礦的結合保證了專案的穩定發展和社群的持續活力。專案透過DeFi生態系統上流動性、產量礦池和NFT的獨特性將其與盲盒遊戲模式結合。


盲盒遊戲軟體開發的最大特點是寫在智慧合約上,保證公開透明,盲盒一旦滿足相應的開獎條件後,點選立即開獎,開獎結果便已經生成,無法纂改。因為智慧合約本身與其執行過程都是可觀察的,支援監管和可信,智慧合約中涉及的所有各方都確信該合同是以100%中立和無偏見的方式執行的,不會有欺詐、操縱或未經授權的修改風險。


合約部分

首先將本次合約部分的原始碼直接貼上在remix中進行編譯。原始碼如下:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
   
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
   
contract NftMeta is ERC721Enumerable, Ownable {
    using Strings for uint256;
   
    // 是否準許nft開賣-開關
    bool public _isSaleActive = false;
    // 初始化盲盒,等到一定時機可以隨機開箱,變成true
    bool public _revealed = false;
   
    // nft的總數量
    uint256 public constant MAX_SUPPLY = 10;
    // 鑄造Nft的價格
    uint256 public mintPrice = 0.3 ether;
    // 鑄造的錢包最多隻能有一個nft數量
    uint256 public maxBalance = 1;
    // 一次mint的nft的數量
    uint256 public maxMint = 1;
   
    // 盲盒開關開啟後,需要顯示開箱的圖片的base地址
    string baseURI;
    // 盲盒圖片的meta,json地址,後文會提到
    string public notRevealedUri;
    // 預設地址的擴充套件型別
    string public baseExtension = ".json";
   
    mapping(uint256 => string) private _tokenURIs;
   
    // 構造器
    constructor(string memory initBaseURI, string memory initNotRevealedUri)
        ERC721("Nft Meta", "NM") // 實現了ERC721的父類構造器,是子類繼承的一種實現方式
    {
        setBaseURI(initBaseURI);
        setNotRevealedURI(initNotRevealedUri);
    } 
    // 外部地址進行鑄造nft的函式呼叫
    function mintNftMeta(uint256 tokenQuantity) public payable {
        // 校驗總供應量+每次鑄造的數量<= nft的總數量
        require(
            totalSupply() + tokenQuantity <= MAX_SUPPLY,
            "Sale would exceed max supply"
        );
        // 校驗是否開啟開賣狀態
        require(_isSaleActive, "Sale must be active to mint NicMetas");
        // 校驗鑄造的錢包地址中的nft的數量 + 本次鑄造的數量 <= 該錢包最大擁有的nft的數量
        require( 
            balanceOf(msg.sender) + tokenQuantity <= maxBalance,
            "Sale would exceed max balance"
        );
        // 校驗本次鑄造的數量*鑄造的價格 <= 本次訊息附帶的eth的數量
        require(
            tokenQuantity * mintPrice <= msg.value,
            "Not enough ether sent"
        );
        // 校驗本次鑄造的數量 <= 本次鑄造的最大數量
        require(tokenQuantity <= maxMint, "Can only mint 1 tokens at a time");
        // 以上校驗條件滿足,進行nft的鑄造
        _mintNftMeta(tokenQuantity);
    }
   
    // 進行鑄造
    function _mintNftMeta(uint256 tokenQuantity) internal {
        for (uint256 i = 0; i < tokenQuantity; i++) {
            // mintIndex是鑄造nft的序號,按照總供應量從0開始累加
            uint256 mintIndex = totalSupply();
            if (totalSupply() < MAX_SUPPLY) {
                // 呼叫erc721的安全鑄造方法進行呼叫
                _safeMint(msg.sender, mintIndex);
            }
        }
    }
   
    // 返回每個nft地址的Uri,這裡包含了nft的整個資訊,包括名字,描述,屬性等
    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );
   
        // 盲盒還沒開啟,那麼預設是一張黑色背景圖片或者其他圖片
        if (_revealed == false) {
            return notRevealedUri;
        }
   
        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();
   
        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return
            string(abi.encodePacked(base, tokenId.toString(), baseExtension));
    }
   
    // internal
    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }
   
    //only owner
    function flipSaleActive() public onlyOwner {
        _isSaleActive = !_isSaleActive;
    }
   
    function flipReveal() public onlyOwner {
        _revealed = !_revealed;
    }
   
    function setMintPrice(uint256 _mintPrice) public onlyOwner {
        mintPrice = _mintPrice;
    }
   
    function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
        notRevealedUri = _notRevealedURI;
    }
   
    function setBaseURI(string memory _newBaseURI) public onlyOwner {
        baseURI = _newBaseURI;
    }
   
    function setBaseExtension(string memory _newBaseExtension)
        public
        onlyOwner
    {
        baseExtension = _newBaseExtension;
    }
   
    function setMaxBalance(uint256 _maxBalance) public onlyOwner {
        maxBalance = _maxBalance;
    }
   
    function setMaxMint(uint256 _maxMint) public onlyOwner {
        maxMint = _maxMint;
    }
   
    function withdraw(address to) public onlyOwner {
        uint256 balance = address(this).balance;
        payable(to).transfer(balance);
    }
}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011332/viewspace-2937612/,如需轉載,請註明出處,否則將追究法律責任。

相關文章