Contract 0xeba37f4d2495fa2097b4001f9c7a350bdec84604

Contract Overview

Balance:
0 MATIC
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x0f04251d6944db1ebd1c9678bc3a848f405cbb1a6cb88627e5850e0a90765686Checkin283205712022-09-27 9:49:04372 days 3 hrs ago0xa3d9b830aa243276e383f116bf3029b03a009d67 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000511847206 2.906620819
0xeb6df943003ae343965b6390d20df9a849e8363f530ab8d44d573a11de529f98Checkin283183212022-09-27 6:40:34372 days 6 hrs ago0xa595fdc5c259164d173c770fc6d9cc43b0d96237 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.00072760576 4.131564886
0x91dcb004c51abd4643cdb0ef19c92760b030e1e5a1f7b0b835e59c98cf76a609Checkin283134822022-09-26 23:56:04372 days 13 hrs ago0xa595fdc5c259164d173c770fc6d9cc43b0d96237 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000751633212 4.268000005
0x4e043a26df95d9def37bcdc429c3e2ff21fb3a197b1471d1207afa10ffd7a736Checkin282113562022-09-21 1:37:54378 days 11 hrs ago0x30539f204f1add140f59350c4fe727473cdc0113 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000774879599 4.399999997
0x3085119a7295ceddbfacf299287c5445a89101f0a2602ec9f405f73e2c521b61Checkin280252452022-09-10 6:15:38389 days 7 hrs ago0x595fd965ae317e34dfadc4bb9c5d8ca60ee77809 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000427064326 2.425000011
0xf900ec006710a9efa09a3c5aa899707fcf8c11f0d12deff0866b61b99b9b1601Checkin279227922022-09-04 7:26:39395 days 5 hrs ago0x595fd965ae317e34dfadc4bb9c5d8ca60ee77809 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000289813501 1.500000008
0x4b2c0df86872a907d8d87699b3c23daf8c11beee956a351b5b32ce84219f1ee0Checkin278722222022-09-01 8:59:19398 days 4 hrs ago0x0fadba9677d7c0b535eeef30edb7bd609e1089d7 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000264163501 1.500000008
0x236b7c5f81d7e6ef565ba33dc6c98fb789486fbd7f5222b08c21d77fed5476fbCheckin278250682022-08-29 6:39:53401 days 6 hrs ago0x26ab01d5e27d0bcb3d27fac726d26b1e5fe08624 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000533034742 3.352230016
0x71b6bd9bb8b4bd70ba883e60bbf056e9f3b9cd747b85576a7cccf41d4397f50cCheckin278234392022-08-29 4:09:03401 days 9 hrs ago0x26ab01d5e27d0bcb3d27fac726d26b1e5fe08624 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000757495136 4.301285775
0x8f9f15eeb4dfc03ac4a90aaf35424037677d149d094c8e8eabf906a4d21ed446Checkin278227432022-08-29 3:06:12401 days 10 hrs ago0x59ac583282595cef79665338eafcea1d9a0b891c IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.00142297833 8.0801
0x23b986aa9123995404963677ff8f50bec7c4cfd1e76804ef1b81f6bbc04f4b33Checkin278227332022-08-29 3:04:32401 days 10 hrs ago0x59ac583282595cef79665338eafcea1d9a0b891c IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.001408458143 7.99765
0xf9cfe5cdc51dfcf3856a2d954f223e1eed4794eed1e929ef4d3f9a03693af6f1Checkin278227332022-08-29 3:04:32401 days 10 hrs ago0xdefac19dfda9e7522eaa081ec740c2f97b336be7 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.001284813155 8.080128518
0x84905c02a424c0b8863e74849be743af75f90c202a031ccc8a3b73c6f5fcf316Checkin278227312022-08-29 3:04:12401 days 10 hrs ago0x547877c23c842ab6b4808b56653cedf6fdc4dd58 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.001422983353 8.080128518
0xc2740b5321f64cdcac103abea6377ee16c32a4c66cd1853bf6f84180838b4d1fCheckin278227292022-08-29 3:03:52401 days 10 hrs ago0xdefac19dfda9e7522eaa081ec740c2f97b336be7 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.001422983353 8.080128518
0x5131453a1ce6abdf43a029447207d89852a648572a683aef42b804837b3dd116Checkin278227282022-08-29 3:03:42401 days 10 hrs ago0x547877c23c842ab6b4808b56653cedf6fdc4dd58 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.001408458143 7.99765
0xe135eadd8a8c9e26ec8b55c0232cb69de3eb218854bbaac4378c4669a64e3f9eCheckin278227252022-08-29 3:03:12401 days 10 hrs ago0x59ac583282595cef79665338eafcea1d9a0b891c IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.001452018705 8.245
0x00c8bd29d239c180ed80f3c5d997b656cfd52c92c5b22ba81574a5c1f56496a7Checkin278227242022-08-29 3:03:02401 days 10 hrs ago0x547877c23c842ab6b4808b56653cedf6fdc4dd58 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.001311029205 8.245
0xaeeb6ec70f3fa23a9bb2fc682ea9c7ddedbed79418cd3c2f0ca2b69f7a28246dCheckin278227232022-08-29 3:02:52401 days 10 hrs ago0xdefac19dfda9e7522eaa081ec740c2f97b336be7 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.001452018705 8.245
0x96982e4c391dccdcd9aa7b6ab90c13a9e1059a66bf7269105d6ced143da893e6Checkin278123372022-08-28 10:41:09402 days 2 hrs ago0xa595fdc5c259164d173c770fc6d9cc43b0d96237 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000264163501 1.500000008
0x030705aa1f5f14e852f55ef74c49fa0be5c96a092b7f316b5841e1d8637b5db9Checkin278123372022-08-28 10:41:09402 days 2 hrs ago0x59ac583282595cef79665338eafcea1d9a0b891c IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000308477461 1.94000001
0xd97212d112b1ac86da2dd21df2094a7c08dc41cc74a3edb9bb3b07d6c1ca73fbCheckin278123372022-08-28 10:41:09402 days 2 hrs ago0x26ab01d5e27d0bcb3d27fac726d26b1e5fe08624 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000308477461 1.94000001
0x3ab47a1787bcad6766758791559a71e490bd88b7979585eacebb119c605234e7Checkin278123372022-08-28 10:41:09402 days 2 hrs ago0x547877c23c842ab6b4808b56653cedf6fdc4dd58 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.00056372491 3.201000008
0xda45540d291974ddb35537fab31eb2892e49a40a65980a8713d6dcd9ff4375bcCheckin278123362022-08-28 10:40:59402 days 2 hrs ago0xdefac19dfda9e7522eaa081ec740c2f97b336be7 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000341651461 1.94000001
0xeae50f25727cbc745326735e1103d64e00fed0f8bb484c2b7afe4bacb7ff396bCheckin278104912022-08-28 7:25:20402 days 5 hrs ago0x547877c23c842ab6b4808b56653cedf6fdc4dd58 IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000275701733 1.733875021
0x25118a83e645f9cd111ab01ba04e20772dfdcb5c86cf224da7f5d25046c90ec1Checkin278104862022-08-28 7:24:55402 days 5 hrs ago0x59ac583282595cef79665338eafcea1d9a0b891c IN  0xeba37f4d2495fa2097b4001f9c7a350bdec846040 MATIC0.000264163501 1.500000008
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
EventCheckin

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 23 : EventCheckin.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "../interfaces/IEventCheckin.sol";
import "../Character.sol";
import "./GameBase.sol";
import "../EventDefinition.sol";
import "../ItemPackDefinition.sol";
import "../ItemPack.sol";

