@@ -21,8 +21,24 @@ contract BasedShop {
2121 uint256 indexed articleId ,
2222 address indexed user ,
2323 string tokenURI ,
24+ uint256 date ,
25+ uint256 price ,
26+ uint256 amount
27+ );
28+ event ArticleBought (
29+ uint256 indexed articleId ,
30+ address indexed buyer ,
31+ address indexed seller ,
32+ uint256 price ,
2433 uint256 date
2534 );
35+ event ArticlePriceUpdated (
36+ uint256 indexed articleId , uint256 oldPrice , uint256 newPrice
37+ );
38+
39+ event ArticleAmountUpdated (
40+ uint256 indexed articleId , uint256 oldAmount , uint256 newAmount
41+ );
2642 event ArticleDeleted (uint256 indexed articleId , uint256 date );
2743 event ArticleLiked (
2844 uint256 indexed articleID , address indexed user , uint256 date
@@ -43,7 +59,7 @@ contract BasedShop {
4359 event ArticleBookmarked (
4460 uint256 indexed articleID , address indexed user , uint256 date
4561 );
46- event ArticleUnshared (
62+ event RemoveBookmark (
4763 uint256 indexed articleID , address indexed user , uint256 date
4864 );
4965 event UserFollowed (
@@ -67,6 +83,11 @@ contract BasedShop {
6783 mapping (uint256 => address ) public articleIdToUser;
6884 mapping (address => uint256 []) public userArticles;
6985
86+ // Article details
87+ mapping (uint256 => uint256 ) public articlePrices;
88+ mapping (uint256 => uint256 ) public articleAmounts;
89+ mapping (uint256 => mapping (address => bool )) public articleBuyers;
90+
7091 // Likes
7192 mapping (uint256 article = > uint256 likes ) public articleToLikes;
7293 mapping (address user = > mapping (uint256 article = > bool liked )) public
@@ -78,7 +99,10 @@ contract BasedShop {
7899 public articleCommentToUser;
79100
80101 // Bookmarked
81- mapping (address user = > uint256 [] sharedArticles ) public
102+ mapping (address user = > mapping (uint256 article = > bool )) public
103+ userToArticleBookmark;
104+ mapping (uint256 article = > uint256 bookmarks ) public articleToBookmarks;
105+ mapping (address user = > uint256 [] bookmarkedArticles ) public
82106 userToBookmarkedArticles;
83107 mapping (address user = > mapping (uint256 article = > uint256 index )) public
84108 userToBookmarkedArticleIndex;
@@ -103,15 +127,67 @@ contract BasedShop {
103127 //////////////////////////////////////////////////////////////*/
104128
105129 function createArticle (
106- string memory _tokenURI
130+ string memory _tokenURI ,
131+ uint256 _price ,
132+ uint256 _amount
107133 ) public {
108134 uint256 articleId = articleIds++ ;
109135 articleIdToUser[articleId] = msg .sender ;
110136 userArticles[msg .sender ].push (articleId);
111137
138+ articlePrices[articleId] = _price;
139+ articleAmounts[articleId] = _amount;
140+
112141 basedArticles.mint (_tokenURI);
113142
114- emit ArticleCreated (articleId, msg .sender , _tokenURI, block .timestamp );
143+ emit ArticleCreated (
144+ articleId, msg .sender , _tokenURI, block .timestamp , _price, _amount
145+ );
146+ }
147+
148+ function buyArticle (
149+ uint256 _articleId
150+ ) public payable {
151+ require (articleAmounts[_articleId] > 0 , "Article is sold out " );
152+ uint256 price = articlePrices[_articleId];
153+ require (msg .value >= price, "Not enough ETH sent " );
154+
155+ address seller = articleIdToUser[_articleId];
156+ require (seller != address (0 ), "Invalid seller address " );
157+
158+ // Transfer the ETH to the seller
159+ (bool success ,) = seller.call { value: msg .value }("" );
160+ require (success, "Transfer failed " );
161+
162+ // Decrease the amount of the article by one
163+ articleAmounts[_articleId]-- ;
164+
165+ // Record the buyer
166+ articleBuyers[_articleId][msg .sender ] = true ;
167+
168+ emit ArticleBought (_articleId, msg .sender , seller, price, block .timestamp );
169+ }
170+
171+ function updateArticlePrice (uint256 _articleId , uint256 _newPrice ) public {
172+ require (
173+ articleIdToUser[_articleId] == msg .sender , "Not the owner of the article "
174+ );
175+
176+ uint256 oldPrice = articlePrices[_articleId];
177+ articlePrices[_articleId] = _newPrice;
178+
179+ emit ArticlePriceUpdated (_articleId, oldPrice, _newPrice);
180+ }
181+
182+ function updateArticleAmount (uint256 _articleId , uint256 _newAmount ) public {
183+ require (
184+ articleIdToUser[_articleId] == msg .sender , "Not the owner of the article "
185+ );
186+
187+ uint256 oldAmount = articleAmounts[_articleId];
188+ articleAmounts[_articleId] = _newAmount;
189+
190+ emit ArticleAmountUpdated (_articleId, oldAmount, _newAmount);
115191 }
116192
117193 function deleteArticle (
@@ -123,85 +199,118 @@ contract BasedShop {
123199
124200 basedArticles.burn (_articleId);
125201
202+ // Remove the price and amount data
203+ delete articlePrices[_articleId];
204+ delete articleAmounts[_articleId];
205+
206+ // Remove the articleId to user mapping
207+ delete articleIdToUser[_articleId];
208+
126209 emit ArticleDeleted (_articleId, block .timestamp );
127210 }
128211
129212 function likeArticle (
130- uint256 _articleID
213+ uint256 _articleId
131214 ) public {
132- _requireArticleExists (_articleID);
133215 require (
134- ! userToArticleLikes[msg .sender ][_articleID],
216+ articleBuyers[_articleId][msg .sender ],
217+ "You must buy the article to like it "
218+ );
219+ _requireArticleExists (_articleId);
220+ require (
221+ ! userToArticleLikes[msg .sender ][_articleId],
135222 "You have already liked this article "
136223 );
137- userToArticleLikes[msg .sender ][_articleID ] = true ;
138- articleToLikes[_articleID ]++ ;
139- emit ArticleLiked (_articleID , msg .sender , block .timestamp );
224+ userToArticleLikes[msg .sender ][_articleId ] = true ;
225+ articleToLikes[_articleId ]++ ;
226+ emit ArticleLiked (_articleId , msg .sender , block .timestamp );
140227 }
141228
142229 function unlikeArticle (
143- uint256 _articleID
230+ uint256 _articleId
144231 ) public {
145- _requireArticleExists (_articleID );
232+ _requireArticleExists (_articleId );
146233 require (
147- userToArticleLikes[msg .sender ][_articleID ],
234+ userToArticleLikes[msg .sender ][_articleId ],
148235 "You have not liked this article yet "
149236 );
150- userToArticleLikes[msg .sender ][_articleID ] = false ;
151- articleToLikes[_articleID ]-- ;
152- emit ArticleUnliked (_articleID , msg .sender , block .timestamp );
237+ userToArticleLikes[msg .sender ][_articleId ] = false ;
238+ articleToLikes[_articleId ]-- ;
239+ emit ArticleUnliked (_articleId , msg .sender , block .timestamp );
153240 }
154241
155- function commentOnArticle (uint256 _articleID , string memory _text ) public {
156- _requireArticleExists (_articleID);
242+ function commentOnArticle (uint256 _articleId , string memory _text ) public {
243+ require (
244+ articleBuyers[_articleId][msg .sender ],
245+ "You must buy the article to comment on it "
246+ );
247+ _requireArticleExists (_articleId);
157248 // set max length at 250 characters
158249 require (
159250 bytes (_text).length <= 250 , "Comment must be less than 250 characters "
160251 );
161- uint256 commentIndex = articleToComments[_articleID ].length ;
162- articleToComments[_articleID ].push (Comment (msg .sender , _text, commentIndex));
252+ uint256 commentIndex = articleToComments[_articleId ].length ;
253+ articleToComments[_articleId ].push (Comment (msg .sender , _text, commentIndex));
163254 emit ArticleCommented (
164- _articleID , msg .sender , _text, commentIndex, block .timestamp
255+ _articleId , msg .sender , _text, commentIndex, block .timestamp
165256 );
166257 }
167258
168- function deleteComment (uint256 _articleID , uint256 _commentID ) public {
169- _requireArticleExists (_articleID );
259+ function deleteComment (uint256 _articleId , uint256 _commentID ) public {
260+ _requireArticleExists (_articleId );
170261 require (
171- articleCommentToUser[_articleID ][_commentID] == msg .sender ,
262+ articleCommentToUser[_articleId ][_commentID] == msg .sender ,
172263 "You can't erase what you didn't article! "
173264 );
174- delete articleCommentToUser[_articleID ][_commentID];
175- delete articleToComments[_articleID ][_commentID];
176- emit ArticleCommentDeleted (_articleID , msg .sender , block .timestamp );
265+ delete articleCommentToUser[_articleId ][_commentID];
266+ delete articleToComments[_articleId ][_commentID];
267+ emit ArticleCommentDeleted (_articleId , msg .sender , block .timestamp );
177268 }
178269
179- function shareArticle (
180- uint256 _articleID
181- ) public {
182- _requireArticleExists (_articleID);
183- userToBookmarkedArticles[msg .sender ].push (_articleID);
184- // userToBookmarkedArticleIndex[msg.sender][_articleID] =
185- // userToBookmarkedArticles[msg.sender].length - 1;
186- emit ArticleBookmarked (_articleID, msg .sender , block .timestamp );
270+ // Function to bookmark an article
271+ function bookmarkArticle (
272+ uint256 _articleId
273+ ) external {
274+ _requireArticleExists (_articleId);
275+ require (
276+ ! userToArticleBookmark[msg .sender ][_articleId],
277+ "Article already bookmarked "
278+ );
279+
280+ userToArticleBookmark[msg .sender ][_articleId] = true ;
281+ articleToBookmarks[_articleId] += 1 ;
282+
283+ userToBookmarkedArticles[msg .sender ].push (_articleId);
284+ userToBookmarkedArticleIndex[msg .sender ][_articleId] =
285+ userToBookmarkedArticles[msg .sender ].length - 1 ;
286+
287+ emit ArticleBookmarked (_articleId, msg .sender , block .timestamp );
187288 }
188289
189- function deleteBookmarkedArticle (
190- uint256 _articleID
290+ function removeBookmark (
291+ uint256 _articleId
191292 ) public {
192- _requireArticleExists (_articleID);
293+ _requireArticleExists (_articleId);
294+
295+ require (
296+ userToArticleBookmark[msg .sender ][_articleId], "Article not bookmarked "
297+ );
298+
299+ userToArticleBookmark[msg .sender ][_articleId] = false ;
300+ articleToBookmarks[_articleId] -= 1 ;
193301
194- // Retrieve the index of the article to be deleted
195- uint256 index = userToBookmarkedArticleIndex[msg .sender ][_articleID];
302+ uint256 index = userToBookmarkedArticleIndex[msg .sender ][_articleId];
303+ uint256 lastArticleId = userToBookmarkedArticles[msg .sender ][userToBookmarkedArticles[msg
304+ .sender].length - 1 ];
196305
197- // Set the article to a default value (e.g., 0)
198- userToBookmarkedArticles [msg .sender ][index ] = 0 ;
306+ userToBookmarkedArticles[ msg . sender ][index] = lastArticleId;
307+ userToBookmarkedArticleIndex [msg .sender ][lastArticleId ] = index ;
199308
200- // Delete the index entry for the deleted article
201- delete userToBookmarkedArticleIndex[msg .sender ][_articleID ];
309+ userToBookmarkedArticles[ msg . sender ]. pop ();
310+ delete userToBookmarkedArticleIndex[msg .sender ][_articleId ];
202311
203312 // Emit the ArticleUnshared event
204- emit ArticleUnshared (_articleID , msg .sender , block .timestamp );
313+ emit RemoveBookmark (_articleId , msg .sender , block .timestamp );
205314 }
206315
207316 function followUser (
@@ -244,8 +353,8 @@ contract BasedShop {
244353 //////////////////////////////////////////////////////////////*/
245354
246355 function _requireArticleExists (
247- uint256 _articleID
356+ uint256 _articleId
248357 ) internal view {
249- require (basedArticles.tokenId () >= _articleID , "Article does not exist " );
358+ require (basedArticles.tokenId () >= _articleId , "Article does not exist " );
250359 }
251360}
0 commit comments