Posted By : Suchit
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.
An on-chain allowlist offers several advantages for NFT projects:
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
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
The contract is designed to be upgradeable, ensuring future modifications without redeploying.
The contract allows the owner to manage a list of addresses that are permitted to mint NFTs.
Only addresses on the allowlist can mint new NFTs.
The contract supports royalty payments to the original creator of the NFT.
The contract keeps track of the unique identifier for each minted NFT.
The contract includes internal functions to manage token IDs and update supply counts.\
The contract overrides necessary functions to interact with other standards like ERC2981.
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
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.
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!
October 5, 2024 at 08:15 am
Your comment is awaiting moderation.