Contract 0xA13Db2f412cef4b4186ed1D2d12c9eC16BDE82F4 1

 

Contract Overview

Balance:
0.00000000000022185 Ether

EtherValue:
Less Than $0.01 (@ $1,229.40/ETH)

Token:
 
Txn Hash
Method
Block
From
To
Value
0x0039df44ff1d68f468d54b8f36b58880dbf22e6f2b588024af5ee8482c66200aRegister User156215242022-09-27 1:50:5971 days 7 hrs agoENS Name paragonicalism.eth IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.00109741 9.9096197
0x061b2b3c8fe735db6006d82d640d04b83cb3b2a6c9164a3ba1c6755d2ad328bdRegister User94757982020-02-13 16:36:061027 days 16 hrs ago0xb9b27d7c7b7f593bceeb58e00b842c2102670014 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000151765
0xd32845d2d1092cde39db65ae6858ca3617073a0d848dde2b1dfcfa0113128899Register User94757972020-02-13 16:36:021027 days 16 hrs ago0xb9b27d7c7b7f593bceeb58e00b842c2102670014 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000523155
0x4125e066b55dcecc1d3c86f759bc0ba3eaccf468a426c73f8f1fff06ce430672Register User85570842019-09-15 23:43:291178 days 9 hrs ago0x82f381972e7cbbc6a0ebe747c6a8162e541b2d52 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496915
0xfb3e577368360ff6351b74d46d9fc47ce5edf59f2ff3e3d3e68b0b276e80af61Register User78593242019-05-30 6:24:431287 days 2 hrs ago0x22ce379077543be1f820731665df704afca11cfd IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496595
0x133e4f0d188312e3df6b01898808a924db8052b56501b5ea22b1a1232bc23e31Register User76295112019-04-24 10:08:491322 days 23 hrs ago0xb5e4324e04e2e24b0f3730fda349c508ab14df64 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496275
0x31e7b6959d455fac64629edcc5201bed5aff775646a956217fb3f6bafe1e9a84Register User76232912019-04-23 10:35:241323 days 22 hrs ago0xe52f09b2b8af439c0a541c2a5f493ff68485e632 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496275
0xbb48726f09b6bac7514714593f37552e1c6f84902d72fae4d0cb743d6d11458cRegister User75920642019-04-18 13:54:281328 days 19 hrs ago0x0174e08b8dbc42a1ddc9f7032533c97089343e6f IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496595
0xa6be6aad99ddbf2d044bff55481c25df52de4d6b75ac9999059693a90da4ef8fRegister User75905762019-04-18 8:04:171329 days 1 hr ago0xc73bd5ead8d7b2add7ffbb63fb6052a244a7531f IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000501075
0xc309951c5752ba5eb1ddd0bd08f18f9c65a7c4b48ae32dcf6a1ce33bc9d1c32dRegister User75893542019-04-18 3:29:561329 days 5 hrs agoENS Name me-ra.eth IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000497555
0x129f15ff43cc36616efd6a535d862e330b4015ce643e341203e6ca3721cab3f7Register User72974062019-03-03 15:36:051374 days 17 hrs ago0x9a76faef4e53ebbb0d92ee4ebc049a60d1aa5b1f IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000136885
0x8cc00c30e1401752096131fb1d488911df851cfa0e20f98e6a261747ff2852c2Register User72974042019-03-03 15:35:501374 days 17 hrs ago0x9a76faef4e53ebbb0d92ee4ebc049a60d1aa5b1f IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496275
0xeebbdeef3e2a24dfd6709692414d80307883caf91881a68f730eebfa41aa545eRegister User72313402019-02-17 9:26:381388 days 23 hrs ago0x284ffda66ddff73bc6e8fb5e2b723ebe0ef9ec59 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496915
0x7b6065a5a302e783a2f3c2a6d568f4beb8a90ebc1633461857da22393ae162e3Register User72126822019-02-12 22:13:121393 days 10 hrs ago0x26b350f462ae30ec1c48c36ba944ab66f06dafee IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000495635
0x5f7c5cc889d8a05a8fb0f04c2250b649721d3f0a9c4cfaf8e9e9144fddfa06e3Register User71457542019-01-29 21:23:391407 days 11 hrs ago0xd130d1e2c89b47f0263b4ace251a50deec1c9d84 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000495955
0xa27fcb6eaefb3c24f1f8ea554c5f84060744a4f5b30b777263fc63de2eaf089eRegister User70569322019-01-13 2:51:591424 days 6 hrs ago0x1be5081e3fa7b431674a3bb1b5f0d3acc37242bf IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000495635
0xc7c8fc68f6136417e5c03f423b0437facfd08bcc0b9470e9d76bf7af841f4d09Register User70526002019-01-12 8:24:011425 days 46 mins agoENS Name sochi108.eth IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000136885
0x6e07b73b6749e04a6e3ba18b6af69930d512715d042c2d9bef7245d8513a8989Register User70525992019-01-12 8:23:511425 days 46 mins agoENS Name sochi108.eth IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000136245
0xaa94d622521e7cbc2e42734a3a6db234d06e375cdb94decd2dcedcec20818467Register User70525982019-01-12 8:23:411425 days 46 mins agoENS Name sochi108.eth IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000136245
0x14d6ff40b3e22a088e463ade621b6652dca3dfe2af8290140d039370d8971a17Register User70525952019-01-12 8:22:301425 days 47 mins agoENS Name sochi108.eth IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000136245
0xdc0a5a99c37272db69cbad8109ca9f37151f674678c95266ef942cc0c05eaf0aRegister User70525942019-01-12 8:22:241425 days 48 mins agoENS Name sochi108.eth IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000495635
0x35563a219f28a63c909dc0504326479c6e958a018f74cad4f45d5edd8b34ae78Register User70201872019-01-06 12:57:061430 days 20 hrs ago0xfefff7b6f681f9ca077b83a1750e7e55ae5cf655 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.00013725
0xe9e8331de7a0b2b28b337af0208fba55443c2582154b119fb05ebce9f9d04a7aRegister User70201852019-01-06 12:56:151430 days 20 hrs ago0xfefff7b6f681f9ca077b83a1750e7e55ae5cf655 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496595
0x315c6dd2efd2ad80c92b9bf2ffb4abf0700fe7ee5fb4b0e323160b57ec56f59aRegister User70183432019-01-06 5:02:281431 days 4 hrs ago0x980dade8ce2b2869280316404462e4852d2530e5 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000496275
0xa975ac89486beb8f139238fc1ffa13612f4613e804d8ba8616805346ae730203Register User70180552019-01-06 3:49:301431 days 5 hrs ago0x3d4bf64d870eebfb656bb47a17eb8bb3e824b020 IN  0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether0.000298143
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xbbaf3e73cfcb62c8fc4bc3ec5b1f35900cc03d849de96f3f3113999d916bd65869024822018-12-17 9:49:021450 days 23 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4500 wei
0x1c9561e58807c8485a61e601098e0ae3df43179ae03d0df683d19364084ad45b66727852018-11-09 14:11:451488 days 18 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4500 wei
0x1d1cdea5f2852440baaa158b5dc6c6fe5ccd50956f1ae46bcbcd6a3835c0bc6266727832018-11-09 14:11:011488 days 18 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0x21f1b8e6cf3756cfc4b7bdd933eaf0c0a1c0d2d5aa58e819aa1c4a796e04696f66727692018-11-09 14:07:311488 days 19 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0x4952ff6950aecce06625d18ec9a8214ff862016be8eca5100ec4fe99fef62e6466727442018-11-09 13:59:191488 days 19 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4300 wei
0x50eddbfee10b8abf38c5c414a74f6bc6d8fe83f5f00082ccbbfe1a3d804237b566727372018-11-09 13:57:431488 days 19 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4500 wei
0x1c7edc1ad4adc217e025868a34319e3f2c40ea11019e56279b7d7d13272af24666727252018-11-09 13:55:021488 days 19 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4500 wei
0x319c8fff12cc866d67c99db0b082eac855b208327a867c0d223b815053686d2666727032018-11-09 13:50:151488 days 19 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0xc515860d74b5323b5682140b2bf92f8dcea2009a59ebe29a6ecd897aec8b1f7a66726982018-11-09 13:48:251488 days 19 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0x7833c78a582b500c8b4fccdf68f36a3dc47d94978a85bcf3e2dcadb5cf77c03366726372018-11-09 13:32:341488 days 19 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4500 wei
0xd83fad9fc87288c27ea0e1f01cddad4c9c566f5d9b8b784cde110e6566d8e32062456412018-08-31 8:52:121559 days 18 mins ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4400 wei
0x867946d36b7c96ded03b9e8918df68f78199a0f9771f69f96070d9c0f21bb4c662327162018-08-29 4:27:201561 days 4 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0xe3d595ca402cb2f7781db5aac43463d01bf993374de90266a58fb2ad4c35852462218272018-08-27 8:21:031563 days 49 mins ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4500 wei
0x958ec35e6c12ce7e38927b64b1bc1370bf7484541024baccf0cfd62e9626a4fb62138662018-08-26 0:01:031564 days 9 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0x5fc6d8655ba73f0f7079c24aa62b8db8b4f94828d0dc9e6b5a480c1afdabe07362137402018-08-25 23:37:201564 days 9 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4300 wei
0x6be97df57bb238c3e86e9dfe8e3c4928673942c69325b7639b3980d6b7d48aaa62137352018-08-25 23:36:211564 days 9 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4500 wei
0xed291fb12219013ba089b44852872d37fd329749811c85c52d910eaffaed4be962137102018-08-25 23:31:151564 days 9 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0x5387aea581a4b0b6ca56ba781fa087f0adfc9fc18384ad246ccbf2486cfea5d961911512018-08-22 3:44:021568 days 5 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4100 wei
0xeb5a0a49f272f42029e7611e0948ea210efdca8770928979aaa0f98919dc9d8961911222018-08-22 3:37:481568 days 5 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0xc13c1867c201f4e6f0769c24c0032cf604c7de453c71066405addc9ad4f1f2dd61805442018-08-20 9:04:381570 days 5 mins ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0x1cb5e588d9af23b94e702438720dc9d34088c87d6f80feed1985c64206827cc361789752018-08-20 2:36:511570 days 6 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f450 wei
0x08ffcce95c867ac3e1fb2a327ebc80f4ddaf8f2322bc7589a2ee847ffe3127f661787682018-08-20 1:49:461570 days 7 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0x704b13cbba93251b135378689ca54a2a6f41218ec1a6055b8cfb7f5ef7e7098561786772018-08-20 1:30:101570 days 7 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f40 Ether
0x0772c03c5427cc626c49d8df028076b1d62f5546dd3a6895838697371f2bcbf061717742018-08-18 21:30:311571 days 11 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4250 wei
0x4a01d0494b03b7c687ac52cc802db8612cdf6fbb97782f726fbaf514809379bb61717632018-08-18 21:27:491571 days 11 hrs ago 0xda1641a37c453a43880684140cb305dc3fac98ba 0xa13db2f412cef4b4186ed1d2d12c9ec16bde82f4250 wei
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GameV001

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-08-04
*/

pragma solidity ^0.4.24;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


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


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipRenounced(owner);
    owner = address(0);
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function transferOwnership(address _newOwner) public onlyOwner {
    _transferOwnership(_newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address _newOwner) internal {
    require(_newOwner != address(0));
    emit OwnershipTransferred(owner, _newOwner);
    owner = _newOwner;
  }
}

/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
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();
  }
}

/**
 * @title Claimable
 * @dev Extension for the Ownable contract, where the ownership needs to be claimed.
 * This allows the new owner to accept the transfer.
 */
contract Claimable is Ownable {
  address public pendingOwner;

  /**
   * @dev Modifier throws if called by any account other than the pendingOwner.
   */
  modifier onlyPendingOwner() {
    require(msg.sender == pendingOwner);
    _;
  }

  /**
   * @dev Allows the current owner to set the pendingOwner address.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) onlyOwner public {
    pendingOwner = newOwner;
  }

  /**
   * @dev Allows the pendingOwner address to finalize the transfer.
   */
  function claimOwnership() onlyPendingOwner public {
    emit OwnershipTransferred(owner, pendingOwner);
    owner = pendingOwner;
    pendingOwner = address(0);
  }
}