contract EventCheckin is IEventCheckin, GameBase {
    uint256 public checkinCount;

    // key: eventDefinitionId, value: count
    mapping(uint256 => uint256) public checkinCountsPerEvent;

    // key: Player Wallet, value: (key: eventDefinitionId, value: count)
    mapping(address => mapping(uint256 => uint256)) public checkinCountsPerPlayer;

    constructor(address game)
    GameBase(game) {
    }

    function canCheckin(uint256 worldId, uint256 eventId) external override view returns(bool) {
        // TODO: implement
        return true;
    }

    // TODO: add access control modifier
    function checkin(address playerWallet, uint256 worldId, uint256 eventDefinitionId) external virtual override {
        // TODO: check record number of executions(whole, per user)

        checkinCount++;
        checkinCountsPerEvent[eventDefinitionId]++;
        checkinCountsPerPlayer[playerWallet][eventDefinitionId]++;
        _mintItemPack(playerWallet, worldId, eventDefinitionId);

        // TODO: Emit Event
        emit Checkin(playerWallet, worldId, eventDefinitionId);
    }

    function _mintItemPack(address playerWallet, uint256 worldId, uint256 eventDefinitionId) private {
        World world = getWorld(worldId);
        EventDefinition eventDefinition = world.eventDefinition();
        uint256 itemPackDefinitionId = eventDefinition.getItemPackDefinitionId(eventDefinitionId);

        // TODO: check eventDefinitionId, itemPackDefinitionId;
        ItemPack itemPack = world.itemPack();

        // TODO: mint Event / ItemPack NFT
        // TODO: set NFT address/tokenId
        itemPack.addItemPack(playerWallet, address(0), 0, itemPackDefinitionId);
    }
}

File 2 of 23 : IEventCheckin.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface IEventCheckin {
    event Checkin(address indexed playerWallet, uint256 indexed worldId, uint256 eventDefinitionId);

    function checkin(address playerWallet, uint256 worldId, uint256 eventDefinitionId) external;

    function canCheckin(uint256 worldId, uint256 eventId) external view returns(bool);
}

