CryptoKitties: Smart Contract Breakdown

Explaining its functionality by grouping lines of code

Nazar Ilamanov
Better Programming

--

The CryptoKitties project has always been interesting to me. It was the first popular NFT game ever. But I didn’t understand its appeal, why it blew up. I also never quite understood the game dynamics. So I decided to finally learn what the game is about and how it’s implemented under the hood.

It was clear to me that the NFT part was implemented as an ERC-721. But I wanted to understand how breeding is implemented. What’s kept on-chain vs off-chain? As I started exploring the game, I learned that it has an auction mechanism. How is that implemented?

And how much do people actually earn from this thing? Are people still playing it? Or has it been entirely superseded by more successful Axie Infinity?

In this article, we will answer all these questions and break down the smart contracts behind CryptoKitties. Here is the outline of this article:

  • What is CryptoKitties?
  • Code structure (core, breeding, auction)
  • Timeline of CryptoKitties
  • My opinion on the code

What is CryptoKitties — short game dynamics

At first, I wanted to do a breakdown of the Axie Infinity(AI). But turns out AI does not open source most of their Smart Contracts (SCs). So I pivoted to CryptoKitties(CK) (its contracts are public). It’s a simplified version of AI with similar game dynamics:

  • Blockchain-based, play-to-earn game
  • People collect and trade kitties
  • Can breed two kitties to get a new kitty
  • Earn real ETH by selling your kitties or rent them out for breeding
  • Breeding works based on “genes”. Child kitty gets a mix of parents’ genes
  • Kitties do not have a gender
  • CK makes money by charging a cut in its marketplace (auctioneer fee) and minting new kitties
  • To enter the game you need to purchase some kitties

Here is a video of the CK gameplay if you’re interested.

Axie Infinity was inspired by CryptoKitties, Pokemon (for battling), and later Clash of Clans (for the lands). More on the origins and the business side of AI.

Code structure

CK has 3 smart contracts: Core, Breeding, and Auction.

Source code:

Core contract

The core contract is broken down into many sub-contracts: KittyBase contract inherits/extends KittyAccessControl contract, KittyOwnership extends KittyBase, etc. KittyCore has everything combined.

  • KittyAccessControl: creates 3 roles: CEO, CFO, COO, and restricts access of some functions to these roles. CEO can reassign roles, change pointers to sibling contracts. CFO can withdraw funds. COO can mint new kitties.
  • KittyBase: data structure of kitties; stores all kitties and ownership info; transferring of ownership.
  • KittyOwnership: implementation of ERC-721 interface. I explained the implementation of ERC-721 in my BAYC smart contract breakdown. Check it out if you’re interested.

Did you know that CryptoKitties pioneered ERC-721 standard and coined the term NFT?

  • KittyBreeding: will be explained in the “Breeding” section.
  • KittyAuction: will be explained in the “Auction” section.
  • KittyMinting: only 50K kitties can be minted — 5K are promo kitties, the rest are regular gen0 kitties. (Difference: promo can be transferred to a specific address at the mint time, regular gen0 can only be auctioned). Any genes can be specified during minting.
  • KittyCore: ties everything together, adds payments/withdrawals, and handles upgradeability - covered later in the article.

Payments in Ethereum 101:
- to accept a payment, just make your function payable. msg.value variable has the amount that was sent
- to send a payment to an address, just use address.send.

Breeding

The breeding logic is implemented in the KittyBreeding sub-contract of the core contract.

  • First, there are a bunch of helper functions like isReadyToBreed, isSiringPermitted, isValidMatingPair, etc.
  • Then there are 2 functions that actually do the breeding. breedWith starts the breeding process and giveBirth ends it. giveBirth call will succeed only after the gestation period is complete.

Midwives and auto-birth

We can assume that breedWith is called from the front-end of CK when someone initiates breeding. But how is giveBirth called? There are no callbacks or cron jobs in Solidity. So someone needs to call giveBirth in the future.

This is where midwives come in. CK has a network of autoBirth daemons which call giveBirth at the right time. Anyone can set up a daemon.

But calling giveBirth costs gas. Why would daemons pay gas for someone else? This is where autoBirthFee comes in. When a player initiates breeding, he needs to pay autoBirthFee to CK (0.04 ETH currently). CK will later compensate the daemon when he calls giveBirth.

Super-secret genetic combination algorithm

You probably noticed that the giveBirth function calls mixGenes function to get the child genes. This mixGenes function is actually a part of a sibling contract called GeneScience (source code: v1 and v2). KittyBreeding just stores a pointer to GeneScience contract.