/// @title AccessByGame
contract AccessByGame is Pausable, Claimable {
  mapping(address => bool) internal contractAccess;

  modifier onlyAccessByGame {
    require(!paused && (msg.sender == owner || contractAccess[msg.sender] == true));
    _;
  }

  function grantAccess(address _address)
    onlyOwner
    public
  {
    contractAccess[_address] = true;
  }

  function revokeAccess(address _address)
    onlyOwner
    public
  {
    contractAccess[_address] = false;
  }
}

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  function totalSupply() public view returns (uint256);
  function balanceOf(address who) public view returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender)
    public view returns (uint256);

  function transferFrom(address from, address to, uint256 value)
    public returns (bool);

  function approve(address spender, uint256 value) public returns (bool);
  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

/**
 * @title ERC827 interface, an extension of ERC20 token standard
 *
 * @dev Interface of a ERC827 token, following the ERC20 standard with extra
 * @dev methods to transfer value and data and execute calls in transfers and
 * @dev approvals.
 */
contract ERC827 is ERC20 {
  function approveAndCall(
    address _spender,
    uint256 _value,
    bytes _data
  )
    public
    payable
    returns (bool);

  function transferAndCall(
    address _to,
    uint256 _value,
    bytes _data
  )
    public
    payable
    returns (bool);

  function transferFromAndCall(
    address _from,
    address _to,
    uint256 _value,
    bytes _data
  )
    public
    payable
    returns (bool);
}

/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    c = a * b;
    assert(c / a == b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    // uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return a / b;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
    c = a + b;
    assert(c >= a);
    return c;
  }
}

