forked from JessicaChg/semanticSBT
/
Follow.sol
99 lines (73 loc) · 2.94 KB
/
Follow.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "@openzeppelin/contracts/utils/Strings.sol";
import "../core/SemanticSBTUpgradeable.sol";
import "../interfaces/social/IFollow.sol";
contract Follow is IFollow, SemanticSBTUpgradeable {
using Strings for uint256;
using Strings for address;
SubjectPO[] private ownerSubjectPO;
uint256 constant FOLLOWING_PREDICATE_INDEX = 1;
uint256 constant SOUL_CLASS_INDEX = 1;
mapping(address => bool) _isFollowing;
address public representedAddress;
address public verifyContract;
modifier onlyVerifyContract{
require(msg.sender == verifyContract, "Follow: must be verify contract");
_;
}
/* ============ External Functions ============ */
function initialize(
address owner,
address minter,
address verifyContract_,
string memory name_,
string memory symbol_,
string memory baseURI_,
string memory schemaURI_,
string[] memory classes_,
Predicate[] memory predicates_
) external override {
super.initialize(minter, name_, symbol_, baseURI_, schemaURI_, classes_, predicates_);
_setOwner(owner);
verifyContract = verifyContract_;
}
function follow() external returns (uint256){
return _follow(msg.sender);
}
function unfollow() external returns (uint256){
return _unfollow(msg.sender);
}
function followBySigner(address addr) external onlyVerifyContract returns (uint256) {
return _follow(addr);
}
function unfollowBySigner(address addr) external onlyVerifyContract returns (uint256){
return _unfollow(addr);
}
function isFollowing(address addr) external view returns (bool){
return _isFollowing[addr];
}
function supportsInterface(bytes4 interfaceId) public view virtual override(SemanticSBTUpgradeable) returns (bool) {
return interfaceId == type(IFollow).interfaceId ||
super.supportsInterface(interfaceId);
}
/* ============ Internal Functions ============ */
function _setOwner(address owner) internal {
uint256 sIndex = SemanticSBTLogicUpgradeable.addSubject(owner.toHexString(), SOUL_CLASS_NAME, _subjects, _subjectIndex, _classIndex);
ownerSubjectPO.push(SubjectPO(FOLLOWING_PREDICATE_INDEX, sIndex));
representedAddress = owner;
}
function _follow(address addr) internal returns (uint256){
require(!_isFollowing[addr], "Follow:Already followed!");
_isFollowing[addr] = true;
uint256 tokenId = _addEmptyToken(addr, 0);
_mint(tokenId, addr, new IntPO[](0), new StringPO[](0), new AddressPO[](0), ownerSubjectPO, new BlankNodePO[](0));
return tokenId;
}
function _unfollow(address addr) internal returns (uint256){
uint256 tokenId = tokenOfOwnerByIndex(addr, 0);
super._burn(tokenId);
_isFollowing[addr] = false;
return tokenId;
}
}