简体   繁体   English

如何使用版税调用 Openzeppelin safeTransferFrom() function 以避免错误,ERC721:所有者查询不存在的令牌?

[英]How to call Openzeppelin safeTransferFrom() function with Royalty to avoid error, ERC721: owner query for nonexistent token?

I am creating a smart contract using Openzeppelin NFT standard and code copied from Tatum, where the safeTransferFrom function looks like this,我正在使用 Openzeppelin NFT 标准和从 Tatum 复制的代码创建智能合约,其中safeTransferFrom function 看起来像这样,

function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata dataBytes
    ) public payable virtual override {
        uint256 index;
        uint256 value; // price 1000 matic
        uint256 percentSum;
        IERC20 token;
        (index, value) = _bytesCheck(dataBytes);

        // return error if token id is odd
        if (tokenId % 2 == 1) {
            
            //if block time is earlier than 2023 march 1 timestamp
            if (block.timestamp < 1677628800) {
                revert("You have to wait until 2023 March 1 to mint this token");
            }
          
        }

        if (_customToken[tokenId] != address(0)) {
            token = IERC20(_customToken[tokenId]);
        }
        if (_cashbackRecipients[tokenId].length > 0) {
            for (uint256 i = 0; i < _cashbackValues[tokenId].length; i++) {
                uint256 iPercent = (_cashbackValues[tokenId][i] * value) /
                    10000;
                if (iPercent >= _fixedValues[tokenId][i]) {
                    percentSum += iPercent;
                } else {
                    percentSum += _fixedValues[tokenId][i];
                }
            }
            if (_customToken[tokenId] == address(0)) {
                if (percentSum > msg.value) {
                    payable(from).transfer(msg.value);
                    revert(
                        "Value should be greater than or equal to cashback value"
                    );
                }
            } else {
                if (percentSum > token.allowance(to, address(this))) {
                    revert(
                        "Insufficient ERC20 allowance balance for paying for the asset."
                    );
                }
            }
            for (uint256 i = 0; i < _cashbackRecipients[tokenId].length; i++) {
                // transferring cashback to authors
                uint256 cbvalue = (_cashbackValues[tokenId][i] * value) / 10000;
                if (_customToken[tokenId] == address(0)) {
                    cbvalue = _cashbackCalculator(
                        cbvalue,
                        _fixedValues[tokenId][i]
                    );
                    payable(_cashbackRecipients[tokenId][i]).transfer(cbvalue);
                } else {
                    cbvalue = _cashbackCalculator(
                        cbvalue,
                        _fixedValues[tokenId][i]
                    );

                    token.transferFrom(
                        to,
                        _cashbackRecipients[tokenId][i],
                        cbvalue
                    );
                }
            }
            if (_customToken[tokenId] != address(0) && msg.value > 0) {
                payable(from).transfer(msg.value);
            }
            if (_customToken[tokenId] == address(0) && msg.value > percentSum) {
                payable(from).transfer(msg.value - percentSum);
            }
        }
        _safeTransfer(from, to, tokenId, dataBytes);
        string calldata dataString = string(dataBytes);
        _appendTokenData(tokenId, dataString);
        emit TransferWithProvenance(tokenId, to, dataString[:index], value);
    }

It pays royalty using the ERC721 standard.它使用 ERC721 标准支付版税。 I am calling this function like this,我这样称呼这个 function,

import { ethers } from "hardhat";

const contractAddressRoyalty = "0x1903344651b356ce3b755458008c0fe74f8cc1c9";

const trans = async () => {

  const CannesRoyalty = await ethers.getContractAt(
    "Cant",
    contractAddressRoyalty
  );

  const name = await CannesRoyalty.symbol();

  //   // transfer
  const safeTransferFrom = await CantRoyalty[
    "safeTransferFrom(address,address,uint256)"
  ](
    "0x888a7E4DAE1d9009694dEdf240F976EC498D7D90",
    "0x7542A9d09589B21b5a671e14254318D2016A0A0c",
    4,
    {
      from: "0x888a7E4DAE1d9009694dEdf240F976EC498D7D90",
      gasLimit: 2000000,
      gasPrice: ethers.utils.parseUnits("10", "gwei"),
      value: ethers.utils.parseEther("0"),
    }
  );
  console.log(safeTransferFrom);
  console.log(name);
};

trans();

I am getting this error, https://mumbai.polygonscan.com/tx/0xdefbb122ab45bb85c29ffda0a14b61b77564f2748ece65f87067e24b4624cfd5我收到此错误, https://mumbai.polygonscan.com/tx/0xdefbb122ab45bb85c29ffda0a14b61b77564f2748ece65f87067e24b4624cfd5

Message - Fail with error 'ERC721: owner query for nonexistent token'消息 -失败并出现错误“ERC721:所有者查询不存在的令牌”

But the token is minted.但是令牌是铸造的。 I have also approved.我也同意了。 I don't know if I am messing up the input values.我不知道我是否弄乱了输入值。 I have tried tokenId, 4 and "4".我试过 tokenId、4 和“4”。 But seems no luck.但似乎没有运气。

It appears the token you're trying to transfer is 'nonexistent'.您尝试转移的令牌似乎“不存在”。 This usually means that it wasn't minted yet.这通常意味着它还没有被铸造。 Can you verify if the tokenId 4 returns anything when you call the public function tokenUri with tokenId 4?当您使用 tokenId 4 调用公共 function tokenUri 时,您能否验证 tokenId 4 是否返回任何内容?

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

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