@@ -10,6 +10,8 @@ contract Project is IProject, OwnableUpgradeable, ERC721Upgradeable {
1010 event SetMinter (address indexed minter );
1111 event SetName (uint256 indexed projectId , string name );
1212 event AddMetadata (uint256 indexed projectId , string name , bytes32 key , bytes value );
13+ event AddOperator (uint256 indexed projectId , address operator );
14+ event RemoveOperator (uint256 indexed projectId , address operator );
1315
1416 address public minter;
1517 uint256 nextProjectId;
@@ -18,6 +20,22 @@ contract Project is IProject, OwnableUpgradeable, ERC721Upgradeable {
1820 mapping (uint256 => string ) names;
1921 mapping (uint256 => uint8 ) types;
2022 mapping (uint256 => mapping (bytes32 => bytes )) _metadata;
23+ mapping (uint256 => mapping (address => bool )) operators;
24+
25+ modifier onlyMinter () {
26+ require (msg .sender == minter, "not minter " );
27+ _;
28+ }
29+
30+ modifier onlyProjectOwner (uint256 projectId ) {
31+ require (msg .sender == ownerOf (projectId), "invalid owner " );
32+ _;
33+ }
34+
35+ modifier onlyProjectOperator (uint256 projectId ) {
36+ require (msg .sender == ownerOf (projectId) || operators[projectId][msg .sender ], "invalid operator " );
37+ _;
38+ }
2139
2240 function initialize (string calldata _name , string calldata _symbol ) public initializer {
2341 __Ownable_init ();
@@ -26,9 +44,7 @@ contract Project is IProject, OwnableUpgradeable, ERC721Upgradeable {
2644 }
2745
2846 // @deprecated
29- function mint (address _owner ) external returns (uint256 projectId_ ) {
30- require (msg .sender == minter, "not minter " );
31-
47+ function mint (address _owner ) external onlyMinter returns (uint256 projectId_ ) {
3248 projectId_ = ++ nextProjectId;
3349 _mint (_owner, projectId_);
3450 }
@@ -41,8 +57,11 @@ contract Project is IProject, OwnableUpgradeable, ERC721Upgradeable {
4157 return _mintProject (_owner, _name, _type);
4258 }
4359
44- function _mintProject (address _owner , string calldata _name , uint8 _type ) internal returns (uint256 projectId_ ) {
45- require (msg .sender == minter, "not minter " );
60+ function _mintProject (
61+ address _owner ,
62+ string calldata _name ,
63+ uint8 _type
64+ ) internal onlyMinter returns (uint256 projectId_ ) {
4665 bytes32 _nameHash = keccak256 (abi.encodePacked (_name));
4766 require (_nameHash != EMPTY_NAME_HASH, "empty name " );
4867 require (! nameHashes[_nameHash], "exist name " );
@@ -72,15 +91,18 @@ contract Project is IProject, OwnableUpgradeable, ERC721Upgradeable {
7291 return _metadata[_projectId][_key];
7392 }
7493
75- function setMetadata (uint256 _projectId , string calldata _name , bytes calldata _value ) external {
76- require (msg .sender == ownerOf (_projectId), "invalid owner " );
94+ function setMetadata (
95+ uint256 _projectId ,
96+ string calldata _name ,
97+ bytes calldata _value
98+ ) external onlyProjectOperator (_projectId) {
7799 bytes32 _key = keccak256 (abi.encodePacked (_name));
78100
79101 _metadata[_projectId][_key] = _value;
80102 emit AddMetadata (_projectId, _name, _key, _value);
81103 }
82104
83- function setName (uint256 _projectId , string calldata _name ) external {
105+ function setName (uint256 _projectId , string calldata _name ) external onlyProjectOwner (_projectId) {
84106 require (msg .sender == ownerOf (_projectId), "invalid owner " );
85107 bytes32 _nameHash = keccak256 (abi.encodePacked (_name));
86108 require (_nameHash != EMPTY_NAME_HASH, "empty name " );
@@ -95,6 +117,20 @@ contract Project is IProject, OwnableUpgradeable, ERC721Upgradeable {
95117 emit SetName (_projectId, _name);
96118 }
97119
120+ function addOperator (uint256 _projectId , address _operator ) external onlyProjectOwner (_projectId) {
121+ require (! operators[_projectId][_operator], "already operator " );
122+
123+ operators[_projectId][_operator] = true ;
124+ emit AddOperator (_projectId, _operator);
125+ }
126+
127+ function removeOperator (uint256 _projectId , address _operator ) external onlyProjectOwner (_projectId) {
128+ require (operators[_projectId][_operator], "not operator " );
129+
130+ operators[_projectId][_operator] = false ;
131+ emit RemoveOperator (_projectId, _operator);
132+ }
133+
98134 function setMinter (address _minter ) public onlyOwner {
99135 minter = _minter;
100136
0 commit comments