Back to Home

CRYPTOCATS(CCAT)

0x78eea094e1d3...a7bfcc921f9e
Spurious DragonContract #136KSource VerifiedEdit this contract
Deployed November 11, 2017 (8 years ago)Block 4,532,036

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

Token Name
CRYPTOCATS
Symbol
CCAT
Decimals
0

Key Facts

Deployment Block
4,532,036
Deployment Date
Nov 11, 2017, 11:15 AM
Code Size
8.3 KB
Gas at Deploy
3,293,077
Transactions by Year
20172
20212
202512

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

SolidityNear-exact bytecode match
Compiler: v0.4.18

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.

Block span: 2,675,0004,369,999
November 22, 2016October 16, 2017

Bytecode Overview

Opcodes8,451
Unique Opcodes200
Jump Instructions236
Storage Operations150

Verified Source Available

Source verified through compiler archaeology (near-exact bytecode match).

View Verification Proof
Show 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;
    }

}

External Links