/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 */
contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) balances;

  uint256 totalSupply_;

  /**
  * @dev total number of tokens in existence
  */
  function totalSupply() public view returns (uint256) {
    return totalSupply_;
  }

  /**
  * @dev transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_to != address(0));
    require(_value <= balances[msg.sender]);

    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param _owner The address to query the the balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function balanceOf(address _owner) public view returns (uint256) {
    return balances[_owner];
  }

}

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * @dev https://github.com/ethereum/EIPs/issues/20
 * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract StandardToken is ERC20, BasicToken {

  mapping (address => mapping (address => uint256)) internal allowed;


  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amount of tokens to be transferred
   */
  function transferFrom(
    address _from,
    address _to,
    uint256 _value
  )
    public
    returns (bool)
  {
    require(_to != address(0));
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    emit Transfer(_from, _to, _value);
    return true;
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   *
   * Beware that changing an allowance with this method brings the risk that someone may use both the old
   * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
   * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value) public returns (bool) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param _owner address The address which owns the funds.
   * @param _spender address The address which will spend the funds.
   * @return A uint256 specifying the amount of tokens still available for the spender.
   */
  function allowance(
    address _owner,
    address _spender
   )
    public
    view
    returns (uint256)
  {
    return allowed[_owner][_spender];
  }

  /**
   * @dev Increase the amount of tokens that an owner allowed to a spender.
   *
   * approve should be called when allowed[_spender] == 0. To increment
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _addedValue The amount of tokens to increase the allowance by.
   */
  function increaseApproval(
    address _spender,
    uint _addedValue
  )
    public
    returns (bool)
  {
    allowed[msg.sender][_spender] = (
      allowed[msg.sender][_spender].add(_addedValue));
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   *
   * approve should be called when allowed[_spender] == 0. To decrement
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseApproval(
    address _spender,
    uint _subtractedValue
  )
    public
    returns (bool)
  {
    uint oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue > oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

}

contract ERC827Caller {
  function makeCall(address _target, bytes _data) external payable returns (bool) {
    // solium-disable-next-line security/no-call-value
    return _target.call.value(msg.value)(_data);
  }
}

/**
 * @title ERC827, an extension of ERC20 token standard
 *
 * @dev Implementation the ERC827, following the ERC20 standard with extra
 * @dev methods to transfer value and data and execute calls in transfers and
 * @dev approvals.
 *
 * @dev Uses OpenZeppelin StandardToken.
 */
contract ERC827Token is ERC827, StandardToken {
  ERC827Caller internal caller_;

  constructor() public {
    caller_ = new ERC827Caller();
  }

  /**
   * @dev Addition to ERC20 token methods. It allows to
   * @dev approve the transfer of value and execute a call with the sent data.
   *
   * @dev Beware that changing an allowance with this method brings the risk that
   * @dev someone may use both the old and the new allowance by unfortunate
   * @dev transaction ordering. One possible solution to mitigate this race condition
   * @dev is to first reduce the spender's allowance to 0 and set the desired value
   * @dev afterwards:
   * @dev https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   *
   * @param _spender The address that will spend the funds.
   * @param _value The amount of tokens to be spent.
   * @param _data ABI-encoded contract call to call `_to` address.
   *
   * @return true if the call function was executed successfully
   */
  function approveAndCall(
    address _spender,
    uint256 _value,
    bytes _data
  )
    public
    payable
    returns (bool)
  {
    require(_spender != address(this));

    super.approve(_spender, _value);

    // solium-disable-next-line security/no-call-value
    require(caller_.makeCall.value(msg.value)(_spender, _data));

    return true;
  }

  /**
   * @dev Addition to ERC20 token methods. Transfer tokens to a specified
   * @dev address and execute a call with the sent data on the same transaction
   *
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amout of tokens to be transfered
   * @param _data ABI-encoded contract call to call `_to` address.
   *
   * @return true if the call function was executed successfully
   */
  function transferAndCall(
    address _to,
    uint256 _value,
    bytes _data
  )
    public
    payable
    returns (bool)
  {
    require(_to != address(this));

    super.transfer(_to, _value);

    // solium-disable-next-line security/no-call-value
    require(caller_.makeCall.value(msg.value)(_to, _data));
    return true;
  }

  /**
   * @dev Addition to ERC20 token methods. Transfer tokens from one address to
   * @dev another and make a contract call on the same transaction
   *
   * @param _from The address which you want to send tokens from
   * @param _to The address which you want to transfer to
   * @param _value The amout of tokens to be transferred
   * @param _data ABI-encoded contract call to call `_to` address.
   *
   * @return true if the call function was executed successfully
   */
  function transferFromAndCall(
    address _from,
    address _to,
    uint256 _value,
    bytes _data
  )
    public payable returns (bool)
  {
    require(_to != address(this));

    super.transferFrom(_from, _to, _value);

    // solium-disable-next-line security/no-call-value
    require(caller_.makeCall.value(msg.value)(_to, _data));
    return true;
  }

  /**
   * @dev Addition to StandardToken methods. Increase the amount of tokens that
   * @dev an owner allowed to a spender and execute a call with the sent data.
   *
   * @dev approve should be called when allowed[_spender] == 0. To increment
   * @dev allowed value is better to use this function to avoid 2 calls (and wait until
   * @dev the first transaction is mined)
   * @dev From MonolithDAO Token.sol
   *
   * @param _spender The address which will spend the funds.
   * @param _addedValue The amount of tokens to increase the allowance by.
   * @param _data ABI-encoded contract call to call `_spender` address.
   */
  function increaseApprovalAndCall(
    address _spender,
    uint _addedValue,
    bytes _data
  )
    public
    payable
    returns (bool)
  {
    require(_spender != address(this));

    super.increaseApproval(_spender, _addedValue);

    // solium-disable-next-line security/no-call-value
    require(caller_.makeCall.value(msg.value)(_spender, _data));

    return true;
  }

  /**
   * @dev Addition to StandardToken methods. Decrease the amount of tokens that
   * @dev an owner allowed to a spender and execute a call with the sent data.
   *
   * @dev approve should be called when allowed[_spender] == 0. To decrement
   * @dev allowed value is better to use this function to avoid 2 calls (and wait until
   * @dev the first transaction is mined)
   * @dev From MonolithDAO Token.sol
   *
   * @param _spender The address which will spend the funds.
   * @param _subtractedValue The amount of tokens to decrease the allowance by.
   * @param _data ABI-encoded contract call to call `_spender` address.
   */
  function decreaseApprovalAndCall(
    address _spender,
    uint _subtractedValue,
    bytes _data
  )
    public
    payable
    returns (bool)
  {
    require(_spender != address(this));

    super.decreaseApproval(_spender, _subtractedValue);

    // solium-disable-next-line security/no-call-value
    require(caller_.makeCall.value(msg.value)(_spender, _data));

    return true;
  }

}

/**
 * @title Mintable token
 * @dev Simple ERC20 Token example, with mintable token creation
 * @dev Issue: * https://github.com/OpenZeppelin/openzeppelin-solidity/issues/120
 * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
 */
contract MintableToken is StandardToken, Ownable {
  event Mint(address indexed to, uint256 amount);
  event MintFinished();

  bool public mintingFinished = false;


  modifier canMint() {
    require(!mintingFinished);
    _;
  }

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

  /**
   * @dev Function to mint tokens
   * @param _to The address that will receive the minted tokens.
   * @param _amount The amount of tokens to mint.
   * @return A boolean that indicates if the operation was successful.
   */
  function mint(
    address _to,
    uint256 _amount
  )
    hasMintPermission
    canMint
    public
    returns (bool)
  {
    totalSupply_ = totalSupply_.add(_amount);
    balances[_to] = balances[_to].add(_amount);
    emit Mint(_to, _amount);
    emit Transfer(address(0), _to, _amount);
    return true;
  }

  /**
   * @dev Function to stop minting new tokens.
   * @return True if the operation was successful.
   */
  function finishMinting() onlyOwner canMint public returns (bool) {
    mintingFinished = true;
    emit MintFinished();
    return true;
  }
}

/// @title EverGold
/// @dev ERC827 Token for games.
contract EverGold is ERC827Token, MintableToken, AccessByGame {
  string public constant name = "Ever Gold";
  string public constant symbol = "EG";
  uint8 public constant decimals = 0;

/**
   * @dev Function to mint tokens
   * @param _to The address that will receive the minted tokens.
   * @param _amount The amount of tokens to mint.
   * @return A boolean that indicates if the operation was successful.
   */
  function mint(
    address _to,
    uint256 _amount
  )
    onlyAccessByGame
    canMint
    public
    returns (bool)
  {
    totalSupply_ = totalSupply_.add(_amount);
    balances[_to] = balances[_to].add(_amount);
    emit Mint(_to, _amount);
    emit Transfer(address(0), _to, _amount);
    return true;
  }
  function transfer(address _to, uint256 _value)
    public
    whenNotPaused
    returns (bool)
  {
    return super.transfer(_to, _value);
  }

  function transferFrom(address _from, address _to, uint256 _value)
    public
    whenNotPaused
    returns (bool)
  {
    return super.transferFrom(_from, _to, _value);
  }

  function approve(address _spender, uint256 _value)
    public
    whenNotPaused
    returns (bool)
  {
    return super.approve(_spender, _value);
  }

  function approveAndCall(
    address _spender,
    uint256 _value,
    bytes _data
  )
    public
    payable
    whenNotPaused
    returns (bool)
  {
    return super.approveAndCall(_spender, _value, _data);
  }

  function transferAndCall(
    address _to,
    uint256 _value,
    bytes _data
  )
    public
    payable
    whenNotPaused
    returns (bool)
  {
    return super.transferAndCall(_to, _value, _data);
  }

  function transferFromAndCall(
    address _from,
    address _to,
    uint256 _value,
    bytes _data
  )
    public
    payable
    whenNotPaused
    returns (bool)
  {
    return super.transferFromAndCall(_from, _to, _value, _data);
  }

  function increaseApprovalAndCall(
    address _spender,
    uint _addedValue,
    bytes _data
  )
    public
    payable
    whenNotPaused
    returns (bool)
  {
    return super.increaseApprovalAndCall(_spender, _addedValue, _data);
  }

  function decreaseApprovalAndCall(
    address _spender,
    uint _subtractedValue,
    bytes _data
  )
    public
    payable
    whenNotPaused
    returns (bool)
  {
    return super.decreaseApprovalAndCall(_spender, _subtractedValue, _data);
  }
}

library StringLib {
  function generateName(bytes16 _s, uint256 _len, uint256 _n)
    public
    pure
    returns (bytes16 ret)
  {
    uint256 v = _n;
    bytes16 num = 0;
    while (v > 0) {
      num = bytes16(uint(num) / (2 ** 8));
      num |= bytes16(((v % 10) + 48) * 2 ** (8 * 15));
      v /= 10;
    }
    ret = _s | bytes16(uint(num) / (2 ** (8 * _len)));
    return ret;
  }
}

/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Basic {
  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 exists(uint256 _tokenId) public view returns (bool _exists);

  function approve(address _to, uint256 _tokenId) public;
  function getApproved(uint256 _tokenId)
    public view returns (address _operator);

  function setApprovalForAll(address _operator, bool _approved) public;
  function isApprovedForAll(address _owner, address _operator)
    public view returns (bool);

  function transferFrom(address _from, address _to, uint256 _tokenId) public;
  function safeTransferFrom(address _from, address _to, uint256 _tokenId)
    public;

  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    public;
}

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Enumerable is ERC721Basic {
  function totalSupply() public view returns (uint256);
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    public
    view
    returns (uint256 _tokenId);

  function tokenByIndex(uint256 _index) public view returns (uint256);
}


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Metadata is ERC721Basic {
  function name() public view returns (string _name);
  function symbol() public view returns (string _symbol);
  function tokenURI(uint256 _tokenId) public view returns (string);
}


/**
 * @title ERC-721 Non-Fungible Token Standard, full implementation interface
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
}

/**
 * Utility library of inline functions on addresses
 */
library AddressUtils {

  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract,
   *  as the code is not actually created until after the constructor finishes.
   * @param addr address to check
   * @return whether the target address is a contract
   */
  function isContract(address addr) internal view returns (bool) {
    uint256 size;
    // XXX Currently there is no better way to check if there is a contract in an address
    // than to check the size of the code at that address.
    // See https://ethereum.stackexchange.com/a/14016/36603
    // for more details about how this works.
    // TODO Check this again before the Serenity release, because all addresses will be
    // contracts then.
    // solium-disable-next-line security/no-inline-assembly
    assembly { size := extcodesize(addr) }
    return size > 0;
  }

}

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 *  from ERC721 asset contracts.
 */
contract ERC721Receiver {
  /**
   * @dev Magic value to be returned upon successful reception of an NFT
   *  Equals to `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`,
   *  which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
   */
  bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba;

  /**
   * @notice Handle the receipt of an NFT
   * @dev The ERC721 smart contract calls this function on the recipient
   *  after a `safetransfer`. 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)"))`
   */
  function onERC721Received(
    address _from,
    uint256 _tokenId,
    bytes _data
  )
    public
    returns(bytes4);
}

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721BasicToken is ERC721Basic {
  using SafeMath for uint256;
  using AddressUtils for address;

  // Equals to `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
  // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
  bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba;

  // Mapping from token ID to owner
  mapping (uint256 => address) internal tokenOwner;

  // Mapping from token ID to approved address
  mapping (uint256 => address) internal tokenApprovals;

  // Mapping from owner to number of owned token
  mapping (address => uint256) internal ownedTokensCount;

  // Mapping from owner to operator approvals
  mapping (address => mapping (address => bool)) internal operatorApprovals;

  /**
   * @dev Guarantees msg.sender is owner of the given token
   * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender
   */
  modifier onlyOwnerOf(uint256 _tokenId) {
    require(ownerOf(_tokenId) == msg.sender);
    _;
  }

  /**
   * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator
   * @param _tokenId uint256 ID of the token to validate
   */
  modifier canTransfer(uint256 _tokenId) {
    require(isApprovedOrOwner(msg.sender, _tokenId));
    _;
  }

  /**
   * @dev Gets the balance of the specified address
   * @param _owner address to query the balance of
   * @return uint256 representing the amount owned by the passed address
   */
  function balanceOf(address _owner) public view returns (uint256) {
    require(_owner != address(0));
    return ownedTokensCount[_owner];
  }

  /**
   * @dev Gets the owner of the specified token ID
   * @param _tokenId uint256 ID of the token to query the owner of
   * @return owner address currently marked as the owner of the given token ID
   */
  function ownerOf(uint256 _tokenId) public view returns (address) {
    address owner = tokenOwner[_tokenId];
    require(owner != address(0));
    return owner;
  }

  /**
   * @dev Returns whether the specified token exists
   * @param _tokenId uint256 ID of the token to query the existence of
   * @return whether the token exists
   */
  function exists(uint256 _tokenId) public view returns (bool) {
    address owner = tokenOwner[_tokenId];
    return owner != address(0);
  }

  /**
   * @dev Approves another address to transfer the given token ID
   * @dev The zero address indicates there is no approved address.
   * @dev There can only be one approved address per token at a given time.
   * @dev Can only be called by the token owner or an approved operator.
   * @param _to address to be approved for the given token ID
   * @param _tokenId uint256 ID of the token to be approved
   */
  function approve(address _to, uint256 _tokenId) public {
    address owner = ownerOf(_tokenId);
    require(_to != owner);
    require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

    if (getApproved(_tokenId) != address(0) || _to != address(0)) {
      tokenApprovals[_tokenId] = _to;
      emit Approval(owner, _to, _tokenId);
    }
  }

  /**
   * @dev Gets the approved address for a token ID, or zero if no address set
   * @param _tokenId uint256 ID of the token to query the approval of
   * @return address currently approved for the given token ID
   */
  function getApproved(uint256 _tokenId) public view returns (address) {
    return tokenApprovals[_tokenId];
  }

  /**
   * @dev Sets or unsets the approval of a given operator
   * @dev An operator is allowed to transfer all tokens of the sender on their behalf
   * @param _to operator address to set the approval
   * @param _approved representing the status of the approval to be set
   */
  function setApprovalForAll(address _to, bool _approved) public {
    require(_to != msg.sender);
    operatorApprovals[msg.sender][_to] = _approved;
    emit ApprovalForAll(msg.sender, _to, _approved);
  }

  /**
   * @dev Tells whether an operator is approved by a given owner
   * @param _owner owner address which you want to query the approval of
   * @param _operator operator address which you want to query the approval of
   * @return bool whether the given operator is approved by the given owner
   */
  function isApprovedForAll(
    address _owner,
    address _operator
  )
    public
    view
    returns (bool)
  {
    return operatorApprovals[_owner][_operator];
  }

  /**
   * @dev Transfers the ownership of a given token ID to another address
   * @dev Usage of this method is discouraged, use `safeTransferFrom` whenever possible
   * @dev Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
  */
  function transferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    public
    canTransfer(_tokenId)
  {
    require(_from != address(0));
    require(_to != address(0));

    clearApproval(_from, _tokenId);
    removeTokenFrom(_from, _tokenId);
    addTokenTo(_to, _tokenId);

    emit Transfer(_from, _to, _tokenId);
  }

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * @dev If the target address is a contract, it must implement `onERC721Received`,
   *  which is called upon a safe transfer, and return the magic value
   *  `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`; otherwise,
   *  the transfer is reverted.
   * @dev Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
  */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    public
    canTransfer(_tokenId)
  {
    // solium-disable-next-line arg-overflow
    safeTransferFrom(_from, _to, _tokenId, "");
  }

  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * @dev If the target address is a contract, it must implement `onERC721Received`,
   *  which is called upon a safe transfer, and return the magic value
   *  `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`; otherwise,
   *  the transfer is reverted.
   * @dev Requires the msg sender to be the owner, approved, or operator
   * @param _from current owner of the token
   * @param _to address to receive the ownership of the given token ID
   * @param _tokenId uint256 ID of the token to be transferred
   * @param _data bytes data to send along with a safe transfer check
   */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    public
    canTransfer(_tokenId)
  {
    transferFrom(_from, _to, _tokenId);
    // solium-disable-next-line arg-overflow
    require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
  }

  /**
   * @dev Returns whether the given spender can transfer a given token ID
   * @param _spender address of the spender to query
   * @param _tokenId uint256 ID of the token to be transferred
   * @return bool whether the msg.sender is approved for the given token ID,
   *  is an operator of the owner, or is the owner of the token
   */
  function isApprovedOrOwner(
    address _spender,
    uint256 _tokenId
  )
    internal
    view
    returns (bool)
  {
    address owner = ownerOf(_tokenId);
    // Disable solium check because of
    // https://github.com/duaraghav8/Solium/issues/175
    // solium-disable-next-line operator-whitespace
    return (
      _spender == owner ||
      getApproved(_tokenId) == _spender ||
      isApprovedForAll(owner, _spender)
    );
  }

  /**
   * @dev Internal function to mint a new token
   * @dev Reverts if the given token ID already exists
   * @param _to The address that will own the minted token
   * @param _tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address _to, uint256 _tokenId) internal {
    require(_to != address(0));
    addTokenTo(_to, _tokenId);
    emit Transfer(address(0), _to, _tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * @dev Reverts if the token does not exist
   * @param _tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address _owner, uint256 _tokenId) internal {
    clearApproval(_owner, _tokenId);
    removeTokenFrom(_owner, _tokenId);
    emit Transfer(_owner, address(0), _tokenId);
  }

  /**
   * @dev Internal function to clear current approval of a given token ID
   * @dev Reverts if the given address is not indeed the owner of the token
   * @param _owner owner of the token
   * @param _tokenId uint256 ID of the token to be transferred
   */
  function clearApproval(address _owner, uint256 _tokenId) internal {
    require(ownerOf(_tokenId) == _owner);
    if (tokenApprovals[_tokenId] != address(0)) {
      tokenApprovals[_tokenId] = address(0);
      emit Approval(_owner, address(0), _tokenId);
    }
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * @param _to address representing the new owner of the given token ID
   * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function addTokenTo(address _to, uint256 _tokenId) internal {
    require(tokenOwner[_tokenId] == address(0));
    tokenOwner[_tokenId] = _to;
    ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * @param _from address representing the previous owner of the given token ID
   * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function removeTokenFrom(address _from, uint256 _tokenId) internal {
    require(ownerOf(_tokenId) == _from);
    ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
    tokenOwner[_tokenId] = address(0);
  }

  /**
   * @dev Internal function to invoke `onERC721Received` on a target address
   * @dev The call is not executed if the target address is not a contract
   * @param _from address representing the previous owner of the given token ID
   * @param _to target address that will receive the tokens
   * @param _tokenId uint256 ID of the token to be transferred
   * @param _data bytes optional data to send along with the call
   * @return whether the call correctly returned the expected magic value
   */
  function checkAndCallSafeTransfer(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes _data
  )
    internal
    returns (bool)
  {
    if (!_to.isContract()) {
      return true;
    }
    bytes4 retval = ERC721Receiver(_to).onERC721Received(
      _from, _tokenId, _data);
    return (retval == ERC721_RECEIVED);
  }
}

/**
 * @title Full ERC721 Token
 * This implementation includes all the required and some optional functionality of the ERC721 standard
 * Moreover, it includes approve all functionality using operator terminology
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721Token is ERC721, ERC721BasicToken {
  // Token name
  string internal name_;

  // Token symbol
  string internal symbol_;

  // Mapping from owner to list of owned token IDs
  mapping(address => uint256[]) internal ownedTokens;

  // Mapping from token ID to index of the owner tokens list
  mapping(uint256 => uint256) internal ownedTokensIndex;

  // Array with all token ids, used for enumeration
  uint256[] internal allTokens;

  // Mapping from token id to position in the allTokens array
  mapping(uint256 => uint256) internal allTokensIndex;

  // Optional mapping for token URIs
  mapping(uint256 => string) internal tokenURIs;

  /**
   * @dev Constructor function
   */
  constructor(string _name, string _symbol) public {
    name_ = _name;
    symbol_ = _symbol;
  }

  /**
   * @dev Gets the token name
   * @return string representing the token name
   */
  function name() public view returns (string) {
    return name_;
  }

  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
  function symbol() public view returns (string) {
    return symbol_;
  }

  /**
   * @dev Returns an URI for a given token ID
   * @dev Throws if the token ID does not exist. May return an empty string.
   * @param _tokenId uint256 ID of the token to query
   */
  function tokenURI(uint256 _tokenId) public view returns (string) {
    require(exists(_tokenId));
    return tokenURIs[_tokenId];
  }

  /**
   * @dev Gets the token ID at a given index of the tokens list of the requested owner
   * @param _owner address owning the tokens list to be accessed
   * @param _index uint256 representing the index to be accessed of the requested tokens list
   * @return uint256 token ID at the given index of the tokens list owned by the requested address
   */
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    public
    view
    returns (uint256)
  {
    require(_index < balanceOf(_owner));
    return ownedTokens[_owner][_index];
  }

  /**
   * @dev Gets the total amount of tokens stored by the contract
   * @return uint256 representing the total amount of tokens
   */
  function totalSupply() public view returns (uint256) {
    return allTokens.length;
  }

  /**
   * @dev Gets the token ID at a given index of all the tokens in this contract
   * @dev Reverts if the index is greater or equal to the total number of tokens
   * @param _index uint256 representing the index to be accessed of the tokens list
   * @return uint256 token ID at the given index of the tokens list
   */
  function tokenByIndex(uint256 _index) public view returns (uint256) {
    require(_index < totalSupply());
    return allTokens[_index];
  }

  /**
   * @dev Internal function to set the token URI for a given token
   * @dev Reverts if the token ID does not exist
   * @param _tokenId uint256 ID of the token to set its URI
   * @param _uri string URI to assign
   */
  function _setTokenURI(uint256 _tokenId, string _uri) internal {
    require(exists(_tokenId));
    tokenURIs[_tokenId] = _uri;
  }

  /**
   * @dev Internal function to add a token ID to the list of a given address
   * @param _to address representing the new owner of the given token ID
   * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function addTokenTo(address _to, uint256 _tokenId) internal {
    super.addTokenTo(_to, _tokenId);
    uint256 length = ownedTokens[_to].length;
    ownedTokens[_to].push(_tokenId);
    ownedTokensIndex[_tokenId] = length;
  }

  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * @param _from address representing the previous owner of the given token ID
   * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function removeTokenFrom(address _from, uint256 _tokenId) internal {
    super.removeTokenFrom(_from, _tokenId);

    uint256 tokenIndex = ownedTokensIndex[_tokenId];
    uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
    uint256 lastToken = ownedTokens[_from][lastTokenIndex];

    ownedTokens[_from][tokenIndex] = lastToken;
    ownedTokens[_from][lastTokenIndex] = 0;
    // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
    // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
    // the lastToken to the first position, and then dropping the element placed in the last position of the list

    ownedTokens[_from].length--;
    ownedTokensIndex[_tokenId] = 0;
    ownedTokensIndex[lastToken] = tokenIndex;
  }

  /**
   * @dev Internal function to mint a new token
   * @dev Reverts if the given token ID already exists
   * @param _to address the beneficiary that will own the minted token
   * @param _tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address _to, uint256 _tokenId) internal {
    super._mint(_to, _tokenId);

    allTokensIndex[_tokenId] = allTokens.length;
    allTokens.push(_tokenId);
  }

  /**
   * @dev Internal function to burn a specific token
   * @dev Reverts if the token does not exist
   * @param _owner owner of the token to burn
   * @param _tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address _owner, uint256 _tokenId) internal {
    super._burn(_owner, _tokenId);

    // Clear metadata (if any)
    if (bytes(tokenURIs[_tokenId]).length != 0) {
      delete tokenURIs[_tokenId];
    }

    // Reorg all tokens array
    uint256 tokenIndex = allTokensIndex[_tokenId];
    uint256 lastTokenIndex = allTokens.length.sub(1);
    uint256 lastToken = allTokens[lastTokenIndex];

    allTokens[tokenIndex] = lastToken;
    allTokens[lastTokenIndex] = 0;

    allTokens.length--;
    allTokensIndex[_tokenId] = 0;
    allTokensIndex[lastToken] = tokenIndex;
  }

}

contract CastleToken is ERC721Token, AccessByGame {
  string constant NAME = "Crypto Ninja Game Castle";
  string constant SYMBOL = "CNC";

  uint256 constant MAX_WIDTH = 10;

  uint8 constant LOG_SET = 0;
  uint8 constant LOG_RESET = 1;
  uint8 constant LOG_WIN = 2;
  uint8 constant LOG_LOSS = 3;

  struct Castle {
    bytes16 name;
    uint16 level;
    uint32 exp;
    uint8 width;
    uint8 depth;
    uint32 readyTime;
    uint16 tryCount;
    uint16 winCount;
    uint16 lossCount;
    uint8 levelPoint;
    uint16 reward;
  }

  mapping (uint256 => bytes) internal traps;
  mapping (uint256 => bytes32[]) internal logs;

  EverGold internal goldToken;

  uint8 public initWidth = 5;
  uint8 public initDepth = 8;

  uint256 public itemsPerPage = 10;

  uint8 internal expOnSuccess = 3;
  uint8 internal expOnFault = 1;
  uint8 internal leveupExp = 10;

  uint256 internal cooldownTime = 5 minutes;

  Castle[] internal castles;

  uint16 public price = 1000;

  event NewCastle(uint256 castleid, uint256 width, uint256 depth);
  event SetTraps(uint256 castleid);
  event ResetTraps(uint256 castleid);
  event UseTrap(uint256 castleid, uint256 path, uint256 trapIndex, uint256 power);

  event AddLog(uint8 id, uint32 datetime, uint256 castleid, uint256 ninjaid, uint8 x, uint8 y, bool win);

  constructor()
    public
    ERC721Token(NAME, SYMBOL)
  {
    castles.push(Castle({
      name: "DUMMY", level: 0, exp: 0,
      width: 0, depth: 0,
      readyTime: 0,
      tryCount: 0, winCount: 0, lossCount: 0,
      levelPoint: 0,
      reward: 0}));
  }

  function mint(address _beneficiary)
    public
    whenNotPaused
    onlyAccessByGame
    returns (bool)
  {
    require(_beneficiary != address(0));
    return _create(_beneficiary, initWidth, initDepth);
  }

  function setTraps(
    uint256 _castleid,
    uint16 _reward,
    bytes _traps)
    public
    whenNotPaused()
    onlyAccessByGame
    returns (bool)
  {
    require((_castleid > 0) && (_castleid < castles.length));
    require(_reward > 0);
    Castle storage castle = castles[_castleid];
    castle.reward = _reward;
    traps[_castleid] = _traps;

    logs[_castleid].push(_generateLog(uint32(now), LOG_SET, 0, 0, 0, 0));

    emit SetTraps(_castleid);

    return true;
  }

  function resetTraps(uint256 _castleid)
    public
    onlyAccessByGame
    returns (bool)
  {
    require((_castleid > 0) && (_castleid < castles.length));
    Castle storage castle = castles[_castleid];
    for (uint256 i = 0; i < castle.width * castle.depth; i++) {
      traps[_castleid][i] = byte(0);
    }
    castle.reward = 0;
    logs[_castleid].push(_generateLog(uint32(now), LOG_RESET, 0, 0, 0, 0));

    emit ResetTraps(_castleid);

    return true;
  }

  function win(
    uint256 _castleid, uint256 _ninjaid, uint256 _path, bytes _steps, uint256 _count)
    public
    onlyAccessByGame
    returns (bool)
  {
    require((_castleid > 0) && (_castleid < castles.length));
    uint8 width = getWidth(_castleid);
    for (uint256 i = 0; i < _count; i++) {
      traps[_castleid][uint256(_steps[i])] = byte(0);
    }
    Castle storage castle = castles[_castleid];
    castle.winCount++;
    castle.exp += expOnSuccess;
    castle.levelPoint += expOnSuccess;
    _levelUp(castle);
    logs[_castleid].push(
      _generateLog(
        uint32(now), LOG_WIN, uint32(_ninjaid),
        uint8(_path % width), uint8(_path / width), 1
      )
    );

    _triggerCooldown(_castleid);

    return true;
  }

  function lost(uint256 _castleid, uint256 _ninjaid)
    public
    onlyAccessByGame
    returns (bool)
  {
    require((_castleid > 0) && (_castleid < castles.length));
    Castle storage castle = castles[_castleid];
    castle.reward = 0;
    castle.lossCount++;
    castle.exp += expOnFault;
    castle.levelPoint += expOnFault;
    _levelUp(castle);

    logs[_castleid].push(_generateLog(uint32(now), LOG_LOSS, uint32(_ninjaid), 0, 0, 0));

    resetTraps(_castleid);

    _triggerCooldown(_castleid);

    return true;
  }

  function setName(uint256 _castleid, bytes16 _newName)
    external
    onlyOwnerOf(_castleid)
  {
    castles[_castleid].name = _newName;
  }

  function setGoldContract(address _goldTokenAddress)
    public
    onlyOwner
  {
    require(_goldTokenAddress != address(0));

    goldToken = EverGold(_goldTokenAddress);
  }

  function setFee(uint16 _price)
    external
    onlyOwner
  {
    price = _price;
  }

  function setItemPerPage(uint16 _amount)
    external
    onlyOwner
  {
    itemsPerPage = _amount;
  }

  function setMaxCoordinate(uint256 _cooldownTime)
    public
    onlyOwner
  {
    cooldownTime = _cooldownTime;
  }

  function _create(address _beneficiary, uint8 _width, uint8 _depth)
    internal
    onlyAccessByGame
    returns (bool)
  {
    require(_beneficiary != address(0));
    require((_width > 0) && (_depth > 0));
    uint256 tokenid = castles.length;
    bytes16 name = StringLib.generateName("CASTLE#", 7, tokenid);

    uint256 id = castles.push(Castle({
      name: name, level: 1, exp: 0,
      width: _width, depth: _depth,
      readyTime: uint32(now + cooldownTime),
      tryCount: 0, winCount: 0, lossCount: 0,
      levelPoint: 0,
      reward: 0})) - 1;

    traps[id] = new bytes(_width * _depth);
    _mint(_beneficiary, id);
    emit NewCastle(id, _width, _depth);

    return true;
  }

  function _levelUp(Castle storage _castle)
    internal
    onlyAccessByGame
  {
    if (_castle.levelPoint >= leveupExp) {
      _castle.levelPoint -= leveupExp;
      _castle.level++;
    }
  }

  function _triggerCooldown(uint256 _castleid)
    internal
    onlyAccessByGame
  {
    require((_castleid > 0) && (_castleid < castles.length));
    Castle storage castle = castles[_castleid];
    castle.readyTime = uint32(now + cooldownTime);
  }

  function getAll()
    external
    view
    returns (uint256[] result)
  {
    return allTokens;
  }

  function getOpen(uint256 _startIndex)
    external
    view
    returns (uint256[] result)
  {
    uint256 n = 0;
    uint256 i = 0;
    for (i = _startIndex; i < castles.length; i++) {
      Castle storage castle = castles[i];
      if ((castle.reward > 0) &&
          (ownerOf(i) != msg.sender)) {
        n++;
        if (n >= _startIndex) {
          break;
        }
      }
    }
    uint256[] memory castleids = new uint256[](itemsPerPage + 1);
    n = 0;
    while (i < castles.length) {
      castle = castles[i];
      if ((castle.reward > 0) &&
          (ownerOf(i) != msg.sender)) {
        castleids[n++] = i;
        if (n > itemsPerPage) {
          break;
        }
      }
      i++;
    }
    return castleids;
  }

  function getByOwner(address _owner)
    external
    view
    returns (uint256[] result)
  {
    return ownedTokens[_owner];
  }

  function getInfo(uint256 _castleid)
    external
    view
    returns (bytes16, uint16, uint32,
      uint8, uint8, uint16, uint16,
      uint16)
  {
    require((_castleid > 0) && (_castleid < castles.length));
    Castle storage castle = castles[_castleid];
    return (
      castle.name,
      castle.level,
      castle.exp,
      castle.width,
      castle.depth,
      castle.winCount,
      castle.lossCount,
      castle.reward);
  }

  function getLevel(uint256 _castleid)
    external
    view
    returns (uint16)
  {
    Castle storage castle = castles[_castleid];
    return castle.level;
  }

  function getLogs(uint256 _castleid)
    external
    view
    returns (bytes32[])
  {
    require((_castleid > 0) && (_castleid < castles.length));
    return logs[_castleid];
  }

  function getTrapInfo(uint256 _castleid)
    external
    view
    returns (bytes)
  {
    require((ownerOf(_castleid) == msg.sender) || (contractAccess[msg.sender] == true));
    return traps[_castleid];
  }

  function isReady(uint256 _castleid)
    public
    view
    returns (bool)
  {
    require((_castleid > 0) && (_castleid < castles.length));
    Castle storage castle = castles[_castleid];
    return (castle.readyTime <= now);
  }

  function getReward(uint256 _castleid)
    public
    view
    returns (uint16)
  {
    require((_castleid > 0) && (_castleid < castles.length));
    Castle storage castle = castles[_castleid];
    return castle.reward;
  }

  function getWidth(uint256 _castleid)
    public
    view
    returns (uint8)
  {
    require((_castleid > 0) && (_castleid < castles.length));
    Castle storage castle = castles[_castleid];
    return castle.width;
  }

  function getTrapid(uint256 _castleid, uint8 _path)
    public
    onlyAccessByGame
    view
    returns (uint8)
  {
    return uint8(traps[_castleid][_path]);
  }

  function getPrice()
    public
    view
    returns (uint256)
  {
    return price;
  }

  function _generateLog(
    uint32 _datetime,
    uint8 _id,
    uint32 _ninjaid,
    uint8 _x,
    uint8 _y,
    uint8 _win)
    internal
    pure
    returns (bytes32)
  {
    return
      bytes32(
        (uint256(_datetime) * (2 ** (8 * 28))) |
        (uint256(_id) * (2 ** (8 * 24))) |
        (uint256(_ninjaid) * (2 ** (8 * 20))) |
        (uint256(_x) * (2 ** (8 * 16))) |
        (uint256(_y) * (2 ** (8 * 12))) |
        (uint256(_win) * (2 ** (8 * 8))));
  }
}

contract ItemToken is AccessByGame {
  struct Item {
    bytes16 name;
    uint16 price;
    uint16 power;
    bool enabled;
  }

  EverGold internal goldToken;

  Item[] private items;

  uint8 public itemKindCount = 0;

  mapping (address => mapping (uint256 => uint256)) private ownedItems;

  event NewItem(bytes32 name, uint16 price, uint16 power);
  event UseItem(uint256 itemid, uint256 amount);

  constructor()
    public
  {
    addItem("None", 0, 0, false);
    addItem("Arrow", 10, 10, true);
    addItem("Tiger", 30, 20, true);
    addItem("Spear", 50, 30, true);
    addItem("Wood", 50, 20, true);
    addItem("Fire", 50, 20, true);
    addItem("Earth", 50, 20, true);
    addItem("Metal", 50, 20, true);
    addItem("Water", 50, 20, true);
  }

  function setGoldContract(address _goldTokenAddress)
    public
    onlyOwner
  {
    require(_goldTokenAddress != address(0));

    goldToken = EverGold(_goldTokenAddress);
  }

  function buy(address _to, uint256 _itemid, uint256 _amount)
    public
    onlyAccessByGame
    whenNotPaused
    returns (bool)
  {
    require(_amount > 0);
    require(_itemid > 0 && _itemid < itemKindCount);
    ownedItems[_to][_itemid] += _amount;

    return true;
  }

  function useItem(address _owner, uint256 _itemid, uint256 _amount)
    public
    onlyAccessByGame
    whenNotPaused
    returns (bool)
  {
    require(_amount > 0);
    require((_itemid > 0) && (_itemid < itemKindCount));
    require(_amount <= ownedItems[_owner][_itemid]);

    ownedItems[_owner][_itemid] -= _amount;

    emit UseItem(_itemid, _amount);

    return true;
  }

  function addItem(bytes16 _name, uint16 _price, uint16 _power, bool _enabled)
    public
    onlyOwner()
    returns (bool)
  {
    require(_name != 0x0);
    items.push(Item({
      name:_name,
      price: _price,
      power: _power,
      enabled: _enabled
      }));
    itemKindCount++;

    emit NewItem(_name, _price, _power);
    return true;
  }

  function setItemAvailable(uint256 _itemid, bool _enabled)
    public
    onlyOwner()
  {
    require(_itemid > 0 && _itemid < itemKindCount);

    items[_itemid].enabled = _enabled;
  }

  function getItemCounts()
    public
    view
    returns (uint256[])
  {
    uint256[] memory itemCounts = new uint256[](itemKindCount);
    for (uint256 i = 0; i < itemKindCount; i++) {
      itemCounts[i] = ownedItems[msg.sender][i];
    }
    return itemCounts;
  }

  function getItemCount(uint256 _itemid)
    public
    view
    returns (uint256)
  {
    require(_itemid > 0 && _itemid < itemKindCount);
    return ownedItems[msg.sender][_itemid];
  }

  function getItemKindCount()
    public
    view
    returns (uint256)
  {
    return itemKindCount;
  }

  function getItem(uint256 _itemid)
    public
    view
    returns (bytes16 name, uint16 price, uint16 power, bool enabled)
  {
    require(_itemid < itemKindCount);
    return (items[_itemid].name, items[_itemid].price, items[_itemid].power, items[_itemid].enabled);
  }

  function getPower(uint256 _itemid)
    public
    view
    returns (uint16 power)
  {
    require(_itemid < itemKindCount);
    return items[_itemid].power;
  }

  function getPrice(uint256 _itemid)
    public
    view
    returns (uint16)
  {
    require(_itemid < itemKindCount);
    return items[_itemid].price;
  }
}

contract NinjaToken is ERC721Token, AccessByGame {
  string public constant NAME = "Crypto Ninja Game Ninja";
  string public constant SYMBOL = "CNN";

  event NewNinja(uint256 ninjaid, bytes16 name, bytes32 pattern);

  struct Ninja {
    bytes32 pattern;
    bytes16 name;
    uint16 level;
    uint32 exp;
    uint8 dna1;
    uint8 dna2;
    uint32 readyTime;
    uint16 winCount;
    uint8 levelPoint;
    uint16 lossCount;
    uint16 reward;
    uint256 lastAttackedCastleid;
  }

  mapping (uint256 => bytes) private paths;

  mapping (uint256 => bytes) private steps;

  EverGold internal goldToken;

  uint8 internal expOnSuccess = 3;
  uint8 internal expOnFault = 1;
  uint8 internal leveupExp = 10;

  uint256 internal cooldownTime = 5 minutes;

  uint256 internal maxCoordinate = 12;

  Ninja[] internal ninjas;

  uint256 private randNonce = 0;

  uint8 public kindCount = 2;
  uint32[] public COLORS = [
    0xD7003A00,
    0xF3980000,
    0x00552E00,
    0x19448E00,
    0x543F3200,
    0xE7609E00,
    0xFFEC4700,
    0x68BE8D00,
    0x0095D900,
    0xE9DFE500,
    0xEE836F00,
    0xF2F2B000,
    0xAACF5300,
    0x0A3AF00,
    0xF8FBF800,
    0xF4B3C200,
    0x928C3600,
    0xA59ACA00,
    0xABCED800,
    0x30283300,
    0xFDEFF200,
    0xDDBB9900,
    0x74539900,
    0xAA4C8F00
  ];

  uint256 public price = 1000;

  constructor()
      public
      ERC721Token(NAME, SYMBOL)
  {
    ninjas.push(Ninja({
      pattern: 0, name: "DUMMY", level: 0, exp: 0,
      dna1: 0, dna2: 0,
      readyTime: 0,
      winCount: 0, lossCount: 0,
      levelPoint:0, reward: 0,
      lastAttackedCastleid: 0 }));
  }

  function mint(address _beneficiary)
    public
    whenNotPaused
    onlyAccessByGame
    returns (bool)
  {
    require(_beneficiary != address(0));
    return _create(_beneficiary, 0, 0);
  }

  function burn(uint256 _tokenId) external onlyOwnerOf(_tokenId) {
    super._burn(msg.sender, _tokenId);
  }

  function setPath(
    uint256 _ninjaid,
    uint256 _castleid,
    bytes _path,
    bytes _steps)
    public
    onlyAccessByGame
  {
    Ninja storage ninja = ninjas[_ninjaid];
    ninja.lastAttackedCastleid = _castleid;
    paths[_ninjaid] = _path;
    steps[_ninjaid] = _steps;
  }

  function win(uint256 _ninjaid)
    public
    onlyAccessByGame
    returns (bool)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    ninja.winCount++;
    ninja.exp += expOnSuccess;
    ninja.levelPoint += expOnSuccess;
    _levelUp(ninja);

    _triggerCooldown(_ninjaid);

    return true;
  }

  function lost(uint256 _ninjaid)
    public
    onlyAccessByGame
    returns (bool)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    ninja.lossCount++;
    ninja.exp += expOnFault;
    ninja.levelPoint += expOnFault;
    _levelUp(ninja);

    _triggerCooldown(_ninjaid);

    return true;
  }

  function setName(uint256 _ninjaid, bytes16 _newName)
    external
    onlyOwnerOf(_ninjaid)
  {
    ninjas[_ninjaid].name = _newName;
  }

  function setGoldContract(address _goldTokenAddress)
    public
    onlyOwner
  {
    require(_goldTokenAddress != address(0));

    goldToken = EverGold(_goldTokenAddress);
  }

  function setNinjaKindCount(uint8 _kindCount)
    public
    onlyOwner
  {
    kindCount = _kindCount;
  }

  function setPrice(uint16 _price)
    public
    onlyOwner
  {
    price = _price;
  }

  function setMaxCoordinate(uint16 _maxCoordinate)
    public
    onlyOwner
  {
    maxCoordinate = _maxCoordinate;
  }

  function setMaxCoordinate(uint256 _cooldownTime)
    public
    onlyOwner
  {
    cooldownTime = _cooldownTime;
  }

  function _create(address _beneficiary, uint8 _dna1, uint8 _dna2)
    private
    returns (bool)
  {
    bytes32 pattern = _generateInitialPattern();
    uint256 tokenid = ninjas.length;
    bytes16 name = StringLib.generateName("NINJA#", 6, tokenid);

    uint256 id = ninjas.push(Ninja({
      pattern: pattern, name: name, level: 1, exp: 0,
      dna1: _dna1, dna2: _dna2,
      readyTime: uint32(now + cooldownTime),
      winCount: 0, lossCount: 0,
      levelPoint:0, reward: 0,
      lastAttackedCastleid: 0})) - 1;
    super._mint(_beneficiary, id);

    emit NewNinja(id, name, pattern);

    return true;
  }

  function _triggerCooldown(uint256 _ninjaid)
    internal
    onlyAccessByGame
  {
    Ninja storage ninja = ninjas[_ninjaid];
    ninja.readyTime = uint32(now + cooldownTime);
  }

  function _levelUp(Ninja storage _ninja)
    internal
    onlyAccessByGame
  {
    if (_ninja.levelPoint >= leveupExp) {
      _ninja.levelPoint -= leveupExp;
      _ninja.level++;
      if (_ninja.level == 2) {
        _ninja.dna1 = uint8(_getRandom(6));
      } else if (_ninja.level == 5) {
        _ninja.dna2 = uint8(_getRandom(6));
      }
    }
  }

  function getByOwner(address _owner)
    external
    view
    returns(uint256[] result)
  {
    return ownedTokens[_owner];
  }

  function getInfo(uint256 _ninjaid)
    external
    view
    returns (bytes16, uint32, uint16, uint16, bytes32, uint8, uint8)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    return (ninja.name, ninja.level, ninja.winCount, ninja.lossCount, ninja.pattern,
      ninja.dna1, ninja.dna2);
  }

  function getHp(uint256 _ninjaid)
    public
    view
    returns (uint32)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    return uint32(100 + (ninja.level - 1) * 10);
  }

  function getDna1(uint256 _ninjaid)
    public
    view
    returns (uint8)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    return ninja.dna1;
  }

  function getDna2(uint256 _ninjaid)
    public
    view
    returns (uint8)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    return ninja.dna2;
  }

  function isReady(uint256 _ninjaid)
    public
    view
    returns (bool)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    return (ninja.readyTime <= now);
  }

  function getReward(uint256 _ninjaid)
    public
    view
    onlyOwnerOf(_ninjaid)
    returns (uint16)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    return ninja.reward;
  }

  function getPath(uint256 _ninjaid)
    public
    view
    onlyOwnerOf(_ninjaid)
    returns (bytes path)
  {
    return paths[_ninjaid];
  }

  function getLastAttack(uint256 _ninjaid)
    public
    view
    onlyOwnerOf(_ninjaid)
    returns (uint256 castleid, bytes path)
  {
    Ninja storage ninja = ninjas[_ninjaid];
    return (ninja.lastAttackedCastleid, paths[_ninjaid]);
  }

  function getAttr(bytes32 _pattern, uint256 _n)
    internal
    pure
    returns (bytes4)
  {
    require(_n < 8);
    uint32 mask = 0xffffffff;
    return bytes4(uint256(_pattern) / (2 ** ((7 - _n) * 8)) & mask);
  }

  function _getRandom(uint256 _modulus)
    internal
    onlyAccessByGame
    returns(uint32)
  {
    randNonce = randNonce.add(1);
    return uint32(uint256(keccak256(abi.encodePacked(now, msg.sender, randNonce))) % _modulus);
//    return uint8(uint256(keccak256(block.timestamp, block.difficulty))%251);
  }

  function _generateInitialPattern()
    internal
    onlyAccessByGame
    returns (bytes32)
  {
    uint256 pattern = 0;

    uint32 color = COLORS[(_getRandom(COLORS.length))];
    for (uint256 i = 0; i < 8; i++) {
      uint32 temp = color;
      if (i == 1) {
        temp |= _getRandom(2);
      } else {
        temp |= _getRandom(maxCoordinate);
      }
      pattern = pattern | (temp * 2 ** (8 * 4 * (7 - i)));
    }
    return bytes32(pattern);
  }

  function getPrice()
    public
    view
    returns (uint256)
  {
    return price;
  }
}

contract UserToken is AccessByGame {
  struct User {
    string name;
    uint32 registeredDate;
  }

  string constant public DEFAULT_NAME = "NONAME";

  User[] private users;

  uint256 public userCount = 0;

  mapping (address => uint256) private ownerToUser;

  constructor()
    public
  {
    mint(msg.sender, "OWNER");
  }

  function mint(address _beneficiary, string _name)
    public
    onlyAccessByGame
    whenNotPaused()
    returns (bool)
  {
    require(_beneficiary != address(0));
    require(ownerToUser[_beneficiary] == 0);

    User memory user = User({
      name: _name,
      registeredDate: uint32(now)
    });

    uint256 id = users.push(user) - 1;

    ownerToUser[_beneficiary] = id;

    userCount++;

    return true;
  }

  function setName(string _name)
    public
    whenNotPaused()
    returns (bool)
  {
    require(bytes(_name).length > 1);
    require(ownerToUser[msg.sender] != 0);

    uint256 userid = ownerToUser[msg.sender];
    users[userid].name = _name;

    return true;
  }

  function getUserid(address _owner)
    external
    view
    onlyAccessByGame
    returns(uint256 result)
  {
    if (ownerToUser[_owner] == 0) {
      return 0;
    }
    return ownerToUser[_owner];
  }

  function getUserInfo()
    public
    view
    returns (uint256, string, uint32)
  {
    uint256 userid = ownerToUser[msg.sender];
    return getUserInfoById(userid);
  }

  function getUserInfoById(uint256 _userid)
    public
    view
    returns (uint256, string, uint32)
  {
    User storage user = users[_userid];
    return (_userid, user.name, user.registeredDate);
  }
}

/**
 * @title TokenDestructible:
 * @author Remco Bloemen <[email protected]π.com>
 * @dev Base contract that can be destroyed by owner. All funds in contract including
 * listed tokens will be sent to the owner.
 */
contract TokenDestructible is Ownable {

  constructor() public payable { }

  /**
   * @notice Terminate contract and refund to owner
   * @param tokens List of addresses of ERC20 or ERC20Basic token contracts to
   refund.
   * @notice The called token contracts could try to re-enter this contract. Only
   supply token contracts you trust.
   */
  function destroy(address[] tokens) onlyOwner public {

    // Transfer tokens to owner
    for (uint256 i = 0; i < tokens.length; i++) {
      ERC20Basic token = ERC20Basic(tokens[i]);
      uint256 balance = token.balanceOf(this);
      token.transfer(owner, balance);
    }

    // Transfer Eth to owner and terminate contract
    selfdestruct(owner);
  }
}

contract GameV001 is AccessByGame, TokenDestructible {
  using SafeMath for uint256;

  uint8 constant INIT_WIDTH = 5;
  uint8 constant INIT_DEPTH = 8;

  UserToken private userToken;
  EverGold private goldToken;
  CastleToken private castleToken;
  NinjaToken private ninjaToken;
  ItemToken private itemToken;

  struct AttackLog {
    uint256 castleid;
    uint16 reward;
    uint32 hp;
    uint8 path;
    uint32 trapDamage;
    bool dead;
  }

  mapping (uint256 => AttackLog[]) private attackLogs;
  mapping (uint256 => uint256) private numAttackLogs;

  event Attack(uint256 ninjaid, uint256 castleid, uint32 hp, uint8 path, uint32 trapDamage, uint32 damage);
  event AttackStart(uint256 ninjaid, uint256 castleid, uint32 hp);
  event AttackEnd(uint256 ninjaid, uint256 castleid, bool result);

  constructor(
    address _goldTokenAddress,
    address _castleTokenAddress,
    address _ninjaTokenAddress,
    address _userTokenAddress,
    address _itemTokenAddress)
    public
  {
    require(_goldTokenAddress != address(0));
    require(_castleTokenAddress != address(0));
    require(_ninjaTokenAddress != address(0));
    require(_userTokenAddress != address(0));
    require(_itemTokenAddress != address(0));

    goldToken = EverGold(_goldTokenAddress);
    castleToken = CastleToken(_castleTokenAddress);
    ninjaToken = NinjaToken(_ninjaTokenAddress);
    userToken = UserToken(_userTokenAddress);
    itemToken = ItemToken(_itemTokenAddress);
  }

  function  registerUser(string _name)
    public
    returns (bool)
  {
    require(msg.sender != address(0));
    require(userToken.mint(msg.sender, _name));

    return true;
  }

  function  buyNinja(address _beneficiary)
    public
    payable
    returns (bool)
  {
    require(msg.sender != address(0));
    uint256 price = ninjaToken.getPrice();
    require(msg.value == price);
    require(ninjaToken.mint(_beneficiary));

    return true;
  }

  function buyCastle(address _beneficiary)
    public
    payable
    returns (bool)
  {
    require(msg.sender != address(0));
    uint256 price = castleToken.getPrice();
    require(msg.value == price);
    require(castleToken.mint(_beneficiary));

    return true;
  }

  function buyItem(address _beneficiary, uint8 _itemid, uint256 _amount)
    public
    payable
    returns (bool)
  {
    require(msg.sender != address(0));
    uint16 price = itemToken.getPrice(_itemid);
    uint256 totalPrice = price * _amount;
    require(msg.value == totalPrice);
    require(itemToken.buy(_beneficiary, _itemid, _amount));

    return true;
  }

  function defence(
    address _beneficiary,
    uint256 _castleid,
    uint16 _reward,
    bytes _traps,
    uint256[] _useTraps)
    public
    payable
    whenNotPaused
    returns (bool)
  {
    require(msg.value == _reward);

    for (uint256 i = 1; i < _useTraps.length; i++) {
      if (_useTraps[i] > 0) {
        require(itemToken.useItem(_beneficiary, i, _useTraps[i]));
      }
    }
    require(castleToken.setTraps(_castleid, _reward, _traps));

    return true;
  }

  function addTraps(
    uint256 _castleid,
    bytes _traps,
    uint256[] _useTraps)
    public
    whenNotPaused
    returns (bool)
  {
    require(castleToken.getReward(_castleid) > 0);
    bytes memory traps = castleToken.getTrapInfo(_castleid);
    for (uint256 i = 1; i < _useTraps.length; i++) {
      if ((traps[i]) == 0 &&
        (_useTraps[i] > 0)) {
        require(itemToken.useItem(msg.sender, i, _useTraps[i]));
      }
    }
    require(castleToken.setTraps(_castleid, castleToken.getReward(_castleid), _traps));
    return true;
  }

  function attack(
    uint256 _ninjaid,
    uint256 _castleid,
    bytes _path)
    public
    payable
    whenNotPaused
    returns (bool)
  {
    uint16 reward = castleToken.getReward(_castleid);
    require(msg.value == reward / 2);

    uint32 hp = ninjaToken.getHp(_ninjaid);

    _clearAttackLog(_ninjaid);

    bytes memory steps = new bytes(_path.length);
    uint256 count = 0;
    uint32 damage = 0;
    for (uint256 i = 0; i < _path.length; i++) {
      uint32 trapDamage = _computeDamage(_castleid, _ninjaid, uint8(_path[i]));
      if (trapDamage > 0) {
        steps[count++] = _path[i];
        damage = damage + trapDamage;
        if (hp <= damage) {
          _insertAttackLog(_ninjaid, _castleid, reward, hp, uint8(_path[i]), trapDamage, true);
          address castleOwner = castleToken.ownerOf(_castleid);
          goldToken.transfer(castleOwner, reward / 2);
          castleToken.win(_castleid, _ninjaid, uint256(_path[i]), steps, count);
          ninjaToken.lost(_ninjaid);
          ninjaToken.setPath(_ninjaid, _castleid, _path, steps);
          emit AttackEnd(_ninjaid, _castleid, false);

          return true;
        }
      }
      _insertAttackLog(_ninjaid, _castleid, reward, hp, uint8(_path[i]), trapDamage, false);
    }
    require(goldToken.transfer(ninjaToken.ownerOf(_ninjaid), reward + reward / 2));
    require(castleToken.lost(_castleid, _ninjaid));
    require(ninjaToken.win(_ninjaid));
    ninjaToken.setPath(_ninjaid, _castleid, _path, steps);
    emit AttackEnd(_ninjaid, _castleid, true);
    return true;
  }

  function _computeDamage(uint256 _castleid, uint256 _ninjaid, uint8 _itemid)
    internal
    view
    returns (uint32)
  {
    uint32 trapPower = itemToken.getPower(castleToken.getTrapid(_castleid, uint8(_itemid)));
    if (trapPower <= 0) {
      return 0;
    }
    uint32 trapDamage = trapPower + castleToken.getLevel(_castleid) - 1;
    uint8 dna1 = ninjaToken.getDna1(_ninjaid);
    uint8 dna2 = ninjaToken.getDna2(_ninjaid);
    if (_itemid == 1) {
      if (dna1 == 4) {
        trapDamage *= 2;
      }
      if (dna2 == 4) {
        trapDamage *= 2;
      }
      if (dna1 == 3) {
        trapDamage /= 2;
      }
      if (dna2 == 3) {
        trapDamage /= 2;
      }
    } else if (_itemid == 2) {
      if (dna1 == 5) {
        trapDamage *= 2;
      }
      if (dna2 == 5) {
        trapDamage *= 2;
      }
      if (dna1 == 4) {
        trapDamage /= 2;
      }
      if (dna2 == 4) {
        trapDamage /= 2;
      }
    } else if (_itemid == 3) {
      if (dna1 == 1) {
        trapDamage *= 2;
      }
      if (dna2 == 1) {
        trapDamage *= 2;
      }
      if (dna1 == 5) {
        trapDamage /= 2;
      }
      if (dna2 == 5) {
        trapDamage /= 2;
      }
    } else if (_itemid == 4) {
      if (dna1 == 2) {
        trapDamage *= 2;
      }
      if (dna2 == 2) {
        trapDamage *= 2;
      }
      if (dna1 == 1) {
        trapDamage /= 2;
      }
      if (dna2 == 1) {
        trapDamage /= 2;
      }
    } else if (_itemid == 5) {
      if (dna1 == 3) {
        trapDamage *= 2;
      }
      if (dna2 == 3) {
        trapDamage *= 2;
      }
      if (dna1 == 2) {
        trapDamage /= 2;
      }
      if (dna2 == 2) {
        trapDamage /= 2;
      }
    }
    return trapDamage;
  }

  function _insertAttackLog(
    uint256 _ninjaid,
    uint256 _castleid,
    uint16 _reward,
    uint32 _hp,
    uint8 _path,
    uint32 _trapDamage,
    bool _dead)
    private
  {
    if(numAttackLogs[_ninjaid] == attackLogs[_ninjaid].length) {
      attackLogs[_ninjaid].length += 1;
    }
    AttackLog memory log = AttackLog(_castleid, _reward, _hp, _path, _trapDamage, _dead);
    attackLogs[_ninjaid][numAttackLogs[_ninjaid]++] = log;
  }

  function _clearAttackLog(uint256 _ninjaid)
    private
  {
    numAttackLogs[_ninjaid] = 0;
  }

  function setGoldContract(address _goldTokenAddress)
    public
    onlyOwner
  {
    require(_goldTokenAddress != address(0));

    goldToken = EverGold(_goldTokenAddress);
  }

  function setCastleContract(address _castleTokenAddress)
    public
    onlyOwner
  {
    require(_castleTokenAddress != address(0));

    castleToken = CastleToken(_castleTokenAddress);
  }

  function setNinjaContract(address _ninjaTokenAddress)
    public
    onlyOwner
  {
    require(_ninjaTokenAddress != address(0));

    ninjaToken = NinjaToken(_ninjaTokenAddress);
  }

  function setItemContract(address _itemTokenAddress)
    public
    onlyOwner
  {
    require(_itemTokenAddress != address(0));

    itemToken = ItemToken(_itemTokenAddress);
  }

  function setUserContract(address _userTokenAddress)
    public
    onlyOwner
  {
    require(_userTokenAddress != address(0));

    userToken = UserToken(_userTokenAddress);
  }

  function getLastAttack(uint256 _ninjaid, uint256 _index)
    public
    view
    returns (uint256 castleid, uint16 reward, uint32 hp, uint8 path, uint32 trapDamage, bool dead)
  {
    require(ninjaToken.ownerOf(_ninjaid) == msg.sender);
    AttackLog memory log = attackLogs[_ninjaid][_index];
    return (log.castleid, log.reward, log.hp, log.path, log.trapDamage, log.dead);
  }

  function getLastAttackCount(uint256 _ninjaid)
    public
    view
    returns (uint256)
  {
    require(ninjaToken.ownerOf(_ninjaid) == msg.sender);
    return numAttackLogs[_ninjaid];
  }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"_ninjaid","type":"uint256"},{"name":"_castleid","type":"uint256"},{"name":"_path","type":"bytes"}],"name":"attack","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"grantAccess","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_castleid","type":"uint256"},{"name":"_traps","type":"bytes"},{"name":"_useTraps","type":"uint256[]"}],"name":"addTraps","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_goldTokenAddress","type":"address"}],"name":"setGoldContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_beneficiary","type":"address"}],"name":"buyCastle","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_beneficiary","type":"address"},{"name":"_castleid","type":"uint256"},{"name":"_reward","type":"uint16"},{"name":"_traps","type":"bytes"},{"name":"_useTraps","type":"uint256[]"}],"name":"defence","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"claimOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"registerUser","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"revokeAccess","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ninjaid","type":"uint256"}],"name":"getLastAttackCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_userTokenAddress","type":"address"}],"name":"setUserContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_itemTokenAddress","type":"address"}],"name":"setItemContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_beneficiary","type":"address"}],"name":"buyNinja","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_ninjaid","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"getLastAttack","outputs":[{"name":"castleid","type":"uint256"},{"name":"reward","type":"uint16"},{"name":"hp","type":"uint32"},{"name":"path","type":"uint8"},{"name":"trapDamage","type":"uint32"},{"name":"dead","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_castleTokenAddress","type":"address"}],"name":"setCastleContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokens","type":"address[]"}],"name":"destroy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pendingOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_ninjaTokenAddress","type":"address"}],"name":"setNinjaContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_beneficiary","type":"address"},{"name":"_itemid","type":"uint8"},{"name":"_amount","type":"uint256"}],"name":"buyItem","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_goldTokenAddress","type":"address"},{"name":"_castleTokenAddress","type":"address"},{"name":"_ninjaTokenAddress","type":"address"},{"name":"_userTokenAddress","type":"address"},{"name":"_itemTokenAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"ninjaid","type":"uint256"},{"indexed":false,"name":"castleid","type":"uint256"},{"indexed":false,"name":"hp","type":"uint32"},{"indexed":false,"name":"path","type":"uint8"},{"indexed":false,"name":"trapDamage","type":"uint32"},{"indexed":false,"name":"damage","type":"uint32"}],"name":"Attack","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"ninjaid","type":"uint256"},{"indexed":false,"name":"castleid","type":"uint256"},{"indexed":false,"name":"hp","type":"uint32"}],"name":"AttackStart","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"ninjaid","type":"uint256"},{"indexed":false,"name":"castleid","type":"uint256"},{"indexed":false,"name":"result","type":"bool"}],"name":"AttackEnd","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

