How to Implement an On-Chain NFT Allowlist

Posted By : Suchit

Sep 02, 2024

In the dynamic world of NFTs, creating an NFT project that provides exclusive access to a specific group of users is a common requirement. One effective way to achieve this is by implementing an on-chain allowlist using NFT development services. By restricting access to specific functions of your smart contract, such as minting or transferring NFTs, you can ensure that only approved users can participate. In this blog, we'll dive into the details of building an on-chain allowlist for your ERC1155 NFT project using Solidity. We'll leverage the robust OpenZeppelin libraries to create a secure, upgradeable, and feature-rich solution.

 

Why Use an On-Chain NFT Allowlist?

 

An on-chain allowlist offers several advantages for NFT projects:

 

  • Security: Restricts access to specific functions, reducing the risk of malicious activity.
  • Exclusivity: Ensures only designated users for example early supporters or special invitees can mint or transfer NFTs.
  • Flexibility: Allows dynamic updates to the list of approved addresses, adapting to changing requirements.

     

You may also like | Creating a Smart Contract with NFT Royalties
 

An Example of an Upgradeable AllowlistNFT ERC1155 Token Contract with Built-in Allowlist Functionality

 

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import '@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol';

contract AllowlistNFT is
    Initializable,
    ERC1155Upgradeable,
    ERC1155BurnableUpgradeable,
    ERC1155SupplyUpgradeable,
    ERC1155URIStorageUpgradeable,
    ERC2981Upgradeable,
    OwnableUpgradeable,
    UUPSUpgradeable
{
    uint256 private _tokenIdCounter;

    string public name;
    string public symbol;
    
    // Allowlist mapping
    mapping(address => bool) public isAllowlistAddress;

    error ArrayLengthMismatch();
    error TokenDoesNotExists();
    error Unauthorized();

    event UpdatedURIs(uint256[] tokenId, string[] newUri);
    event UpdatedDefaultRoyalty(address receiver, uint256 feeNumerator);

    modifier onlyAllowlistAddress() {
	if (!isAllowlistAddress[msg.sender]) {
            revert Unauthorized();
        }
        _;
    }
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initialize(
        string memory _name,
        string memory _symbol,
        address _initialOwner,
        address _royaltyReceiver,
        uint96 _royaltyFeeNumerator
    ) public initializer {
        __ERC1155Burnable_init();
        __ERC1155Supply_init();
        __ERC1155URIStorage_init();
        __UUPSUpgradeable_init();
        __ERC2981_init();
        __Ownable_init(_initialOwner);
        name = _name;
        symbol = _symbol;

        _setDefaultRoyalty(_royaltyReceiver, _royaltyFeeNumerator);
    }

    // Allowlist addresses
    function allowlistAddresses(address[] calldata wAddresses) public onlyOwner {
        for (uint i = 0; i < wAddresses.length; i++) {
            isAllowlistAddress[wAddresses[i]] = true;
        }
    }
    
    function whitelistMint(
        address to,
        uint256 amount,
        string memory tokenUri
    ) external  onlyAllowlistAddress {
        uint256 tokenId = _incrementTokenId();
        _setURI(tokenId, tokenUri);
        _mint(to, tokenId, amount, '');
    }


    function updateDefaultRoyalty(
        address receiver,
        uint96 feeNumerator
    ) external onlyOwner {
        _setDefaultRoyalty(receiver, feeNumerator);
        emit UpdatedDefaultRoyalty(receiver, feeNumerator);
    }

    function getLatestTokenId() external view returns (uint256) {
        return _tokenIdCounter;
    }


    function _incrementTokenId() internal returns (uint256) {
        return ++_tokenIdCounter;
    }

    function _update(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory values
    ) internal virtual override(ERC1155SupplyUpgradeable, ERC1155Upgradeable) {
        super._update(from, to, ids, values);
    }

    function uri(
        uint256 tokenId
    )
        public
        view
        virtual
        override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)
        returns (string memory)
    {
        return super.uri(tokenId);
    }

    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        override(ERC2981Upgradeable, ERC1155Upgradeable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    function _authorizeUpgrade(
        address newImplementation
    ) internal override onlyOwner {}
}

 

The AllowlistNFT contract is an ERC1155 token contract designed to provide exclusive access to a specific group of users. It features on-chain allowlist management, royalty settings, and a dynamic URI system. The contract uses OpenZeppelin's upgradeable libraries for flexibility and security. Key functions include whitelist minting, royalty updates, and token ID management. The contract also overrides necessary functions for compatibility with other standards and ensures secure access control through modifiers.

 

Also, Read | How to Create a Dynamic NFT

 

Initialization and Upgradeability

 

The contract is designed to be upgradeable, ensuring future modifications without redeploying.

 

Allowlist Management

 

The contract allows the owner to manage a list of addresses that are permitted to mint NFTs.

 

Minting Functionality

 

Only addresses on the allowlist can mint new NFTs.

 

Royalty Management

 

The contract supports royalty payments to the original creator of the NFT.

 

Token ID Management

 

The contract keeps track of the unique identifier for each minted NFT.

 

Internal Helper Functions

 

The contract includes internal functions to manage token IDs and update supply counts.\

 

Overriding Functions for Compatibility

 

The contract overrides necessary functions to interact with other standards like ERC2981.

 

Access Control

 

The contract ensures that only the contract owner and approved addresses can perform certain actions.

 

Also, Check | How to Create an ERC 721 NFT Token

 

Conclusion

 

In this guide, we've explored the implementation of an on-chain allowlist for an ERC1155 NFT project, highlighting the benefits and practical steps involved. By utilizing OpenZeppelin's upgradeable libraries, we've created a robust and secure smart contract that offers exclusive access to a specified group of users.

 

Key Takeaways

 

On-Chain Allowlist: Provides enhanced security and exclusivity by restricting access to NFT minting and transfers.
Upgradeable Smart Contract: Leverages OpenZeppelin's libraries to ensure flexibility and future-proofing.
Royalty Management: Ensures ongoing compensation for creators through built-in royalty settings.
Dynamic URI System: Allows for easy updates and management of NFT metadata.

 

By incorporating these features, your NFT project can effectively manage user access, maintain security, and ensure ongoing creator rewards. This approach not only enhances the functionality of your NFTs but also aligns with best practices in smart contract development.

 

Ready to take your NFT project to the next level? Connect with our skilled NFT developers to learn how we can help you implement a secure, upgradeable on-chain allowlist and other advanced features for your ERC1155 tokens!

Leave a

Comment

Name is required

Invalid Name

Comment is required

Recaptcha is required.

blog-detail

October 5, 2024 at 08:15 am

Your comment is awaiting moderation.

By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.

Chat with Us
Telegram Button
Youtube Button
Contact Us

Oodles | Blockchain Development Company

Name is required

Please enter a valid Name

Please enter a valid Phone Number

Please remove URL from text