I am developing a dapp/smart contract, where users will be able to sell/buy NFTs from each other (market). Users grant authority to the smart contract to sell any of their items on their behalf using the setApprovalForAll openzeppelin function. Once this authority granted, users can put their items on sale. I am having difficulty understanding how to actually execute a sale. If another user accesses the front-end dapp with their wallet to purchase an NFT from another user, since they are initiating the token transfer, the transfer fails since they are obviously not authorised to initiate this transfer (but only the owner and the contract are). How is this logic usually implemented in such smart contract so that the purchaser (initiating the transfer) has the ability to buy an item from another owner. Do I need to transfer the token ownership to the smart contract? I thought that the setApprovalForAll function was meant to avoid this.

 // Front-end Code
 let totAmount = price + commission
 this.contInst.methods.tokTransfer(tokOwner, this.account, aId, price, commission).send({
    from: this.account,
    value: this.web3.utils.toWei(totAmount, 'ether')
    }).then((receipt) => {

 // Smart Contract Code
 function tokTransfer(address payable from, address to, uint256 tokenId, uint256 price, uint256 commission) payable external {
    safeTransferFrom(from, to, tokenId);

Thank you. J

  • Please include more details. Which openzeppelin's contracts are you using ERC721, ERC1155? Who called setApprovalForAll? How was it called? Is market and token the same contract or two contracts?
    – Ismael
    Feb 27, 2021 at 15:51
  • Hi Ismael. I am using ERC721. The owner of the token called setApprovalForAll before putting his item on sale, from the front-end dapp using: this.contInst.methods.setApprovalForAll(this.contAdd, true).send({ from: this.account }). There is only one contract.
    – JF0001
    Feb 27, 2021 at 15:56
  • That call to setApprovalForAll allows this.contAdd to call transferFrom for tokens from this.account. Instead you want the token owner to call it like this: this.contInst.methods.setApprovalForAll(this.contInst.options.address, true).send({ from: tokOwner }).
    – Ismael
    Feb 27, 2021 at 18:29
  • Thank you Ismael. "this.account" in my code actually corresponds to the user (token owner) logged into the wallet calling the setApprovalForAll function. This code is working properly, for the contract does get approved for selling the owner's tokens. However, when it is time to purchase a token that was put on sale, the purchaser who initiates the call is obviously not authorised to perform the sell on the smart contract, but only the contract and the owner are. Furthermore, I am not sure I understand the this.contInst.options.address statement. Thank you again.
    – JF0001
    Feb 27, 2021 at 19:14
  • What I am trying to achieve is the following: The owner puts his token on sale. Logs out of the dapp. The purchaser logs into the app, and purchases the token that was put on sale. The contract needs to be authorised somehow to transfer that token from the seller, who is no longer logged in, to the purchaser, who initiates the purchase.
    – JF0001
    Feb 27, 2021 at 19:46


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.