Contract Overview |  GU_RarePackTwo
Balance: 0 Ether
Ether Value: $0
Transactions: 618 txns
Misc:
Address Watch: Add To Watch List
Contract Creator: 0x32001fcccc7e1b3193818bb88b5eb1bd827e2bc6at txn 0x88614d9aae5111d050cd1383f5292f783b4d9c30638aca77c3858720a30dbddd
 Latest 25 transactions from a total of 618 transactions

TxHash Age From To Value [TxFee]
0xfa6e9ca37ef9bd1127622bc0395fa8ccd59e4ab7fa7cc2853242a06c7ef9024c165 days 2 hrs ago0xf3027f384aabd2d5a5f0021bd192c00defe52edb  IN   GU_RarePackTwo0.041 Ether0.00022368
0x242bd6719d9ef2376c500e14ae9ea0dc3b148f5dfc3f2ffd65b8acb5c20bd2c8165 days 2 hrs ago0xf3027f384aabd2d5a5f0021bd192c00defe52edb  IN   GU_RarePackTwo0.041 Ether0.00022368
0x0fbd456bbdf9dd75a475bf9fa30655d9d4aa3f1cd7ae524708f8985a151df60d165 days 2 hrs ago0xf3027f384aabd2d5a5f0021bd192c00defe52edb  IN   GU_RarePackTwo0.041 Ether0.000201312
0xd099262b1ef07947cf038c995c4cd921d34fab385da531b6ac955478b8b5fea0179 days 16 hrs ago0x95b697e13f227d55ef4336f7aa762fe243eef590  IN   GU_RarePackTwo0 Ether0.00027448
0x416e58716a98938470622a35fb32b8006af9db94e81366a5697849cb4a72446f179 days 16 hrs ago0xcb3562dd15807e2bcf35092b1e873971af0a51da  IN   GU_RarePackTwo0 Ether0.00022175
0x05404391de8f52d0e0cd48e443c45151cb4b5f410eb91a8c7b26aa3995ca9d49184 days 1 hr ago0xd3a9ac5ffcfeb6100349644d90376577d966f78e  IN   GU_RarePackTwo0.0405 Ether0.000022368
0x3494becd2be2589ee2649d35553d30845d8536173841c3e3ddafd6f22309ddd7187 days 13 hrs ago0xa2c384daff26de217c00e55978c72373ac661952  IN   GU_RarePackTwo0 Ether0.00037972
0x2e8153915ec65e0747cd8f0e660a7ccd9d09f6e9158a6fdc9b95b27c076d86d5187 days 22 hrs ago0x1e2d425f30576432a8c74c8f74f0c8ff8a62f728  IN   GU_RarePackTwo0.405 Ether0.000313152
0x769ee9e948d430176d740dd7e31099ccb9ee16c9df60860c00d633db73463e16187 days 22 hrs ago0x1e2d425f30576432a8c74c8f74f0c8ff8a62f728  IN   GU_RarePackTwo0.405 Ether0.000268416
0x5dce2f00c49451df0ae8dcde5e5c26e9c43bcfb2ef1d5702c7d3f1d55e884644188 days 5 hrs ago0x09fff5e07db359e2fd26664981f0e9fa9cbc031a  IN   GU_RarePackTwo0.0405 Ether0.000357888
0x5c1b673437211e811e7502f1de33f55796559856c07336ecab2ea7ce26e4ac21188 days 22 hrs ago0xafe7e3264efca320af481af3408d6f348878ec88  IN   GU_RarePackTwo0.0415 Ether0.00022368
0xf2c2f01d6230304440d750f3766a79a4dd22362bd81e1b888dded820a74f20fc189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.00089472
0xbe6e7a047e8bf11440412e9b3583306fdb52e04953fd26fe19193c63b290b679189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.000984192
0x8b85195a74412a80355cb6967ed080502c738cb3606e1456a962a91b118b565b189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.000581568
0xa1e402b9e969fe147da080c14ba48e8a939f5d400f5a50cc6fe91caf7aa7b751189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.000872352
0xcb0644a5616c1bc52970f1603d3e001e99d8358271cf48dfde1e1806be938e42189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.000917088
0x62e159eda2d536ba3da266d06b2ca88331d397fbe9a8d9b9dc8f91357f856e1d189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.000693408
0x801264316b6fc567fd53aed9289aa231497247262721d6e1dc50370f3e66d25d189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.000738144
0x5f539d09dbf14c04692c08bc93f4963f3291c5aca16b50947a6be62da92c56b5189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.000738144
0xa19a3f38eb1a47fd7761d09326aaa2797694bf3b3a8a81bfb85dbced8ba10249189 days 7 hrs ago0xdc94fb2cef70695874f4e4703d9fa077df99a6c8  IN   GU_RarePackTwo0.0415 Ether0.000715776
0xed4ef20b8f2034df56987662f0497842e936aabc38f14f0e20a7b8323f032f43190 days 3 hrs ago0x0cdd0ff2ea99e5a2476c709eeb705a70934a5c6f  IN   GU_RarePackTwo0.0405 Ether0.001599312
0x2453a013eb667b2b7928431007bbca21ba98eab9949ecf39b5bf9a4e26de3313190 days 7 hrs ago0x879641ab948d6f50f74eb4bf957bad5315fdcf6a  IN   GU_RarePackTwo0.0405 Ether0.000178944
0x05039a0a58a39012b20a598cb905ebd89195f24b3714a03e02e127565d659314190 days 19 hrs ago0xbc209738a1f91c99efa7fae4eca6ebc4f9c6479c  IN   GU_RarePackTwo0.0405 Ether0.000201312
0xeb06d13ad5c224ae23e3b8a2bf8ac928251a5b4be52ac09155d48674415ee708190 days 21 hrs ago0xe0fb7622091e3d9ef9b438471b10b9ea88c7cf6b  IN   GU_RarePackTwo0.041 Ether0.00023648
0x90f56cad5a7067600ce64b7e0759fca2d0894cfd7eefb7ae7c1c81f93a11ef78190 days 21 hrs ago0xe0fb7622091e3d9ef9b438471b10b9ea88c7cf6b  IN   GU_RarePackTwo0.041 Ether0.000212832
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 25 Internal Txns, Click here To View More View All
ParentTxHash Block Age From To Value
0x413db52c4039f49697a66dbcee53e8c2c5fe93f2754aee9848e10ce5b9db82d65965985192 days 8 mins ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x05071038e6a8254f592938fe6057679c4051f27f0b06c4c6c9c8d0f5581e71915965803192 days 53 mins ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0xa88e868ed1e46630f2119b00235786b98f62c9a47cad4413ba3184f0ca35becb5965778192 days 59 mins ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0xeec62eb666013ad4a9b0a56ec3a5459297722d5207901cd03be2dfb3884059e35965690192 days 1 hr ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x288816230ac9a378893b7c21b3fe050aff25dff92f377b6545d2f747e3fd540d5965640192 days 1 hr ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x56419f80f1c7b1fc290a824c0d964254f13006af9400c668ed92ceead75806495965322192 days 2 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0xf8752f3cfe755fe20363e65878b1ce88378099d1c96bc1054648d4586b75cf395965312192 days 2 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0xe681984f4d77eff39e144d6cdf8830b74871e804e6e55a4f31b4bba659ded91a5965308192 days 2 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x3211af04d7f04242561b5587ae8c6e79952cd2bacec6fec4e1c879f2fdce85665965300192 days 3 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x144d46b31105bcd325fa69a773cef4f57c722026cc041c01c5d903aee5dfa4d45964605192 days 5 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x618478cf758f3ba3bf47ba7e1fbf0f73c66fac3f5673528483ead01f112e5bba5964602192 days 5 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x1dbd3d0b21c4f8bbd44b90a7a73d6b1d3ce15ff6bec31a4d0195144592ff67b35964598192 days 5 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x472aab0babe74a76c85dd5e2da2aeb8cc57c04f904b7b203400d075e2f2f3d005964597192 days 5 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0xce6182c6168135cbd94e0649a9329cf186fdb74e4db4786f5bd0e9957b2b6eeb5964528192 days 6 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.252 Ether
0x253b9f425f7f7c6e7d80c3301cb7bd42e835ff85d7a5a590cf5a3c5840dc9a965964429192 days 6 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.252 Ether
0x6bf34de7251dc21870a1f7eb091de38ad797ede4fe4874693f25b5767afc6e415964177192 days 7 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x0e2134720d1cc2992be9478f67cee0a6a51f1da17cb815fcd41221be5be534e75963869192 days 8 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x2b717d3af726668a13333f3ce6a28d90aa7c02eae89c129df53dd3cc0eb22e5a5963838192 days 9 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x38c1d0cd154572ccaa4b60078cfdaa1596cfc4434c02d10ea6577b349f8b5b3a5963820192 days 9 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0x82cd3f1749aaf149cf16604dc7cf4d66f010635e7d8e1e8d09ff1dcc01465d045963782192 days 9 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0xf4680d14ddcba7bad66db5f1e678acd6855aeba0e967734a55ee222c583144e55963740192 days 9 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0xbb7e628bf7681683227aabe4b8e5a231a9ccc6233cdad43121ec5452b8b33e695963404192 days 10 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.0378 Ether
0xbb7e628bf7681683227aabe4b8e5a231a9ccc6233cdad43121ec5452b8b33e695963404192 days 10 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900xcb3562dd15807e2bcf35092b1e873971af0a51da0.0042 Ether
0xc62bf55a3c2e73c1388142b04fb69fc7260a1f8aff574826d535c39677a9eb195963337192 days 10 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.042 Ether
0xbebe5842ed7365bc40abe8f3b428024bd8e79ae015318467808bf1c8b8c30fe25963331192 days 10 hrs ago0xca6746f65d53d2df5022b5d775817e62e84626900x91b9d2835ad914bc1dcfe09bd1816febd04fd6890.42 Ether
[ Download CSV Export  ] 
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) SolidityCompiler Bugs.

