Midwives for CryptoKitties: Little Kitten is Yours, but Birthing Fee is Mine, Part 2
By: Zhongqiang Chen
Tags: Ethereum Blockchain, Crypto Midwife Service, Storage Refund, Contract Refund, Cryptokitties

CryptoKitties game

The CryptoKitties is a game that consists of collecting virtual cats. Cats in the game can be created by Axiom Zen, the company behind the game, or created by the players of the game who can breed two cats to generate a new one. The physical attributes of each is determined by its own genetic sequence, which is mainly inherited from its parents’ genes with some randomness.

A summary on the set of smart contracts related to CryptoKitties game is given below.

KittyCore: 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d

creator: 0xba52c75764d6F594735dc735Be7F1830CDf58dDf

time: Nov-23-2017 05:41:19 AM +UTC GeneScience: 0xf97e0A5b616dfFC913e72455Fde9eA8bBe946a2B

creator: 0xba52c75764d6F594735dc735Be7F1830CDf58dDf

time: Nov-23-2017 05:40:25 AM +UTC SiringClockAuction: 0xC7af99Fe5513eB6710e6D5f44F9989dA40F27F26

creator: 0xba52c75764d6F594735dc735Be7F1830CDf58dDf

time: Nov-23-2017 05:41:47 AM +UTC SaleClockAuction: 0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C

creator: 0xba52c75764d6F594735dc735Be7F1830CDf58dDf

time: Nov-23-2017 05:41:27 AM +UTC

Among these smart contracts, KittyCore provides the main functions of the CryptoKitties game to the players such as kitty breeding and child delivery. The smart contract GeneScience provides functionality on determination of genomes for newly born kittens. The smart contract SaleClockAuction is the platform for buying and selling cats. Another market, which is for “renting” cats for breeding purposes is provided by smart contract SiringClockAuction.

For more information on the CryptoKitties game, please refer to part 1 of this article.

Smart contracts for Crypto-Midwife

In this part of the article, we introduce another set of smart contracts that together provide the midwife service for the CryptoKitties game.

The first smart contract in the set is the one that is deployed on the Ethereum blockchain by the following transaction.

Transaction Hash: 0x4e7b83562aca39002b5728198e232b85af5a9c3832636cb1d5ab61738a0b8829

Status: Success

Block: 6699405 1968240 Block Confirmations

Timestamp: 323 days 7 hrs ago (Nov-13-2018 10:38:23 PM +UTC)

From: 0x1b0dff20922e219276ff0a3496afdc02d92948a2

To: [Contract 0x896b516eb300e61cfc96ee1de4b297374e7b70ed Created]

Value: 0 Ether ($0.00)

Transaction Fee: 0.00035128 Ether ($0.06)

Gas Limit: 100,000

Gas Used by Transaction: 70,256 (70.26%)

Gas Price: 0.000000005 Ether (5 Gwei)

Nonce Position 3845 17

Input Data:

This smart contract is deployed by account 0x1b0d. The address of the smart contract is 0x896b, and its creation time is Nov-13–2018 10:38:23 PM +UTC.

As the creator of this smart contract did not publish the source code of the smart contract, we employ reverse engineering techniques to recover most of the source code.

The source code of this smart contract, called contracts _896b, is as follows.

pragma solidity ^0.5.1; contract contract_896b {

address constant master = 0x000007222Caeb29694719E804b24Fb3eE5116a8a;

constructor () public {

}

function () external payable {

uint8 firstByte = uint8(msg.data[0]);

uint256 len = 3;

uint256 num = uint256(blockhash(block.number - 1)); if ((num % (firstByte / 0x10)) == (firstByte & 0x0f)) {

// entire input except the first byte

len = msg.data.length - 1;

} // skip first byte

uint256 start = msg.value + 1;

bytes memory data;

assembly {

calldatacopy(add(data, 0x20), start, len)

} // invoke fallback function in master

(bool success,) = master.call.value(msg.value)(data);

}

}

The smart contract contract_896b consists of an empty constructor and the fallback function. Thus, all the functionality is implemented in its fallback function.

