61 lines
1.8 KiB
Solidity
61 lines
1.8 KiB
Solidity
// SPDX-License-Identifier: CC0-1.0
|
|
|
|
pragma solidity ^0.8.16;
|
|
|
|
import "./IERC6381.sol";
|
|
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
|
|
|
|
contract EmotableRepository is IERC6381 {
|
|
// Used to avoid double emoting and control undoing
|
|
mapping(address => mapping(address => mapping(uint256 => mapping(bytes4 => uint256))))
|
|
private _emotesUsedByEmoter; // Cheaper than using a bool
|
|
mapping(address => mapping(uint256 => mapping(bytes4 => uint256)))
|
|
private _emotesPerToken;
|
|
|
|
function emoteCountOf(
|
|
address collection,
|
|
uint256 tokenId,
|
|
bytes4 emoji
|
|
) public view returns (uint256) {
|
|
return _emotesPerToken[collection][tokenId][emoji];
|
|
}
|
|
|
|
function hasEmoterUsedEmote(
|
|
address emoter,
|
|
address collection,
|
|
uint256 tokenId,
|
|
bytes4 emoji
|
|
) public view returns (bool) {
|
|
return _emotesUsedByEmoter[emoter][collection][tokenId][emoji] == 1;
|
|
}
|
|
|
|
function emote(
|
|
address collection,
|
|
uint256 tokenId,
|
|
bytes4 emoji,
|
|
bool state
|
|
) public {
|
|
bool currentVal = _emotesUsedByEmoter[msg.sender][collection][tokenId][
|
|
emoji
|
|
] == 1;
|
|
if (currentVal != state) {
|
|
if (state) {
|
|
_emotesPerToken[collection][tokenId][emoji] += 1;
|
|
} else {
|
|
_emotesPerToken[collection][tokenId][emoji] -= 1;
|
|
}
|
|
_emotesUsedByEmoter[msg.sender][collection][tokenId][emoji] = state
|
|
? 1
|
|
: 0;
|
|
emit Emoted(msg.sender, collection, tokenId, emoji, state);
|
|
}
|
|
}
|
|
|
|
function supportsInterface(
|
|
bytes4 interfaceId
|
|
) public view virtual returns (bool) {
|
|
return
|
|
interfaceId == type(IERC6381).interfaceId ||
|
|
interfaceId == type(IERC165).interfaceId;
|
|
}
|
|
} |