Thanks, got it working! Highly appreciate
Hello everyone! I am testing out the ethereum boilerplate mainly the ethereum NFT marketplace boilerplate but I wanted to ask is there some way that I make it so that the users can only strictly use my coin on the marketplace. Thanks in advance!
Yes it is possible, you just need to have that in your ERC20 coin defined/hard coded in your smart contract for more questions related to the NFT marketplace boilerplate, I recommend you to post your questions here, the creator of the boilerplate can help you directly there. Cheers~
ok thanks a lot appreciate it
Hi. How can I limit the NFTs displayed on “NFT Balances” to just one contract? I want to display all the NFTs the user owns for just one contract. I can do this with REST but unsure where to approach it in this boilerplate code.
When I go to transfer an NFT it gives me “Undefined” after all the steps. When I console.log all of the props they come up fine. Is there a setting missing?
Hello again, Still looking into this. Any help?
guys how do i paste my ABI into moralisdapprovider in string format like the video says
i was not able to figure out the issue. I have the test website at https://dex.swaptoken.com/1inch
I’m using the latest git pull.
Let me know what I’m missing here.
Thank you.
I got it to work. Thank you.
Thanks, ivan.
I’m now following the tutorial on YouTube(now reached the middle stage) (about 1 hour passed)
But i have a problem here on selling functionality.
Once I clicked on the Sell button, metamask window popup, but it says something has gone wrong.
I’ll attach the image now.
Can you tell me why this happens?
Thanks
thanks, YosephKS
Here’s my Sol code.
NFTBalance.jsx
import React, { useState } from "react";
import { useMoralis, useWeb3ExecuteFunction } from "react-moralis";
import { Card, Image, Tooltip, Modal, Input } from "antd";
import { useNFTBalance } from "hooks/useNFTBalance";
import { FileSearchOutlined, SendOutlined, ShoppingCartOutlined } from "@ant-design/icons";
import { useMoralisDapp } from "providers/MoralisDappProvider/MoralisDappProvider";
import { getExplorer } from "helpers/networks";
import { List } from "antd/lib/form/Form";
const { Meta } = Card;
const styles = {
NFTs: {
display: "flex",
flexWrap: "wrap",
WebkitBoxPack: "start",
justifyContent: "flex-start",
margin: "0 auto",
maxWidth: "1000px",
gap: "10px",
},
};
function NFTBalance() {
const { NFTBalance } = useNFTBalance();
const { chainId, marketAddress, contractABI } = useMoralisDapp();
const { Moralis } = useMoralis();
const [visible, setVisibility] = useState(false);
const [price, setPrice] = useState();
const [nftToSell, setNftToSell] = useState(null);
const [isPending, setIsPending] = useState(false);
const contractProcessor = useWeb3ExecuteFunction();
const contractABIJson = JSON.parse(contractABI);
const listItemFunction = "createMarketItem";
const list = async (nft, currentPrice) => {
const p = currentPrice * ("1e" + 18);
const ops = {
contractAddress: marketAddress,
functionName: listItemFunction,
abi: contractABIJson,
params: {
nftContract: nft.token_address,
tokenId: nft.token_id,
price: String(p)
}
}
await contractProcessor.fetch({
params: ops,
onSuccss: () => alert("item sold"),
onError: () => alert("Something went wrong!")
});
}
const handleSellClick = (nft) => {
setNftToSell(nft);
setVisibility(true);
};
return (
<>
<div style={styles.NFTs}>
{NFTBalance &&
NFTBalance.map((nft, index) => (
<Card
hoverable
actions={[
<Tooltip title="View On Blockexplorer">
<FileSearchOutlined
onClick={() =>
window.open(`${getExplorer(chainId)}address/${nft.token_address}`, "_blank")
}
/>
</Tooltip>,
<Tooltip title="Sell this NFT">
<ShoppingCartOutlined onClick={() => handleSellClick(nft)} />
</Tooltip>,
]}
style={{ width: 240, border: "2px solid #e7eaf3" }}
cover={
<Image
preview={false}
src={nft?.image || "error"}
fallback="data:image/png;base64,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"
alt=""
style={{ height: "300px" }}
/>
}
key={index}
>
<Meta title={nft.name} description={nft.token_address} />
</Card>
))}
</div>
<Modal
title={`Sell ${nftToSell?.name || "NFT"}`}
visible={visible}
onCancel={() => setVisibility(false)}
onOk={() => list(nftToSell, price)}
confirmLoading={isPending}
okText="Sell"
>
<img
src={nftToSell?.image}
style={{
width: "250px",
margin: "auto",
borderRadius: "10px",
marginBottom: "15px",
}}>
</img>
<Input autoFocus placeholder="Set Price in ETH" onChange={evt => setPrice(evt.target.value)}></Input>
</Modal>
</>
);
}
export default NFTBalance;
I mean like the smart contract solidity code
I used the code provided on GitHub as a sample.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol";
import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
import "github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol";
contract marketPlaceBoilerPlate is ReentrancyGuard {
using Counters for Counters.Counter;
Counters.Counter private _itemIds;
Counters.Counter private _itemsSold;
address public owner;
constructor() {
owner = msg.sender;
}
struct MarketItem {
uint itemId;
address nftContract;
uint256 tokenId;
address payable seller;
address payable owner;
uint256 price;
bool sold;
}
mapping(uint256 => MarketItem) private idToMarketItem;
event MarketItemCreated (
uint indexed itemId,
address indexed nftContract,
uint256 indexed tokenId,
address seller,
address owner,
uint256 price,
bool sold
);
event MarketItemSold (
uint indexed itemId,
address owner
);
function createMarketItem(
address nftContract,
uint256 tokenId,
uint256 price
) public payable nonReentrant {
require(price > 0, "Price must be greater than 0");
_itemIds.increment();
uint256 itemId = _itemIds.current();
idToMarketItem[itemId] = MarketItem(
itemId,
nftContract,
tokenId,
payable(msg.sender),
payable(address(0)),
price,
false
);
IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId);
emit MarketItemCreated(
itemId,
nftContract,
tokenId,
msg.sender,
address(0),
price,
false
);
}
function createMarketSale(
address nftContract,
uint256 itemId
) public payable nonReentrant {
uint price = idToMarketItem[itemId].price;
uint tokenId = idToMarketItem[itemId].tokenId;
bool sold = idToMarketItem[itemId].sold;
require(msg.value == price, "Please submit the asking price in order to complete the purchase");
require(sold != true, "This Sale has alredy finnished");
emit MarketItemSold(
itemId,
msg.sender
);
idToMarketItem[itemId].seller.transfer(msg.value);
IERC721(nftContract).transferFrom(address(this), msg.sender, tokenId);
idToMarketItem[itemId].owner = payable(msg.sender);
_itemsSold.increment();
idToMarketItem[itemId].sold = true;
}
function fetchMarketItems() public view returns (MarketItem[] memory) {
uint itemCount = _itemIds.current();
uint unsoldItemCount = _itemIds.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(0)) {
uint currentId = i + 1;
MarketItem storage currentItem = idToMarketItem[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
}
Looks like there is transferFrom
here to have the Marketplace contract to take ERC721 from your wallet
IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId);
So did you approve the transfer yet?
Can you explain in more details?
What shall I do now to fix this bug?
you just need to add a step in your app to do and approval for the martketplace smart contract on your ERC721 token that you want to sell/list
how can i do this?
the marketplace smart contract is only the receiver.
i cant find any differences in sol code that appear in the tutorial on youtube!
but no similar errors are on this video.
there must be something wrong or I missed here.
@ivan @Yomoo Hi,
Have three questions:
- Since we can’t add slippage fees above Moralis 1% slippage fees. How am I going to benefit from developing this project?
- Can anyone help with the code example of adding a token search box on the token drop-down menu?
- Can you guys help with pulling each token logo instead of loading all tokens’ Eth logo on the balance page?
Thank you!