By looking at the fallback function, we can see that the function is quite simple. It takes a byte sequence as its input, then checks whether or not the block hash of the previous block follows the pattern specified by the first byte of the input. If so, the function simply uses the remaining input as an argument to call the fallback function of another smart contract at address 0x000007222Caeb29694719E804b24Fb3eE5116a8a, let us call it contract_7222. Otherwise, the function uses the first three bytes of the remaining byte sequence in the input as argument for the fallback function of contract_7222.

It is interesting that there is no access control on the invocation of the fallback function in contract_896b, so, everyone can trigger the fallback function.

As the fallback function of contract_896b eventually calls the fallback function in contract_7222, thus, the smart contract contract_896b is actually a wrapper for contract_7222.

The contract_7222 is deployed on the Ethereum blockchain by the following transaction.

Transaction Hash: 0x976535c0e6551af6423b8a5143ab11ebd87d4b9c4ea73a610953e9fc11b91ed6

Status: Success

Block: 6607801 2045496 Block Confirmations

Timestamp: 336 days 2 hrs ago (Oct-29-2018 10:11:02 PM +UTC)

From: 0x7e35ad5d816a1c4814a2c9e74f498db05dc3a038

To: [Contract 0x000007222caeb29694719e804b24fb3ee5116a8a Created]

Value: 0 Ether ($0.00)

Transaction Fee: 0.001208895 Ether ($0.22)

Gas Limit: 241,779

Gas Used by Transaction: 241,779 (100%)

Gas Price: 0.000000005 Ether (5 Gwei)

Nonce Position 0 16

Input Data:

The deployer of this smart contract is 0x7e35, which is not the same as that creating the wrapper contract contract_896b.

The creation time of this smart contract is Oct-29–2018 10:11:02 PM +UTC, and it is about two weeks before the wrapper contract is created, which is on Nov-13–2018 10:38:23 PM +UTC.

Again, as the source code of the contract_7222 is not made by its creator to the public, we use reverse engineering methods to restore most of its source code.

The source code of contract_7222 is given below.

pragma solidity ^0.5.1; contract contract_7222 {

address constant admin = 0x3A91B432b27Eb9A805C9Fd32d9f5517E9dD42Aa4;

address constant target = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;

constructor () public payable {

}

function () external payable {

if (msg.value != 0) {

return;

} address addr = tx.origin;

uint256 allow;

assembly {

allow := sload(addr)

} if ((allow == 0) && (tx.origin != admin)) {

return;

} uint256 len = msg.data.length;

bytes memory data;

assembly {

calldatacopy(add(add(data, 0x20), 0x1f), 0, len)

} uint8 cmd = uint8(msg.data[0]); if (cmd == 0x01) {

uint256 offset = 0x02;

uint256 slot;

assembly {

slot := mload(add(add(data, 0x20), offset))

} slot = (slot & 0xffff); while (true) {

uint256 matronId;

assembly {

matronId := mload(add(add(add(data, 0x20), offset), 0x04))

} matronId = matronId & 0xffffffff;

if (matronId == 0) {

if (slot != 0) {

assembly {

sstore(slot, 0)

}

} return;

} // function giveBirth() selector: 0x88c2a0bf

(bool success,) = target.call(

abi.encodeWithSelector(0x88c2a0bf, matronId)); if (!success) {

offset = offset + 0x07;

continue;

} offset = offset + 0x07; uint256 nonceStart; assembly {

nonceStart := mload(add(add(data, 0x20), offset))

} nonceStart = nonceStart & 0xffffff; if (nonceStart == 0) {

continue;

} for (uint256 idx = 0x05; idx >= 0; idx--) {

uint256 nonce = (nonceStart + idx);

if (nonce >= 0x010000) {

addr = address(uint160(bytes20(

keccak256(abi.encodePacked(

bytes1(0xd9),

bytes1(0x94),

address(this),

bytes1(0x83),

uint24(nonce)

))))); addr.call.value(msg.value)("");

continue;

} if (nonce >= 0x0100) {

addr = address(uint160(bytes20(

keccak256(abi.encodePacked(

bytes1(0xd8),

bytes1(0x94),

address(this),

bytes1(0x82),

uint16(nonce)

))))); addr.call.value(msg.value)("");

continue;

} if (nonce >= 0x80) {

addr = address(uint160(bytes20(

keccak256(abi.encodePacked(

bytes1(0xd7),

bytes1(0x94),

address(this),

bytes1(0x81),

uint8(nonce)

))))); addr.call.value(msg.value)("");

continue;

} addr = address(uint160(bytes20(

keccak256(abi.encodePacked(

bytes1(0xd6),

bytes1(0x94),

address(this),

uint8(nonce)

))))); addr.call.value(msg.value)("");

}

} return;

} if (cmd == 0x10) {

// 0x9c40 = 40000

while (gasleft() > 40000) {

new agent();

} return;

} if (cmd == 0x02) {

uint256 offset = 2;

uint256 slot;

assembly {

slot := mload(add(add(data, 0x20), offset))

} while ((slot & 0xffff) != 0) {

uint256 num = block.number;

assembly {

sstore(slot, num)

} offset = offset + 2;

assembly {

slot := mload(add(add(data, 0x20), offset))

}

} return;

} if (cmd == 0x03) {

uint256 amount;

assembly {

amount := mload(add(add(data, 0x20), 0x20))

} if (amount == 0) {

amount = address(this).balance;

} tx.origin.call.value(amount)(""); return;

} if (cmd == 0x11) {

bool success;

uint256 g = gasleft();

assembly {

addr := calldataload(0x14)

success := call(g, addr, 0, 0, 0, 0, 0)

} return;

} if (cmd == 0x20) {

uint256 offset = 0x14;

uint256 input;

assembly {

input := mload(add(add(data, 0x20), offset))

} addr = address(input); while (addr != address(0)) {

uint256 allow;

assembly {

allow := mload(add(add(add(data, 0x20), offset), 1))

} allow = allow & 1; assembly {

sstore(addr, allow)

} offset = offset + 0x15;

assembly {

input := mload(add(add(data, 0x20), offset))

} addr = address(input);

} return;

} if (cmd == 0xff) {

selfdestruct(tx.origin);

} return;

} }