Contract Source Code Verified (Exact Match)
Contract Name: RarePackTwo
Compiler Text: v0.4.24+commit.e67f0147
Optimization Enabled: No
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity 0.4.24;

contract Governable {

    event Pause();
    event Unpause();

    address public governor;
    bool public paused = false;

    constructor() public {
        governor = msg.sender;
    }

    function setGovernor(address _gov) public onlyGovernor {
        governor = _gov;
    }

    modifier onlyGovernor {
        require(msg.sender == governor);
        _;
    }

    /**
    * @dev Modifier to make a function callable only when the contract is not paused.
    */
    modifier whenNotPaused() {
        require(!paused);
        _;
    }

    /**
    * @dev Modifier to make a function callable only when the contract is paused.
    */
    modifier whenPaused() {
        require(paused);
        _;
    }

    /**
    * @dev called by the owner to pause, triggers stopped state
    */
    function pause() onlyGovernor whenNotPaused public {
        paused = true;
        emit Pause();
    }

    /**
    * @dev called by the owner to unpause, returns to normal state
    */
    function unpause() onlyGovernor whenPaused public {
        paused = false;
        emit Unpause();
    }

}

contract CardBase is Governable {


    struct Card {
        uint16 proto;
        uint16 purity;
    }

    function getCard(uint id) public view returns (uint16 proto, uint16 purity) {
        Card memory card = cards[id];
        return (card.proto, card.purity);
    }

    function getShine(uint16 purity) public pure returns (uint8) {
        return uint8(purity / 1000);
    }

    Card[] public cards;
    
}

