CryptoCats pre-launch test contract (Nov 2017). The first version to introduce cat names and the allInitialOwnersAssigned() initialization pattern.
Token Information
Key Facts
Description
Deployed one day before the public CryptoCats launch on 2017-11-12, this test contract introduced the catName string field in the Offer struct, baking "Cat 0" through "Cat 11" directly into the blockchain. Unlike the production v3 contract (0x088C), this version has only 18 functions with no marketplace functions yet. The struct follows v3 field order: {bool isForSale; uint catIndex; address seller; string catName}. Compiled with Solidity 0.4.18 + optimizer. Source reconstructed by EthereumHistory.com achieved 98.1% match (5715/5823 bytes). The 108-byte gap is dead code from the constructor-only cat initialization function.
Source Verified
5715/5823 bytes (98.1%). All 18 selectors match. All function logic matches. 108-byte gap isolated to cat init dead code region (optimizer behavior with pre-release 0.4.18 build). Struct confirmed: {bool isForSale; address seller; string catName; uint catIndex;}
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology (near-exact bytecode match).
View Verification ProofShow source code (Solidity)
/**
* CryptoCatsMarket - Pre-launch Test Contract 1
*
* Contract address: 0xD23AdE68C693264Aa9e8f8303F912A3E54718456
* Deploy block: 4530388
* Deploy date: 2017-11-11 (one day before CryptoCats public launch)
* Deploy tx: 0x94efb7f...
*
* Source reconstructed by EthereumHistory.com
* https://www.ethereumhistory.com/contract/0xD23AdE68C693264Aa9e8f8303F912A3E54718456
*
* Compilation: Solidity 0.4.18 + optimizer ON
* Verification status: near_exact_match
* - Reconstructed: 5715 bytes
* - On-chain: 5823 bytes
* - Match: 98.1%
*
* Notes:
* This was the first pre-launch test of the CryptoCats marketplace.
* It introduced the catName string field in the Offer struct and the
* allInitialOwnersAssigned() function that bakes all 12 cats into storage.
* The 108-byte gap is in the cat initialization block; the exact compiler
* build (possibly a pre-release 0.4.18 nightly) has not been recovered.
*
* The verified CryptoCats v3 production contract is:
* 0x088C6Ad962812b5Aa905BA6F3c5c145f9D4C079f (Solidity 0.4.19)
*/
pragma solidity ^0.4.18;
contract CryptoCatsMarket {
string public imageHash = "3b82cfd5fb39faff3c2c9241ca5a24439f11bdeaa7d6c0771eb782ea7c963917";
address owner;
string public standard = 'CryptoCats';
string public name;
string public symbol;
uint8 public decimals;
uint256 public _totalSupply;
bool public allCatsAssigned = false;
bool public allInitialOwnersAssigned = false;
uint public catsRemainingToAssign = 0;
mapping (uint => address) public catIndexToAddress;
mapping (address => uint) public balanceOf;
struct Offer {
bool isForSale;
address seller;
string catName;
uint catIndex;
}
mapping (uint => Offer) public catDetails;
event Assign(address indexed to, uint256 catIndex);
event Transfer(address indexed from, address indexed to, uint256 value);
function CryptoCatsMarket() payable {
owner = msg.sender;
_totalSupply = 12;
catsRemainingToAssign = _totalSupply;
name = "CRYPTOCATS";
symbol = "CCAT";
decimals = 0;
}
function allInitialOwnersAssigned() {
require(msg.sender == owner);
catDetails[0] = Offer(false, msg.sender, "Cat 0", 0);
catDetails[1] = Offer(false, msg.sender, "Cat 1", 1);
catDetails[2] = Offer(false, msg.sender, "Cat 2", 2);
catDetails[3] = Offer(false, msg.sender, "Cat 3", 3);
catDetails[4] = Offer(false, msg.sender, "Cat 4", 4);
catDetails[5] = Offer(false, msg.sender, "Cat 5", 5);
catDetails[6] = Offer(false, msg.sender, "Cat 6", 6);
catDetails[7] = Offer(false, msg.sender, "Cat 7", 7);
catDetails[8] = Offer(false, msg.sender, "Cat 8", 8);
catDetails[9] = Offer(false, msg.sender, "Cat 9", 9);
catDetails[10] = Offer(false, msg.sender, "Cat 10", 10);
catDetails[11] = Offer(false, msg.sender, "Cat 11", 11);
allCatsAssigned = true;
}
function claimCat(uint catIndex) {
require(!allCatsAssigned);
require(catsRemainingToAssign != 0);
require(catIndexToAddress[catIndex] == 0x0);
require(catIndex < _totalSupply);
catIndexToAddress[catIndex] = msg.sender;
balanceOf[msg.sender]++;
catsRemainingToAssign--;
Assign(msg.sender, catIndex);
}
function getCatDetail(uint catIndex) public returns (uint _catIndex, bool isForSale, address seller, string catName) {
Offer storage offer = catDetails[catIndex];
_catIndex = offer.catIndex;
isForSale = offer.isForSale;
seller = offer.seller;
catName = offer.catName;
}
function transfer(address _to, uint256 _value) returns (bool success) {
if (_value < _totalSupply && catIndexToAddress[_value] == msg.sender && balanceOf[msg.sender] > 0) {
balanceOf[msg.sender]--;
catIndexToAddress[_value] = _to;
balanceOf[_to]++;
Transfer(msg.sender, _to, _value);
success = true;
} else {
success = false;
}
return success;
}
function balanceOf(address _owner) constant returns (uint256 balance) {
require(balanceOf[_owner] != 0);
return balanceOf[_owner];
}
function totalSupply() constant returns (uint256 totalSupply) {
return _totalSupply;
}
function getCatOwner(uint256 catIndex) public returns (address) {
require(catIndexToAddress[catIndex] != 0x0);
return catIndexToAddress[catIndex];
}
function getContractOwner() public returns (address) {
return owner;
}
}