ERC-721: How to get all token ids?

Viewed 6296

I want to iterate over all token ids of a ethereum ERC-721 contract. Some contracts have counting ids (0, 1, 2, 3, ...) which is easy, but some have random ids, e.g. https://etherscan.io/token/0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d#inventory

Sadly etherscan only shows the last 10000 token ids used, but I want to iterate over all 79490. Is there a way to accomplish this? For me, everything is fine. Setup my own ethereum node, using some API.

2 Answers

You can loop through all Transfer() events emitted by the collection contract.

You're looking for transfers from address 0x0 (minted tokens). And excluding from the list transfers to address 0x0 (destroyed tokens).

One way to achieve this is by using the Web3 Contract getPastEvents() function (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);
    }
});

There's no easy way to do it with an Ethereum node in a contract-agnostic way...the ERC-721 does not specify any interface methods that allow querying for all token ID, so unless the contract you're looking at uses sequential token ids, there's no way to guess all token ids from a simple node query.

Unless you want to iterate over the whole transaction history of the contract to get the ids of every minted NFT (you'd need an archive node for that, as a full node would not have the full transaction history) you should use an API from services that index all NFT activity.

You could use this API from CovalentHQ: https://www.covalenthq.com/docs/api/#/0/Class-A/Get-NFT-Token-IDs-for-contract/lng=en

Or this one from Moralis: https://docs.moralis.io/moralis-server/web3-sdk/token#getalltokenids

Related