DEV Community

Discussion on: How to Build a Full Stack NFT Marketplace - V2 (2022)

Collapse
 
ssf profile image
Sione

if you have a setForSell function in the Market contract say after a user buys then decides to sell again, will you then need to transfer the token to the market address? like IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId). Because I have tried this and it is giving me error 'ERC721: transfer caller is not owner nor approved' but the owner of the token is the one making the transfer. Maybe im not doing something right. Please help

Collapse
 
mateusasferreira profile image
Mateus Ferreira

Hey, I'm having the same problem :( were you able to solve it since you posted this?

Collapse
 
ssf profile image
Sione

I have not. Still looking for a solution

Thread Thread
 
mateusasferreira profile image
Mateus Ferreira

Solved my issue yesterday by writing a custom function to tranfer tokens on my NFT contract. Like this:

contract NFT is ERC721URIStorage {
    (...)
    function transferToken(address from, address to, uint256 tokenId) external {
        require(ownerOf(tokenId) == from, "From address must be token owner");
        _transfer(from, to, tokenId);
    }
}
Enter fullscreen mode Exit fullscreen mode

And in my Market Contract:

import "./NFT.sol";

contract NFTMarket is ReentrancyGuard {
    (...)
    function putItemToResell(address nftContract, uint256 itemId, uint256 newPrice)
        public
        payable
        nonReentrant
        onlyItemOwner(itemId)
    {
        (...)
        uint256 tokenId = idToMarketItem[itemId].tokenId;

        NFT tokenContract = NFT(nftContract);

        tokenContract.transferToken(msg.sender, address(this), tokenId);        
    }

}
Enter fullscreen mode Exit fullscreen mode

Don't know all the implications of this solutions and if it may fail or cause security issues somehow but it solved my problem for know.

Thread Thread
 
ssf profile image
Sione

Thanks that solution works but I agree with the implications it may bring if any. Thank you though! Ill update you if I find another stable solution.

Thread Thread
 
mateusasferreira profile image
Mateus Ferreira

my pleasure! Keep me posted about the solutions you may find.

Thread Thread
 
javilonte profile image
Javilonte

Hi, thank you for posting this, i would like to use your function on my code but it says "onlyItemOwner(itemId)" never used, am i missing something? thanks again!

Thread Thread
 
mateusasferreira profile image
Mateus Ferreira

Hey there! its a modifier that you're missing. I added this to my contract so I can use it in functions to ensure only the item's owner can execute it:


    modifier onlyItemOwner(uint256 id) {
        require(
            idToMarketItem[id].owner == msg.sender,
            "Only product owner can do this operation"
        );
        _;
    }

Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
javilonte profile image
Javilonte

thanksss

Collapse
 
mateusasferreira profile image
Mateus Ferreira

Hey, I posted my entire solution for this issue, if somebody is still facing it:
dev.to/mateusasferreira/how-to-cre...
Hope it helps ;)

Collapse
 
yawnxyz profile image
Jan Z

There's a way to change the deploy script w/o changing the contract itself. This is happening because of a Mumbai error, outputting the wrong contract address. This causes the NFT contract to not approve the Marketplace's contract address to sell the NFTs. Redeploy with this script, by replacing main() in deploy.js with:

async function main() {
  const [deployer] = await hre.ethers.getSigners();

  console.log(
    "Deploying contracts with the account:",
    deployer.address
  );

  let txHash, txReceipt
  const NFTMarket = await hre.ethers.getContractFactory("NFTMarket");
  const nftMarket = await NFTMarket.deploy();
  await nftMarket.deployed();

  txHash = nftMarket.deployTransaction.hash;
  txReceipt = await ethers.provider.waitForTransaction(txHash);
  let nftMarketAddress = txReceipt.contractAddress

  console.log("nftMarket deployed to:", nftMarketAddress);

  const NFT = await hre.ethers.getContractFactory("NFT");
  const nft = await NFT.deploy(nftMarketAddress);
  await nft.deployed();


  txHash = nft.deployTransaction.hash;
  // console.log(`NFT hash: ${txHash}\nWaiting for transaction to be mined...`);
  txReceipt = await ethers.provider.waitForTransaction(txHash);
  let nftAddress = txReceipt.contractAddress

  console.log("nft deployed to:", nftAddress);
}
Enter fullscreen mode Exit fullscreen mode