contract CardProto is CardBase {

    event NewProtoCard(
        uint16 id, uint8 season, uint8 god, 
        Rarity rarity, uint8 mana, uint8 attack, 
        uint8 health, uint8 cardType, uint8 tribe, bool packable
    );

    struct Limit {
        uint64 limit;
        bool exists;
    }

    // limits for mythic cards
    mapping(uint16 => Limit) public limits;

    // can only set limits once
    function setLimit(uint16 id, uint64 limit) public onlyGovernor {
        Limit memory l = limits[id];
        require(!l.exists);
        limits[id] = Limit({
            limit: limit,
            exists: true
        });
    }

    function getLimit(uint16 id) public view returns (uint64 limit, bool set) {
        Limit memory l = limits[id];
        return (l.limit, l.exists);
    }

    // could make these arrays to save gas
    // not really necessary - will be update a very limited no of times
    mapping(uint8 => bool) public seasonTradable;
    mapping(uint8 => bool) public seasonTradabilityLocked;
    uint8 public currentSeason;

    function makeTradeable(uint8 season) public onlyGovernor {
        seasonTradable[season] = true;
    }

    function makeUntradable(uint8 season) public onlyGovernor {
        require(!seasonTradabilityLocked[season]);
        seasonTradable[season] = false;
    }

    function makePermanantlyTradable(uint8 season) public onlyGovernor {
        require(seasonTradable[season]);
        seasonTradabilityLocked[season] = true;
    }

    function isTradable(uint16 proto) public view returns (bool) {
        return seasonTradable[protos[proto].season];
    }

    function nextSeason() public onlyGovernor {
        //Seasons shouldn't go to 0 if there is more than the uint8 should hold, the governor should know this ¯\_(ツ)_/¯ -M
        require(currentSeason <= 255); 

        currentSeason++;
        mythic.length = 0;
        legendary.length = 0;
        epic.length = 0;
        rare.length = 0;
        common.length = 0;
    }

    enum Rarity {
        Common,
        Rare,
        Epic,
        Legendary, 
        Mythic
    }

    uint8 constant SPELL = 1;
    uint8 constant MINION = 2;
    uint8 constant WEAPON = 3;
    uint8 constant HERO = 4;

    struct ProtoCard {
        bool exists;
        uint8 god;
        uint8 season;
        uint8 cardType;
        Rarity rarity;
        uint8 mana;
        uint8 attack;
        uint8 health;
        uint8 tribe;
    }

    // there is a particular design decision driving this:
    // need to be able to iterate over mythics only for card generation
    // don't store 5 different arrays: have to use 2 ids
    // better to bear this cost (2 bytes per proto card)
    // rather than 1 byte per instance

    uint16 public protoCount;
    
    mapping(uint16 => ProtoCard) protos;

    uint16[] public mythic;
    uint16[] public legendary;
    uint16[] public epic;
    uint16[] public rare;
    uint16[] public common;

    function addProtos(
        uint16[] externalIDs, uint8[] gods, Rarity[] rarities, uint8[] manas, uint8[] attacks, uint8[] healths, uint8[] cardTypes, uint8[] tribes, bool[] packable
    ) public onlyGovernor returns(uint16) {

        for (uint i = 0; i < externalIDs.length; i++) {

            ProtoCard memory card = ProtoCard({
                exists: true,
                god: gods[i],
                season: currentSeason,
                cardType: cardTypes[i],
                rarity: rarities[i],
                mana: manas[i],
                attack: attacks[i],
                health: healths[i],
                tribe: tribes[i]
            });

            _addProto(externalIDs[i], card, packable[i]);
        }
        
    }

    function addProto(
        uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 cardType, uint8 tribe, bool packable
    ) public onlyGovernor returns(uint16) {
        ProtoCard memory card = ProtoCard({
            exists: true,
            god: god,
            season: currentSeason,
            cardType: cardType,
            rarity: rarity,
            mana: mana,
            attack: attack,
            health: health,
            tribe: tribe
        });

        _addProto(externalID, card, packable);
    }

    function addWeapon(
        uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 durability, bool packable
    ) public onlyGovernor returns(uint16) {

        ProtoCard memory card = ProtoCard({
            exists: true,
            god: god,
            season: currentSeason,
            cardType: WEAPON,
            rarity: rarity,
            mana: mana,
            attack: attack,
            health: durability,
            tribe: 0
        });

        _addProto(externalID, card, packable);
    }

    function addSpell(uint16 externalID, uint8 god, Rarity rarity, uint8 mana, bool packable) public onlyGovernor returns(uint16) {

        ProtoCard memory card = ProtoCard({
            exists: true,
            god: god,
            season: currentSeason,
            cardType: SPELL,
            rarity: rarity,
            mana: mana,
            attack: 0,
            health: 0,
            tribe: 0
        });

        _addProto(externalID, card, packable);
    }

    function addMinion(
        uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe, bool packable
    ) public onlyGovernor returns(uint16) {

        ProtoCard memory card = ProtoCard({
            exists: true,
            god: god,
            season: currentSeason,
            cardType: MINION,
            rarity: rarity,
            mana: mana,
            attack: attack,
            health: health,
            tribe: tribe
        });

        _addProto(externalID, card, packable);
    }

    function _addProto(uint16 externalID, ProtoCard memory card, bool packable) internal {

        require(!protos[externalID].exists);

        card.exists = true;

        protos[externalID] = card;

        protoCount++;

        emit NewProtoCard(
            externalID, currentSeason, card.god, 
            card.rarity, card.mana, card.attack, 
            card.health, card.cardType, card.tribe, packable
        );

        if (packable) {
            Rarity rarity = card.rarity;
            if (rarity == Rarity.Common) {
                common.push(externalID);
            } else if (rarity == Rarity.Rare) {
                rare.push(externalID);
            } else if (rarity == Rarity.Epic) {
                epic.push(externalID);
            } else if (rarity == Rarity.Legendary) {
                legendary.push(externalID);
            } else if (rarity == Rarity.Mythic) {
                mythic.push(externalID);
            } else {
                require(false);
            }
        }
    }

    function getProto(uint16 id) public view returns(
        bool exists, uint8 god, uint8 season, uint8 cardType, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe
    ) {
        ProtoCard memory proto = protos[id];
        return (
            proto.exists,
            proto.god,
            proto.season,
            proto.cardType,
            proto.rarity,
            proto.mana,
            proto.attack,
            proto.health,
            proto.tribe
        );
    }

    function getRandomCard(Rarity rarity, uint16 random) public view returns (uint16) {
        // modulo bias is fine - creates rarity tiers etc
        // will obviously revert is there are no cards of that type: this is expected - should never happen
        if (rarity == Rarity.Common) {
            return common[random % common.length];
        } else if (rarity == Rarity.Rare) {
            return rare[random % rare.length];
        } else if (rarity == Rarity.Epic) {
            return epic[random % epic.length];
        } else if (rarity == Rarity.Legendary) {
            return legendary[random % legendary.length];
        } else if (rarity == Rarity.Mythic) {
            // make sure a mythic is available
            uint16 id;
            uint64 limit;
            bool set;
            for (uint i = 0; i < mythic.length; i++) {
                id = mythic[(random + i) % mythic.length];
                (limit, set) = getLimit(id);
                if (set && limit > 0){
                    return id;
                }
            }
            // if not, they get a legendary :(
            return legendary[random % legendary.length];
        }
        require(false);
        return 0;
    }

    // can never adjust tradable cards
    // each season gets a 'balancing beta'
    // totally immutable: season, rarity
    function replaceProto(
        uint16 index, uint8 god, uint8 cardType, uint8 mana, uint8 attack, uint8 health, uint8 tribe
    ) public onlyGovernor {
        ProtoCard memory pc = protos[index];
        require(!seasonTradable[pc.season]);
        protos[index] = ProtoCard({
            exists: true,
            god: god,
            season: pc.season,
            cardType: cardType,
            rarity: pc.rarity,
            mana: mana,
            attack: attack,
            health: health,
            tribe: tribe
        });
    }

}

interface ERC721Metadata /* is ERC721 */ {
    /// @notice A descriptive name for a collection of NFTs in this contract
    function name() external pure returns (string _name);

    /// @notice An abbreviated name for NFTs in this contract
    function symbol() external pure returns (string _symbol);

    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
    ///  3986. The URI may point to a JSON file that conforms to the "ERC721
    ///  Metadata JSON Schema".
    function tokenURI(uint256 _tokenId) external view returns (string);
}

interface ERC721Enumerable /* is ERC721 */ {
    /// @notice Count NFTs tracked by this contract
    /// @return A count of valid NFTs tracked by this contract, where each one of
    ///  them has an assigned and queryable owner not equal to the zero address
    function totalSupply() public view returns (uint256);

    /// @notice Enumerate valid NFTs
    /// @dev Throws if `_index` >= `totalSupply()`.
    /// @param _index A counter less than `totalSupply()`
    /// @return The token identifier for the `_index`th NFT,
    ///  (sort order not specified)
    function tokenByIndex(uint256 _index) external view returns (uint256);

    /// @notice Enumerate NFTs assigned to an owner
    /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
    ///  `_owner` is the zero address, representing invalid NFTs.
    /// @param _owner An address where we are interested in NFTs    owned by them
    /// @param _index A counter less than `balanceOf(_owner)`
    /// @return The token identifier for the `_index`th NFT assigned to `_owner`,
    ///   (sort order not specified)
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _tokenId);
}

