美文网首页
以太坊合约开发ERC721 NFT

以太坊合约开发ERC721 NFT

作者: Sunooo | 来源:发表于2023-04-18 18:56 被阅读0次

    ERC721

    ERC721 是以太坊上的一个标准协议,用于创建不可分割、不可互换的独特资产,如数字艺术品、游戏物品、收藏品等。每个 ERC721 资产都有一个唯一的标识符,被称为 token ID。这个标准协议定义了一组功能和事件,使得 ERC721 资产可以被安全地转移、拥有、交易和检索。与传统的货币不同,每个 ERC721 资产都是独特的,并且不可替代,因此它们可以用于代表任何种类的独特资产,并且具有非常广泛的应用。

    Mint

    可以在以下测试网络自己mint,具体步骤可以参考 Github

    Network Contract Address
    Ethereum Speolia 0x8b6c7d03bd8911236feaa43afacbb8b0e563d93a
    BNB Chain Testnet 0xfD9585145A5BC2D7A74c82E78aB9314723683BA8
    Polygon Mumbai 0x9B1AAb1492c375F011811cBdBd88FFEf3ce2De76
    Avalanche Testnet 0x825706F885445867958A3f3a4dec8189e0E02524
    Arbitrum Goerli 0x1E2c6DD54b473B63112416850E73B2F567DDE3Df
    Optimism Goerili 0x825706f885445867958a3f3a4dec8189e0e02524
    Base Testnet 0x155afc7fbaedda178c6185ec9151964b9719828b

    开发

    Openzeppelin 的帮助下可以很快的入手开发ERC721标准的NFT合约。参考之前测试用的NFT代码,自行编译并且发布到了更多的测试网络上,可以很方便的进行ERC721 NFT测试。
    引入ERC721库之后,自己只需要实现setBaseURI mint等自定义方法即可,非常简单。
    合约开发使用的是VSCode和hardhat,合约验证使用hardhat flattening

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.9;
    
    import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
    import "@openzeppelin/contracts/access/Ownable.sol";
    
    contract TestToadz is ERC721, Ownable {
        uint256 public constant maxTokens = 6969;
        uint256 public numAvailableTokens = 6969;
        uint256 public constant maxMintsPerTx = 5;
        mapping(address => uint256) public addressToNumOwned;
        string private _contractURI;
        bool public devMintLocked = false;
        uint256[10000] private _availableTokens;
    
        constructor() ERC721("TestToadz", "TESTTOADZ") {}
    
        // metadata URI
        string private _baseTokenURI =
            "ipfs://QmWEFSMku6yGLQ9TQr66HjSd9kay8ZDYKbBEfjNi4pLtrr/";
    
        function _baseURI() internal view virtual override returns (string memory) {
            return _baseTokenURI;
        }
    
        function tokenURI(uint256 _serialId)
            public
            view
            override
            returns (string memory)
        {
            string memory base = _baseURI();
            string memory _tokenURI = Strings.toString(_serialId);
    
            // If there is no base URI, return the token URI.
            if (bytes(base).length == 0) {
                return _tokenURI;
            }
    
            return string(abi.encodePacked(base, _tokenURI));
        }
    
        function getNumAvailableTokens() public view returns (uint256) {
            return numAvailableTokens;
        }
    
        function setBaseURI(string calldata baseURI) external onlyOwner {
            _baseTokenURI = baseURI;
        }
    
        //Minting
        function mint(uint256 quantity) public {
            uint256 updatedNumAvailableTokens = numAvailableTokens;
            require(
                block.timestamp >= 1337133769,
                "Sale starts at whatever this time is"
            );
            require(
                quantity <= maxMintsPerTx,
                "There is a limit on minting too many at a time!"
            );
            require(
                updatedNumAvailableTokens - quantity >= 0,
                "Minting this many would exceed supply!"
            );
            require(
                addressToNumOwned[msg.sender] + quantity <= 40,
                "Can't own more than 20 toadz"
            );
            require(msg.sender == tx.origin, "No contracts!");
            for (uint256 i = 0; i < quantity; i++) {
                uint256 tokenId = getRandomSerialToken(quantity, i);
                _safeMint(msg.sender, tokenId);
                updatedNumAvailableTokens--;
            }
            numAvailableTokens = updatedNumAvailableTokens;
            addressToNumOwned[msg.sender] =
                addressToNumOwned[msg.sender] +
                quantity;
        }
    
        //Dev mint special tokens
        function mintSpecial(uint256[] memory specialIds) external onlyOwner {
            require(!devMintLocked, "Dev Mint Permanently Locked");
            uint256 num = specialIds.length;
            for (uint256 i = 0; i < num; i++) {
                uint256 specialId = specialIds[i];
                _safeMint(msg.sender, specialId);
            }
        }
    
        function getRandomSerialToken(uint256 _numToFetch, uint256 _i)
            internal
            returns (uint256)
        {
            uint256 randomNum = uint256(
                keccak256(
                    abi.encode(
                        msg.sender,
                        tx.gasprice,
                        block.number,
                        block.timestamp,
                        blockhash(block.number - 1),
                        _numToFetch,
                        _i
                    )
                )
            );
            uint256 randomIndex = randomNum % numAvailableTokens;
            uint256 valAtIndex = _availableTokens[randomIndex];
            uint256 result;
            if (valAtIndex == 0) {
                result = randomIndex;
            } else {
                result = valAtIndex;
            }
    
            uint256 lastIndex = numAvailableTokens - 1;
            if (randomIndex != lastIndex) {
                uint256 lastValInArray = _availableTokens[lastIndex];
                if (lastValInArray == 0) {
                    _availableTokens[randomIndex] = lastIndex;
                } else {
                    _availableTokens[randomIndex] = lastValInArray;
                }
            }
    
            numAvailableTokens--;
            return result;
        }
    
        function lockDevMint() public onlyOwner {
            devMintLocked = true;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:以太坊合约开发ERC721 NFT

          本文链接:https://www.haomeiwen.com/subject/ufmxjdtx.html