4. KittyBreeding: Cats Get Down and Dirty

This file contains the methods necessary to breed cats together, including keeping track of siring offers, and relies on an external genetic combination contract.

The “external genetic combination contract” ( geneScience ) is stored in a separate contract, which is not open source.

The KittyBreeding contract contains a method for the CEO to set the address of this external contract:

They did it this way so the game would not be too easy — if you could just read how a kitty’s DNA was determined, it would be a lot easier to know which cats to breed in order to get a “fancy cat”.

This external geneScience contract is later used in the giveBirth() function (which we’ll see in a bit) to determine the new cat’s DNA.

Now let’s see what happens when two cats are bred together:

So this function takes the ID of the mother and father, looks them up in the master kitties array, and sets the siringWithId on the mother to the father’s ID. (When siringWithId is non-zero, it indicates that the mother is pregnant).

It also executes triggerCooldown on both parents, which makes it so they can’t breed again for a set amount of time.

Next, we have a public giveBirth() function which creates a new cat:

The in-line commenting on the code is pretty self-explanatory. Basically the code first performs some checks to see if the mother is ready to give birth. It then determines the child’s genes using geneScience.mixGenes() , assigns ownership of the new kitty to the mother’s owner, then calls the _createKitty() function we looked at in KittyBase.

Note that the geneScience.mixGenes() function is a black box, since that contract is closed-source. So we don’t actually know how the child’s genes are determined, but we know it’s some function of the mother’s genes, the father’s genes, and the mother’s cooldownEndBlock .

5. KittyAuctions: Buying, Selling, and Pimpin’ of Cats

Here we have the public methods for auctioning or bidding on cats or siring services. The actual auction functionality is handled in two sibling contracts (one for sales and one for siring), while auction creation and bidding is mostly mediated through this facet of the core contract.

According to the devs, they split this auction functionality into “sibling” contracts because “their logic is somewhat complex and there’s always a risk of subtle bugs. By keeping them in their own contracts, we can upgrade them without disrupting the main contract that tracks kitty ownership.”

So this KittyAuctions contract contains the functions setSaleAuctionAddress() and setSiringAuctionAddress() , which like setGeneScienceAddress() can only be called by the CEO, and sets the address of an external contract that handles these functions.

Note: “Siring” is referring to pimping out your cat — putting it up for auction, where another user can pay you Ether for your cat to breed with theirs. Lols.

This means that even if the CryptoKitties contract itself were immutable, the CEO has the flexibility to change the address of these auction contracts down the line, which would change the rules of the auctions. Again, not necessarily a bad thing since sometimes developers need to fix bugs, but something to be aware of.

I’m not going to go in depth into how exactly the auction & bidding logic is handled to keep this article from getting too long (it’s already long enough!), but you can check out the code in EthFiddle (search for KittyAuctions).

6. KittyMinting: The Gen0 Cat Factory

This final facet contains the functionality we use for creating new gen0 cats. We can make up to 5000 “promo” cats that can be given away (especially important when the community is new), and all others can only be created and then immediately put up for auction via an algorithmically determined starting price. Regardless of how they are created, there is a hard limit of 50k gen0 cats. After that, it’s all up to the community to breed, breed, breed!

The number of promo cats and gen0 cats the contract is able to create is hard-coded here:

uint256 public constant PROMO_CREATION_LIMIT = 5000;

uint256 public constant GEN0_CREATION_LIMIT = 45000;

And here’s the code where the “COO” can create promo kitties and gen0 kitties:

So with createPromoKitty() , it looks like the COO can create a new kitty with whatever genes he wants, and send it to whoever he wants (up to a max of 5000 kitties). I’m guessing they use this for early beta testers, friends and family, to give away free kitties for promotion purposes, etc.

But this also means that your cat may not be as unique as you think, since he can potentially print 5000 identical copies of it!

For createGen0Auction() , the COO also provides the genetic code for the new kitty. But instead of assigning it to a specific person’s address, it creates an auction where users would bid Ether to buy the kitty.

7. KittyCore: The Master Contract

This is the main CryptoKitties contract, which is what is compiled and running on the Ethereum blockchain. This contract ties everything together.

Because of the inheritance structure, it inherits from all the contracts we looked at prior to this, and adds a few more final methods, like this function for getting all a Kitty’s data using its ID:

This is a public method that will return all the data for a specific kitty from the blockchain. I imagine this is what is queried by their web server for displaying the cats on the web site.

Wait… I don’t see any image data. What determines what a kitty looks like?

As we can see from the code above, a “kitty” basically comes down to a 256-bit unsigned integer that represents its genetic code.

There’s nothing in the Solidity contract code that stores a cat’s image, or its description, or that determines what that 256-bit integer actually means. The interpretation of that genetic code happens on CryptoKitty’s web server.

So while this is a really clever demonstration of a game on the blockchain, it’s not actually 100% blockchain-based. If their website was taken offline in the future, unless someone had backed up all the images, you would be left with only owning a meaningless 256-bit integer.

In the contract code, I did find a contract called ERC721Metadata , but it never ends up getting used for anything. So my guess is they originally planned on storing everything in the blockchain, but later decided against it (too cost prohibitive to store a lot of data in Ethereum?) and so they ended up needing to store it on their web server instead.

Tying It All Together

Ok… So to sum everything up, here we’ve looked at:

How kitties are represented as data

How all kitties in existence are stored in a single smart contract, and how it keeps track of who owns what

How gen0 kitties are produced

How kitties are bred together to form new kitties

This was just a top-level overview. If you’re looking for a more in-depth tutorial on how to build your own game, you may be interested in an interactive code school we’ll be releasing within the next couple weeks.

UPDATE: We released the interactive code school. Check it out at CryptoZombies.io!