【问题标题】:VM Exception while processing transaction: revert处理事务时出现 VM 异常:还原
【发布时间】:2021-11-23 12:24:45
【问题描述】:

我有 2 个合同。一种是 ERC721 令牌 (NFTCollectables)。另一个是包含拍卖系统的市场 (NFTMarket)。 拍卖结束后只能由出价最高的人申领。 在进行拍卖时,调用NFTCollectables 合约的transfer 方法将NFT 从市场地址转移到出价最高者的地址。

我不完全理解为什么会出现异常,但它发生在 NFTCollectables 合约的 transfer 方法中/内部。奇怪的是,即使transfer 方法中的最后一行代码也被执行(通过在_transfer(msg.sender, to, nftId) 之后放置require(false, 'test') 进行测试)。但ctr.transfer(auction.highestBid.bidder, auction.nftId) 之后没有任何内容被执行(通过在其后放置require(false, 'test') 进行测试)。

会不会和gas限制有关?

感谢任何想法,谢谢!

NFT 市场
function claimAuction(uint auctionIndex) external {
    require(auctionIndex < auctions.length, "no auction");
    Auction memory auction = auctions[auctionIndex];
    require(block.timestamp <= auction.end, "auction still active");

    NFTCollectables ctr = NFTCollectables(nftCollectablesAddress);
    ctr.transfer(auction.highestBid.bidder, auction.nftId);

    // deleting auction from active auctions list
    for (uint i; i < activeAuctionIndexes.length; i++) {
      if (activeAuctionIndexes[i] == auctionIndex) {
        delete activeAuctionIndexes[i];
        break;
      }
    }

    emit AuctionEnd(auction.highestBid.bidder, auction.highestBid.price, auction.nftId);
}
NFTCollectables
function transfer(address payable to, uint nftId) external payable {
    require(_exists(nftId), "transfer of non existing token");
    require(_isApprovedOrOwner(msg.sender, nftId), "Sender not approved nor owner");
    _transfer(msg.sender, to, nftId);
}

【问题讨论】:

  • 如果你确定“transfer”的最后一行都被执行了,这意味着你的配置有错误。

标签: blockchain ethereum solidity truffle ganache


【解决方案1】:

如果您已将合约部署在公共网络上,如主网或测试网,请使用https://tenderly.co 或 EtherScan 调试恢复原因。

如果您正在使用单元测试运行合同,请继续修改合同,例如通过删除行来查看它何时开始失败。或者使用更好的智能合约开发框架,例如Brownie,它可以让您立即恢复。

【讨论】:

  • 奇怪的是,当transfer 方法为空时,我仍然会收到回复事件...您知道这可能会做什么吗?关于布朗尼的想法;我明天测试一下
  • 因为问题不包含可重复的例子,所以你的猜测和我的一样好。我建议自己学习如何调试此类问题,这样您就可以系统地确定还原原因,而无需进行猜测。
【解决方案2】:

我们已经在我们的代码库上实现了一个功能,我可以与您分享。此函数用于将 nft 的所有权转让给赢得拍卖的人。

function transferNFTtoNewOwner(NFTItem memory t,address oldOwner, address newOwner) internal {
    require(newOwner != address(0), "New owner can't be address zero.");
    XXXX storage r = creatureList[t.tokenAddress][t.tokenId];
    IERC721 nft = IERC721(t.tokenAddress);
    nft.safeTransferFrom(oldOwner, newOwner, t.tokenId); 
    address currOwner = nft.ownerOf(t.tokenId);
    require(newOwner == currOwner, "Problem on nft transfer");
    r.owner = newOwner; 
}

主要区别在于我们从这里使用了安全转移。如果你的合约拥有 NFT,那么你可以调用 safeTransfer。之后我们用 require 语句检查了 nft 所有者。如果您输入此语句并将您的传输功能更改为 safetransfer 并且交易仍然恢复并且在 etherscan 上没有给出任何错误,那么您可以调查您的 nft 合约。

【讨论】:

    猜你喜欢
    • 2021-07-10
    • 2022-08-08
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 2019-10-11
    • 2022-08-11
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多