簡體   English   中英

如何獲取ERC-721 tokenID?

[英]How to get ERC-721 tokenID?

我創建了一個部署在 ropston.network 上的 ERC-721 合約。 使用合同,我正在創建 NFT,並且它完全可以正常工作。

現在對於轉移部分,我需要獲取任何 NFT 的 tokenID 並轉移到其他地址,但是每當我從 etherscan 或使用 web3 獲取交易詳細信息時,我都無法獲取 tokenID。

我想將 tokenID 存儲在數據庫中,以便在轉移到其他地址時可以使用它。

在此處輸入圖像描述

我已經圈出上圖中所需的確切 tokenID。

我正在使用以下代碼:

window.ethereum
    .request({
        method: 'eth_sendTransaction',
        params: [
            {
                from: fromAddress,
                to: contractAddress,
                gas: '50000',
                data: nftContract.methods.transferFrom(fromAddress, toAddress, tokenNumber).encodeABI()
            },
        ],
    })

我只想在創建 NFT 時獲取 tokenID 並存儲到數據庫中以供參考並執行業務邏輯。

function mintNFT(address recipient, string memory tokenURI)
        public onlyOwner
        returns (uint256)
    {
        _tokenIds.increment();

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

        return newItemId;
    }

以上是負責創建 NFT 的 solidity function。

你可以試試:

const receipt = await web3.eth.getTransactionReceipt(hash)
const tokenId = Web3.utils.hexToNumber(receipt.logs[0].topics[3])

I check hash from ropsten testnet: https://ropsten.etherscan.io/tx/0x59928012c3e0605b9346215c24654e84be29f2bf47949a2284aecf9991996a28

output 是 11

您的mintNFT() function 不會發出任何包含newItemId的事件。

solidity 使用的是標准的 transfer 定義

沒有“標准定義”, ERC-721標准只定義了一個接口和一些其他規則——並且(接口的)實際實現由每個開發人員負責。 但是,我假設“標准定義”是指OpenZeppelin 實現,它是 ERC-721 標准的廣泛使用的實現,許多開始使用 Solidity 編碼的人都在使用它。

您可以在鏈接的實現中看到,OZ _mint() function 發出Transfer()事件,其中第三個參數是鑄造的令牌 ID。

因此,執行mintNFT() function 會有效地發出Transfer()事件,其中包含新鑄造的令牌 ID 作為第三個參數的值。


從 JS 代碼執行mintNFT()合約 function 后,它會返回一個PromiEvent object,您可以使用它來捕獲其receipt事件。

收據包含發出的日志,您也可以在其中找到Transfer()日志。

const tx = nftContract.methods.mintNFT(...).send({from: ...});

tx.on('receipt', function(receipt){
    console.log(logs[0].topics[3]); // this prints the hex value of the tokenId
    // you can use `web3.utils.hexToNumber()` to convert it to decimal
});

如果您想從已經存在的交易中獲取令牌 ID(使用 tx 哈希),您可以使用以下代碼段:

web3.eth.getTransactionReceipt('0x258a6d35445814d091ae67ec01cf60f87a4a58fa5ac1de25d0746edf8472f189').then(function(data){
    let transaction = data;
    let logs = data.logs;
    console.log(logs);
    console.log(web3.utils.hexToNumber(logs[0].topics[3]));
});

您可以在 web3 文檔中找到send() 方法收據的更多詳細信息。


如果receipt.logs[0].topics[3]不起作用,試試這個:

receipt.events.Transfer.returnValues.tokenId

出於某種原因,我的 tokenId 在receipt.logs[1].topics[3]而不是receipt.logs[0].topics[3]下(與索引 arguments 有關?)。 不過很容易找到,就好像您的 ID 是自動生成的(通常是這樣),它會顯示在日志中,例如 tokenId 3:

0x0000000000000000000000000000000000000000000000000000000000000003

因此,只要您的 ID 小於 10,就可以將它們識別為小數, 0x00...03 = 3

您可以在 you.network Scanner 的日志中看到它。

那么這只是將它從十六進制轉換為十進制的情況。 您可以在普通 JS 中執行此操作,將基數 16 傳遞給十六進制:

const tokenId = parseInt(receipt.logs[1].topics[3], 16);

暫無
暫無

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

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