File 3 of 23 : Character.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "./CharacterDefinition.sol";

contract Character {
    uint256 public worldId;
    uint256 public tokenId;
    uint256 public characterDefinitionId;
    // key: statusSlotIndex, value: itemId
    mapping(uint256 => int64) public statuses;
    // key: equipmentSlotIndex, value: itemId
    mapping(uint256 => uint256) public equipments;
    // key: itemId, value: itemCount
    mapping(uint256 => int64) public items;
    CharacterDefinition public characterDefinition;

    constructor(uint256 worldId_, uint256 tokenId_, uint256 characterDefinitionId_, address characterDefinition_) {
        worldId = worldId_;
        tokenId = tokenId_;
        characterDefinitionId = characterDefinitionId_;
        characterDefinition = CharacterDefinition(characterDefinition_);
    }

    // TODO: add access control modifier
    function addItem(uint256 itemId, int64 value) public virtual {
        // TODO: check itemId
        items[itemId] += value;
    }

    // TODO: add access control modifier
    function addItems(uint256[] memory itemIds, int64[] memory amounts) public virtual {
        require(itemIds.length == amounts.length, "wrong length");

        for (uint256 i; i < itemIds.length; i++) {
            addItem(itemIds[i], amounts[i]);
        }
    }

    // TODO: add access control modifier
    function setEquipments(uint256[] memory itemIds) public virtual {
        for (uint256 equipmentSlotIndex; equipmentSlotIndex < itemIds.length; equipmentSlotIndex++) {
            uint256 itemId = itemIds[equipmentSlotIndex];
            uint256 oldItemId = equipments[equipmentSlotIndex];

            require(characterDefinition.isValidEquipmentSlot(characterDefinitionId, equipmentSlotIndex), "invalid propertyId");
            require(itemId == 0 || items[itemId] > 0 || itemId == oldItemId, "No items");
            require(itemId == 0 || characterDefinition.canEquip(characterDefinitionId, itemId, equipmentSlotIndex), "Cannot equip");

            if (itemId > 0) {
                items[itemId] -= 1;
            }
            equipments[equipmentSlotIndex] = itemId;
            if (oldItemId > 0) {
                items[oldItemId] += 1;
            }
        }
    }

    function getEquipments() public virtual view returns(uint256[] memory) {
        CharacterDefinition.EquipmentSlot[] memory propertyTypes = characterDefinition.getEquipmentSlots(characterDefinitionId);
        uint256[] memory result = new uint256[](propertyTypes.length);
        for (uint256 i; i < propertyTypes.length; i++) {
            result[i] = equipments[i];
        }

        return result;
    }

    // TODO: add access control modifier
    function setStatus(uint256 statusSlotIndex, int64 value) public virtual {
        uint256[] memory statusSlots = characterDefinition.getStatusSlots(characterDefinitionId);
        uint256 itemId = statusSlots[statusSlotIndex];

        require(characterDefinition.isValidStatusSlot(characterDefinitionId, statusSlotIndex, itemId), "invalid statusSlotIndex");
        require(itemId != 0 || items[itemId] > value, "No items");

        items[itemId] -= value;
        statuses[statusSlotIndex] += value;
    }

    function getStatuses() public virtual view returns(int64[] memory) {
        uint256[] memory statusSlots = characterDefinition.getStatusSlots(characterDefinitionId);

        int64[] memory result = new int64[](statusSlots.length);
        for (uint256 i; i < statusSlots.length; i++) {
            result[i] = statuses[i];
        }

        return result;
    }

    function getItems(uint256[] memory itemIds) public virtual view returns(int64[] memory) {
        int64[] memory result = new int64[](itemIds.length);
        for (uint256 i; i < itemIds.length; i++) {
            result[i] = items[itemIds[i]];
        }

        return result;
    }

    function hasItem(uint256 itemId, int64 amount) public virtual view returns(bool) {
        return items[itemId] >= amount;
    }
}

File 4 of 23 : GameBase.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "../Game.sol";
import "../World.sol";
import "../Character.sol";

contract GameBase {
    Game internal _game;

    constructor(address game) {
        _game = Game(game);
    }

    function getWorld(uint256 worldId) internal view virtual returns(World) {
        return _game.worlds(worldId);
    }

    function getCharacter(uint256 worldId, uint256 tokenId) internal view virtual returns(Character) {
        World world = getWorld(worldId);
        return world.characters(tokenId);
    }
}

File 5 of 23 : EventDefinition.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

