2

我有一个 nftToken 合约,它将代币铸造到 msg.sender,然后我在市场合约中有一个功能,将 nft 从所有者转移到市场合约。但是,我收到一条错误消息:ERC721: transfer caller is not owner or approved。

这是我的 nftContract (nft) 函数片段:

   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;
  }

这是我的市场代码(stripeMarket Contract)功能片段:

  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);    
  }

在这里,我尝试使用 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}}); 
}

但我收到错误。任何帮助表示赞赏,谢谢!

4

1 回答 1

6

nftContract执行 时setApprovalForAll(contractAddress, true),它允许contractAddress(市场合约)操作所有的nftContract代币

但是新铸造的代币归msg.sender-而不是nftContract. 因此,批准不适用于此令牌。


根据您的用例,您可以

  1. 将新代币铸造到nftContract(而不是msg.sender),以便允许市场合约操作它。或者直接将其铸造到市场合约中。

    // the owner is the `nftContract`
    _mint(address(this), newItemId);
    
    // the Market contract is allowed to operate the `nftContract`'s tokens
    setApprovalForAll(contractAddress, true);
    
  2. msg.sender执行. approve(marketAddress, tokenId)_ nftContract_createItem()

    这将使市场合约批准操作由msg.sender. (假设它与 - 的地址相同,_owner否则它将失败。)

于 2021-09-26T08:28:28.500 回答