ETH Price: $3,245.23 (-0.42%)
Gas: 1 Gwei

Contract

0xA13Db2f412cef4b4186ed1D2d12c9eC16BDE82F4
 

Overview

ETH Balance

0.00000000000022185 ETH

Eth Value

Less Than $0.01 (@ $3,245.23/ETH)

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Register User156215242022-09-27 1:50:59670 days ago1664243459IN
0xA13Db2f4...16BDE82F4
0 ETH0.001097419.9096197
Register User94757982020-02-13 16:36:061626 days ago1581611766IN
0xA13Db2f4...16BDE82F4
0 ETH0.000151765
Register User94757972020-02-13 16:36:021626 days ago1581611762IN
0xA13Db2f4...16BDE82F4
0 ETH0.000523155
Register User85570842019-09-15 23:43:291777 days ago1568591009IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496915
Register User78593242019-05-30 6:24:431885 days ago1559197483IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496595
Register User76295112019-04-24 10:08:491921 days ago1556100529IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496275
Register User76232912019-04-23 10:35:241922 days ago1556015724IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496275
Register User75920642019-04-18 13:54:281927 days ago1555595668IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496595
Register User75905762019-04-18 8:04:171927 days ago1555574657IN
0xA13Db2f4...16BDE82F4
0 ETH0.000501075
Register User75893542019-04-18 3:29:561927 days ago1555558196IN
0xA13Db2f4...16BDE82F4
0 ETH0.000497555
Register User72974062019-03-03 15:36:051973 days ago1551627365IN
0xA13Db2f4...16BDE82F4
0 ETH0.000136885
Register User72974042019-03-03 15:35:501973 days ago1551627350IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496275
Register User72313402019-02-17 9:26:381987 days ago1550395598IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496915
Register User72126822019-02-12 22:13:121992 days ago1550009592IN
0xA13Db2f4...16BDE82F4
0 ETH0.000495635
Register User71457542019-01-29 21:23:392006 days ago1548797019IN
0xA13Db2f4...16BDE82F4
0 ETH0.000495955
Register User70569322019-01-13 2:51:592023 days ago1547347919IN
0xA13Db2f4...16BDE82F4
0 ETH0.000495635
Register User70526002019-01-12 8:24:012023 days ago1547281441IN
0xA13Db2f4...16BDE82F4
0 ETH0.000136885
Register User70525992019-01-12 8:23:512023 days ago1547281431IN
0xA13Db2f4...16BDE82F4
0 ETH0.000136245
Register User70525982019-01-12 8:23:412023 days ago1547281421IN
0xA13Db2f4...16BDE82F4
0 ETH0.000136245
Register User70525952019-01-12 8:22:302023 days ago1547281350IN
0xA13Db2f4...16BDE82F4
0 ETH0.000136245
Register User70525942019-01-12 8:22:242023 days ago1547281344IN
0xA13Db2f4...16BDE82F4
0 ETH0.000495635
Register User70201872019-01-06 12:57:062029 days ago1546779426IN
0xA13Db2f4...16BDE82F4
0 ETH0.00013725
Register User70201852019-01-06 12:56:152029 days ago1546779375IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496595
Register User70183432019-01-06 5:02:282029 days ago1546750948IN
0xA13Db2f4...16BDE82F4
0 ETH0.000496275
Register User70180552019-01-06 3:49:302029 days ago1546746570IN
0xA13Db2f4...16BDE82F4
0 ETH0.000298143
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
69024822018-12-17 9:49:022049 days ago1545040142
0xA13Db2f4...16BDE82F4
500 wei
66727852018-11-09 14:11:452087 days ago1541772705
0xA13Db2f4...16BDE82F4
500 wei
66727832018-11-09 14:11:012087 days ago1541772661
0xA13Db2f4...16BDE82F4
0 ETH
66727692018-11-09 14:07:312087 days ago1541772451
0xA13Db2f4...16BDE82F4
0 ETH
66727442018-11-09 13:59:192087 days ago1541771959
0xA13Db2f4...16BDE82F4
300 wei
66727372018-11-09 13:57:432087 days ago1541771863
0xA13Db2f4...16BDE82F4
500 wei
66727252018-11-09 13:55:022087 days ago1541771702
0xA13Db2f4...16BDE82F4
500 wei
66727032018-11-09 13:50:152087 days ago1541771415
0xA13Db2f4...16BDE82F4
0 ETH
66726982018-11-09 13:48:252087 days ago1541771305
0xA13Db2f4...16BDE82F4
0 ETH
66726372018-11-09 13:32:342087 days ago1541770354
0xA13Db2f4...16BDE82F4
500 wei
62456412018-08-31 8:52:122157 days ago1535705532
0xA13Db2f4...16BDE82F4
400 wei
62327162018-08-29 4:27:202159 days ago1535516840
0xA13Db2f4...16BDE82F4
0 ETH
62218272018-08-27 8:21:032161 days ago1535358063
0xA13Db2f4...16BDE82F4
500 wei
62138662018-08-26 0:01:032163 days ago1535241663
0xA13Db2f4...16BDE82F4
0 ETH
62137402018-08-25 23:37:202163 days ago1535240240
0xA13Db2f4...16BDE82F4
300 wei
62137352018-08-25 23:36:212163 days ago1535240181
0xA13Db2f4...16BDE82F4
500 wei
62137102018-08-25 23:31:152163 days ago1535239875
0xA13Db2f4...16BDE82F4
0 ETH
61911512018-08-22 3:44:022166 days ago1534909442
0xA13Db2f4...16BDE82F4
100 wei
61911222018-08-22 3:37:482166 days ago1534909068
0xA13Db2f4...16BDE82F4
0 ETH
61805442018-08-20 9:04:382168 days ago1534755878
0xA13Db2f4...16BDE82F4
0 ETH
61789752018-08-20 2:36:512169 days ago1534732611
0xA13Db2f4...16BDE82F4
50 wei
61787682018-08-20 1:49:462169 days ago1534729786
0xA13Db2f4...16BDE82F4
0 ETH
61786772018-08-20 1:30:102169 days ago1534728610
0xA13Db2f4...16BDE82F4
0 ETH
61717742018-08-18 21:30:312170 days ago1534627831
0xA13Db2f4...16BDE82F4
250 wei
61717632018-08-18 21:27:492170 days ago1534627669
0xA13Db2f4...16BDE82F4
250 wei
View All Internal Transactions
Loading...
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 <remco@2π.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

