forked from DecentralizedClimateFoundation/DCIPs
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;
|
||
|
}
|
||
|
}
|