Asked in a discord community: How to create a non-transferable, burnable ERC721
1 Like
NonTransferrableERC721Token.sol
Uses OpenZeppelin 3.0 Release Candidate
This contract has not been tested nor audited
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/token/ERC721/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721Metadata.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract NonTransferrableERC721Token is ERC721Enumerable, ERC721Metadata, ERC721Burnable, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BASEURI_SETTER_ROLE = keccak256(
"BASEURI_SETTER_ROLE"
);
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() public ERC721Metadata("Simple ERC721 Token", "SIM") {
_grantRole(MINTER_ROLE, msg.sender);
_grantRole(BASEURI_SETTER_ROLE, msg.sender);
_setBaseURI("https://example.com/tokens/");
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
internal
virtual
override(ERC721Enumerable, ERC721Metadata, ERC721)
{
require(from == address(0) || to == address(0), "NonTransferrableERC721Token: non transferrable");
super._beforeTokenTransfer(from, to, tokenId);
}
function mint(address to) public {
require(
hasRole(MINTER_ROLE, msg.sender),
"NonTransferrableERC721Token: account does not have minter role"
);
_tokenIds.increment();
uint256 newTokenId = _tokenIds.current();
_mint(to, newTokenId);
_setTokenURI(newTokenId, Strings.fromUint256(newTokenId));
}
function setBaseURI(string memory baseURI) public {
require(
hasRole(BASEURI_SETTER_ROLE, msg.sender),
"NonTransferrableERC721Token: account does not have setter role"
);
_setBaseURI(baseURI);
}
}
1 Like
Looks good to me, thank you.