简体   繁体   English

ERC721:转接呼叫者既不是所有者也不是批准的

[英]ERC721: transfer caller is not owner nor approved

I have a nftToken Contract that mints token to msg.sender, then I have a function in a market contract that transfers the nft from owner to market contract.我有一个 nftToken 合约,它将代币铸造到 msg.sender,然后我在市场合约中有一个 function,将 nft 从所有者转移到市场合约。 However, I am getting an error that says: ERC721: transfer caller is not owner nor approved.但是,我收到一条错误消息:ERC721: transfer caller is not owner or approved。

here is my nftContract (nft) function snippet:这是我的 nftContract (nft) function 片段:

function createToken(string memory tokenURI) public returns (uint) {
  _tokenIds.increment();
  uint256 newItemId = _tokenIds.current();

  _mint(msg.sender, newItemId);
  _setTokenURI(newItemId, tokenURI);
  setApprovalForAll(contractAddress, true);
  return newItemId;
}

here is my market code (stripeMarket Contract) function snippet:这是我的市场代码(stripeMarket Contract)function 片段:

function createItem(
    address nftContract,
    uint256 tokenId
    ) public payable{
     address _owner = IERC721(nftContract).ownerOf(tokenId);
     IERC721(nftContract).transferFrom(_owner, address(this),tokenId);
      IERC721(nftContract).approve(address(this),tokenId);    
}

and here I am trying to call it from the frontend with web3:在这里,我尝试使用 web3 从前端调用它:

const getItems=async()=>{
      await contracts.nft.methods.createToken("https://i.ytimg.com/vi/nYxGhQYi0s4/maxresdefault.jpg").send({from: accounts[0]});
      const owners = await contracts.nft.methods.ownerOf(1).call({from:accounts[0]});
      await contracts.stripeMarket.methods.createItem(contracts.nft._address,1).send({from: {owners}}); 
}

But I am getting the error:但我收到错误:

ERC721: transfer caller is not owner nor approved. ERC721:转接呼叫者既不是所有者也不是批准的。

When the nftContract executes the setApprovalForAll(contractAddress, true) , it allows the contractAddress (the Market contract) to operate all of the nftContract 's tokens .nftContract执行setApprovalForAll(contractAddress, true)时,它允许contractAddress (市场合约)操作所有nftContract的代币

But the newly minted token is owned by the msg.sender - not by the nftContract .但是新铸造的代币归msg.sender拥有,而不是nftContract So the approval does not apply to this token.因此,批准不适用于此令牌。


Depending on your use case, you can根据您的用例,您可以

  1. Mint the new token to the nftContract (instead of the msg.sender ) so that the Market contract is allowed to operate it.将新令牌铸造到nftContract (而不是msg.sender ),以便允许市场合约操作它。 Or mint it to the Market contract directly.或者直接将其铸造到市场合约中。

     // the owner is the `nftContract` _mint(address(this), newItemId); // the Market contract is allowed to operate the `nftContract`'s tokens setApprovalForAll(contractAddress, true);
  2. Have the msg.sender (the token owner) execute approve(marketAddress, tokenId) on the nftContract before executing the createItem() .在执行createItem()之前,让msg.sender (令牌所有者)在nftContract上执行approve(marketAddress, tokenId) ) 。

    This will give the Market contract approval to operate this particular token owned by the msg.sender .这将使市场合约批准操作msg.sender拥有的这个特定令牌。 (Assuming it's the same address as the _owner - otherwise it will fail.) (假设它与_owner的地址相同 - 否则它将失败。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM