Solidity

Web3.js。當交易需要幾分鐘才能被探勘時如何獲得返回值

  • January 25, 2022

我有一個可靠的合約,其中包含一種鑄造 ERC721 代幣並返回 tokenId 的方法

function createItem(string memory tokenURI) public returns (uint256)
   {
       _tokenIds.increment();

       uint256 newItemId = _tokenIds.current();
       _mint(msg.sender, newItemId);
       _setTokenURI(newItemId, tokenURI);

       return newItemId;
   }

在反應應用程序中,我正在對該方法進行“發送”呼叫以獲取 tokenId。通常,它運作良好。

問題是當交易需要時間時,Metamask 會返回錯誤“交易未在 50 個塊內開採”,因此我無法獲取 tokenId。

我有 transactionHash,我有收據(通過呼叫web3.eth.getTransactionReceipt(transactionHash);)但我無法獲得 tokenId

我試著從事件中得到它:

const receipt = await new web3.eth.getTransactionReceipt(transactionHash);
   console.log(receipt);
   if (receipt && receipt.status === true && !status) {
       if (receipt.events) {
           const { Transfer } = receipt.events;
           const tokenId = Transfer && Transfer["returnValues"] ? Transfer["returnValues"]["tokenId"] : 0;
           if (tokenId) {
               console.log(tokenId);
           }

同樣從日誌中,就像在我的松露測試中一樣,我可以從那裡獲取 tokenId:

it("Should create 3rd nft", async () => {
   var tokenIdResponse = await instance.createItem("www.somemetadata.com", { from: owner });
   assert.equal(tokenIdResponse.logs[0].args.tokenId, 3);
 });

但是我在呼叫 getTransactionReceipt 時得到的收據對像在日誌中沒有該資訊: 日誌截圖

那麼,有人可以幫助我嗎?我被困住了。

當“發送”沒有立即返回時,如何獲得返回值?

您必須收聽契約事件。“mint”函式由應該發出 Mint 事件的標準完成。然後你可以做這樣的事情:

contract.events.allEvents()
.on('data', (event) => {
   console.log(event);
})
.on('error', console.error);

有很多關於“監聽智能合約事件”的手冊

引用自:https://ethereum.stackexchange.com/questions/119882