如何获取 ERC-721 令牌 ID?

时间:2021-06-02 10:12:08

标签: ethereum solidity web3

我创建了一个部署在 ropston 网络上的 ERC-721 合约。 使用合同我正在创建 NFT 并且它完全工作正常。

现在对于转移部分,我需要获取任何 NFT 的 tokenID 并转移到其他地址,但是每当我从 etherscan 或使用 web3 获取交易详细信息时我都无法获取 tokenID。

我想将 tokenID 存储在 DB 中,以便在转移到其他地址时可以使用它。

enter image description here

我已经圈出了上图中所需的确切 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 函数。

1 个答案:

答案 0 :(得分:1)

您的 mintNFT() 函数不会发出任何包含 newItemId 的事件。

<块引用>

solidity 是使用转移的标准定义

没有“标准定义”,ERC-721 标准只定义了一个接口和很少的其他规则 - 并且(接口的)实际实现取决于每个开发人员。但是,我假设“标准定义”是指 OpenZeppelin implementation,它是 ERC-721 标准的广泛使用的实现,并且被许多开始使用 Solidity 编码的人使用。

您可以在链接的实现中看到,OZ _mint() 函数发出 Transfer() 事件,其中第三个参数是铸造的令牌 ID。

因此,执行 mintNFT() 函数会有效地发出 Transfer() 事件,该事件包含新生成的令牌 ID 作为第三个参数的值。


在您的 JS 代码中执行 mintNFT() 合约函数后,它会返回一个 PromiEvent 对象,您可以使用它来捕获其 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]));
});

您可以在 send() methodreceipt 的 web3 文档中找到更多详细信息。