contract agent {

address constant master = 0x000007222Caeb29694719E804b24Fb3eE5116a8a;

constructor () public {

}

function () external {

require (msg.sender == master);

selfdestruct(msg.sender);

}

}

In this smart contract, all functionality is provided in its fallback function. When entering the fallback function, it first checks whether or not the caller of the function has the authorization to use the service. If the caller is authorized to use the service, the function does nothing and simply exits. The caller is legitimate to the service if it is the administrator of the smart contract or if it is granted permit by the administrator.

The administrator is hard coded in the smart contract when the smart contract is created. The address of the administrator is 0x3a91, and it is stored in storage variable “admin”.

The input to the fallback function is a byte sequence. The first byte of the input acts as the “service type” the caller likes to use. The smart contract offers the following types of services.

service type 1: service for child delivery service type 2: service for creating a bank of storage slots service type 16: service for creating a pool of agent contracts service type 3: service for money withdraw service type 17: service for calling the fallback function in given address service type 32: service for granting access permit to specified addresses service type 255: service for destructing the smart contract

The main service is of course service type 1, which is used to give birth to new kittens.

In addition to this main service, the smart contract also provides other services that are mainly used to grant access permit to specified addresses, to create a bank of storage or a pool of contracts, and to withdraw money.

Similar to the midwife service introduced in part 1 of this article, the midwife service described above also takes advantage of storage refund and contract refund offered by the EVM of the Ethereum blockchain. When a storage slot is released, EVM gives the caller the storage refund as a reward. Similarly, the caller will get a refund when a smart contract is destroyed.

The service types 2 and 16 are provided by the smart contract to create a bank of storage and a pool of contracts, respectively.

The bank of storage and the pool of contracts are used to compensate the costs for child delivery. More specifically, when a kitten is successfully delivered, one storage slot will be released and 6 agent contracts will be destructed, so that the storage refund and contract refund can be obtained from EVM to cover part of the costs caused by calling the giveBirth() function in the CryptoKitties game. The key to the storage to be release and the starting nonce for the agent contracts to be destroyed are provided in the input to the fallback function.

To further reduce the cost of kitten delivery, multiple births can be delivered within a single transaction. the matron Ids of he to-be-born babies are provided in the input sequence to the fallback function.

The CryptoMidwife service in action