contract EventDefinition {
    struct EventDefinitionRecord {
        uint256 eventDefinitionId;
        address eventNftAddress;
        address itemPackNftAddress;
        uint256 itemPackDefinitionId;

        uint256 executableTimes;
        uint256 executableTimesPerUser;
    }

    uint256 public worldId;
    mapping(uint256 => EventDefinitionRecord) private _eventDefinitions;

    constructor(uint256 worldId_) {
        worldId = worldId_;
    }

    function getEventDefinition(uint256 eventDefinitionId) public virtual view returns(uint256, address, address, uint256, uint256, uint256) {
        EventDefinitionRecord memory record = _eventDefinitions[eventDefinitionId];

        return (record.eventDefinitionId, record.eventNftAddress, record.itemPackNftAddress, record.itemPackDefinitionId, record.executableTimes, record.executableTimesPerUser);
    }

    function getItemPackDefinitionId(uint256 eventDefinitionId) public virtual view returns(uint256) {
        EventDefinitionRecord memory record = _eventDefinitions[eventDefinitionId];

        return record.itemPackDefinitionId;
    }


    // TODO: add access control modifier
    function setEventDefinitions(EventDefinitionRecord[] memory eventDefinitions_) public virtual {
        for (uint256 i; i < eventDefinitions_.length; i++) {
            EventDefinitionRecord memory record = eventDefinitions_[i];
            _addEventDefinition(
                record.eventDefinitionId,
                record.eventNftAddress,
                record.itemPackNftAddress,
                record.itemPackDefinitionId,
                record.executableTimes,
                record.executableTimesPerUser
            );
        }
    }

    function _addEventDefinition(
        uint256 eventDefinitionId,
        address eventNftAddress_,
        address itemPackNftAddress_,
        uint256 itemPackDefinitionId_,
        uint256 executableTimes_,
        uint256 executableTimesPerUser_
    ) private {
        _eventDefinitions[eventDefinitionId] = EventDefinitionRecord(
            eventDefinitionId,
            eventNftAddress_,
            itemPackNftAddress_,
            itemPackDefinitionId_,
            executableTimes_,
            executableTimesPerUser_
        );
    }
}

File 6 of 23 : ItemPackDefinition.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract ItemPackDefinition {
    struct ItemPackDefinitionRecord {
        uint256 itemPackDefinitionId;
        address nftAddress;
        uint256[] itemDefinitionIds;
        int64[] amounts;
    }

    uint256 public worldId;

    // key: itemPackDefinitionId
    mapping(uint256 => ItemPackDefinitionRecord) private _itemPackDefinitionRecords;

    constructor(uint256 worldId_) {
        worldId = worldId_;
    }

    function getItemPackDefinition(uint256 itemPackDefinitionId) public virtual view returns(address, uint256[] memory, int64[] memory) {
        ItemPackDefinitionRecord memory record = _itemPackDefinitionRecords[itemPackDefinitionId];

        return (record.nftAddress, record.itemDefinitionIds, record.amounts);
    }

    function setItemPackDefinitions(ItemPackDefinitionRecord[] memory itemPacks) public virtual {
        for (uint256 i; i < itemPacks.length; i++) {
            ItemPackDefinitionRecord memory itemPack = itemPacks[i];

            // TODO: check itemId
            require(itemPack.itemDefinitionIds.length == itemPack.amounts.length, "wrong ItemPack");

            _itemPackDefinitionRecords[itemPack.itemPackDefinitionId] = itemPack;
        }
    }
}

File 7 of 23 : ItemPack.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract ItemPack {
    uint256 public worldId;
    uint256 private _currentIndex;

    struct ItemPackRecord {
        uint256 itemPackId;
        uint256 itemPackDefinitionId;
        bool isRevealed;
    }

    // key: itemPackId, value: array of ItemPackRecord
    mapping(uint256 => ItemPackRecord) private _itemPackRecords;

    // key: NFT contract address, value: (key: tokenId, value: itemPackId)
    mapping(address => mapping(uint256 => uint256)) private _itemPackIdsByNft;

    // key: Wallet address, array of itemPackId
    mapping(address => uint256[]) private _itemPackIdsByWallet;

    constructor(uint256 worldId_) {
        worldId = worldId_;
    }

    // TODO: add access control modifier
    function addItemPack(address playerWallet, address nftAddress, uint256 nftTokenId, uint256 itemPackDefinitionId_) public virtual {
        _currentIndex++;

        _itemPackRecords[_currentIndex] = ItemPackRecord(_currentIndex, itemPackDefinitionId_, false);
        _itemPackIdsByNft[nftAddress][nftTokenId] = _currentIndex;

        // TODO: should not use wallet address
        _itemPackIdsByWallet[playerWallet].push(_currentIndex);
    }

    function getItemPackIds(address playerWallet) public virtual view returns(uint256[] memory) {
        // TODO: should not use wallet address
        return _itemPackIdsByWallet[playerWallet];
    }

    function itemPackDefinitionId(uint256 itemPackId) public virtual view returns (uint256) {
        return _itemPackRecords[itemPackId].itemPackDefinitionId;
    }

    function isRevealed(uint256 itemPackId) public virtual view returns (bool) {
        return _itemPackRecords[itemPackId].isRevealed;
    }

    // TODO: add access control modifier
    function updateItemPack(uint256 itemPackId_, uint256 itemPackDefinitionId_, bool isRevealed_) public virtual {
        _itemPackRecords[itemPackId_] = ItemPackRecord(itemPackId_, itemPackDefinitionId_, isRevealed_);
    }
}