Initially, GeneScience was not open-source to “deliberately cultivate mystery and discovery around the CryptoKitties genome”. But the community built tools to reverse engineer the gene science algorithm. CK then open-sourced it and even released a second version with slight improvements(CK_blog_post).

Timeline of GeneScience contract: v1 released in Nov 2017, open-sourced in Jan 2019, v2 released in Feb 2019 (already open-source).

I won’t cover GeneScience code because it’s too low level. But I will highlight a few points.

GeneScience involves lots of bit manipulation to mix the genes of the parent kitties. Remember that genes are stored as a 256-bit number in the Kitty struct. These bits are mapped to traits (or cattributes as CK likes to say) that determine the appearance of the kittie.

How is randomness generated?
Solidity does not have a random number generator so CK uses the block number of when the offspring is born as a seed for randomness. This block number is hard to manipulate so it should give enough randomness

Auctions

The final contract of CK is for auctions. CK uses a “clock auction”: you set starting and ending prices and duration. The price then changes linearly from the starting to the ending price. Whoever bids first, wins.

Here is the structure of the auction contract and how it fits with the rest:

  • ClockAuctionBase: keeps track of existing auctions and a function to bid
  • ClockAuction: Just a wrapper on top of ClockAuctionBase
  • SiringClockAuction and SaleClockAuction: auctions for renting out your kittie for breeding and for selling your kittie, respectively. These need to be separate because the actions taken after a successful bid are quite different for each case.
  • SaleClockAuction does not add much except tracking the last 5 prices of auctions used to set the optimal auction starting price for the newly minted kitties.
  • SiringClockAuction is yet another wrapper on ClockAuction contract, except it transfers the rented kittie back to the owner instead of the bidder (bidder keeps the offspring).

They are linked to the core contract in the KittyAuction subcontract:

To summarize auctions: you create an auction for your kittie, it’s transferred to the auction contract and a new auction is created. Whenever someone bids successfully, either the kitty is transferred to the bidder (when it’s a selling auction), or the kitty is transferred back to you but the bidder keeps the offspring (when it’s a siring auction).

Timeline of CryptoKitties

We saw the code. But the code is static, it doesn’t tell us the dynamic picture. What happened after deploying the contract?

You can inspect the entire history of transactions of this contract on Etherscan. If we go way back to the beginning:

We can see that the contract was deployed on Nov 23, 2017. Then they set the addresses of the sibling contracts and set the CEO/CFO roles. Then they created a bunch of promo kitties (3K to be exact).

Then they unpause the contract (which means most functionality is now available) and the action began:

Here is the contract balance over time (from Etherscan analytics):

blue: ETH balance (scale is on the left). black: USD balance (scale is on the right)

The sharp declines are the withdrawals by the CK team. We see that most of the action happened from Nov 2017 until Nov 2018. From the CK timeline website, it looks like CK had 250K users at the peak in Jan 2018. Also in Dec 2017, CK accounted for 25% of traffic on Ethereum.

Here is the graph of transaction frequency:

While there are still a significant number of transactions from Nov 2018 until Jul 2019, they are all low-value because the balance stays relatively flat in that region.

My opinion on the code

  • First and foremost, the art does not live on-chain. The genes are kept on-chain but ideally, the images of kitties would also be generated on-chain (like Art Blocks).
  • CK did not even put the links to the artwork on-chain. They could have used the getMetadata function to return the links to immutable images. Instead, they just return “Hello World” 🤷‍♂️. The mapping from tokenIds to images happens on the frontend. So if CK were to shut down their website, you would only be left with a meaningless 256-bit number.
  • Upgradeability is not ideal. The core contract can be updated via setting a new address in the KittyCore contract. In that case, an event will be emitted and it’s up to the clients to listen to it and switch to the new contract. The old one will be forever paused.

Now onto the positive

  • Good separation of concerns: breeding and auction are separate from the core contract to minimize bugs. You can plug in updated versions of the sibling contracts without disrupting the core.
  • Clean code and a solid understanding of Solidity. Lots of useful comments throughout the contract. Guarding against reentrancy attack and maximizing gas efficiency:
  • Good sense of humor:

That’s it for the CryptoKittes smart contract breakdown! I hope this was helpful. Let me know in the comments if you have any questions.

I am planning to do more breakdowns of popular smart contracts like Aave and Art Blocks, so follow me either on Medium or Twitter to get updates.

You can also check out breakdowns of other smart contracts and more stuff for Solidity noobs at solidnoob.com.

Want to Connect?Follow me on Twitter.

--

--