interface ERC165 {
    /// @notice Query if a contract implements an interface
    /// @param interfaceID The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    ///  uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

contract ERC721 {
    event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
    event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    function balanceOf(address _owner) public view returns (uint256 _balance);
    function ownerOf(uint256 _tokenId) public view returns (address _owner);
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) public payable;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) public payable;
    function transfer(address _to, uint256 _tokenId) public payable;
    function transferFrom(address _from, address _to, uint256 _tokenId) public payable;
    function approve(address _to, uint256 _tokenId) public payable;
    function setApprovalForAll(address _to, bool _approved) public;
    function getApproved(uint256 _tokenId) public view returns (address);
    function isApprovedForAll(address _owner, address _operator) public view returns (bool);
}

contract NFT is ERC721, ERC165, ERC721Metadata, ERC721Enumerable {}

contract CardOwnership is NFT, CardProto {

    // doing this strategy doesn't save gas
    // even setting the length to the max and filling in
    // unfortunately - maybe if we stop it boundschecking
    // address[] owners;
    mapping(uint => address) owners;
    mapping(uint => address) approved;
    // support multiple operators
    mapping(address => mapping(address => bool)) operators;

    // save space, limits us to 2^40 tokens (>1t)
    mapping(address => uint40[]) public ownedTokens;

    mapping(uint => string) uris;

    // save space, limits us to 2^24 tokens per user (~17m)
    uint24[] indices;

    uint public burnCount;

    /**
    * @return the name of this token
    */
    function name() public view returns (string) {
        return "Gods Unchained";
    }

    /**
    * @return the symbol of this token
    */  
    function symbol() public view returns (string) {
        return "GODS";
    }

    /**
    * @return the total number of cards in circulation
    */
    function totalSupply() public view returns (uint) {
        return cards.length - burnCount;
    }

    /**
    * @param to : the address to which the card will be transferred
    * @param id : the id of the card to be transferred
    */
    function transfer(address to, uint id) public payable {
        require(owns(msg.sender, id));
        require(isTradable(cards[id].proto));
        require(to != address(0));
        _transfer(msg.sender, to, id);
    }

    /**
    * internal transfer function which skips checks - use carefully
    * @param from : the address from which the card will be transferred
    * @param to : the address to which the card will be transferred
    * @param id : the id of the card to be transferred
    */
    function _transfer(address from, address to, uint id) internal {
        approved[id] = address(0);
        owners[id] = to;
        _addToken(to, id);
        _removeToken(from, id);
        emit Transfer(from, to, id);
    }

    /**
    * initial internal transfer function which skips checks and saves gas - use carefully
    * @param to : the address to which the card will be transferred
    * @param id : the id of the card to be transferred
    */
    function _create(address to, uint id) internal {
        owners[id] = to;
        _addToken(to, id);
        emit Transfer(address(0), to, id);
    }

    /**
    * @param to : the address to which the cards will be transferred
    * @param ids : the ids of the cards to be transferred
    */
    function transferAll(address to, uint[] ids) public payable {
        for (uint i = 0; i < ids.length; i++) {
            transfer(to, ids[i]);
        }
    }

    /**
    * @param proposed : the claimed owner of the cards
    * @param ids : the ids of the cards to check
    * @return whether proposed owns all of the cards 
    */
    function ownsAll(address proposed, uint[] ids) public view returns (bool) {
        for (uint i = 0; i < ids.length; i++) {
            if (!owns(proposed, ids[i])) {
                return false;
            }
        }
        return true;
    }

    /**
    * @param proposed : the claimed owner of the card
    * @param id : the id of the card to check
    * @return whether proposed owns the card
    */
    function owns(address proposed, uint id) public view returns (bool) {
        return ownerOf(id) == proposed;
    }

    /**
    * @param id : the id of the card
    * @return the address of the owner of the card
    */
    function ownerOf(uint id) public view returns (address) {
        return owners[id];
    }

    /**
    * @param id : the index of the token to burn
    */
    function burn(uint id) public {
        // require(isTradable(cards[id].proto));
        require(owns(msg.sender, id));
        burnCount++;
        // use the internal transfer function as the external
        // has a guard to prevent transfers to 0x0
        _transfer(msg.sender, address(0), id);
    }

    /**
    * @param ids : the indices of the tokens to burn
    */
    function burnAll(uint[] ids) public {
        for (uint i = 0; i < ids.length; i++){
            burn(ids[i]);
        }
    }

    /**
    * @param to : the address to approve for transfer
    * @param id : the index of the card to be approved
    */
    function approve(address to, uint id) public payable {
        require(owns(msg.sender, id));
        require(isTradable(cards[id].proto));
        approved[id] = to;
        emit Approval(msg.sender, to, id);
    }

    /**
    * @param to : the address to approve for transfer
    * @param ids : the indices of the cards to be approved
    */
    function approveAll(address to, uint[] ids) public payable {
        for (uint i = 0; i < ids.length; i++) {
            approve(to, ids[i]);
        }
    }

    /**
    * @param id : the index of the token to check
    * @return the address approved to transfer this token
    */
    function getApproved(uint id) public view returns(address) {
        return approved[id];
    }

    /**
    * @param owner : the address to check
    * @return the number of tokens controlled by owner
    */
    function balanceOf(address owner) public view returns (uint) {
        return ownedTokens[owner].length;
    }

    /**
    * @param id : the index of the proposed token
    * @return whether the token is owned by a non-zero address
    */
    function exists(uint id) public view returns (bool) {
        return owners[id] != address(0);
    }

    /**
    * @param to : the address to which the token should be transferred
    * @param id : the index of the token to transfer
    */
    function transferFrom(address from, address to, uint id) public payable {
        
        require(to != address(0));
        require(to != address(this));

        // TODO: why is this necessary
        // if you're approved, why does it matter where it comes from?
        require(ownerOf(id) == from);

        require(isSenderApprovedFor(id));

        require(isTradable(cards[id].proto));

        _transfer(ownerOf(id), to, id);
    }

    /**
    * @param to : the address to which the tokens should be transferred
    * @param ids : the indices of the tokens to transfer
    */
    function transferAllFrom(address to, uint[] ids) public payable {
        for (uint i = 0; i < ids.length; i++) {
            transferFrom(address(0), to, ids[i]);
        }
    }

    /**
     * @return the number of cards which have been burned
     */
    function getBurnCount() public view returns (uint) {
        return burnCount;
    }

    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return operators[owner][operator];
    }

    function setApprovalForAll(address to, bool toApprove) public {
        require(to != msg.sender);
        operators[msg.sender][to] = toApprove;
        emit ApprovalForAll(msg.sender, to, toApprove);
    }

    bytes4 constant magic = bytes4(keccak256("onERC721Received(address,uint256,bytes)"));

    function safeTransferFrom(address from, address to, uint id, bytes data) public payable {
        require(to != address(0));
        transferFrom(from, to, id);
        if (_isContract(to)) {
            bytes4 response = ERC721TokenReceiver(to).onERC721Received.gas(50000)(from, id, data);
            require(response == magic);
        }
    }

    function safeTransferFrom(address from, address to, uint id) public payable {
        safeTransferFrom(from, to, id, "");
    }

    function _addToken(address to, uint id) private {
        uint pos = ownedTokens[to].push(uint40(id)) - 1;
        indices.push(uint24(pos));
    }

    function _removeToken(address from, uint id) public payable {
        uint24 index = indices[id];
        uint lastIndex = ownedTokens[from].length - 1;
        uint40 lastId = ownedTokens[from][lastIndex];

        ownedTokens[from][index] = lastId;
        ownedTokens[from][lastIndex] = 0;
        ownedTokens[from].length--;
    }

    function isSenderApprovedFor(uint256 id) internal view returns (bool) {
        return owns(msg.sender, id) || getApproved(id) == msg.sender || isApprovedForAll(ownerOf(id), msg.sender);
    }

    function _isContract(address test) internal view returns (bool) {
        uint size; 
        assembly {
            size := extcodesize(test)
        }
        return (size > 0);
    }

    function tokenURI(uint id) public view returns (string) {
        return uris[id];
    }
    
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 _tokenId){
        return ownedTokens[owner][index];
    }

    function tokenByIndex(uint256 index) external view returns (uint256){
        return index;
    }

    function supportsInterface(bytes4 interfaceID) public view returns (bool) {
        return (
            interfaceID == this.supportsInterface.selector || // ERC165
            interfaceID == 0x5b5e139f || // ERC721Metadata
            interfaceID == 0x6466353c || // ERC-721 on 3/7/2018
            interfaceID == 0x780e9d63
        ); // ERC721Enumerable
    }

    function implementsERC721() external pure returns (bool) {
        return true;
    }

    function getOwnedTokens(address user) public view returns (uint40[]) {
        return ownedTokens[user];
    }
    

}