File 8 of 23 : CharacterDefinition.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

contract CharacterDefinition {
    uint256 public worldId;

    enum EquipmentSlot { Invalid, Normal }
    enum ItemType { Invalid, Normal, Status }

    // key: characterDefinitionId
    mapping(uint256 => bool) characters;

    // key: characterDefinitionId
    mapping(uint256 => EquipmentSlot[]) public equipmentSlots;

    // key: characterDefinitionId, value: itemId[]
    mapping(uint256 => uint256[]) public statusSlots;

    // key: characterDefinitionId, value: (key: itemId, value: equipmentSlotIndex)
    mapping(uint256 => mapping(uint256 => uint256)) public equipableItems;

    constructor(uint256 worldId_) {
        worldId = worldId_;
    }

    // TODO: add access control modifier
    function setCharacter(uint256 characterDefinitionId, bool enabled) public virtual {
        require(characterDefinitionId > 0);

        characters[characterDefinitionId] = enabled;
    }

    // TODO: add access control modifier
    function setEquipmentSlots(uint256 characterDefinitionId, EquipmentSlot[] memory equipmentSlots_) public virtual {
        require(characters[characterDefinitionId] == true, "character disabled");
        require(equipmentSlots_.length > 0);

        equipmentSlots[characterDefinitionId] = equipmentSlots_;
    }

    function getEquipmentSlots(uint256 characterDefinitionId) public view virtual returns(EquipmentSlot[] memory) {
        return equipmentSlots[characterDefinitionId];
    }

    function isValidEquipmentSlot(uint256 characterDefinitionId, uint256 equipmentSlotIndex) public view virtual returns(bool) {
        return equipmentSlotIndex >= 0 && equipmentSlotIndex < equipmentSlots[characterDefinitionId].length && equipmentSlots[characterDefinitionId][equipmentSlotIndex] != EquipmentSlot.Invalid;
    }

    // TODO: add access control modifier
    function setStatusSlots(uint256 characterDefinitionId, uint256[] memory statusSlots_) public virtual {
        require(characters[characterDefinitionId] == true);
        require(statusSlots_.length > 0);

        statusSlots[characterDefinitionId] = statusSlots_;
    }

    function getStatusSlots(uint256 characterDefinitionId) public view virtual returns(uint256[] memory) {
        return statusSlots[characterDefinitionId];
    }

    function isValidStatusSlot(uint256 characterDefinitionId, uint256 statusSlotIndex, uint256 itemId) public view virtual returns(bool) {
        return statusSlotIndex >= 0 && statusSlotIndex < statusSlots[characterDefinitionId].length && statusSlots[characterDefinitionId][statusSlotIndex] == itemId;
    }

    // TODO: add access control modifier
    function setEquipable(uint256 characterDefinitionId, uint256 itemId, uint256 equipmentSlotIndex) public virtual {
        require(characters[characterDefinitionId] == true);

        equipableItems[characterDefinitionId][itemId] = equipmentSlotIndex;
    }

    function canEquip(uint256 characterDefinitionId, uint256 itemId, uint256 equipmentSlotIndex) public virtual view returns(bool) {
        return equipableItems[characterDefinitionId][itemId] == equipmentSlotIndex || itemId == 0;
    }
}

File 9 of 23 : Game.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./World.sol";
import "./interfaces/ICharacterEquipment.sol";
import "./interfaces/ICharacterItem.sol";
import "./interfaces/ICharacterReveal.sol";
import "./interfaces/ICharacterStatus.sol";
import "./interfaces/IItemTransfer.sol";
import "./interfaces/IItemPackReveal.sol";

contract Game is Ownable {
    mapping(uint256 => World) public worlds;

    uint256 public _worldIndex;

    ICharacterEquipment public characterEquipment;
    ICharacterItem public characterItem;
    ICharacterReveal public characterReveal;
    ICharacterStatus public characterStatus;
    IItemTransfer public itemTransfer;
    IEventCheckin public eventCheckin;
    IItemPackReveal public itemPackReveal;

    constructor() {
    }

    function setCharacterEquipment(address characterEquipment_) public onlyOwner {
        characterEquipment = ICharacterEquipment(characterEquipment_);
    }

    function setCharacterItem(address characterItem_) public onlyOwner {
        characterItem = ICharacterItem(characterItem_);
    }

    function setCharacterReveal(address characterReveal_) public onlyOwner {
        characterReveal = ICharacterReveal(characterReveal_);
    }

    function setCharacterStatus(address characterStatus_) public onlyOwner {
        characterStatus = ICharacterStatus(characterStatus_);
    }

    function setItemTransfer(address itemTransfer_) public onlyOwner {
        itemTransfer = IItemTransfer(itemTransfer_);
    }

    function setEventCheckin(address eventCheckin_) public onlyOwner {
        eventCheckin = IEventCheckin(eventCheckin_);
    }

    function setItemPackReveal(address itemPackReveal_) public onlyOwner {
        itemPackReveal = IItemPackReveal(itemPackReveal_);
    }

    function addWorld() public onlyOwner {
        _worldIndex++;
        worlds[_worldIndex] = new World(address(this), _worldIndex);
    }
}

