2023-06-28 16:26:17 +08:00

163 lines
4.1 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
abstract contract BEBase is AccessControl, ERC721Enumerable, Ownable {
mapping(uint256 => bool) public lockedTokens;
string private _baseTokenURI = "https://market.cebg.games/api/nft/info/";
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURN_ROLE = keccak256("BURN_ROLE");
bytes32 public constant LOCK_ROLE = keccak256("LOCK_ROLE");
event Lock(uint256 indexed tokenId);
event UnLock(uint256 indexed tokenId);
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
/**
* @dev Creates a new token for `to`. Its token ID will be automatically
* assigned (and available on the emitted {IERC721-Transfer} event), and the token
* URI autogenerated based on the base URI passed at construction.
*
* See {ERC721-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(
address to,
uint256 tokenId
) external virtual onlyRole(MINTER_ROLE) {
require(!_exists(tokenId), "Must have unique tokenId");
_mint(to, tokenId);
}
/**
* @dev Add factory to mint item
*/
function setMintFactory(address factory) external onlyOwner {
_grantRole(MINTER_ROLE, factory);
}
/**
* @dev Remove factory
*/
function removeMintFactory(address factory) external onlyOwner {
_revokeRole(MINTER_ROLE, factory);
}
/**
* @dev Add factory to burn item
*/
function grantBurnRole(address proxy) external onlyOwner {
_grantRole(BURN_ROLE, proxy);
}
/**
* @dev Remove proxy
*/
function revokeBurnProxy(address proxy) external onlyOwner {
_revokeRole(BURN_ROLE, proxy);
}
/**
* @dev Add address to lock item
*/
function grantLockRole(address account) external onlyOwner {
_grantRole(LOCK_ROLE, account);
}
/**
* @dev Remove address for lock item
*/
function revokeLockRole(address account) external onlyOwner {
_revokeRole(LOCK_ROLE, account);
}
/**
* @dev Lock token to use in game or for rental
*/
function lock(uint256 tokenId) external onlyRole(LOCK_ROLE) {
require(_exists(tokenId), "Must be valid tokenId");
require(!lockedTokens[tokenId], "Token has already locked");
lockedTokens[tokenId] = true;
emit Lock(tokenId);
}
/**
* @dev Unlock token to use blockchain or sale on marketplace
*/
function unlock(uint256 tokenId) external onlyRole(LOCK_ROLE) {
require(_exists(tokenId), "Must be valid tokenId");
require(lockedTokens[tokenId], "Token has already unlocked");
lockedTokens[tokenId] = false;
emit UnLock(tokenId);
}
/**
* @dev Get lock status
*/
function isLocked(uint256 tokenId) external view returns (bool) {
return lockedTokens[tokenId];
}
/**
* @dev Set token URI
*/
function updateBaseURI(string calldata baseTokenURI) external onlyOwner {
_baseTokenURI = baseTokenURI;
}
/**
* @dev See {IERC165-_beforeTokenTransfer}.
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual override {
super._beforeTokenTransfer(from, to, firstTokenId, batchSize);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(
bytes4 interfaceId
)
public
view
virtual
override(AccessControl, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
/**
* @dev Burns `tokenId`.
*
* Requirements:
*
* - The caller must own `tokenId` or be an approved operator.
*/
function burn(
address owner,
uint256 tokenId
) external virtual onlyRole(BURN_ROLE) {
require(_exists(tokenId), "TokenId not exists");
require(!lockedTokens[tokenId], "Can not burn locked token");
require(
ownerOf(tokenId) == owner,
"current address is not owner of this item now"
);
_burn(tokenId);
}
}