Deployed Bytecode

0x608060405260043610610149576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806308151de11461014e5780630ae5e739146101d65780631a918bdd1461021957806333771860146102e75780633735ab751461032a5780633f4ba83a146103785780634319dfd91461038f5780634e71e0c81461047e5780635c975abb14610495578063704f1b94146104c4578063715018a6146105455780638456cb591461055c57806385e68531146105735780638da5cb5b146105b65780639ebafad61461060d578063a1206d4e1461064e578063a712043314610691578063acf1e9fa146106d4578063bd780d0d14610722578063c42890b6146107ba578063c6786e5a146107fd578063e30c397814610863578063ea636aca146108ba578063ec8fe065146108fd578063f2fde38b14610962575b600080fd5b6101bc6004803603810190808035906020019092919080359060200190929190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506109a5565b604051808215151515815260200191505060405180910390f35b3480156101e257600080fd5b50610217600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a3f565b005b34801561022557600080fd5b506102cd60048036038101908080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290505050611af5565b604051808215151515815260200191505060405180910390f35b3480156102f357600080fd5b50610328600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612152565b005b61035e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061222d565b604051808215151515815260200191505060405180910390f35b34801561038457600080fd5b5061038d61244a565b005b610464600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803561ffff169060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290505050612508565b604051808215151515815260200191505060405180910390f35b34801561048a57600080fd5b50610493612801565b005b3480156104a157600080fd5b506104aa6129a0565b604051808215151515815260200191505060405180910390f35b3480156104d057600080fd5b5061052b600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506129b3565b604051808215151515815260200191505060405180910390f35b34801561055157600080fd5b5061055a612b69565b005b34801561056857600080fd5b50610571612c6b565b005b34801561057f57600080fd5b506105b4600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612d2b565b005b3480156105c257600080fd5b506105cb612de1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561061957600080fd5b5061063860048036038101908080359060200190929190505050612e06565b6040518082815260200191505060405180910390f35b34801561065a57600080fd5b5061068f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f28565b005b34801561069d57600080fd5b506106d2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613003565b005b610708600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506130de565b604051808215151515815260200191505060405180910390f35b34801561072e57600080fd5b5061075760048036038101908080359060200190929190803590602001909291905050506132fb565b604051808781526020018661ffff1661ffff1681526020018563ffffffff1663ffffffff1681526020018460ff1660ff1681526020018363ffffffff1663ffffffff16815260200182151515158152602001965050505050505060405180910390f35b3480156107c657600080fd5b506107fb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613530565b005b34801561080957600080fd5b506108616004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929050505061360b565b005b34801561086f57600080fd5b506108786138b2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156108c657600080fd5b506108fb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506138d8565b005b610948600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803560ff169060200190929190803590602001909291905050506139b3565b604051808215151515815260200191505060405180910390f35b34801561096e57600080fd5b506109a3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613bfe565b005b6000806000606060008060008060008060149054906101000a900460ff161515156109cf57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c4b774b8c6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015610a6057600080fd5b505af1158015610a74573d6000803e3d6000fd5b505050506040513d6020811015610a8a57600080fd5b8101908080519060200190929190505050975060028861ffff16811515610aad57fe5b0461ffff1634141515610abf57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638458bd708d6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015610b5057600080fd5b505af1158015610b64573d6000803e3d6000fd5b505050506040513d6020811015610b7a57600080fd5b81019080805190602001909291905050509650610b968c613c9d565b89516040519080825280601f01601f191660200182016040528015610bca5781602001602082028038833980820191505090505b5095506000945060009350600092505b89518310156114b257610c698b8d8c86815181101515610bf657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004613cb9565b915060008263ffffffff16111561141a578983815181101515610c8857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000028686806001019750815181101515610ce757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081840193508363ffffffff168763ffffffff1611151561141957610dbc8c8c8a8a8e88815181101515610d4657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004876001614371565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8c6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015610e4d57600080fd5b505af1158015610e61573d6000803e3d6000fd5b505050506040513d6020811015610e7757600080fd5b81019080805190602001909291905050509050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8260028b61ffff16811515610ed957fe5b046040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018261ffff16815260200192505050602060405180830381600087803b158015610f6357600080fd5b505af1158015610f77573d6000803e3d6000fd5b505050506040513d6020811015610f8d57600080fd5b810190808051906020019092919050505050600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ce8775a48c8e8d87815181101515610fed57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090048a8a6040518663ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018086815260200185815260200184815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156110e05780820151818401526020810190506110c5565b50505050905090810190601f16801561110d5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561113057600080fd5b505af1158015611144573d6000803e3d6000fd5b505050506040513d602081101561115a57600080fd5b810190808051906020019092919050505050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637cbc4eb68d6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1580156111fd57600080fd5b505af1158015611211573d6000803e3d6000fd5b505050506040513d602081101561122757600080fd5b810190808051906020019092919050505050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663896581638d8d8d8a6040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808581526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156112f65780820151818401526020810190506112db565b50505050905090810190601f1680156113235780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561135c578082015181840152602081019050611341565b50505050905090810190601f1680156113895780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b1580156113ac57600080fd5b505af11580156113c0573d6000803e3d6000fd5b505050507fd48638341d777adbc6fcdbeb2a9d73e8a0e177ad1d5e8f6c5285f41d33a061228c8c60006040518084815260200183815260200182151515158152602001935050505060405180910390a160019850611a30565b5b6114a58c8c8a8a8e8881518110151561142f57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004876000614371565b8280600101935050610bda565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8f6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561158157600080fd5b505af1158015611595573d6000803e3d6000fd5b505050506040513d60208110156115ab57600080fd5b810190808051906020019092919050505060028b61ffff168115156115cc57fe5b048b016040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018261ffff16815260200192505050602060405180830381600087803b15801561165857600080fd5b505af115801561166c573d6000803e3d6000fd5b505050506040513d602081101561168257600080fd5b8101908080519060200190929190505050151561169e57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663c9dfa7318c8e6040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200182815260200192505050602060405180830381600087803b15801561173757600080fd5b505af115801561174b573d6000803e3d6000fd5b505050506040513d602081101561176157600080fd5b8101908080519060200190929190505050151561177d57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635bc60cfc8d6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561180e57600080fd5b505af1158015611822573d6000803e3d6000fd5b505050506040513d602081101561183857600080fd5b8101908080519060200190929190505050151561185457600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663896581638d8d8d8a6040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808581526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156119115780820151818401526020810190506118f6565b50505050905090810190601f16801561193e5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561197757808201518184015260208101905061195c565b50505050905090810190601f1680156119a45780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b1580156119c757600080fd5b505af11580156119db573d6000803e3d6000fd5b505050507fd48638341d777adbc6fcdbeb2a9d73e8a0e177ad1d5e8f6c5285f41d33a061228c8c60016040518084815260200183815260200182151515158152602001935050505060405180910390a1600198505b50505050505050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a9a57600080fd5b6001600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000606060008060149054906101000a900460ff16151515611b1657600080fd5b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c4b774b886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015611ba957600080fd5b505af1158015611bbd573d6000803e3d6000fd5b505050506040513d6020811015611bd357600080fd5b810190808051906020019092919050505061ffff16111515611bf457600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638f50fb06876040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b158015611c8557600080fd5b505af1158015611c99573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015611cc357600080fd5b810190808051640100000000811115611cdb57600080fd5b82810190506020810184811115611cf157600080fd5b8151856001820283011164010000000082111715611d0e57600080fd5b50509291905050509150600190505b8351811015611f265760007f0100000000000000000000000000000000000000000000000000000000000000028282815181101515611d5857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148015611de9575060008482815181101515611ddd57fe5b90602001906020020151115b15611f1957600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663345cad7e33838785815181101515611e3c57fe5b906020019060200201516040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b158015611ed257600080fd5b505af1158015611ee6573d6000803e3d6000fd5b505050506040513d6020811015611efc57600080fd5b81019080805190602001909291905050501515611f1857600080fd5b5b8080600101915050611d1d565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634c207ac887600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631c4b774b8a6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015611ff657600080fd5b505af115801561200a573d6000803e3d6000fd5b505050506040513d602081101561202057600080fd5b8101908080519060200190929190505050886040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156120b1578082015181840152602081019050612096565b50505050905090810190601f1680156120de5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156120ff57600080fd5b505af1158015612113573d6000803e3d6000fd5b505050506040513d602081101561212957600080fd5b8101908080519060200190929190505050151561214557600080fd5b6001925050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156121ad57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156121e957600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561226c57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166398d5fdca6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156122f257600080fd5b505af1158015612306573d6000803e3d6000fd5b505050506040513d602081101561231c57600080fd5b81019080805190602001909291905050509050803414151561233d57600080fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a627842846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1580156123fa57600080fd5b505af115801561240e573d6000803e3d6000fd5b505050506040513d602081101561242457600080fd5b8101908080519060200190929190505050151561244057600080fd5b6001915050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156124a557600080fd5b600060149054906101000a900460ff1615156124c057600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600080600060149054906101000a900460ff1615151561252757600080fd5b8461ffff163414151561253957600080fd5b600190505b825181101561269f576000838281518110151561255757fe5b90602001906020020151111561269257600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663345cad7e888386858151811015156125b557fe5b906020019060200201516040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018381526020018281526020019350505050602060405180830381600087803b15801561264b57600080fd5b505af115801561265f573d6000803e3d6000fd5b505050506040513d602081101561267557600080fd5b8101908080519060200190929190505050151561269157600080fd5b5b808060010191505061253e565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634c207ac88787876040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561275f578082015181840152602081019050612744565b50505050905090810190601f16801561278c5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156127ad57600080fd5b505af11580156127c1573d6000803e3d6000fd5b505050506040513d60208110156127d757600080fd5b810190808051906020019092919050505015156127f357600080fd5b600191505095945050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561285d57600080fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600060149054906101000a900460ff1681565b60008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515156129f057600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0def52133846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612acd578082015181840152602081019050612ab2565b50505050905090810190601f168015612afa5780820380516001836020036101000a031916815260200191505b509350505050602060405180830381600087803b158015612b1a57600080fd5b505af1158015612b2e573d6000803e3d6000fd5b505050506040513d6020811015612b4457600080fd5b81019080805190602001909291905050501515612b6057600080fd5b60019050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612bc457600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612cc657600080fd5b600060149054906101000a900460ff16151515612ce257600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612d8657600080fd5b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015612eb057600080fd5b505af1158015612ec4573d6000803e3d6000fd5b505050506040513d6020811015612eda57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16141515612f0d57600080fd5b60096000838152602001908152602001600020549050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612f8357600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612fbf57600080fd5b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561305e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561309a57600080fd5b80600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561311d57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166398d5fdca6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156131a357600080fd5b505af11580156131b7573d6000803e3d6000fd5b505050506040513d60208110156131cd57600080fd5b8101908080519060200190929190505050905080341415156131ee57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636a627842846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1580156132ab57600080fd5b505af11580156132bf573d6000803e3d6000fd5b505050506040513d60208110156132d557600080fd5b810190808051906020019092919050505015156132f157600080fd5b6001915050919050565b60008060008060008061330c614533565b3373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8b6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1580156133b457600080fd5b505af11580156133c8573d6000803e3d6000fd5b505050506040513d60208110156133de57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff1614151561341157600080fd5b600860008a81526020019081526020016000208881548110151561343157fe5b906000526020600020906002020160c06040519081016040529081600082015481526020016001820160009054906101000a900461ffff1661ffff1661ffff1681526020016001820160029054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016001820160069054906101000a900460ff1660ff1660ff1681526020016001820160079054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160018201600b9054906101000a900460ff1615151515815250509050806000015181602001518260400151836060015184608001518560a00151965096509650965096509650509295509295509295565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561358b57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156135c757600080fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561366b57600080fd5b600092505b835183101561387857838381518110151561368757fe5b9060200190602002015191508173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561372e57600080fd5b505af1158015613742573d6000803e3d6000fd5b505050506040513d602081101561375857600080fd5b810190808051906020019092919050505090508173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561382f57600080fd5b505af1158015613843573d6000803e3d6000fd5b505050506040513d602081101561385957600080fd5b8101908080519060200190929190505050508280600101935050613670565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561393357600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561396f57600080fd5b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060008073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515156139f357600080fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e7572230866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260ff168152602001915050602060405180830381600087803b158015613a8757600080fd5b505af1158015613a9b573d6000803e3d6000fd5b505050506040513d6020811015613ab157600080fd5b81019080805190602001909291905050509150838261ffff160290508034141515613adb57600080fd5b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a59ac6dd8787876040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018360ff1681526020018281526020019350505050602060405180830381600087803b158015613bab57600080fd5b505af1158015613bbf573d6000803e3d6000fd5b505050506040513d6020811015613bd557600080fd5b81019080805190602001909291905050501515613bf157600080fd5b6001925050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515613c5957600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600960008381526020019081526020016000208190555050565b6000806000806000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663017fe809600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f80eba7c8b8a6040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808381526020018260ff1660ff16815260200192505050602060405180830381600087803b158015613d9e57600080fd5b505af1158015613db2573d6000803e3d6000fd5b505050506040513d6020811015613dc857600080fd5b81019080805190602001909291905050506040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808260ff168152602001915050602060405180830381600087803b158015613e2e57600080fd5b505af1158015613e42573d6000803e3d6000fd5b505050506040513d6020811015613e5857600080fd5b810190808051906020019092919050505061ffff16935060008463ffffffff16111515613e885760009450614366565b6001600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166386481d408a6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015613f1b57600080fd5b505af1158015613f2f573d6000803e3d6000fd5b505050506040513d6020811015613f4557600080fd5b810190808051906020019092919050505061ffff168501039250600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9b542bd886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015613ff057600080fd5b505af1158015614004573d6000803e3d6000fd5b505050506040513d602081101561401a57600080fd5b81019080805190602001909291905050509150600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b11b40a1886040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1580156140be57600080fd5b505af11580156140d2573d6000803e3d6000fd5b505050506040513d60208110156140e857600080fd5b8101908080519060200190929190505050905060018660ff1614156141765760048260ff16141561411a576002830292505b60048160ff16141561412d576002830292505b60038260ff16141561414f5760028363ffffffff1681151561414b57fe5b0492505b60038160ff1614156141715760028363ffffffff1681151561416d57fe5b0492505b614362565b60028660ff1614156141f15760058260ff161415614195576002830292505b60058160ff1614156141a8576002830292505b60048260ff1614156141ca5760028363ffffffff168115156141c657fe5b0492505b60048160ff1614156141ec5760028363ffffffff168115156141e857fe5b0492505b614361565b60038660ff16141561426c5760018260ff161415614210576002830292505b60018160ff161415614223576002830292505b60058260ff1614156142455760028363ffffffff1681151561424157fe5b0492505b60058160ff1614156142675760028363ffffffff1681151561426357fe5b0492505b614360565b60048660ff1614156142e75760028260ff16141561428b576002830292505b60028160ff16141561429e576002830292505b60018260ff1614156142c05760028363ffffffff168115156142bc57fe5b0492505b60018160ff1614156142e25760028363ffffffff168115156142de57fe5b0492505b61435f565b60058660ff16141561435e5760038260ff161415614306576002830292505b60038160ff161415614319576002830292505b60028260ff16141561433b5760028363ffffffff1681151561433757fe5b0492505b60028160ff16141561435d5760028363ffffffff1681151561435957fe5b0492505b5b5b5b5b5b8294505b505050509392505050565b614379614533565b6008600089815260200190815260200160002080549050600960008a81526020019081526020016000205414156143d5576001600860008a8152602001908152602001600020818180549050019150816143d3919061457f565b505b60c0604051908101604052808881526020018761ffff1681526020018663ffffffff1681526020018560ff1681526020018463ffffffff168152602001831515815250905080600860008a8152602001908152602001600020600960008b815260200190815260200160002060008154809291906001019190505581548110151561445c57fe5b90600052602060002090600202016000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff16021790555060408201518160010160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160066101000a81548160ff021916908360ff16021790555060808201518160010160076101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600101600b6101000a81548160ff0219169083151502179055509050505050505050505050565b60c06040519081016040528060008152602001600061ffff168152602001600063ffffffff168152602001600060ff168152602001600063ffffffff1681526020016000151581525090565b8154818355818111156145ac576002028160020283600052602060002091820191016145ab91906145b1565b5b505050565b61464091905b8082111561463c576000808201600090556001820160006101000a81549061ffff02191690556001820160026101000a81549063ffffffff02191690556001820160066101000a81549060ff02191690556001820160076101000a81549063ffffffff021916905560018201600b6101000a81549060ff0219169055506002016145b7565b5090565b905600a165627a7a723058206748c88da20db5ca8e69cf19e896fd6989cb711c5591a57a1f710f617c670bbf0029

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
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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.