I had need to find the owner of an NFT on a private blockchain (testnet) Ethereum for a project. This calls the ownerOf function of an NFT. On the mainnet there are many ways to do this, on a private network not so many. An NFT is not like a typical token that shows up in your Eth account. Instead an NFT is its own entity that has a function ownerOf() that shows who owns it. This is why many wallets don’t automatically show an NFT an account has, instead you have to enter the NFT address and a tokenID to add it to a wallet.

I assumed this would be a painless issue as there are libraries to handle the heavy lifting for every language out there. In this case the project was already using PHP. Sadly the main php ethereum library hasn’t been updated for a few years, it has no ownerOf function. After a quick check the missing code was more than I wanted to attempt with the short time window so I went for a workaround. I found a variety of close code examples to use yet none did ownerOf. Here is the result, although I don’t recall where the various snippets came from, I’ll keep the open source nature around with giving this example.

Requires Geth, using Ubuntu.

First, you need to define an ABI. The Ethereum Application Binary Interface (ABI) lets you specify how to interact with a contract and return data in a format you’re expecting. I only care about ownerOf.

Add a new file, ownerof.abi :

abi = [{ "constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"owner","type"
:"address"}], "type":"function" }]

Then a quick script with two passed arguments the NFT contract address and the tokenID of the NFT you are querying for ownership: NFTcheck.sh

/home/geth/geth -attach << EOF | grep "ADDRESS:" | sed "s/ADDRESS: //"
caddr = "$1";
c = web3.eth.contract(abi).at(caddr);
d = c.ownerOf.getData($2);
var addy = web3.eth.call({to: caddr, data: d});
console.log("ADDRESS: " + addy);

Then run this command like so ./NFTcheck.sh <contract> <tokenID>

If there is such a contract and tokenID it will return the owner of the NFT. This is perfect for a php exec() or any other language that you don’t need a full library to do something simple.

Note, the address returned is a byte32 and all lower case. You will need to slice the last 40 characters and use a checksum address to get the proper upper and lowercase of the actual address. For comparison against a known address it works fine.

The web3 that comes with geth is 0.20.1 so you can’t use toChecksumAddress() on the return.