Keeping Token Balances on Transfer

Wouldn't it be nice if we could tell how many punks someone owns without checking all 10,000 punk ids?

LarvaLabs took care of this! Based on the ERC20 token standard, which keeps track of holder balances too, the CryptoPunksMarketplace contract has a balanceOf mapping:

mapping (address => uint256) public balanceOf;

This mapping would look like this as a table:

Owner addressBalance uint
0xe08c32737c021c7d05d116b00a68a02f2d144ac01
0xb88f61e6fbda83fbfffabe364112137480398018218
0x897aea3d51dcba918c41ae23f5d9a7411671dee09
......

In the context of our code, implementing this balance tracker looks like this:

contract CryptoPunksMarket {  // Our storage that keeps track of punk ownership.  mapping (uint => address) public punkIndexToAddress;  // Keeps track how many punks are owned by an address.  mapping (address => uint256) public balanceOf;  // Transfer ownership of a punk to another user without requiring payment  function transferPunk(address to, uint punkIndex) {    // Throw an error if called by anyone but the punk owner    if (punkIndexToAddress[punkIndex] != msg.sender) throw;    // Our contract only allows managing punks #0 – #9,999    if (punkIndex >= 10000) throw;    // Assign the new owner    punkIndexToAddress[punkIndex] = to;    // Remove the punk from the total balance of the previous owner    balanceOf[msg.sender]--;    // Add the punk to the total balance of the new owner    balanceOf[to]++;    // Let outside applications know of the transfer by emitting an Event    PunkTransfer(msg.sender, to, punkIndex);  }}

Note: The ++ and -- are shorthands for adding/subtracting 1 from the number. So the following two lines do exactly the same thing:

// This syntax shugar shorthand...balanceOf[msg.sender]--;// Is the same as...balanceOf[msg.sender] = balanceOf[msg.sender] - 1;

If you want to read actual balances from chain we can use Etherscan, just like we did for checking punk ownership here:

Query holder balances via Etherscan.