Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update CeloNFT.sol #2

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 48 additions & 119 deletions contract/contracts/CeloNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,161 +6,90 @@ import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract CeloNFT is ERC721URIStorage {

/// @notice implement the Counter libarary for counting tokenId
using Counters for Counters.Counter;
Counters.Counter private _tokenId; // tokenId
Counters.Counter private _soldItems; // total items
Counters.Counter private _tokenId;
address payable owner;
mapping (uint256 => NFT) NFT_ID;

// nft struct
struct NFT {
mapping(uint256 => NFT) private nfts;
mapping(address => uint256[]) private ownedNFTs;

struct NFT {
address owner;
address seller;
uint256 price;
bool sold;
uint256 tokenId;
}

/// @notice NFT event action
/// @dev handled all events related to nfts in the contract
/// @param tokenId, @param owner, @param seller, @param price, @param sold
event NFT_Action(
uint256 tokenId,
address owner,
address seller,
uint256 price,
bool sold,
string message
);


constructor() ERC721("CeloNFT", "ASG"){
constructor() ERC721("CeloNFT", "ASG") {
owner = payable(msg.sender);
}

/// @dev mint token , set tokenURI and return currentTokenId
/// @param _tokenURI, a tokenURI obtained from IPFS
/// @return currentTokenId, current token id
function createToken(string memory _tokenURI, uint256 price) external returns(uint256) {
_tokenId.increment(); // increment tokenId
uint256 currentTokenId = _tokenId.current(); // get current tokenId
_mint(msg.sender,currentTokenId); // mint token
_setTokenURI(currentTokenId,_tokenURI); // set token uri from IPFS
createNFT(currentTokenId,price);
function createToken(string memory _tokenURI, uint256 price) external returns (uint256) {
_tokenId.increment();
uint256 currentTokenId = _tokenId.current();
_mint(msg.sender, currentTokenId);
_setTokenURI(currentTokenId, _tokenURI);
createNFT(currentTokenId, price);
return currentTokenId;
}

function createNFT(uint256 tokenId, uint256 price) internal {
uint256 currentTokenId = _tokenId.current();
NFT_ID[currentTokenId] = NFT(
payable(address(this)),
payable(msg.sender),
price,
false,
tokenId
);

_transfer(msg.sender,address(this),tokenId); // transfer ownership of nft to the marketplace owner

emit NFT_Action(
tokenId,
address(this),
msg.sender,
price,
false,
"NFT created successfuly"
);

function createNFT(uint256 tokenId, uint256 price) internal {
nfts[tokenId] = NFT(payable(msg.sender), price, false);
ownedNFTs[msg.sender].push(tokenId);
emit NFT_Action(tokenId, msg.sender, price, false, "NFT created successfully");
}

/// @dev NFT sales functionality and process payment to seller
/// @param tokenId, NFT token id
function sellNFT(uint256 tokenId) external payable {
uint256 _price = NFT_ID[tokenId].price;
address seller = NFT_ID[tokenId].seller;
require(msg.value == _price, "incorrect amount");
(bool success,) = payable(seller).call{value : _price}(""); // make payment to seller
require(success, "payment failed");
NFT_ID[tokenId].owner = payable(msg.sender);
NFT_ID[tokenId].seller = payable(address(0)); // set seller to empty address
NFT_ID[tokenId].sold = true;
_soldItems.increment();
_transfer(address(this),msg.sender,tokenId); // transfer ownership to sender

emit NFT_Action(
tokenId,
msg.sender,
address(0),
_price,
true,
"Sold NFT successfully"
);
require(ownerOf(tokenId) == msg.sender, "You don't own this NFT");
uint256 _price = nfts[tokenId].price;
require(msg.value == _price, "Incorrect amount sent");
(bool success, ) = payable(owner).call{value: _price}("");
require(success, "Payment to seller failed");

nfts[tokenId].owner = payable(msg.sender);
nfts[tokenId].sold = true;

_transfer(msg.sender, address(this), tokenId);
emit NFT_Action(tokenId, msg.sender, _price, true, "Sold NFT successfully");
}

/// @notice All nfts retrieval,
/// @return props
function allNfts() external view returns (NFT[] memory) {
uint currentTokenId = _tokenId.current();
NFT[] memory items = new NFT[](currentTokenId);
for (uint i = 0; i < items.length; i++) {
items[i] = NFT_ID[i + 1];
uint256 count = 0;
for (uint256 i = 1; i <= _tokenId.current(); i++) {
if (!nfts[i].sold) {
count++;
}
}

return items;
}
NFT[] memory items = new NFT[](count);
uint256 index = 0;
for (uint256 i = 1; i <= _tokenId.current(); i++) {
if (!nfts[i].sold) {
items[index] = nfts[i];
index++;
}
}

/// @notice retrieval of single nft
/// @return props
function singleNFT(uint256 tokenId) external view returns(NFT memory props){
props = NFT_ID[tokenId];
return items;
}

/// @notice retrieval of all purchased nfts that belong to a user
/// @return props
function userNfts() external view returns (NFT[] memory) {
uint currentTokenId = _tokenId.current();
uint itemCount = 0;

for (uint i = 1; i <= currentTokenId; i++) {
if (NFT_ID[i].owner == msg.sender) {
itemCount++;
uint256[] memory userNFTs = ownedNFTs[msg.sender];
NFT[] memory items = new NFT[](userNFTs.length);
for (uint256 i = 0; i < userNFTs.length; i++) {
items[i] = nfts[userNFTs[i]];
}
return items;
}

NFT[] memory items = new NFT[](itemCount);
itemCount = 0;

// Populate the array with user's NFTs
for (uint i = 1; i <= currentTokenId; i++) {
if (NFT_ID[i].owner == msg.sender) {
items[itemCount] = NFT_ID[i];
itemCount++;
}
function getNftPrice(uint256 tokenId) external view returns (uint256) {
return nfts[tokenId].price;
}

return items;
}

/// @notice retrieve nft price
/// @param tokenId ,tokenId
/// @return uint256
function getNftPrice(uint256 tokenId) external view returns(uint256){
return NFT_ID[tokenId].price;
}














}