File 10 of 23 : World.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

import "./access/GameOnly.sol";

import "./Game.sol";
import "./Character.sol";
import "./CharacterDefinition.sol";
import "./ItemDefinition.sol";
import "./EventDefinition.sol";
import "./ItemPack.sol";
import "./CommandDefinition.sol";
import "./ItemPackDefinition.sol";
import "./game/EventCheckin.sol";

contract World is GameOnly, Ownable {
    IERC721 private _l1Nft;
    IERC721[] private _l2Nfts;

    uint256 public worldId;

    uint256 private _characterIndex;
    uint256 private _characterDefinitionIndex;
    uint256 private _ItemDefinitionIndex;

    // key: tokenId
    mapping(uint256 => Character) public characters;

    CharacterDefinition public characterDefinition;
    ItemDefinition public itemDefinition;
    ItemPack public itemPack;
    ItemPackDefinition public itemPackDefinition;
    EventDefinition public eventDefinition;

    // key: commandDefinitionId
    mapping(uint256 => CommandDefinition) public commandDefinitions;

    constructor(address game, uint256 worldId_)
    GameOnly(game) {
        worldId = worldId_;
        characterDefinition = new CharacterDefinition(worldId_);
        itemPack = new ItemPack(worldId_);
        itemPackDefinition = new ItemPackDefinition(worldId_);
        eventDefinition = new EventDefinition(worldId_);
        itemDefinition = new ItemDefinition(worldId_);
    }

    // TODO: add access control modifier
    function setCharacterDefinition(address characterDefinition_) public {
        characterDefinition = CharacterDefinition(characterDefinition_);
    }

    // TODO: add access control modifier
    function addCharacter(uint256 tokenId, uint256 characterDefinitionId) public {
        characters[tokenId] = new Character(worldId, tokenId, characterDefinitionId, address(characterDefinition));
    }

    // TODO: add access control modifier
    function setupCharacters(uint256[] memory tokenIds, uint256[] memory characterDefinitionIds, uint256[][] memory items, int64[][] memory amounts,  uint256[][] memory equipments) public {
        require(tokenIds.length == characterDefinitionIds.length, "wrong characterDefinitionIds length");
        require(tokenIds.length == items.length, "wrong items length");
        require(tokenIds.length == amounts.length, "wrong amounts length");
        require(tokenIds.length == equipments.length, "wrong equipments length");

        for (uint256 i; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            uint256 characterDefinitionId = characterDefinitionIds[i];
            Character character = new Character(worldId, tokenId, characterDefinitionId, address(characterDefinition));

            characters[tokenId] = character;
            character.addItems(items[i], amounts[i]);
            character.setEquipments(equipments[i]);
        }
    }

    // TODO: add access control modifier
    function addItemDefinitions(uint256[] memory itemIds_, string[] memory categories_, ItemDefinition.ItemType[] memory itemTypes_) public {
        require(itemIds_.length == categories_.length, "wrong length");
        require(itemIds_.length == itemTypes_.length, "wrong length");

        for (uint256 i; i < itemIds_.length; i++) {
            itemDefinition.setItemDefinition(itemIds_[i], categories_[i], itemTypes_[i]);
        }
    }

    // TODO: add access control modifier
    function addCharacterDefinition(uint256 characterDefinitionId, CharacterDefinition.EquipmentSlot[] memory equipableSlots_, uint256[] memory statusSlots_, uint256[][] memory equipables_) public {
        characterDefinition.setCharacter(characterDefinitionId, true);
        characterDefinition.setEquipmentSlots(characterDefinitionId, equipableSlots_);
        characterDefinition.setStatusSlots(characterDefinitionId, statusSlots_);

        for (uint256 i; i < equipables_.length; i++) {
            uint256[] memory equipable = equipables_[i];
            uint256 itemId = equipable[0];
            uint256 slotIndex = equipable[1];

            characterDefinition.setEquipable(characterDefinitionId, itemId, slotIndex);
        }
    }
}

File 11 of 23 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 12 of 23 : ICharacterEquipment.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface ICharacterEquipment {
    event Equip(uint256 indexed worldId, uint256 indexed tokenId, uint256[] itemIds);

    function equip(uint256 worldId, uint256 tokenId, uint256[] calldata itemIds) external;

    function canEquip(uint256 worldId, uint256 tokenId, uint256[] calldata itemIds) external view returns(bool);

    // Returns an array of Equipment ItemId
    function getEquipments(uint256 worldId, uint256 tokenId) external view returns(uint256[] memory);
}

