How to Find the Solana NFT’s Someone Owns
Ethereum is Hard
On Ethereum, it's incredibly difficult to figure out what NFTs someone owns.
Each Ethereum NFT is linked to a smart contract that minted the NFT. But since every NFT collection deploys their own smart contract, there are millions (?) of smart contracts that you need to scan over and check.
When implementing token gated events for Luma, we used the Opensea's API to query for the NFTs that an address owns. Opensea has already done the hard work for us by scanning over all of Ethereum's contracts and blocks.
But this kinda sucks, doesn't it? The blockchain is supposed to be a decentralized database and we just ended up querying a centralized provider...
Solana is Different
On Solana, we store data across the blockchain in key / value pairs. The terminology is kind of confusing, but each key / value pair is called an account. And everything is an account... But let's not get too sidetracked.
When you mint a Solana NFT, you have a few different accounts involved in the transaction:
your Wallet
the Solana Token Program — This is part of the Solana Program Library (the standard library for Solana) and is the program we are running to mint the NFT.
the Mint account — This account serves as the ID of the NFT and it owns the metadata about the NFT.
the Associated Token Account — This is generated by combining your Wallet address with the Mint. As a consequence, you will have at most one Associated Token Account for each type of token.
The last account is the most interesting. That's where we will store that you own the NFT.
So if wanted to check if wallet WALRUS
owns an NFT with the mint PUNK
, we would look up the Associated Token Account by combining WALRUS
and PUNK
with a special function, let's say that outputs WALPUNK
. Then we would read the data in WALPUNK
to see if WALRUS
owns PUNK
.
Now we are at parity with Ethereum. Given an NFT and a wallet, we can see who owns it. But we can do so much more...
On Solana, each validator node stores the full state of the system. This state is stored in what Solana calls the Accounts DB. The Accounts DB lets us do queries that would be impossible on Ethereum.
In this case, we can easily go from a Wallet address to a list of all of the Associated Token Programs associated with that Wallet.
Tada! On Solana, we can quickly find all the NFTs (and other tokens) that someone owns. And we don't have to rely on a centralized service like Opensea.
Appendix: Diving into the Technical Details
This covers how we go from a Wallet address to all of the Associated Token Accounts associated with the Wallet. From those accounts, it's relatively straightforward to find information on the NFTs someone owns (although, I can write about that if people are interested...).
web3
Using Solana's web3 library, you call getParsedTokenAccountsByOwner.
This makes a getTokenAccountsByOwner
RPC request to the URL that you specified when creating the collection.
Solana Runtime
This request gets processed by a node running the Solana Runtime. The runtime interprets the request and calls a Rust function get_token_accounts_by_owner
. This in turn calls several functions:
get_token_accounts_by_owner
get_filtered_spl_token_accounts_by_owner
get_filtered_indexed_accounts
accounts.load_by_index_key_with_filter
accounts_db.index_scan_accounts
accounts_index.index_scan_accounts
That last step is interesting! That's the Accounts DB that we mentioned above. Each node running Solana keeps the full Account DB in memory which makes it easy to query and find data.
OK, so I'm sure that a lot of that went over your head. A lot of it is still pretty confusing to me and I'm sure that I'm getting some of the details wrong. So if you have questions, ping me on Twitter!
And if you want to build dope, meaningful stuff on top of Solana, join us!