简体   繁体   English

处理事务时出现 VM 异常:还原

[英]VM Exception while processing transaction: revert

I have 2 Contracts.我有 2 份合同。 One is an ERC721 Token ( NFTCollectables ).一种是 ERC721 令牌 ( NFTCollectables )。 The other one is a market including an auction system ( NFTMarket ).另一个是包括拍卖系统( NFTMarket )的市场。 An auction can be claimed after it ended and only by the highest bidder.拍卖结束后只能由出价最高的人提出要求。 When claiming an auction the transfer method of the NFTCollectables contract is called to transfer the NFT from the markets address to the address of the highest bidder.当要求拍卖时, NFTCollectables合约的transfer方法被调用以将 NFT 从市场地址转移到最高出价者的地址。

I do not exactly understand why the exception comes, but it occurs at/inside the transfer method of the NFTCollectables contract.我不完全理解为什么会出现异常,但它发生在NFTCollectables合约的transfer方法中/内部。 The strange thing is that even the last line of code inside the transfer method is getting executed (tested by putting a require(false, 'test') after _transfer(msg.sender, to, nftId) ).奇怪的是,即使是transfer方法中的最后一行代码也被执行了(通过在_transfer(msg.sender, to, nftId) ) 之后放置require(false, 'test')进行测试)。 But nothing after ctr.transfer(auction.highestBid.bidder, auction.nftId) is getting executed (tested by putting a require(false, 'test') after it).但是在ctr.transfer(auction.highestBid.bidder, auction.nftId)之后什么都没有被执行(通过在它后面放置一个require(false, 'test') )。

Could it have to do with the gas limit?它可能与气体限制有关吗?

Any idea is appreciated, thanks!任何想法表示赞赏,谢谢!

NFTMarket 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 NFT收藏品
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);
}

If you have deployed the contracts on the public.network, like mai.net or tes.net, use https://tenderly.co or EtherScan to debug the revert reason.如果您已经将合约部署在 public.network 上,例如 mai.net 或 tes.net,请使用https://tenderly.co或 EtherScan 来调试回滚原因。

If you are running the contracts using unit tests then keep modifying the contracts eg by removing lines to see when it starts failing.如果您使用单元测试运行合同,则继续修改合同,例如通过删除行以查看它何时开始失败。 Or alternatively use a better smart contract development framework like Brownie which will give you the cause of revert right away.或者使用更好的智能合约开发框架,如Brownie ,它会立即为您提供恢复的原因。

We had implemented a function on our codebase that i can share with you.我们已经在我们的代码库上实现了一个 function,我可以与您分享。 This function is used to transfer ownership of nft to who wins the auction.这个 function 用于将 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; 
}

The major differences are we used safetransferfrom here.主要区别是我们在这里使用了 safetransferfrom。 If your contract owns the NFT then you can call safeTransfer.如果你的合约拥有 NFT,那么你可以调用 safeTransfer。 and after that we checked the nft owner with require statement.之后我们用 require 语句检查了 nft 所有者。 If you put this statement and change your transfer function to safetransfer and the transaction still revert without giving any error on etherscan then you can investigate about your nft contract.如果您放置此声明并将您的转账 function 更改为 safetransfer,并且交易仍然恢复且在 etherscan 上没有给出任何错误,那么您可以调查您的 nft 合约。

暂无
暂无

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

相关问题 松露错误:错误:处理事务时VM异常:恢复 - Truffle error: Error: VM Exception while processing transaction: revert Chainlink 返回错误:处理事务时出现 VM 异常:还原 - Chainlink Returned error: VM Exception while processing transaction: revert 无法弄清楚为什么在处理事务时出现 VM 异常:恢复错误 - Cannot figure out why I am getting VM Exception while processing transaction: revert error Openzepplin众包合同获得:处理事务时VM异常:恢复错误 - Openzepplin crowdsale contract got: VM Exception while processing transaction: revert error 错误:返回错误:处理事务时出现 VM 异常:恢复余额不足 — 给出的原因:余额不足 - Error: Returned error: VM Exception while processing transaction: revert Not Enough Balance — Reason given: Not Enough Balance “VM Exception while processing transaction: revert”,当运行chainlink节点并尝试部署TestnetConsumer合约时? - "VM Exception while processing transaction: revert", when running a chainlink node and try to deploy TestnetConsumer contract? 处理事务时出现 VM 异常:恢复 TransferHelper: TRANSFER_FROM_FAILED 运行 bot.js 的 manipulatePrice.js 测试时 - VM Exception while processing transaction: revert TransferHelper: TRANSFER_FROM_FAILED when running manipulatePrice.js test for bot.js 错误 Truffle Migrate “处理事务时出现 VM 异常:操作码无效” - Error Truffle Migrate "VM Exception while processing transaction: invalid opcode" 呼叫恢复异常 - Call Revert Exception 在 solana 上传输 NFT 时交易失败:错误处理指令 0:自定义程序错误:0x1 - Transaction failing while transferring NFT on solana: Error processing Instruction 0: custom program error: 0x1
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM