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 address | Balance uint |
---|---|
0xe08c32737c021c7d05d116b00a68a02f2d144ac0 | 1 |
0xb88f61e6fbda83fbfffabe364112137480398018 | 218 |
0x897aea3d51dcba918c41ae23f5d9a7411671dee0 | 9 |
... | ... |
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: