contract HogeNFT is Context, AccessControl, ERC721Burnable, ERC721Pausable {
    using Counters for Counters.Counter;

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    Counters.Counter private _tokenIdTracker;

    event Received(address, uint);

    receive() external payable {
        emit Received(msg.sender, msg.value);
}

/**
 * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
 * account that deploys the contract.
 *
 * Token URIs will be autogenerated based on `baseURI` and their token IDs.
 * See {ERC721-tokenURI}.
 */
constructor(string memory name, string memory symbol, string memory baseURI) public ERC721(name, symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

_setupRole(MINTER_ROLE, _msgSender());
_setupRole(PAUSER_ROLE, _msgSender());

_setBaseURI(baseURI);
}

/**
 * @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, string memory uri) public returns (uint) {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint");

// We cannot just use balanceOf to create the new tokenId because tokens
// can be burned (destroyed), so we need a separate counter.
_safeMint(to, _tokenIdTracker.current());
_setTokenURI(_tokenIdTracker.current(), uri);
_tokenIdTracker.increment();
}

function mintBatch(address[] memory recipients, bytes32[] memory uri_bytes) public virtual {
require(hasRole(MINTER_ROLE, _msgSender()), "ERC1155PresetMinterPauser: must have minter role to mint");

string[] storage uris;

for (uint256 i = 0; i < uri_bytes.length; i++) {
uris.push(bytes32ToString(uri_bytes[i]));
}

for (uint256 i = 0; i < recipients.length; i++) {
_safeMint(recipients[i], _tokenIdTracker.current());
_setTokenURI(_tokenIdTracker.current(), uris[i]);
_tokenIdTracker.increment();
}
}

function bytes32ToString(bytes32 x) public returns (string memory) {
bytes memory bytesString = new bytes(32);
uint charCount = 0;
for (uint j = 0; j < 32; j++) {
byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
if (char != 0) {
bytesString[charCount] = char;
charCount++;
}
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (uint j = 0; j < charCount; j++) {
bytesStringTrimmed[j] = bytesString[j];
}
return string(bytesStringTrimmed);
}

/**
 * @dev Pauses all token transfers.
 *
 * See {ERC721Pausable} and {Pausable-_pause}.
 *
 * Requirements:
 *
 * - the caller must have the `PAUSER_ROLE`.
 */
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause");
_pause();
}

/**
 * @dev Unpauses all token transfers.
 *
 * See {ERC721Pausable} and {Pausable-_unpause}.
 *
 * Requirements:
 *
 * - the caller must have the `PAUSER_ROLE`.
 */
function unpause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause");
_unpause();
}

function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override(ERC721, ERC721Pausable) {
super._beforeTokenTransfer(from, to, tokenId);
}
}
function pause() public virtual {
require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause");
_pause();
}

/**
 * @dev Pauses all token transfers.
 *
 * See {ERC721Pausable} and {Pausable-_pause}.
 *
 * Requirements:
 *
 * - the caller must have the `PAUSER_ROLE`.
 */