ERC-721:如何获取所有令牌 ID?

Posted

技术标签:

【中文标题】ERC-721:如何获取所有令牌 ID?【英文标题】:ERC-721: How to get all token ids? 【发布时间】:2021-11-17 00:35:20 【问题描述】:

我想遍历以太坊 ERC-721 合约的所有代币 ID。 有些合约有计数 id (0, 1, 2, 3, ...),这很容易,但有些合约有随机 id,例如https://etherscan.io/token/0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d#inventory

遗憾的是 etherscan 仅显示最后使用的 10000 个令牌 ID,但我想遍历所有 79490。 有没有办法做到这一点?对我来说,一切都很好。使用一些 API 设置我自己的以太坊节点。

【问题讨论】:

【参考方案1】:

您可以遍历集合合约发出的所有Transfer() 事件。

您正在寻找转账from 地址0x0(铸造代币)。并从列表中排除转移to 地址0x0(销毁的令牌)。

实现此目的的方法之一是使用 Web3 合约 getPastEvents() 函数 (docs)。

const myContract = new web3.eth.Contract(abiJson, contractAddress);
myContract.getPastEvents('Transfer', 
    filter: 
        _from: '0x0000000000000000000000000000000000000000'
    ,
    fromBlock: 0
).then((events) => 
    for (let event of events) 
        console.log(event.returnValues._tokenId);
    
);

【讨论】:

非常感谢!这适用于少于 10000 个代币的合约。如果还有更多,我会得到query returned more than 10000 results。这是一个 infura 限制吗?是否有助于设置我自己的 geth 实例? @Alai 没错,这个 10k 的限制是 Infura 施加的,你可以使用自己的节点绕过它。 非常感谢。我需要一个存档节点还是一个完整的节点就足够了? @Alai 的同步速度够快吗? 我通过指定 fromBlock: x, toBlock: y 使用上面的代码让它与 infura 一起工作。并在循环中递增 x 和 y,其中 x 和 y 的范围小到足以返回少于 10,000 个结果。 @阿莱【参考方案2】:

没有简单的方法可以通过与合约无关的方式使用以太坊节点...ERC-712 没有指定任何允许查询所有代币 ID 的接口方法,因此除非您正在查看的合约使用顺序令牌 ID,无法从简单的节点查询中猜测所有令牌 ID。

除非您想遍历合约的整个交易历史以获取每个铸造 NFT 的 ID(您需要一个存档节点,因为完整节点不会拥有完整的交易历史)您应该使用来自索引所有 NFT 活动的服务的 API。

您可以使用来自 CovalentHQ 的这个 API: https://www.covalenthq.com/docs/api/#/0/Class-A/Get-NFT-Token-IDs-for-contract/lng=en

或者莫拉利斯的这个: https://docs.moralis.io/moralis-server/web3-sdk/token#getalltokenids

【讨论】:

以上是关于ERC-721:如何获取所有令牌 ID?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 node.js 检查 opensea 上的令牌是 ERC721 还是 ERC1155

如何跨网络传输 ERC721 代币

ERC721 mint()返回'无效地址'错误

如何使用 Flutter 与 ERC721 智能合约交互?

什么是以太坊ERC20和ERC721

如何检查地址是不是允许接收ERC721?