-
-
Save dabit3/eb8866adc22bd86cabf5e6604b408e4a to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.4; | |
import "@openzeppelin/contracts/utils/Counters.sol"; | |
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; | |
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
import "hardhat/console.sol"; | |
contract NFTMarketplace is ERC721URIStorage { | |
using Counters for Counters.Counter; | |
Counters.Counter private _tokenIds; | |
Counters.Counter private _itemsSold; | |
uint256 listingPrice = 0.025 ether; | |
address payable owner; | |
mapping(uint256 => MarketItem) private idToMarketItem; | |
struct MarketItem { | |
uint256 tokenId; | |
address payable seller; | |
address payable owner; | |
uint256 price; | |
bool sold; | |
} | |
event MarketItemCreated ( | |
uint256 indexed tokenId, | |
address seller, | |
address owner, | |
uint256 price, | |
bool sold | |
); | |
constructor() ERC721("Metaverse Tokens", "METT") { | |
owner = payable(msg.sender); | |
} | |
/* Updates the listing price of the contract */ | |
function updateListingPrice(uint _listingPrice) public payable { | |
require(owner == msg.sender, "Only marketplace owner can update listing price."); | |
listingPrice = _listingPrice; | |
} | |
/* Returns the listing price of the contract */ | |
function getListingPrice() public view returns (uint256) { | |
return listingPrice; | |
} | |
/* Mints a token and lists it in the marketplace */ | |
function createToken(string memory tokenURI, uint256 price) public payable returns (uint) { | |
_tokenIds.increment(); | |
uint256 newTokenId = _tokenIds.current(); | |
_mint(msg.sender, newTokenId); | |
_setTokenURI(newTokenId, tokenURI); | |
createMarketItem(newTokenId, price); | |
return newTokenId; | |
} | |
function createMarketItem( | |
uint256 tokenId, | |
uint256 price | |
) private { | |
require(price > 0, "Price must be at least 1 wei"); | |
require(msg.value == listingPrice, "Price must be equal to listing price"); | |
idToMarketItem[tokenId] = MarketItem( | |
tokenId, | |
payable(msg.sender), | |
payable(address(this)), | |
price, | |
false | |
); | |
_transfer(msg.sender, address(this), tokenId); | |
emit MarketItemCreated( | |
tokenId, | |
msg.sender, | |
address(this), | |
price, | |
false | |
); | |
} | |
/* allows someone to resell a token they have purchased */ | |
function resellToken(uint256 tokenId, uint256 price) public payable { | |
require(idToMarketItem[tokenId].owner == msg.sender, "Only item owner can perform this operation"); | |
require(msg.value == listingPrice, "Price must be equal to listing price"); | |
idToMarketItem[tokenId].sold = false; | |
idToMarketItem[tokenId].price = price; | |
idToMarketItem[tokenId].seller = payable(msg.sender); | |
idToMarketItem[tokenId].owner = payable(address(this)); | |
_itemsSold.decrement(); | |
_transfer(msg.sender, address(this), tokenId); | |
} | |
/* Creates the sale of a marketplace item */ | |
/* Transfers ownership of the item, as well as funds between parties */ | |
function createMarketSale( | |
uint256 tokenId | |
) public payable { | |
uint price = idToMarketItem[tokenId].price; | |
address seller = idToMarketItem[tokenId].seller; | |
require(msg.value == price, "Please submit the asking price in order to complete the purchase"); | |
idToMarketItem[tokenId].owner = payable(msg.sender); | |
idToMarketItem[tokenId].sold = true; | |
idToMarketItem[tokenId].seller = payable(address(0)); | |
_itemsSold.increment(); | |
_transfer(address(this), msg.sender, tokenId); | |
payable(owner).transfer(listingPrice); | |
payable(seller).transfer(msg.value); | |
} | |
/* Returns all unsold market items */ | |
function fetchMarketItems() public view returns (MarketItem[] memory) { | |
uint itemCount = _tokenIds.current(); | |
uint unsoldItemCount = _tokenIds.current() - _itemsSold.current(); | |
uint currentIndex = 0; | |
MarketItem[] memory items = new MarketItem[](unsoldItemCount); | |
for (uint i = 0; i < itemCount; i++) { | |
if (idToMarketItem[i + 1].owner == address(this)) { | |
uint currentId = i + 1; | |
MarketItem storage currentItem = idToMarketItem[currentId]; | |
items[currentIndex] = currentItem; | |
currentIndex += 1; | |
} | |
} | |
return items; | |
} | |
/* Returns only items that a user has purchased */ | |
function fetchMyNFTs() public view returns (MarketItem[] memory) { | |
uint totalItemCount = _tokenIds.current(); | |
uint itemCount = 0; | |
uint currentIndex = 0; | |
for (uint i = 0; i < totalItemCount; i++) { | |
if (idToMarketItem[i + 1].owner == msg.sender) { | |
itemCount += 1; | |
} | |
} | |
MarketItem[] memory items = new MarketItem[](itemCount); | |
for (uint i = 0; i < totalItemCount; i++) { | |
if (idToMarketItem[i + 1].owner == msg.sender) { | |
uint currentId = i + 1; | |
MarketItem storage currentItem = idToMarketItem[currentId]; | |
items[currentIndex] = currentItem; | |
currentIndex += 1; | |
} | |
} | |
return items; | |
} | |
/* Returns only items a user has listed */ | |
function fetchItemsListed() public view returns (MarketItem[] memory) { | |
uint totalItemCount = _tokenIds.current(); | |
uint itemCount = 0; | |
uint currentIndex = 0; | |
for (uint i = 0; i < totalItemCount; i++) { | |
if (idToMarketItem[i + 1].seller == msg.sender) { | |
itemCount += 1; | |
} | |
} | |
MarketItem[] memory items = new MarketItem[](itemCount); | |
for (uint i = 0; i < totalItemCount; i++) { | |
if (idToMarketItem[i + 1].seller == msg.sender) { | |
uint currentId = i + 1; | |
MarketItem storage currentItem = idToMarketItem[currentId]; | |
items[currentIndex] = currentItem; | |
currentIndex += 1; | |
} | |
} | |
return items; | |
} | |
} |
Any idea or resource for creating multiple collections? I am currently thinking of using Clones.clone(MarketAddress) to create several collections and saving references in the calling smart contract.
NB: I'm a Newbie
Hi @itzomen I'm trying to create NFT Marketplace that support creating new collection and more features. Hope this helps. https://github.com/kofkuiper/kuiper-nft-marketplace
Hi @itzomen I'm trying to create NFT Marketplace that support creating new collection and more features. Hope this helps. https://github.com/kofkuiper/kuiper-nft-marketplace
Thanks taking a look
Can I use this market place contract for my contract written with the ERC1155 standard, or should I rewrite the marketplace contract with ERC1155 from the beginning?
Hi @itzomen I'm trying to create NFT Marketplace that support creating new collection and more features. Hope this helps. https://github.com/kofkuiper/kuiper-nft-marketplace
Hy Kofkuiper, this repo is amazing, wondering if could ask you some questions
Hey @AbuSantos, Sure. What is it?
Is it better to abstract the market place from the NFT contract so NFTs from different collections can be sold?
@chajaykrishna the reasoning for this lies within the need to declare the storage keyword. Since we are iterating through a for loop and will need to access multiple instances of the
currentItem
, in order to add eachcurrentItem
into theitems
array need to place, and then access them via the storage area of the smart contract. More on the storage keyword here.