簡體   English   中英

處理事務時出現 VM 異常:還原

[英]VM Exception while processing transaction: revert

我有 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') )。

它可能與氣體限制有關嗎?

任何想法表示贊賞,謝謝!

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

如果您已經將合約部署在 public.network 上,例如 mai.net 或 tes.net,請使用https://tenderly.co或 EtherScan 來調試回滾原因。

如果您使用單元測試運行合同,則繼續修改合同,例如通過刪除行以查看它何時開始失敗。 或者使用更好的智能合約開發框架,如Brownie ,它會立即為您提供恢復的原因。

我們已經在我們的代碼庫上實現了一個 function,我可以與您分享。 這個 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; 
}

主要區別是我們在這里使用了 safetransferfrom。 如果你的合約擁有 NFT,那么你可以調用 safeTransfer。 之后我們用 require 語句檢查了 nft 所有者。 如果您放置此聲明並將您的轉賬 function 更改為 safetransfer,並且交易仍然恢復且在 etherscan 上沒有給出任何錯誤,那么您可以調查您的 nft 合約。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM