CryptoCats pre-launch test contract 2 (Nov 2017). Second test deployed the same day as T1, compiled without the optimizer and introducing the v3-style struct an...
Token Information
Key Facts
Description
Second pre-launch test contract for CryptoCats, deployed the same day as T1. Notable differences: compiled without optimizer (8451 bytes vs T1's 5823), seller initialized to zero address (vs msg.sender in T1), and imageHash set to placeholder "INSERT ACTUAL HASH HERE" rather than the actual image hash. The struct and function signatures are identical to T1. At runtime, allInitialOwnersAssigned() only sets allCatsAssigned=true; the actual cat initialization is dead code from the constructor. Source reconstructed by EthereumHistory.com achieved 96.3% match (8137/8451 bytes). Same 314-byte gap from dead constructor code.
Source Verified
8137/8451 bytes (96.3%). All function selectors match. All function logic matches. 314-byte gap isolated to dead code region from constructor-only cat init (no optimizer = full code preserved). Struct confirmed: {bool isForSale; uint catIndex; address seller; string catName;}. getCatDetail return order: (bool, uint, address, string).
Spurious Dragon Era
Continued DoS protection. State trie clearing.
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 2
*
* Contract address: 0x78eea094e1d30141ccade64f8d29a7bfcc921f9e
* Deploy block: 4532036
* Deploy date: 2017-11-11 (one day before CryptoCats public launch)
* Deploy tx: 0x51d6871d7c3021d6392c0bbc6f4aa88be400f066b1ebeb9317e09c27449f5c95
*
* Source reconstructed by EthereumHistory.com
* https://www.ethereumhistory.com/contract/0x78eea094e1d30141ccade64f8d29a7bfcc921f9e
*
* Compilation: Solidity 0.4.18, optimizer OFF
* Verification status: near_exact_match
* - Reconstructed: 8137 bytes
* - On-chain: 8451 bytes
* - Match: 96.3%
*
* Notes:
* This was the second pre-launch test of the CryptoCats marketplace,
* deployed on the same day as Test Contract 1 (0xD23A...).
*
* Key differences from Test Contract 1:
* - Compiled WITHOUT optimizer (produces larger bytecode)
* - Struct field order: {bool isForSale; uint catIndex; address seller; string catName;}
* - getCatDetail() returns (bool, uint, address, string) — v3-style order
* - allInitialOwnersAssigned() at runtime ONLY sets allCatsAssigned=true
* - All 12 cat Offer structs are initialized in the constructor (dead code at runtime)
* - seller = 0x0 (not msg.sender)
* - imageHash was a placeholder string ("INSERT ACTUAL HASH HERE")
*
* The 314-byte gap is dead code from the constructor-only internal cat init
* function. The same root cause as T1 (108 bytes), but larger because the
* optimizer was disabled — all that code is preserved verbatim.
*
* The verified CryptoCats v3 production contract is:
* 0x088C6Ad962812b5Aa905BA6F3c5c145f9D4C079f (Solidity 0.4.19)
*/
pragma solidity ^0.4.18;
contract CryptoCatsMarket {
string public imageHash = "INSERT ACTUAL HASH HERE";
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;
uint catIndex;
address seller;
string catName;
}
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, 0, 0x0, "Cat 0");
catDetails[1] = Offer(false, 1, 0x0, "Cat 1");
catDetails[2] = Offer(false, 2, 0x0, "Cat 2");
catDetails[3] = Offer(false, 3, 0x0, "Cat 3");
catDetails[4] = Offer(false, 4, 0x0, "Cat 4");
catDetails[5] = Offer(false, 5, 0x0, "Cat 5");
catDetails[6] = Offer(false, 6, 0x0, "Cat 6");
catDetails[7] = Offer(false, 7, 0x0, "Cat 7");
catDetails[8] = Offer(false, 8, 0x0, "Cat 8");
catDetails[9] = Offer(false, 9, 0x0, "Cat 9");
catDetails[10] = Offer(false, 10, 0x0, "Cat 10");
catDetails[11] = Offer(false, 11, 0x0, "Cat 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 (bool isForSale, uint _catIndex, address seller, string catName) {
Offer storage offer = catDetails[catIndex];
isForSale = offer.isForSale;
_catIndex = offer.catIndex;
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;
}
}