File 13 of 23 : ICharacterItem.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface ICharacterItem {
    event AddItem(uint256 indexed worldId, uint256 indexed tokenId, uint256 itemId);

    function addItem(uint256 worldId, uint256 tokenId, uint256 itemDefinitionId, int64 value) external;

    function getItems(uint256 worldId, uint256 tokenId, uint256[] memory itemDefinitionIds) external view returns(int64[] memory);
}

File 14 of 23 : ICharacterReveal.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface ICharacterReveal {
    event Reveal(uint256 indexed worldId, address indexed tokenId, address indexed characterDefinitionId);

    function reveal(uint256 worldId, uint256 tokenId) external;

    function isRevealed(uint256 worldId, uint256 tokenId) external view;

    // returns: array of tokenId, array of ItemDefinitionId, array of IsRevealed
    // function getCharacters(uint256 worldId, address playerWallet) external view returns(uint256[] memory, uint256[] memory, bool[] memory);
}

File 15 of 23 : ICharacterStatus.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface ICharacterStatus {
    event UpdateStatus(uint256 indexed worldId, uint256 indexed tokenId, uint256 statusSlotIndex, int64 value);

    function setStatus(uint256 worldId, uint256 tokenId, uint256 statusSlotIndex, int64 value) external;

    function getStatuses(uint256 worldId, uint256 tokenId) external view returns(int64[] memory);

    function getStatusSlots(uint256 worldId, uint256 tokenId) external view returns(uint256[] memory);
}

File 16 of 23 : IItemTransfer.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface IItemTransfer {
    event TransferItem(uint256 indexed worldId, uint256 indexed tokenId, uint256 indexed targetTokenId, uint256 itemId, int64 value);

    function transfer(uint256 worldId, uint256 tokenId, uint256 targetTokenId, uint256 itemId, int64 amount) external;

    function canTransfer(uint256 worldId, uint256 tokenId, uint256 targetTokenId, uint256 itemId, int64 amount) external view returns(bool);
}

File 17 of 23 : IItemPackReveal.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface IItemPackReveal {
    event RevealItemPack(uint256 indexed worldId, uint256 indexed tokenId, uint256 indexed itemPackId);

    function reveal(uint256 worldId, uint256 tokenId, uint256 itemPackId) external;

    function isRevealed(uint256 worldId, uint256 itemPackId) external view returns(bool);

    // returns: array of ItemPackId, array of ItemPackDefinitionId, array of IsRevealed
    function getItemPacks(uint256 worldId, address playerWallet) external view returns(uint256[] memory, uint256[] memory, bool[] memory);
}

File 18 of 23 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 19 of 23 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

File 20 of 23 : GameOnly.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract GameOnly {
    address private _gameAddress;

    constructor(address gameAddress) {
        _gameAddress = gameAddress;
    }

    modifier onlyGame() {
        require(_gameAddress == msg.sender, "GameOnly: caller is not Game");
        _;
    }
}

File 21 of 23 : ItemDefinition.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract ItemDefinition {
    enum ItemType { Invalid, Normal, SoulBound, Status }

    uint256 public worldId;

    // TODO: manage itemDefinitionIds
    // uint256 public itemDefinitionIds;

    // key: itemId
    mapping(uint256 => string) public categories;
    mapping(uint256 => ItemType) public itemTypes;

    constructor(uint256 worldId_) {
        worldId = worldId_;
    }

    // TODO: add access control modifier
    function setItemDefinition(uint256 itemDefinitionId_, string calldata category_, ItemType itemType_) external virtual {
        categories[itemDefinitionId_] = category_;
        itemTypes[itemDefinitionId_] = itemType_;
    }
}

File 22 of 23 : CommandDefinition.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