/// @dev Note: the ERC-165 identifier for this interface is 0xf0b9e5ba
interface ERC721TokenReceiver {
    /// @notice Handle the receipt of an NFT
    /// @dev The ERC721 smart contract calls this function on the recipient
    ///  after a `transfer`. This function MAY throw to revert and reject the
    ///  transfer. This function MUST use 50,000 gas or less. Return of other
    ///  than the magic value MUST result in the transaction being reverted.
    ///  Note: the contract address is always the message sender.
    /// @param _from The sending address
    /// @param _tokenId The NFT identifier which is being transfered
    /// @param _data Additional data with no specified format
    /// @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
    ///  unless throwing
	function onERC721Received(address _from, uint256 _tokenId, bytes _data) external returns(bytes4);
}



contract CardIntegration is CardOwnership {
    
    CardPackTwo[] packs;

    event CardCreated(uint indexed id, uint16 proto, uint16 purity, address owner);

    function addPack(CardPackTwo approved) public onlyGovernor {
        packs.push(approved);
    }

    modifier onlyApprovedPacks {
        require(_isApprovedPack());
        _;
    }

    function _isApprovedPack() private view returns (bool) {
        for (uint i = 0; i < packs.length; i++) {
            if (msg.sender == address(packs[i])) {
                return true;
            }
        }
        return false;
    }

    function createCard(address owner, uint16 proto, uint16 purity) public whenNotPaused onlyApprovedPacks returns (uint) {
        ProtoCard memory card = protos[proto];
        require(card.season == currentSeason);
        if (card.rarity == Rarity.Mythic) {
            uint64 limit;
            bool exists;
            (limit, exists) = getLimit(proto);
            require(!exists || limit > 0);
            limits[proto].limit--;
        }
        return _createCard(owner, proto, purity);
    }

    function _createCard(address owner, uint16 proto, uint16 purity) internal returns (uint) {
        Card memory card = Card({
            proto: proto,
            purity: purity
        });

        uint id = cards.push(card) - 1;

        _create(owner, id);
        
        emit CardCreated(id, proto, purity, owner);

        return id;
    }

    /*function combineCards(uint[] ids) public whenNotPaused {
        require(ids.length == 5);
        require(ownsAll(msg.sender, ids));
        Card memory first = cards[ids[0]];
        uint16 proto = first.proto;
        uint8 shine = _getShine(first.purity);
        require(shine < shineLimit);
        uint16 puritySum = first.purity - (shine * 1000);
        burn(ids[0]);
        for (uint i = 1; i < ids.length; i++) {
            Card memory next = cards[ids[i]];
            require(next.proto == proto);
            require(_getShine(next.purity) == shine);
            puritySum += (next.purity - (shine * 1000));
            burn(ids[i]);
        }
        uint16 newPurity = uint16(((shine + 1) * 1000) + (puritySum / ids.length));
        _createCard(msg.sender, proto, newPurity);
    }*/


    // PURITY NOTES
    // currently, we only
    // however, to protect rarity, you'll never be abl
    // this is enforced by the restriction in the create-card function
    // no cards above this point can be found in packs

    

}

contract CardPackTwo {

    CardIntegration public integration;
    uint public creationBlock;

    constructor(CardIntegration _integration) public payable {
        integration = _integration;
        creationBlock = 5939061; // set to creation block of first contracts
    }

    event Referral(address indexed referrer, uint value, address purchaser);

    /**
    * purchase 'count' of this type of pack
    */
    function purchase(uint16 packCount, address referrer) public payable;

    // store purity and shine as one number to save users gas
    function _getPurity(uint16 randOne, uint16 randTwo) internal pure returns (uint16) {
        if (randOne >= 998) {
            return 3000 + randTwo;
        } else if (randOne >= 988) {
            return 2000 + randTwo;
        } else if (randOne >= 938) {
            return 1000 + randTwo;
        } else {
            return randTwo;
        }
    }

}

contract Ownable {

   address public owner;

   constructor() public {
       owner = msg.sender;
   }

   function setOwner(address _owner) public onlyOwner {
       owner = _owner;
   }

   modifier onlyOwner {
       require(msg.sender == owner);
       _;
   }

}

contract Vault is Ownable {

   function () public payable {

   }

   function getBalance() public view returns (uint) {
       return address(this).balance;
   }

   function withdraw(uint amount) public onlyOwner {
       require(address(this).balance >= amount);
       owner.transfer(amount);
   }

   function withdrawAll() public onlyOwner {
       withdraw(address(this).balance);
   }
}

contract CappedVault is Vault { 

    uint public limit;
    uint withdrawn = 0;

    constructor() public {
        limit = 33333 ether;
    }

    function () public payable {
        require(total() + msg.value <= limit);
    }

    function total() public view returns(uint) {
        return getBalance() + withdrawn;
    }

    function withdraw(uint amount) public onlyOwner {
        require(address(this).balance >= amount);
        owner.transfer(amount);
        withdrawn += amount;
    }

}