As pointed out before, contract contract_896b essentially acts as a wrapper for contract_7222, so all functionalities are provided by contract_7222. Therefore, users of the midwife service can interact with either contract_896b or contract_7222.

Right after the deployment of contract_7222, the administrator of the smart contract contract_7222 is the only one who can use the the service. To allow more users to use the service, the administrator needs to grant them permits.

Here is a sample transaction that triggers the service type 32 to give users permission to access the service.

Transaction Hash: 0x5129b522cd9b4f6b9431d0c5c3c9ad37d6afa0dc2e024b063afed475400cba99

Status: Success

Block: 6608078 2104470 Block Confirmations

Timestamp: 345 days 7 hrs ago (Oct-29-2018 11:11:53 PM +UTC)

From: 0x3a91b432b27eb9a805c9fd32d9f5517e9dd42aa4

To: Contract 0x000007222caeb29694719e804b24fb3ee5116a8a

Value: 0 Ether ($0.00)

Transaction Fee: 0.00043001 Ether ($0.08)

Gas Limit: 100,000

Gas Used by Transaction: 86,002 (86%)

Gas Price: 0.000000005 Ether (5 Gwei)

Nonce Position 20339 4

Input Data:

0x201b0dff20922e219276ff0a3496afdc02d92948a201cc5ddc48ba50a2e9564903eda9653f30a512f2b6011df10b78e4e523985e16d629fb12cd8b45e47ec701

The sender of this transaction is 0x3a91, which is in fact the administrator of the contract_7222. The service type requested by the transaction is 0x20 (i.e., 32). After the successful execution of this transaction, the following addresses will have the rights to access the services provided by the smart contract:

0x1b0dff20922e219276ff0a3496afdc02d92948a2 0xcc5ddc48ba50a2e9564903eda9653f30a512f2b6 0x1df10b78e4e523985e16d629fb12cd8b45e47ec7

It can be seen that within a single transaction, permits can be granted to multiple addresses.

Before the service for child delivery can be used, a bank of storage and a pool of contracts should be first created.

Here is a sample transaction that invokes the service type 2 to build a bank of storage.

Transaction Hash: 0x4547b3eadbcc47d1d93781692098ca5158a63eeeea14899812afcb34548ab155

Status: Success

Block: 6607879 2046505 Block Confirmations

Timestamp: 336 days 6 hrs ago (Oct-29-2018 10:27:31 PM +UTC)

From: 0x3a91b432b27eb9a805c9fd32d9f5517e9dd42aa4

To: Contract 0x000007222caeb29694719e804b24fb3ee5116a8a

Value: 0 Ether ($0.00)

Transaction Fee: 0.006101907 Ether ($1.12)

Gas Limit: 2,050,000

Gas Used by Transaction: 2,033,969 (99.22%)

Gas Price: 0.000000003 Ether (3 Gwei)

Nonce Position 20333 23

Input Data:

0x02000100020003000400050006000700080009000a000b000c000d000e000f0010001100120013001400150016001700180019001a001b001c001d001e001f0020002100220023002400250026002700280029002a002b002c002d002e002f0030003100320033003400350036003700380039003a003b003c003d003e003f0040004100420043004400450046004700480049004a004b004c004d004e004f0050005100520053005400550056005700580059005a005b005c005d005e005f00600061006200630064

It can be observed that the keys to the storage slots that will be created are enumerated in the input to the fallback function. Clearly, these keys are contiguous in most cases, thus, it seems quite inefficient to list them one by one in the input to the fallback function.

Here is a sample transaction for the creation of the agent contract pool by using service type 16 (i.e., 0x10).

Transaction Hash: 0xff0030c7fd9d60619ad6f54bb2a2841e75ab59aa87a5b6465410825a15abfcc8

Status: Success

Block: 6607900 2046485 Block Confirmations

Timestamp: 336 days 6 hrs ago (Oct-29-2018 10:33:00 PM +UTC)

From: 0x3a91b432b27eb9a805c9fd32d9f5517e9dd42aa4

To: Contract 0x000007222caeb29694719e804b24fb3ee5116a8a

Value: 0 Ether ($0.00)

Transaction Fee: 0.006734007 Ether ($1.24)

Gas Limit: 2,250,000

Gas Used by Transaction: 2,244,669 (99.76%)

Gas Price: 0.000000003 Ether (3 Gwei)

Nonce Position 20334 41

Input Data: 0x10

This transaction will create as many agent contracts as the gas limit allows. In particular, a new contract will be created if the remaining gas is still larger than 40000 units. For a gas limit 2,250,000 units, 60 agent contracts can be created as indicated by the internal transactions generated by this transaction.

The contract call From 0x3a91b432b27eb9a805c9fd32d9f5517e9dd42aa4 To 0x000007222caeb29694719e804b24fb3ee5116a8a produced 60 contract Internal Transactions : Type Trace Address From To Value Gas Limit create_0 0x000007222caeb29694719e804b24fb3ee5116a8a 0xa72c69f93968698658bb6364a2a8048343c155eb 0 Ether 2,162,242 create_1 0x000007222caeb29694719e804b24fb3ee5116a8a 0xb69b62d0d43f260e3884d3e713db6534f3c9a8d0 0 Ether 2,125,767 create_2 0x000007222caeb29694719e804b24fb3ee5116a8a 0x02ab19151854e6b024f26cf511679e5ba4813956 0 Ether 2,089,292 create_3 0x000007222caeb29694719e804b24fb3ee5116a8a 0xa86c65cd57fd4ff39a293c013ce14ed6375fd8fb 0 Ether 2,052,817 create_4 0x000007222caeb29694719e804b24fb3ee5116a8a 0x452bcf8f243fb6d950d115305e288f164617ea7a 0 Ether 2,016,342 create_5 0x000007222caeb29694719e804b24fb3ee5116a8a 0x65804ea6e5f7eb1e31145037c93198479c09619d 0 Ether 1,979,867 create_6 0x000007222caeb29694719e804b24fb3ee5116a8a 0x858fb1aafdf0448e3bbca0d414e0b16757eef075 0 Ether 1,943,392 create_7 0x000007222caeb29694719e804b24fb3ee5116a8a 0x376ce66dcfb795256804e810113c7a5093419388 0 Ether 1,906,917 create_8 0x000007222caeb29694719e804b24fb3ee5116a8a 0x92ae297621b99a1c7c6bbc282697e8178eb1dca2 0 Ether 1,870,442 (This part is skipped to save space) create_51 0x000007222caeb29694719e804b24fb3ee5116a8a 0x282449b5358924058b8a59397911b19da041ad25 0 Ether 302,016 create_52 0x000007222caeb29694719e804b24fb3ee5116a8a 0xfaaa50e4f40b38f18c61745a667dfed38fbd27e6 0 Ether 265,541 create_53 0x000007222caeb29694719e804b24fb3ee5116a8a 0xae42d9359c02c8d42ab97472112d613cb595e6fb 0 Ether 229,066 create_54 0x000007222caeb29694719e804b24fb3ee5116a8a 0x3d0906967be6542d956ca98c2a587e434e3b4c28 0 Ether 192,591 create_55 0x000007222caeb29694719e804b24fb3ee5116a8a 0x09a55424cee414c3411cfedd3dbde6d840a962d4 0 Ether 156,115 create_56 0x000007222caeb29694719e804b24fb3ee5116a8a 0xcda5433eb89de1c0205cb8aa82a8c18f6fff3ccf 0 Ether 119,640 create_57 0x000007222caeb29694719e804b24fb3ee5116a8a 0x4274bc30cd3a0e8281461c0232636893b90dfcb7 0 Ether 83,165 create_58 0x000007222caeb29694719e804b24fb3ee5116a8a 0x5b6a96fdf6675689bb230b39d52fab346c01081f 0 Ether 46,690 create_59 0x000007222caeb29694719e804b24fb3ee5116a8a 0xc4285dafda00dadb4122e7f614a28f79452d9fde 0 Ether 10,215

It can be seen that the remaining gas is 10,215 units after the 60th agent contract is created. So, totally 60 contracts are generated by this transaction.

When the service for child delivery is used, the call to giveBirth() function in the CryptoKitties may fail if the transaction arrives late, meaning the the kitten this transaction tries to deliver has already been given birth by a transaction submitted by others.

Here is a sample transaction that attempts to give birth to a kitten but fails.

Transaction Hash: 0x3c7bd6024506caeb3c2022e573eea9797381ad0b8cc5de6fef74fd2d98759224

Status: Success

Block: 6607969 2064435 Block Confirmations

Timestamp: 339 days 1 hr ago (Oct-29-2018 10:48:33 PM +UTC)

From: 0x6df71d63ad1bdd99b61aaf1d67f0b7a1274e5d03

To: Contract 0x000007222caeb29694719e804b24fb3ee5116a8a

Although one or more Error Occurred [Reverted] Contract Execution Completed

Value: 0 Ether ($0.00)

Transaction Fee: 0.00103336198515 Ether ($0.18)

Gas Limit: 1,525,000

Gas Used by Transaction: 32,213 (2.11%)

Gas Price: 0.000000032079035953 Ether (32.079035953 Gwei)

Nonce Position 0 6

Input Data:

0x0100010011539a00000100066f490000070007898700000d000a9522000013000e973d000019

This transaction uses service type 1, which tries to give birth to kittens. Multiple cats are to be delivered within a single transaction. The matron Ids are: 0x0011539a, 0x00066f49, 0x00078987, 0x000a9522, and 0x000e973d.

Here is a sample transaction that successfully gives birth to a kitten.

Transaction Hash: 0x63a4295367a57df42b145076e08a726739c8afe979cf3a53f3a6a4b07209482c

Status: Success

Block: 6607970 2046429 Block Confirmations

Timestamp: 336 days 5 hrs ago (Oct-29-2018 10:49:01 PM +UTC)

From: 0x6df71d63ad1bdd99b61aaf1d67f0b7a1274e5d03

To: Contract 0x000007222caeb29694719e804b24fb3ee5116a8a

SELF DESTRUCT Contract 0x2a88ab66ee13f831e588f3d34d5f9c15509cd2d1

SELF DESTRUCT Contract 0xac063af7d326610bddcf4b9424881185e6324012

SELF DESTRUCT Contract 0xbe78698b259727545452c037bffc57d3eeb30dc2

SELF DESTRUCT Contract 0x1bad56e69e0730a6b1253e2440257f0ad7de5577

SELF DESTRUCT Contract 0x175a8f764aae59027c21c9dcf9a37a2805b607d1

SELF DESTRUCT Contract 0x967bad08255e6cfeaafeb4c5f7544cb72bb7f2af Tokens Transferred:

From 0x0000000000000000000000000000000000000000To 0xef3d9ddf59f3622a04753c61e6c4d596e7fc610dFor ERC-721 TokenID [1138517] CryptoKittie... (CK)

Value: 0 Ether ($0.00)

Transaction Fee: 0.00770226456453 Ether ($1.42)

Gas Limit: 325,000

Gas Used by Transaction: 150,347 (46.26%)

Gas Price: 0.000000051229918552 Ether (51.229918552 Gwei)

Nonce Position 6 44

Input Data: 0x0100020011469400001f

Only a single new baby was born in this transaction. The Id of the new born kitten is 1138517. The matron Id for the new baby is 0x00114694. The key to the storage to be released is 0x0002 and the starting nonce for the contracts to be destroyed is 0x00001f.

The following is the information on the internal transactions generated by this transaction.

The contract call From 0x6df71d63ad1bdd99b61aaf1d67f0b7a1274e5d03 To 0x000007222caeb29694719e804b24fb3ee5116a8a produced 7 contract Internal Transactions : Type Trace Address From To Value Gas Limit call_0_1 0x06012c8cf97bead5deae237070f9587f8e7a266d 0x000007222caeb29694719e804b24fb3ee5116a8a 0.008 Ether 2,300 suicide_1_0 0x2a88ab66ee13f831e588f3d34d5f9c15509cd2d1 0x000007222caeb29694719e804b24fb3ee5116a8a 0 Ether 0 suicide_2_0 0xac063af7d326610bddcf4b9424881185e6324012 0x000007222caeb29694719e804b24fb3ee5116a8a 0 Ether 0 suicide_3_0 0xbe78698b259727545452c037bffc57d3eeb30dc2 0x000007222caeb29694719e804b24fb3ee5116a8a 0 Ether 0 suicide_4_0 0x1bad56e69e0730a6b1253e2440257f0ad7de5577 0x000007222caeb29694719e804b24fb3ee5116a8a 0 Ether 0 suicide_5_0 0x175a8f764aae59027c21c9dcf9a37a2805b607d1 0x000007222caeb29694719e804b24fb3ee5116a8a 0 Ether 0 suicide_6_0 0x967bad08255e6cfeaafeb4c5f7544cb72bb7f2af 0x000007222caeb29694719e804b24fb3ee5116a8a 0 Ether 0