608060405260008060146101000a81548160ff0219169083151502179055503480156200002b57600080fd5b5060405160a080620049b18339810180604052810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614151515620000f457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141515156200013157600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156200016e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515620001ab57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515620001e857600080fd5b84600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505061466f80620003426000396000f300608060405260043610610149576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806308151de11461014e5780630ae5e739146101d65780631a918bdd1461021957806333771860146102e75780633735ab751461032a5780633f4ba83a146103785780634319dfd91461038f5780634e71e0c81461047e5780635c975abb14610495578063704f1b94146104c4578063715018a6146105455780638456cb591461055c57806385e68531146105735780638da5cb5b146105b65780639ebafad61461060d578063a1206d4e1461064e578063a712043314610691578063acf1e9fa146106d4578063bd780d0d14610722578063c42890b6146107ba578063c6786e5a146107fd578063e30c397814610863578063ea636aca146108ba578063ec8fe065146108fd578063f2fde38b14610962575b600080fd5b6101bc6004803603810190808035906020019092919080359060200190929190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506109a5565b604051808215151515815260200191505060405180910390f35b3480156101e257600080fd5b50610217600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a3f565b005b34801561022557600080fd5b506102cd60048036038101908080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290505050611af5565b604051808215151515815260200191505060405180910390f35b3480156102f357600080fd5b50610328600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612152565b005b61035e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061222d565b604051808215151515815260200191505060405180910390f35b34801561038457600080fd5b5061038d61244a565b005b610464600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803561ffff169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290505050612508565b604051808215151515815260200191505060405180910390f35b34801561048a57600080fd5b50610493612801565b005b3480156104a157600080fd5b506104aa6129a0565b604051808215151515815260200191505060405180910390f35b3480156104d057600080fd5b5061052b600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506129b3565b604051808215151515815260200191505060405180910390f35b34801561055157600080fd5b5061055a612b69565b005b34801561056857600080fd5b50610571612c6b565b005b34801561057f57600080fd5b506105b4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612d2b565b005b3480156105c257600080fd5b506105cb612de1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561061957600080fd5b5061063860048036038101908080359060200190929190505050612e06565b6040518082815260200191505060405180910390f35b34801561065a57600080fd5b5061068f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f28565b005b34801561069d57600080fd5b506106d2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613003565b005b610708600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506130de565b604051808215151515815260200191505060405180910390f35b34801561072e57600080fd5b5061075760048036038101908080359060200190929190803590602001909291905050506132fb565b604051808781526020018661ffff1661ffff1681526020018563ffffffff1663ffffffff1681526020018460ff1660ff1681526020018363ffffffff1663ffffffff16815260200182151515158152602001965050505050505060405180910390f35b3480156107c657600080fd5b506107fb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613530565b005b34801561080957600080fd5b506108616004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929050505061360b565b005b34801561086f57600080fd5b506108786138b2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156108c657600080fd5b506108fb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506138d8565b005b610948600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803590602001909291905050506139b3565b604051808215151515815260200191505060405180910390f35b34801561096e57600080fd5b506109a3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bfe565b005b6000806000606060008060008060008060149054906101000a900460ff161515156109cf57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c4b774b8c6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015610a6057600080fd5b505af1158015610a74573d6000803e3d6000fd5b505050506040513d6020811015610a8a57600080fd5b8101908080519060200190929190505050975060028861ffff16811515610aad57fe5b0461ffff1634141515610abf57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638458bd708d6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015610b5057600080fd5b505af1158015610b64573d6000803e3d6000fd5b505050506040513d6020811015610b7a57600080fd5b81019080805190602001909291905050509650610b968c613c9d565b89516040519080825280601f01601f191660200182016040528015610bca5781602001602082028038833980820191505090505b5095506000945060009350600092505b89518310156114b257610c698b8d8c86815181101515610bf657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004613cb9565b915060008263ffffffff16111561141a578983815181101515610c8857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000028686806001019750815181101515610ce757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081840193508363ffffffff168763ffffffff1611151561141957610dbc8c8c8a8a8e88815181101515610d4657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004876001614371565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8c6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015610e4d57600080fd5b505af1158015610e61573d6000803e3d6000fd5b505050506040513d6020811015610e7757600080fd5b81019080805190602001909291905050509050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8260028b61ffff16811515610ed957fe5b046040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018261ffff16815260200192505050602060405180830381600087803b158015610f6357600080fd5b505af1158015610f77573d6000803e3d6000fd5b505050506040513d6020811015610f8d57600080fd5b810190808051906020019092919050505050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce8775a48c8e8d87815181101515610fed57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090048a8a6040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018086815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156110e05780820151818401526020810190506110c5565b50505050905090810190601f16801561110d5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561113057600080fd5b505af1158015611144573d6000803e3d6000fd5b505050506040513d602081101561115a57600080fd5b810190808051906020019092919050505050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cbc4eb68d6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1580156111fd57600080fd5b505af1158015611211573d6000803e3d6000fd5b505050506040513d602081101561122757600080fd5b810190808051906020019092919050505050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663896581638d8d8d8a6040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808581526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156112f65780820151818401526020810190506112db565b50505050905090810190601f1680156113235780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561135c578082015181840152602081019050611341565b50505050905090810190601f1680156113895780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b1580156113ac57600080fd5b505af11580156113c0573d6000803e3d6000fd5b505050507fd48638341d777adbc6fcdbeb2a9d73e8a0e177ad1d5e8f6c5285f41d33a061228c8c60006040518084815260200183815260200182151515158152602001935050505060405180910390a160019850611a30565b5b6114a58c8c8a8a8e8881518110151561142f57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004876000614371565b8280600101935050610bda565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8f6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561158157600080fd5b505af1158015611595573d6000803e3d6000fd5b505050506040513d60208110156115ab57600080fd5b810190808051906020019092919050505060028b61ffff168115156115cc57fe5b048b016040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018261ffff16815260200192505050602060405180830381600087803b15801561165857600080fd5b505af115801561166c573d6000803e3d6000fd5b505050506040513d602081101561168257600080fd5b8101908080519060200190929190505050151561169e57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c9dfa7318c8e6040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200182815260200192505050602060405180830381600087803b15801561173757600080fd5b505af115801561174b573d6000803e3d6000fd5b505050506040513d602081101561176157600080fd5b8101908080519060200190929190505050151561177d57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635bc60cfc8d6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561180e57600080fd5b505af1158015611822573d6000803e3d6000fd5b505050506040513d602081101561183857600080fd5b8101908080519060200190929190505050151561185457600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663896581638d8d8d8a6040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808581526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156119115780820151818401526020810190506118f6565b50505050905090810190601f16801561193e5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561197757808201518184015260208101905061195c565b50505050905090810190601f1680156119a45780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b1580156119c757600080fd5b505af11580156119db573d6000803e3d6000fd5b505050507fd48638341d777adbc6fcdbeb2a9d73e8a0e177ad1d5e8f6c5285f41d33a061228c8c60016040518084815260200183815260200182151515158152602001935050505060405180910390a1600198505b50505050505050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a9a57600080fd5b6001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000606060008060149054906101000a900460ff16151515611b1657600080fd5b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c4b774b886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015611ba957600080fd5b505af1158015611bbd573d6000803e3d6000fd5b505050506040513d6020811015611bd357600080fd5b810190808051906020019092919050505061ffff16111515611bf457600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638f50fb06876040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b158015611c8557600080fd5b505af1158015611c99573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015611cc357600080fd5b810190808051640100000000811115611cdb57600080fd5b82810190506020810184811115611cf157600080fd5b8151856001820283011164010000000082111715611d0e57600080fd5b50509291905050509150600190505b8351811015611f265760007f0100000000000000000000000000000000000000000000000000000000000000028282815181101515611d5857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148015611de9575060008482815181101515611ddd57fe5b90602001906020020151115b15611f1957600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663345cad7e33838785815181101515611e3c57fe5b906020019060200201516040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b158015611ed257600080fd5b505af1158015611ee6573d6000803e3d6000fd5b505050506040513d6020811015611efc57600080fd5b81019080805190602001909291905050501515611f1857600080fd5b5b8080600101915050611d1d565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634c207ac887600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c4b774b8a6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015611ff657600080fd5b505af115801561200a573d6000803e3d6000fd5b505050506040513d602081101561202057600080fd5b8101908080519060200190929190505050886040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156120b1578082015181840152602081019050612096565b50505050905090810190601f1680156120de5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156120ff57600080fd5b505af1158015612113573d6000803e3d6000fd5b505050506040513d602081101561212957600080fd5b8101908080519060200190929190505050151561214557600080fd5b6001925050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156121ad57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156121e957600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561226c57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166398d5fdca6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156122f257600080fd5b505af1158015612306573d6000803e3d6000fd5b505050506040513d602081101561231c57600080fd5b81019080805190602001909291905050509050803414151561233d57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a627842846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1580156123fa57600080fd5b505af115801561240e573d6000803e3d6000fd5b505050506040513d602081101561242457600080fd5b8101908080519060200190929190505050151561244057600080fd5b6001915050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156124a557600080fd5b600060149054906101000a900460ff1615156124c057600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600080600060149054906101000a900460ff1615151561252757600080fd5b8461ffff163414151561253957600080fd5b600190505b825181101561269f576000838281518110151561255757fe5b90602001906020020151111561269257600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663345cad7e888386858151811015156125b557fe5b906020019060200201516040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b15801561264b57600080fd5b505af115801561265f573d6000803e3d6000fd5b505050506040513d602081101561267557600080fd5b8101908080519060200190929190505050151561269157600080fd5b5b808060010191505061253e565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634c207ac88787876040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561275f578082015181840152602081019050612744565b50505050905090810190601f16801561278c5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156127ad57600080fd5b505af11580156127c1573d6000803e3d6000fd5b505050506040513d60208110156127d757600080fd5b810190808051906020019092919050505015156127f357600080fd5b600191505095945050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561285d57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600060149054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515156129f057600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0def52133846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612acd578082015181840152602081019050612ab2565b50505050905090810190601f168015612afa5780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b158015612b1a57600080fd5b505af1158015612b2e573d6000803e3d6000fd5b505050506040513d6020811015612b4457600080fd5b81019080805190602001909291905050501515612b6057600080fd5b60019050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612bc457600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612cc657600080fd5b600060149054906101000a900460ff16151515612ce257600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612d8657600080fd5b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015612eb057600080fd5b505af1158015612ec4573d6000803e3d6000fd5b505050506040513d6020811015612eda57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515612f0d57600080fd5b60096000838152602001908152602001600020549050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612f8357600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612fbf57600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561305e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561309a57600080fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561311d57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166398d5fdca6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156131a357600080fd5b505af11580156131b7573d6000803e3d6000fd5b505050506040513d60208110156131cd57600080fd5b8101908080519060200190929190505050905080341415156131ee57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a627842846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1580156132ab57600080fd5b505af11580156132bf573d6000803e3d6000fd5b505050506040513d60208110156132d557600080fd5b810190808051906020019092919050505015156132f157600080fd5b6001915050919050565b60008060008060008061330c614533565b3373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8b6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1580156133b457600080fd5b505af11580156133c8573d6000803e3d6000fd5b505050506040513d60208110156133de57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561341157600080fd5b600860008a81526020019081526020016000208881548110151561343157fe5b906000526020600020906002020160c06040519081016040529081600082015481526020016001820160009054906101000a900461ffff1661ffff1661ffff1681526020016001820160029054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016001820160069054906101000a900460ff1660ff1660ff1681526020016001820160079054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160018201600b9054906101000a900460ff1615151515815250509050806000015181602001518260400151836060015184608001518560a00151965096509650965096509650509295509295509295565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561358b57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156135c757600080fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561366b57600080fd5b600092505b835183101561387857838381518110151561368757fe5b9060200190602002015191508173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561372e57600080fd5b505af1158015613742573d6000803e3d6000fd5b505050506040513d602081101561375857600080fd5b810190808051906020019092919050505090508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561382f57600080fd5b505af1158015613843573d6000803e3d6000fd5b505050506040513d602081101561385957600080fd5b8101908080519060200190929190505050508280600101935050613670565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561393357600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561396f57600080fd5b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515156139f357600080fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e7572230866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260ff168152602001915050602060405180830381600087803b158015613a8757600080fd5b505af1158015613a9b573d6000803e3d6000fd5b505050506040513d6020811015613ab157600080fd5b81019080805190602001909291905050509150838261ffff160290508034141515613adb57600080fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a59ac6dd8787876040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018360ff1681526020018281526020019350505050602060405180830381600087803b158015613bab57600080fd5b505af1158015613bbf573d6000803e3d6000fd5b505050506040513d6020811015613bd557600080fd5b81019080805190602001909291905050501515613bf157600080fd5b6001925050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613c5957600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600960008381526020019081526020016000208190555050565b6000806000806000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663017fe809600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f80eba7c8b8a6040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808381526020018260ff1660ff16815260200192505050602060405180830381600087803b158015613d9e57600080fd5b505af1158015613db2573d6000803e3d6000fd5b505050506040513d6020811015613dc857600080fd5b81019080805190602001909291905050506040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260ff168152602001915050602060405180830381600087803b158015613e2e57600080fd5b505af1158015613e42573d6000803e3d6000fd5b505050506040513d6020811015613e5857600080fd5b810190808051906020019092919050505061ffff16935060008463ffffffff16111515613e885760009450614366565b6001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166386481d408a6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015613f1b57600080fd5b505af1158015613f2f573d6000803e3d6000fd5b505050506040513d6020811015613f4557600080fd5b810190808051906020019092919050505061ffff168501039250600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9b542bd886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015613ff057600080fd5b505af1158015614004573d6000803e3d6000fd5b505050506040513d602081101561401a57600080fd5b81019080805190602001909291905050509150600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b11b40a1886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1580156140be57600080fd5b505af11580156140d2573d6000803e3d6000fd5b505050506040513d60208110156140e857600080fd5b8101908080519060200190929190505050905060018660ff1614156141765760048260ff16141561411a576002830292505b60048160ff16141561412d576002830292505b60038260ff16141561414f5760028363ffffffff1681151561414b57fe5b0492505b60038160ff1614156141715760028363ffffffff1681151561416d57fe5b0492505b614362565b60028660ff1614156141f15760058260ff161415614195576002830292505b60058160ff1614156141a8576002830292505b60048260ff1614156141ca5760028363ffffffff168115156141c657fe5b0492505b60048160ff1614156141ec5760028363ffffffff168115156141e857fe5b0492505b614361565b60038660ff16141561426c5760018260ff161415614210576002830292505b60018160ff161415614223576002830292505b60058260ff1614156142455760028363ffffffff1681151561424157fe5b0492505b60058160ff1614156142675760028363ffffffff1681151561426357fe5b0492505b614360565b60048660ff1614156142e75760028260ff16141561428b576002830292505b60028160ff16141561429e576002830292505b60018260ff1614156142c05760028363ffffffff168115156142bc57fe5b0492505b60018160ff1614156142e25760028363ffffffff168115156142de57fe5b0492505b61435f565b60058660ff16141561435e5760038260ff161415614306576002830292505b60038160ff161415614319576002830292505b60028260ff16141561433b5760028363ffffffff1681151561433757fe5b0492505b60028160ff16141561435d5760028363ffffffff1681151561435957fe5b0492505b5b5b5b5b5b8294505b505050509392505050565b614379614533565b6008600089815260200190815260200160002080549050600960008a81526020019081526020016000205414156143d5576001600860008a8152602001908152602001600020818180549050019150816143d3919061457f565b505b60c0604051908101604052808881526020018761ffff1681526020018663ffffffff1681526020018560ff1681526020018463ffffffff168152602001831515815250905080600860008a8152602001908152602001600020600960008b815260200190815260200160002060008154809291906001019190505581548110151561445c57fe5b90600052602060002090600202016000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff16021790555060408201518160010160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160066101000a81548160ff021916908360ff16021790555060808201518160010160076101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600101600b6101000a81548160ff0219169083151502179055509050505050505050505050565b60c06040519081016040528060008152602001600061ffff168152602001600063ffffffff168152602001600060ff168152602001600063ffffffff1681526020016000151581525090565b8154818355818111156145ac576002028160020283600052602060002091820191016145ab91906145b1565b5b505050565b61464091905b8082111561463c576000808201600090556001820160006101000a81549061ffff02191690556001820160026101000a81549063ffffffff02191690556001820160066101000a81549060ff02191690556001820160076101000a81549063ffffffff021916905560018201600b6101000a81549060ff0219169055506002016145b7565b5090565b905600a165627a7a723058206748c88da20db5ca8e69cf19e896fd6989cb711c5591a57a1f710f617c670bbf00290000000000000000000000005c493a221ae9b49c3e45f2df8a3b34223855c1f4000000000000000000000000dfe6beca1e3cb35f051276d713e420de5de58577000000000000000000000000acf466567114ce47e4615f527d4dc4020a81438c000000000000000000000000f35470b6182cbd9a0f0c01d8f491b18445707c7d0000000000000000000000000a8b758bbc4a5791c5647ca80351e008f1e3bca1

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