contract Pausable is Ownable {
    
    event Pause();
    event Unpause();

    bool public paused = false;


    /**
    * @dev Modifier to make a function callable only when the contract is not paused.
    */
    modifier whenNotPaused() {
        require(!paused);
        _;
    }

    /**
    * @dev Modifier to make a function callable only when the contract is paused.
    */
    modifier whenPaused() {
        require(paused);
        _;
    }

    /**
    * @dev called by the owner to pause, triggers stopped state
    */
    function pause() onlyOwner whenNotPaused public {
        paused = true;
        emit Pause();
    }

    /**
    * @dev called by the owner to unpause, returns to normal state
    */
    function unpause() onlyOwner whenPaused public {
        paused = false;
        emit Unpause();
    }
}

contract PresalePackTwo is CardPackTwo, Pausable {

    CappedVault public vault;

    Purchase[] purchases;

    struct Purchase {
        uint16 current;
        uint16 count;
        address user;
        uint randomness;
        uint64 commit;
    }

    event PacksPurchased(uint indexed id, address indexed user, uint16 count);
    event PackOpened(uint indexed id, uint16 startIndex, address indexed user, uint[] cardIDs);
    event RandomnessReceived(uint indexed id, address indexed user, uint16 count, uint randomness);

    constructor(CardIntegration integration, CappedVault _vault) public payable CardPackTwo(integration) {
        vault = _vault;
    }

    function basePrice() public returns (uint);
    function getCardDetails(uint16 packIndex, uint8 cardIndex, uint result) public view returns (uint16 proto, uint16 purity);
    
    function packSize() public view returns (uint8) {
        return 5;
    }

    function packsPerClaim() public view returns (uint16) {
        return 15;
    }

    // start in bytes, length in bytes
    function extract(uint num, uint length, uint start) internal pure returns (uint) {
        return (((1 << (length * 8)) - 1) & (num >> ((start * 8) - 1)));
    }

    function purchase(uint16 packCount, address referrer) whenNotPaused public payable {

        require(packCount > 0);
        require(referrer != msg.sender);

        uint price = calculatePrice(basePrice(), packCount);

        require(msg.value >= price);

        Purchase memory p = Purchase({
            user: msg.sender,
            count: packCount,
            commit: uint64(block.number),
            randomness: 0,
            current: 0
        });

        uint id = purchases.push(p) - 1;

        emit PacksPurchased(id, msg.sender, packCount);

        if (referrer != address(0)) {
            uint commission = price / 10;
            referrer.transfer(commission);
            price -= commission;
            emit Referral(referrer, commission, msg.sender);
        }
        
        address(vault).transfer(price); 
    }

    // can be called by anybody
    // can miners withhold blocks --> not really
    // giving up block reward for extra chance --> still really low
    function callback(uint id) public {

        Purchase storage p = purchases[id];

        require(p.randomness == 0);

        bytes32 bhash = blockhash(p.commit);
        // will get the same on every block
        // only use properties which can't be altered by the user
        uint random = uint(keccak256(abi.encodePacked(bhash, p.user, address(this), p.count)));

        // can't callback on the original block
        require(uint64(block.number) != p.commit);

        if (uint(bhash) == 0) {
            // should never happen (must call within next 256 blocks)
            // if it does, just give them 1: will become common and therefore less valuable
            // set to 1 rather than 0 to avoid calling claim before randomness
            p.randomness = 1;
        } else {
            p.randomness = random;
        }

        emit RandomnessReceived(id, p.user, p.count, p.randomness);
    }

    

    function claim(uint id) public {
        
        Purchase storage p = purchases[id];

        require(canClaim);

        uint16 proto;
        uint16 purity;
        uint16 count = p.count;
        uint result = p.randomness;
        uint8 size = packSize();

        address user = p.user;
        uint16 current = p.current;

        require(result != 0); // have to wait for the callback
        // require(user == msg.sender); // not needed
        require(count > 0);

        uint[] memory ids = new uint[](size);

        uint16 end = current + packsPerClaim() > count ? count : current + packsPerClaim();

        require(end > current);

        for (uint16 i = current; i < end; i++) {
            for (uint8 j = 0; j < size; j++) {
                (proto, purity) = getCardDetails(i, j, result);
                ids[j] = integration.createCard(user, proto, purity);
            }
            emit PackOpened(id, (i * size), user, ids);
        }
        p.current += (end - current);
    }

    function predictPacks(uint id) external view returns (uint16[] protos, uint16[] purities) {

        Purchase memory p = purchases[id];

        uint16 proto;
        uint16 purity;
        uint16 count = p.count;
        uint result = p.randomness;
        uint8 size = packSize();

        purities = new uint16[](size * count);
        protos = new uint16[](size * count);

        for (uint16 i = 0; i < count; i++) {
            for (uint8 j = 0; j < size; j++) {
                (proto, purity) = getCardDetails(i, j, result);
                purities[(i * size) + j] = purity;
                protos[(i * size) + j] = proto;
            }
        }
        return (protos, purities);
    }

    function calculatePrice(uint base, uint16 packCount) public view returns (uint) {
        // roughly 6k blocks per day
        uint difference = block.number - creationBlock;
        uint numDays = difference / 6000;
        if (20 > numDays) {
            return (base - (((20 - numDays) * base) / 100)) * packCount;
        }
        return base * packCount;
    }

    function _getCommonPlusRarity(uint32 rand) internal pure returns (CardProto.Rarity) {
        if (rand == 999999) {
            return CardProto.Rarity.Mythic;
        } else if (rand >= 998345) {
            return CardProto.Rarity.Legendary;
        } else if (rand >= 986765) {
            return CardProto.Rarity.Epic;
        } else if (rand >= 924890) {
            return CardProto.Rarity.Rare;
        } else {
            return CardProto.Rarity.Common;
        }
    }

    function _getRarePlusRarity(uint32 rand) internal pure returns (CardProto.Rarity) {
        if (rand == 999999) {
            return CardProto.Rarity.Mythic;
        } else if (rand >= 981615) {
            return CardProto.Rarity.Legendary;
        } else if (rand >= 852940) {
            return CardProto.Rarity.Epic;
        } else {
            return CardProto.Rarity.Rare;
        } 
    }

    function _getEpicPlusRarity(uint32 rand) internal pure returns (CardProto.Rarity) {
        if (rand == 999999) {
            return CardProto.Rarity.Mythic;
        } else if (rand >= 981615) {
            return CardProto.Rarity.Legendary;
        } else {
            return CardProto.Rarity.Epic;
        }
    }

    function _getLegendaryPlusRarity(uint32 rand) internal pure returns (CardProto.Rarity) {
        if (rand == 999999) {
            return CardProto.Rarity.Mythic;
        } else {
            return CardProto.Rarity.Legendary;
        } 
    }

    bool public canClaim = true;

    function setCanClaim(bool claim) public onlyOwner {
        canClaim = claim;
    }

    function getComponents(
        uint16 i, uint8 j, uint rand
    ) internal returns (
        uint random, uint32 rarityRandom, uint16 purityOne, uint16 purityTwo, uint16 protoRandom
    ) {
        random = uint(keccak256(abi.encodePacked(i, rand, j)));
        rarityRandom = uint32(extract(random, 4, 10) % 1000000);
        purityOne = uint16(extract(random, 2, 4) % 1000);
        purityTwo = uint16(extract(random, 2, 6) % 1000);
        protoRandom = uint16(extract(random, 2, 8) % (2**16-1));
        return (random, rarityRandom, purityOne, purityTwo, protoRandom);
    }

    function withdraw() public onlyOwner {
        owner.transfer(address(this).balance);
    }

}