contract CommandDefinition {
    uint256 public commandDefinitionId;
    address private _mintNftAddress;

    uint256[] public costItemIds;
    // key: ItemId, value: amount
    mapping(uint256 => int64) public costItemAmounts;

    uint256[] public itemIds;
    // key: ItemId, value: amount
    mapping(uint256 => int64) public itemAmounts;

    uint256[] public conditionItemIds;
    // key: ItemId, value: amount
    mapping(uint256 => int64) public conditionItemAmounts;

    uint256 public executableTimes;
    uint256 public executableTimesPerUser;

    constructor(address mintNftAddress_) {
        _mintNftAddress = mintNftAddress_;
    }

    function getConditionItemIds() public virtual view returns(uint256[] memory) {
        return conditionItemIds;
    }

    function getCostItemIds() public virtual view returns(uint256[] memory) {
        return costItemIds;
    }

    function getItemIds() public virtual view returns(uint256[] memory) {
        return itemIds;
    }

    // TODO: add access control modifier
    function setItems(uint256[] calldata itemIds_, int64[] calldata amounts_) public virtual {
        require(itemIds_.length == amounts_.length, 'array length mismatch');

        itemIds = itemIds_;
        for (uint256 i; i < itemIds.length; i++) {
            uint256 itemId = itemIds[i];
            int64 amount = amounts_[i];
            itemAmounts[itemId] = amount;
        }
    }

    // TODO: add access control modifier
    function setConditionItems(uint256[] calldata itemIds_, int64[] calldata amounts_) public virtual {
        require(itemIds_.length == amounts_.length, 'array length mismatch');

        conditionItemIds = itemIds_;
        for (uint256 i; i < itemIds.length; i++) {
            uint256 itemId = itemIds[i];
            int64 amount = amounts_[i];
            conditionItemAmounts[itemId] = amount;
        }
    }

    // TODO: add access control modifier
    function setCostItems(uint256[] calldata itemIds_, int64[] calldata amounts_) public virtual {
        require(itemIds_.length == amounts_.length, 'array length mismatch');

        costItemIds = itemIds_;
        for (uint256 i; i < itemIds.length; i++) {
            uint256 itemId = itemIds[i];
            int64 amount = amounts_[i];
            costItemAmounts[itemId] = amount;
        }
    }
}

File 23 of 23 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"game","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"playerWallet","type":"address"},{"indexed":true,"internalType":"uint256","name":"worldId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eventDefinitionId","type":"uint256"}],"name":"Checkin","type":"event"},{"inputs":[{"internalType":"uint256","name":"worldId","type":"uint256"},{"internalType":"uint256","name":"eventId","type":"uint256"}],"name":"canCheckin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"playerWallet","type":"address"},{"internalType":"uint256","name":"worldId","type":"uint256"},{"internalType":"uint256","name":"eventDefinitionId","type":"uint256"}],"name":"checkin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkinCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkinCountsPerEvent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkinCountsPerPlayer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b506040516105d43803806105d483398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b610541806100936000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80631a3dda591461005c5780633d0e5cf21461008f57806374475319146100b5578063da9fa131146100be578063ea901965146100e9575b600080fd5b61007c61006a3660046103f1565b60026020526000908152604090205481565b6040519081526020015b60405180910390f35b6100a561009d36600461040a565b600192915050565b6040519015158152602001610086565b61007c60015481565b61007c6100cc366004610444565b600360209081526000928352604080842090915290825290205481565b6100fc6100f7366004610470565b6100fe565b005b6001805490600061010e836104a5565b9091555050600081815260026020526040812080549161012d836104a5565b90915550506001600160a01b03831660009081526003602090815260408083208484529091528120805491610161836104a5565b91905055506101718383836101ba565b81836001600160a01b03167fb1ea073ac09a6b73cc1842f3dbda1736e0c0d94b33aac1983f2612a5d115b4c7836040516101ad91815260200190565b60405180910390a3505050565b60006101c58361037d565b90506000816001600160a01b031663bf65efb36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610207573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022b91906104ce565b604051631f0c988560e01b8152600481018590529091506000906001600160a01b03831690631f0c988590602401602060405180830381865afa158015610276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029a91906104f2565b90506000836001600160a01b0316634282daf66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061030091906104ce565b604051639a1e8f3160e01b81526001600160a01b03898116600483015260006024830181905260448301526064820185905291925090821690639a1e8f3190608401600060405180830381600087803b15801561035c57600080fd5b505af1158015610370573d6000803e3d6000fd5b5050505050505050505050565b60008054604051631d0cab6760e11b8152600481018490526001600160a01b0390911690633a1956ce90602401602060405180830381865afa1580156103c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103eb91906104ce565b92915050565b60006020828403121561040357600080fd5b5035919050565b6000806040838503121561041d57600080fd5b50508035926020909101359150565b6001600160a01b038116811461044157600080fd5b50565b6000806040838503121561045757600080fd5b82356104628161042c565b946020939093013593505050565b60008060006060848603121561048557600080fd5b83356104908161042c565b95602085013595506040909401359392505050565b60006000198214156104c757634e487b7160e01b600052601160045260246000fd5b5060010190565b6000602082840312156104e057600080fd5b81516104eb8161042c565b9392505050565b60006020828403121561050457600080fd5b505191905056fea264697066735822122099ba85e7550bce74328b5be8663a1149114a4262f68d4f791cf6ff9b5c79c4b464736f6c634300080b00330000000000000000000000005226cfd7123819d74660bdc999ab4eb9c25581be

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

0000000000000000000000005226cfd7123819d74660bdc999ab4eb9c25581be

-----Decoded View---------------
Arg [0] : game (address): 0x5226cfd7123819d74660bdc999ab4eb9c25581be

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000005226cfd7123819d74660bdc999ab4eb9c25581be


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading