如何使用特许权使用费来调用OpenZeppelin Safetransfrom()函数以避免错误,ERC721:所有者查询不存在的令牌?

发布于 2025-01-29 18:01:56 字数 4599 浏览 2 评论 0 原文

我正在使用openzeppelin NFT标准和从tatum复制的代码创建智能合约,其中 safetransfrom 函数看起来像这样,

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

它使用ERC721标准支付了皇室。我称此功能是这样的,

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

我会遇到此错误,

消息 - 消息 - 失败错误'erc721:所有者查询不存在令牌'

,但令牌是铸造的。我也批准了。我不知道我是否弄乱了输入值。我尝试了4和“ 4”的代币。但似乎没有运气。

I am creating a smart contract using Openzeppelin NFT standard and code copied from Tatum, where the safeTransferFrom function looks like this,

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. I am calling this function like this,

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

Message -

Fail with error 'ERC721: owner query for nonexistent token'

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". But seems no luck.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独守阴晴ぅ圆缺 2025-02-05 18:01:56

看来您要转移的代币是“不存在的”。这通常意味着它还没有铸造。您可以验证使用Tokenid 4调用公共功能Tokenuri时,Tokenid 4是否返回任何内容?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文