contract RarePackTwo is PresalePackTwo {

    constructor(CardIntegration integration, CappedVault _vault) public payable PresalePackTwo(integration, _vault) {
        
    }

    function basePrice() public returns (uint) {
        return 50 finney;
    }

    function getCardDetails(uint16 packIndex, uint8 cardIndex, uint result) public view returns (uint16 proto, uint16 purity) {
        uint random;
        uint32 rarityRandom;
        uint16 protoRandom;
        uint16 purityOne;
        uint16 purityTwo;
        CardProto.Rarity rarity;

        (random, rarityRandom, purityOne, purityTwo, protoRandom) = getComponents(packIndex, cardIndex, result);

        if (cardIndex == 4) {
            rarity = _getRarePlusRarity(rarityRandom);
        } else {
            rarity = _getCommonPlusRarity(rarityRandom);
        }

        purity = _getPurity(purityOne, purityTwo);
    
        proto = integration.getRandomCard(rarity, protoRandom);
        return (proto, purity);
    }    

    
    
}

    Contract ABI  
[{"constant":true,"inputs":[],"name":"packSize","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"creationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"claim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"packCount","type":"uint16"},{"name":"referrer","type":"address"}],"name":"purchase","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"integration","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"canClaim","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"packsPerClaim","outputs":[{"name":"","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"packIndex","type":"uint16"},{"name":"cardIndex","type":"uint8"},{"name":"result","type":"uint256"}],"name":"getCardDetails","outputs":[{"name":"proto","type":"uint16"},{"name":"purity","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"claim","type":"bool"}],"name":"setCanClaim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"basePrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"predictPacks","outputs":[{"name":"protos","type":"uint16[]"},{"name":"purities","type":"uint16[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"base","type":"uint256"},{"name":"packCount","type":"uint16"}],"name":"calculatePrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"callback","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"integration","type":"address"},{"name":"_vault","type":"address"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"count","type":"uint16"}],"name":"PacksPurchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"startIndex","type":"uint16"},{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"cardIDs","type":"uint256[]"}],"name":"PackOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":true,"name":"user","type":"address"},{"indexed":false,"name":"count","type":"uint16"},{"indexed":false,"name":"randomness","type":"uint256"}],"name":"RandomnessReceived","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"referrer","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"purchaser","type":"address"}],"name":"Referral","type":"event"}]

  Contract Creation Code Switch To Opcodes View
60806040526000600260146101000a81548160ff0219169083151502179055506001600560006101000a81548160ff021916908315150217905550604051604080611d6d8339810180604052810190808051906020019092919080519060200190929190505050818181806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550625a9f756001819055505033600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050611c24806101496000396000f300608060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306a628d41461011757806313af403514610148578063176345141461018b578063379607f5146101b6578063396c8228146101e35780633ccfd60b146102275780633f4ba83a1461023e5780635c975abb14610255578063622104d9146102845780636dc7a627146102db5780638456cb591461030a5780638be4339b146103215780638da5cb5b14610354578063c2f0bb29146103ab578063c503101e1461041e578063c7876ea41461044d578063ca2bf04714610478578063e3f7faaf14610542578063fbfa77cf14610591578063ff585caf146105e8575b600080fd5b34801561012357600080fd5b5061012c610615565b604051808260ff1660ff16815260200191505060405180910390f35b34801561015457600080fd5b50610189600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061061e565b005b34801561019757600080fd5b506101a06106be565b6040518082815260200191505060405180910390f35b3480156101c257600080fd5b506101e1600480360381019080803590602001909291905050506106c4565b005b610225600480360381019080803561ffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610a7e565b005b34801561023357600080fd5b5061023c610e42565b005b34801561024a57600080fd5b50610253610f20565b005b34801561026157600080fd5b5061026a610fe0565b604051808215151515815260200191505060405180910390f35b34801561029057600080fd5b50610299610ff3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156102e757600080fd5b506102f0611018565b604051808215151515815260200191505060405180910390f35b34801561031657600080fd5b5061031f61102b565b005b34801561032d57600080fd5b506103366110ec565b604051808261ffff1661ffff16815260200191505060405180910390f35b34801561036057600080fd5b506103696110f5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103b757600080fd5b506103f1600480360381019080803561ffff169060200190929190803560ff1690602001909291908035906020019092919050505061111b565b604051808361ffff1661ffff1681526020018261ffff1661ffff1681526020019250505060405180910390f35b34801561042a57600080fd5b5061044b600480360381019080803515159060200190929190505050611279565b005b34801561045957600080fd5b506104626112f2565b6040518082815260200191505060405180910390f35b34801561048457600080fd5b506104a360048036038101908080359060200190929190505050611301565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156104ea5780820151818401526020810190506104cf565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561052c578082015181840152602081019050610511565b5050505090500194505050505060405180910390f35b34801561054e57600080fd5b5061057b60048036038101908080359060200190929190803561ffff169060200190929190505050611574565b6040518082815260200191505060405180910390f35b34801561059d57600080fd5b506105a66115cc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156105f457600080fd5b50610613600480360381019080803590602001909291905050506115f2565b005b60006005905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561067a57600080fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60015481565b6000806000806000806000806060600080600060048d8154811015156106e657fe5b90600052602060002090600302019b50600560009054906101000a900460ff16151561071157600080fd5b8b60000160029054906101000a900461ffff1698508b600101549750610735610615565b96508b60000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1695508b60000160009054906101000a900461ffff1694506000881415151561078357600080fd5b60008961ffff1611151561079657600080fd5b8660ff166040519080825280602002602001820160405280156107c85781602001602082028038833980820191505090505b5093508861ffff166107d86110ec565b860161ffff16116107f2576107eb6110ec565b85016107f4565b885b92508461ffff168361ffff1611151561080c57600080fd5b8491505b8261ffff168261ffff161015610a3b57600090505b8660ff168160ff1610156109895761083e82828a61111b565b809b50819c5050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fb36eba1878d8d6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018361ffff1661ffff1681526020018261ffff1661ffff1681526020019350505050602060405180830381600087803b15801561092257600080fd5b505af1158015610936573d6000803e3d6000fd5b505050506040513d602081101561094c57600080fd5b8101908080519060200190929190505050848260ff1681518110151561096e57fe5b90602001906020020181815250508080600101915050610825565b8573ffffffffffffffffffffffffffffffffffffffff168d7f69ac64af86d3ef40c9def928534f6a6a9e12d85ec3af2948bd66b802afcc10468960ff16850287604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015610a1a5780820151818401526020810190506109ff565b50505050905001935050505060405180910390a38180600101925050610810565b8483038c60000160008282829054906101000a900461ffff160192506101000a81548161ffff021916908361ffff16021790555050505050505050505050505050565b6000610a88611ba0565b600080600260149054906101000a900460ff16151515610aa757600080fd5b60008661ffff16111515610aba57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614151515610af557600080fd5b610b06610b006112f2565b87611574565b9350833410151515610b1757600080fd5b60a060405190810160405280600061ffff1681526020018761ffff1681526020013373ffffffffffffffffffffffffffffffffffffffff168152602001600081526020014367ffffffffffffffff16815250925060016004849080600181540180825580915050906001820390600052602060002090600302016000909192909190915060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a81548161ffff021916908361ffff16021790555060408201518160000160046101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506060820151816001015560808201518160020160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050500391503373ffffffffffffffffffffffffffffffffffffffff16827f861fd6f8fe14603acc05fa404f8cca86371619cac8a65a92edf687f81b9bafbd88604051808261ffff1661ffff16815260200191505060405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141515610dd157600a84811515610cff57fe5b0490508473ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610d48573d6000803e3d6000fd5b5080840393508473ffffffffffffffffffffffffffffffffffffffff167f13aa7090696e2a1d666cfc6046f2f72f1c4e0290649b47bab28d1b370ad737838233604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a25b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f19350505050158015610e39573d6000803e3d6000fd5b50505050505050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e9e57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015610f1d573d6000803e3d6000fd5b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610f7c57600080fd5b600260149054906101000a900460ff161515610f9757600080fd5b6000600260146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600260149054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900460ff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561108757600080fd5b600260149054906101000a900460ff161515156110a357600080fd5b6001600260146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000600f905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000806000806111328b8b8b6118cc565b809850819650829750839950849a50505050505060048a60ff1614156111625761115b85611a48565b905061116e565b61116b85611aa4565b90505b6111788383611b1b565b96506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663caa1916882866040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808360048111156111f457fe5b60ff1681526020018261ffff1661ffff16815260200192505050602060405180830381600087803b15801561122857600080fd5b505af115801561123c573d6000803e3d6000fd5b505050506040513d602081101561125257600080fd5b81019080805190602001909291905050509750878797509750505050505050935093915050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156112d557600080fd5b80600560006101000a81548160ff02191690831515021790555050565b600066b1a2bc2ec50000905090565b60608061130c611ba0565b600080600080600080600060048b81548110151561132657fe5b906000526020600020906003020160a060405190810160405290816000820160009054906101000a900461ffff1661ffff1661ffff1681526020016000820160029054906101000a900461ffff1661ffff1661ffff1681526020016000820160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509750876020015194508760600151935061142a610615565b9250848360ff160261ffff166040519080825280602002602001820160405280156114645781602001602082028038833980820191505090505b509850848360ff160261ffff1660405190808252806020026020018201604052801561149f5781602001602082028038833980820191505090505b509950600091505b8461ffff168261ffff16101561156157600090505b8260ff168160ff161015611554576114d582828661111b565b809750819850505085898260ff168560ff1685020161ffff168151811015156114fa57fe5b9060200190602002019061ffff16908161ffff1681525050868a8260ff168560ff1685020161ffff1681518110151561152f57fe5b9060200190602002019061ffff16908161ffff168152505080806001019150506114bc565b81806001019250506114a7565b8989995099505050505050505050915091565b6000806000600154430391506117708281151561158d57fe5b04905080601411156115ba578361ffff1660648683601403028115156115af57fe5b0486030292506115c4565b8361ffff16850292505b505092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600060048481548110151561160657fe5b906000526020600020906003020192506000836001015414151561162957600080fd5b8260020160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16409150818360000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff16308560000160029054906101000a900461ffff166040516020018085600019166000191681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018261ffff1661ffff167e010000000000000000000000000000000000000000000000000000000000000281526002019450505050506040516020818303038152906040526040518082805190602001908083835b6020831015156117995780518252602082019150602081019050602083039250611774565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206001900490508260020160009054906101000a900467ffffffffffffffff1667ffffffffffffffff164367ffffffffffffffff161415151561180757600080fd5b600082600190041415611823576001836001018190555061182d565b8083600101819055505b8260000160049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16847fedb5ce4012b6e9c5904afa2ffad9811d5c2e91e6bca8914cf7e3ffc28e630c578560000160029054906101000a900461ffff168660010154604051808361ffff1661ffff1681526020018281526020019250505060405180910390a350505050565b6000806000806000878688604051602001808461ffff1661ffff167e010000000000000000000000000000000000000000000000000000000000000281526002018381526020018260ff1660ff167f010000000000000000000000000000000000000000000000000000000000000002815260010193505050506040516020818303038152906040526040518082805190602001908083835b60208310151561198a5780518252602082019150602081019050602083039250611965565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600190049450620f42406119ce866004600a611b78565b8115156119d757fe5b0693506103e86119ea8660026004611b78565b8115156119f357fe5b0692506103e8611a068660026006611b78565b811515611a0f57fe5b06915061ffff611a228660026008611b78565b811515611a2b57fe5b069050848484848494509450945094509450939792965093509350565b6000620f423f8263ffffffff161415611a645760049050611a9f565b620efa6f8263ffffffff16101515611a7f5760039050611a9f565b620d03cc8263ffffffff16101515611a9a5760029050611a9f565b600190505b919050565b6000620f423f8263ffffffff161415611ac05760049050611b16565b620f3bc98263ffffffff16101515611adb5760039050611b16565b620f0e8d8263ffffffff16101515611af65760029050611b16565b620e1cda8263ffffffff16101515611b115760019050611b16565b600090505b919050565b60006103e68361ffff16101515611b385781610bb8019050611b72565b6103dc8361ffff16101515611b5357816107d0019050611b72565b6103aa8361ffff16101515611b6e57816103e8019050611b72565b8190505b92915050565b600060016008830203849060020a900460016008850260019060020a02031690509392505050565b60a060405190810160405280600061ffff168152602001600061ffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600067ffffffffffffffff16815250905600a165627a7a72305820152ab1cc7e7da12b40e0e6c66a89d674ea4adbf5b3192786bad8615e903cbea40029000000000000000000000000512fbd15bde6570ff09e4438af27ede60402451500000000000000000000000091b9d2835ad914bc1dcfe09bd1816febd04fd689

    Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000512fbd15bde6570ff09e4438af27ede60402451500000000000000000000000091b9d2835ad914bc1dcfe09bd1816febd04fd689

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000512fbd15bde6570ff09e4438af27ede604024515
Arg [1] : 00000000000000000000000091b9d2835ad914bc1dcfe09bd1816febd04fd689


   Swarm Source:
bzzr://152ab1cc7e7da12b40e0e6c66a89d674ea4adbf5b3192786bad8615e903cbea4

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.