0000000000000000000000005c493a221ae9b49c3e45f2df8a3b34223855c1f4000000000000000000000000dfe6beca1e3cb35f051276d713e420de5de58577000000000000000000000000acf466567114ce47e4615f527d4dc4020a81438c000000000000000000000000f35470b6182cbd9a0f0c01d8f491b18445707c7d0000000000000000000000000a8b758bbc4a5791c5647ca80351e008f1e3bca1

-----Decoded View---------------
Arg [0] : _goldTokenAddress (address): 0x5C493A221ae9B49C3E45f2DF8A3B34223855c1F4
Arg [1] : _castleTokenAddress (address): 0xDfe6bECa1E3CB35F051276d713e420dE5DE58577
Arg [2] : _ninjaTokenAddress (address): 0xaCf466567114ce47e4615F527d4DC4020A81438c
Arg [3] : _userTokenAddress (address): 0xF35470B6182cBD9A0f0c01D8f491b18445707c7D
Arg [4] : _itemTokenAddress (address): 0x0a8b758BbC4A5791c5647CA80351E008f1E3Bca1

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000005c493a221ae9b49c3e45f2df8a3b34223855c1f4
Arg [1] : 000000000000000000000000dfe6beca1e3cb35f051276d713e420de5de58577
Arg [2] : 000000000000000000000000acf466567114ce47e4615f527d4dc4020a81438c
Arg [3] : 000000000000000000000000f35470b6182cbd9a0f0c01d8f491b18445707c7d
Arg [4] : 0000000000000000000000000a8b758bbc4a5791c5647ca80351e008f1e3bca1


Swarm Source

bzzr://6748c88da20db5ca8e69cf19e896fd6989cb711c5591a57a1f710f617c670bbf
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.