2023-06-14 14:34:43 +08:00

125 lines
3.1 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract NFTSbt is AccessControl, ERC721Enumerable {
using Counters for Counters.Counter;
string private _baseTokenURI = "https://market.cebg.games/api/nft/info/";
bytes32 public constant BURN_ROLE = keccak256("BURN_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
uint256 public immutable supplyLimit;
Counters.Counter private _tokenIdCounter;
constructor(
string memory _name,
string memory _symbol,
uint256 _supplyLimt
) ERC721(_name, _symbol) {
supplyLimit = _supplyLimt;
_setRoleAdmin(BURN_ROLE, DEFAULT_ADMIN_ROLE);
_setRoleAdmin(MINTER_ROLE, DEFAULT_ADMIN_ROLE);
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(MINTER_ROLE, msg.sender);
_setupRole(BURN_ROLE, msg.sender);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(
bytes4 interfaceId
)
public
view
virtual
override(AccessControl, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal override(ERC721Enumerable) {
require(from == address(0) || to == address(0), "Token not transferable");
super._beforeTokenTransfer(from, to, tokenId);
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
/**
* @dev Set token URI
*/
function updateBaseURI(
string calldata baseTokenURI
) external onlyRole(DEFAULT_ADMIN_ROLE) {
_baseTokenURI = baseTokenURI;
}
/**
* @dev one type nft has same tokenURI
*/
function tokenURI(
uint256 tokenId
) public view virtual override returns (string memory) {
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? baseURI : "";
}
function mint(address to) external onlyRole(MINTER_ROLE) returns (uint256) {
require(to != address(0), "Cannot mint to zero address");
if (supplyLimit > 0) {
require((totalSupply() + 1) <= supplyLimit, "Exceed the total supply");
}
_tokenIdCounter.increment();
uint256 tokenId = _tokenIdCounter.current();
_safeMint(to, tokenId);
return tokenId;
}
function burn(uint256 tokenId) external onlyRole(BURN_ROLE) {
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"Caller is not owner nor approved"
);
_burn(tokenId);
}
/**
* @dev Grant mint role to address
*/
function setMintRole(address to) external {
grantRole(MINTER_ROLE, to);
}
/**
* @dev Remove mint role to address
*/
function removeMintRole(address to) external {
revokeRole(MINTER_ROLE, to);
}
/**
* @dev Grant burn role to address
*/
function setBurnRole(address to) external {
grantRole(BURN_ROLE, to);
}
/**
* @dev Remove burn role to address
*/
function removeBurnRole(address to) external {
revokeRole(BURN_ROLE, to);
}
}