The internal transaction “call_0_1” clearly indicates that the birthing fee 0.008 Ethers is transferred from CryptoKitties (i.e., 0x0601) to the contract_7222.

The internal transactions “suicide_1_0” to “suicide_6_0” are generated by the 6 agent contracts that self destruct themselves.

During the execution of giveBirth() function, the smart contract KittyCore emits some events shown below.

Transaction Receipt Event Logs Address 0x06012c8cf97bead5deae237070f9587f8e7a266d

Name Birth (address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes)

Topics 0 0x0a5311bd2a6608f08a180df2ee7c5946819a649b204b554bb8e39825b2c50ad5

Data

000000000000000000000000ef3d9ddf59f3622a04753c61e6c4d596e7fc610d

0000000000000000000000000000000000000000000000000000000000115f55

0000000000000000000000000000000000000000000000000000000000114694

00000000000000000000000000000000000000000000000000000000001146cf

00006b16c2adc44a401380014012d79842309a84b0a41a8017bc2c30c4278c23 Address 0x06012c8cf97bead5deae237070f9587f8e7a266d

Name Transfer (address from, address to, uint256 tokenId)

Topics 0 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

Data

0000000000000000000000000000000000000000000000000000000000000000

000000000000000000000000ef3d9ddf59f3622a04753c61e6c4d596e7fc610d

0000000000000000000000000000000000000000000000000000000000115f55

From the event Birth(), I know that the matron Id and Sire Id of the newly born kitten are 0x114694 and 0x1146cf, respectively. The new kitten has Id of 0x115f55. The owner of matron cat is 0xef3d9ddf59f3622a04753c61e6c4d596e7fc610d.

After the kitten was born, the owner of this new baby is the same as that of its matron, that is, 0xef3d9ddf59f3622a04753c61e6c4d596e7fc610d as indicated in the event Transfer().

In fact, this new kitten is bred by its matron and sire in the following transaction by its owner.

Transaction Hash: 0xaca1df26d32e1fe4f7d23e83c9c8aef051d284c58d509f28bfd9406d3109adde

Status: Success

Block: 6604130 2125380 Block Confirmations

Timestamp: 348 days 15 hrs ago (Oct-29-2018 07:55:23 AM +UTC)

From: 0xef3d9ddf59f3622a04753c61e6c4d596e7fc610d

To: Contract 0x06012c8cf97bead5deae237070f9587f8e7a266d (CryptoKitties: Core)

Value: 0.008 Ether ($1.45)

Transaction Fee: 0.000568613365 Ether ($0.10)

Gas Limit: 119,977

Gas Used by Transaction: 79,985 (66.67%)

Gas Price: 0.000000007109 Ether (7.109 Gwei)

Nonce Position 2148 153

Input Data: Function: breedWithAuto(uint256 _matronId, uint256 _sireId)

MethodID: 0xf7d8c883

[0]: 0000000000000000000000000000000000000000000000000000000000114694

[1]: 00000000000000000000000000000000000000000000000000000000001146cf

The event generated by this transaction is as follows.

Transaction Receipt Event Logs Address 0x06012c8cf97bead5deae237070f9587f8e7a266d

Name Pregnant (address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock) Topics 0 0x241ea03ca20251805084d27d4440371c34a0b85ff108f6bb5611248f73818b80

Data

000000000000000000000000ef3d9ddf59f3622a04753c61e6c4d596e7fc610d

0000000000000000000000000000000000000000000000000000000000114694

00000000000000000000000000000000000000000000000000000000001146cf

000000000000000000000000000000000000000000000000000000000064d462

The event Pregnant() shows that the block for the expected kitten is 0x64d462 (i.e., 6607970), which is exactly the block number where the child delivery service is triggered.

References