Sponsored:   Color Platform: Decentralized App Store - Special Airdrop For Everyone (~17 Sep), Register NOW!
Contract Overview
Balance: 0 Ether
Ether Value: $0
Transactions: 975 txns
Token Tracker: CryptoRome-Land-NFT (CRLAND)
 Latest 25 txns From a total of 975 Transactions
(+1 PendingTxn)

TxHash Age From To Value [TxFee]
0xc84daf778d4ffec1098f639553911c7dbc238d2387f6f12bc4e57de1a0d47409(pending)0xd95c9809b6e7f404488d52c8d82e6d095b37a190  IN  0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether(Pending)
0xfefc0f6c3db97299a5f1179c8599b83e85a89814cd42ad405dfe4d177554597a5 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x8363d595d5daca72073ac3f213d157fb993b8f063bf0eb49cd128fb7feb2081c8 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xab51e6fa2f141ca4eb69fe198c1280e5f792d05e8507747d5b4ab20fd94d50fe8 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xfbb7025a36c1eda9152060e567314bde0da8f5579cc9d03c711c9e1541ec221d9 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x79a40d10d8ab69627faaa03d8247c1ee13331a0a0657cd4a4ea58a07578f3dea9 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x95eaff1136ec6ee468da2e3eede14983825cd9cb8c155f82b1a901d3a708ef2011 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xf48b61f68c1284fc11a7789a3f910952816dda749be830888db4712ae233646a11 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xf79a40f9e7baa55498c47b65930e1babda31f55213ac288f0c4420fc2dfb329611 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x465384a13381d33a436d64d2e2fbc5f124f45616af92032e8eb6ae5504f7b8eb12 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x74e64467221742caf8a41ed1cab7babec8b80cd08a772c3a9430069ce299e5ad14 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x63c77d2c6da83eb1e9424cc89405c1c8947584fe8ce775aa3a81443fab15f32015 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x869d38f44e1ac068f5e934ce5ee50c3282fa2b6225087499a7c19a815a500c6e15 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x4db4ba4b651d09f4ebc06e964ec8e6a6d9ea4e321d819a7c1a032f9595f8f65c21 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.0004146415
0x18067e6aa9d55b6cb43634ab2decf8f9eca4797c8d08cab4ca3b62f4edb4ff4623 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.0004146415
0xa0eca5f9986ec413e8b628dd07d3068c3039d451ab475ce9a2dc543a6896d21723 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.0004146415
0xdd10461f78ae47aa4bb7818c9baa48194e98f2439dfbe8ef804a7010e0410fb124 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000400972
0x8f987727bbfe43e8d990ad613f69c53e76584c0ebced856f3ec83f098d7a666524 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000400972
0x8ef6a386856c14a48d2ccf8864c81e1e34145ed65387b02cfad87deb922b9b4753 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x1d14fc82e8005f83cea5be58b4042b9477180c08e517821f4d1c45497c7695e153 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xeb4b7daa077ff78b61ab240b637026d3db09b0b69d0dcd33db8eb21f6d1241d453 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x07d01cbb5709a1ec4f20a56b5c6dca094ee38e64dfd47c43c3603b68738e8d2754 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0x242fe564dc13bb1aba8cfa5b4f3427a73717951ceca1560ca33ecec22c14e40754 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xf089339f934454d4b644142b16bfc705209fe60960cdd2dc592e5ee3c022c89255 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xbed5c564f53ea677349b200d1c6e136b9a7a655955f6848dbd26122a99c5c4dc56 mins ago0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.0003718104
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 25 Internal Txns, Click Here To View More View All
ParentTxHash Block Age From To Value
0xada69037b77fb17c257d7a4e23945071fd553e388f661cd1f2607debb6834a73637318519 hrs 47 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.06790000000000001 Ether
0xada69037b77fb17c257d7a4e23945071fd553e388f661cd1f2607debb6834a73637318519 hrs 47 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0021 Ether
0x3507fa7608c7f216075102965628599c82c0a1b3c6dc50d064fcf95ee2492d02637310320 hrs 7 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.08245 Ether
0x3507fa7608c7f216075102965628599c82c0a1b3c6dc50d064fcf95ee2492d02637310320 hrs 7 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00255 Ether
0xe4872c2a7251435826ac083590f505923a668aadc6e815b9d11bd5e941ea7295637226323 hrs 29 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.6596 Ether
0xe4872c2a7251435826ac083590f505923a668aadc6e815b9d11bd5e941ea7295637226323 hrs 29 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0204 Ether
0x41ae10913c99e40ebd086f0812b911b92cce363c946af44b114bfc321df63f9e637224723 hrs 33 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.6499 Ether
0x41ae10913c99e40ebd086f0812b911b92cce363c946af44b114bfc321df63f9e637224723 hrs 33 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0201 Ether
0x14cda4869b3ffd52c87baf5abf463c16dbae153f6685a7b11639dd09caef382363682581 day 15 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.06790000000000001 Ether
0x14cda4869b3ffd52c87baf5abf463c16dbae153f6685a7b11639dd09caef382363682581 day 15 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0021 Ether
0x164ffbb8e7f4330abe4a1a9579449ca506ffbcae187ea9621e56217ecc0c26c763640702 days 8 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.7566 Ether
0x164ffbb8e7f4330abe4a1a9579449ca506ffbcae187ea9621e56217ecc0c26c763640702 days 8 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0234 Ether
0x121fd569ca656ce4f95cf681abc41e6dd44fd773596d353db9bbd35a9bb12cf563640582 days 8 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x2643796cb6b4e715140f09c352ea26afff1a7d930.291 Ether
0x121fd569ca656ce4f95cf681abc41e6dd44fd773596d353db9bbd35a9bb12cf563640582 days 8 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.009 Ether
0x0fdf268ddeb29bde362a79fe71e3803858ee9f496341807928d9321e1bb438a063640582 days 8 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x504af27f1cef15772370b7c04b5d9d593ee729f50.582 Ether
0x0fdf268ddeb29bde362a79fe71e3803858ee9f496341807928d9321e1bb438a063640582 days 8 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.018 Ether
0x3efcbca4d8e86609d7b6eaa7db735c084ce0313207292f8ade194d45f7611af163620212 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.0873 Ether
0x3efcbca4d8e86609d7b6eaa7db735c084ce0313207292f8ade194d45f7611af163620212 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0027 Ether
0x9895b119579b1f87c20ca171b567ed64f55c547f862928e5ae872f7dc2f40d6f63620192 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.0776 Ether
0x9895b119579b1f87c20ca171b567ed64f55c547f862928e5ae872f7dc2f40d6f63620192 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0024 Ether
0x617c16ba6a8d6f309d4149afa7946f1a183b8e2a8d5ed83944728908e30c9b3163315187 days 17 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x3632b138a3351270ba5801d1b2e2f79d212d45920.08536 Ether
0x617c16ba6a8d6f309d4149afa7946f1a183b8e2a8d5ed83944728908e30c9b3163315187 days 17 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00264 Ether
0xf8325b959bf794e50a54d7f756a219cfb49f1958ee64dfa97b00845abcba846363313347 days 17 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xa78efc3a01cb8f2f47137b97f9546b46275f54a60.0776 Ether
0xf8325b959bf794e50a54d7f756a219cfb49f1958ee64dfa97b00845abcba846363313347 days 17 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0024 Ether
0xcfaf08bea517b3c1a449bb97d31194fceab25edafa944b4a4ffd9a8feb9c734b63284508 days 5 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x2b99dee3ea70e1dff7f7d98022efca48872e88a21.455 Ether
[ Download CSV Export  ] 
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) SolidityCompiler Bugs.

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



  Contract Source Code   Find Similiar Contracts

pragma solidity ^0.4.24;

/**
 * @summary: CryptoRome Land ERC-998 Bottom-Up Composable NFT Contract (and additional helper contracts)
 * @author: GigLabs, LLC
 */

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

  /**
  * @dev Multiplies two numbers, reverts on overflow.
  */
  function mul(uint256 _a, uint256 _b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring '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;
    }

    uint256 c = _a * _b;
    require(c / _a == _b);

    return c;
  }

  /**
  * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
    require(_b > 0); // Solidity only automatically asserts 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 c;
  }

  /**
  * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
    require(_b <= _a);
    uint256 c = _a - _b;

    return c;
  }

  /**
  * @dev Adds two numbers, reverts on overflow.
  */
  function add(uint256 _a, uint256 _b) internal pure returns (uint256) {
    uint256 c = _a + _b;
    require(c >= _a);

    return c;
  }

  /**
  * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
  * reverts when dividing by zero.
  */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}


/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 *  Note: the ERC-165 identifier for this interface is 0x80ac58cd.
 */
interface ERC721 /* is ERC165 */ {
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
    event Approval(address indexed _tokenOwner, address indexed _approved, uint256 indexed _tokenId);
    event ApprovalForAll(address indexed _tokenOwner, address indexed _operator, bool _approved);

    function balanceOf(address _tokenOwner) external view returns (uint256 _balance);
    function ownerOf(uint256 _tokenId) external view returns (address _tokenOwner);
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) external;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external;
    function transferFrom(address _from, address _to, uint256 _tokenId) external;
    function approve(address _to, uint256 _tokenId) external;
    function setApprovalForAll(address _operator, bool _approved) external;
    function getApproved(uint256 _tokenId) external view returns (address _operator);
    function isApprovedForAll(address _tokenOwner, address _operator) external view returns (bool);
}
 
 
/**
 * @notice Query if a contract implements an interface
 * @dev Interface identification is specified in ERC-165. This function
 * uses less than 30,000 gas.
 */
interface ERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

interface ERC721TokenReceiver {
    /** 
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a `transfer`. This function MAY throw to revert and reject the
     * transfer. Return of other than the magic value MUST result in the
     * transaction being reverted.
     * Note: the contract address is always the message sender.
     * @param _operator The address which called `safeTransferFrom` function
     * @param _from The address which previously owned the token
     * @param _tokenId The NFT identifier which is being transferred
     * @param _data Additional data with no specified format
     * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     * unless throwing
     */
    function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);
}

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 * Note: the ERC-165 identifier for this interface is 0x5b5e139f.
 */
interface ERC721Metadata /* is ERC721 */ {
    function name() external view returns (string _name);
    function symbol() external view returns (string _symbol);
    function tokenURI(uint256 _tokenId) external view returns (string);
}

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 * Note: the ERC-165 identifier for this interface is 0x780e9d63.
 */
interface ERC721Enumerable /* is ERC721 */ {
    function totalSupply() external view returns (uint256);
    function tokenByIndex(uint256 _index) external view returns (uint256);
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
}

/**
 * @title ERC998ERC721 Bottom-Up Composable Non-Fungible Token
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-998.md
 * Note: the ERC-165 identifier for this interface is 0xa1b23002
 */
interface ERC998ERC721BottomUp {
    event TransferToParent(address indexed _toContract, uint256 indexed _toTokenId, uint256 _tokenId);
    event TransferFromParent(address indexed _fromContract, uint256 indexed _fromTokenId, uint256 _tokenId);


    function rootOwnerOf(uint256 _tokenId) public view returns (bytes32 rootOwner);

    /**
    * The tokenOwnerOf function gets the owner of the _tokenId which can be a user address or another ERC721 token.
    * The tokenOwner address return value can be either a user address or an ERC721 contract address.
    * If the tokenOwner address is a user address then parentTokenId will be 0 and should not be used or considered.
    * If tokenOwner address is a user address then isParent is false, otherwise isChild is true, which means that
    * tokenOwner is an ERC721 contract address and _tokenId is a child of tokenOwner and parentTokenId.
    */
    function tokenOwnerOf(uint256 _tokenId) external view returns (bytes32 tokenOwner, uint256 parentTokenId, bool isParent);

    // Transfers _tokenId as a child to _toContract and _toTokenId
    function transferToParent(address _from, address _toContract, uint256 _toTokenId, uint256 _tokenId, bytes _data) public;
    // Transfers _tokenId from a parent ERC721 token to a user address.
    function transferFromParent(address _fromContract, uint256 _fromTokenId, address _to, uint256 _tokenId, bytes _data) public;
    // Transfers _tokenId from a parent ERC721 token to a parent ERC721 token.
    function transferAsChild(address _fromContract, uint256 _fromTokenId, address _toContract, uint256 _toTokenId, uint256 _tokenId, bytes _data) external;

}

/**
 * @title ERC998ERC721 Bottom-Up Composable, optional enumerable extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-998.md
 * Note: The ERC-165 identifier for this interface is 0x8318b539
 */
interface ERC998ERC721BottomUpEnumerable {
    function totalChildTokens(address _parentContract, uint256 _parentTokenId) external view returns (uint256);
    function childTokenByIndex(address _parentContract, uint256 _parentTokenId, uint256 _index) external view returns (uint256);
}

contract ERC998ERC721BottomUpToken is ERC721, ERC721Metadata, ERC721Enumerable, ERC165, ERC998ERC721BottomUp, ERC998ERC721BottomUpEnumerable {
    using SafeMath for uint256;

    struct TokenOwner {
        address tokenOwner;
        uint256 parentTokenId;
    }

    // return this.rootOwnerOf.selector ^ this.rootOwnerOfChild.selector ^
    //   this.tokenOwnerOf.selector ^ this.ownerOfChild.selector;
    bytes32 constant ERC998_MAGIC_VALUE = 0xcd740db5;

    // total number of tokens
    uint256 internal tokenCount;

    // tokenId => token owner
    mapping(uint256 => TokenOwner) internal tokenIdToTokenOwner;

    // 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;

    // root token owner address => (tokenId => approved address)
    mapping(address => mapping(uint256 => address)) internal rootOwnerAndTokenIdToApprovedAddress;

    // parent address => (parent tokenId => array of child tokenIds)
    mapping(address => mapping(uint256 => uint256[])) internal parentToChildTokenIds;

    // tokenId => position in childTokens array
    mapping(uint256 => uint256) internal tokenIdToChildTokenIdsIndex;

    // token owner => (operator address => bool)
    mapping(address => mapping(address => bool)) internal tokenOwnerToOperators;

    // Token name
    string internal name_;

    // Token symbol
    string internal symbol_;

    // Token URI
    string internal tokenURIBase;

    mapping(bytes4 => bool) internal supportedInterfaces;

    //from zepellin ERC721Receiver.sol
    //old version
    bytes4 constant ERC721_RECEIVED = 0x150b7a02;

    function isContract(address _addr) internal view returns (bool) {
        uint256 size;
        assembly {size := extcodesize(_addr)}
        return size > 0;
    }

    constructor () public {
        //ERC165
        supportedInterfaces[0x01ffc9a7] = true;
        //ERC721
        supportedInterfaces[0x80ac58cd] = true;
        //ERC721Metadata
        supportedInterfaces[0x5b5e139f] = true;
        //ERC721Enumerable
        supportedInterfaces[0x780e9d63] = true;
        //ERC998ERC721BottomUp
        supportedInterfaces[0xa1b23002] = true;
        //ERC998ERC721BottomUpEnumerable
        supportedInterfaces[0x8318b539] = true;
    }

    /////////////////////////////////////////////////////////////////////////////
    //
    // ERC165Impl
    //
    /////////////////////////////////////////////////////////////////////////////
    function supportsInterface(bytes4 _interfaceID) external view returns (bool) {
        return supportedInterfaces[_interfaceID];
    }

    /////////////////////////////////////////////////////////////////////////////
    //
    // ERC721 implementation & ERC998 Authentication
    //
    /////////////////////////////////////////////////////////////////////////////
    function balanceOf(address _tokenOwner) public view returns (uint256) {
        require(_tokenOwner != address(0));
        return ownedTokens[_tokenOwner].length;
    }

    // returns the immediate owner of the token
    function ownerOf(uint256 _tokenId) public view returns (address) {
        address tokenOwner = tokenIdToTokenOwner[_tokenId].tokenOwner;
        require(tokenOwner != address(0));
        return tokenOwner;
    }

    function transferFrom(address _from, address _to, uint256 _tokenId) external {
        require(_to != address(this));
        _transferFromOwnerCheck(_from, _to, _tokenId);
        _transferFrom(_from, _to, _tokenId);
    }

    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external {
        _transferFromOwnerCheck(_from, _to, _tokenId);
        _transferFrom(_from, _to, _tokenId);
        require(_checkAndCallSafeTransfer(_from, _to, _tokenId, ""));

    }

    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) external {
        _transferFromOwnerCheck(_from, _to, _tokenId);
        _transferFrom(_from, _to, _tokenId);
        require(_checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
    }

    function _checkAndCallSafeTransfer(address _from, address _to, uint256 _tokenId, bytes _data) internal view returns (bool) {
        if (!isContract(_to)) {
            return true;
        }
        bytes4 retval = ERC721TokenReceiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data);
        return (retval == ERC721_RECEIVED);
    }

    function _transferFromOwnerCheck(address _from, address _to, uint256 _tokenId) internal {
        require(_from != address(0));
        require(_to != address(0));
        require(tokenIdToTokenOwner[_tokenId].tokenOwner == _from);
        require(tokenIdToTokenOwner[_tokenId].parentTokenId == 0);

        // check child approved
        address approvedAddress = rootOwnerAndTokenIdToApprovedAddress[_from][_tokenId];
        if(msg.sender != _from) {
            bytes32 tokenOwner;
            bool callSuccess;
            // 0xeadb80b8 == ownerOfChild(address,uint256)
            bytes memory calldata = abi.encodeWithSelector(0xed81cdda, address(this), _tokenId);
            assembly {
                callSuccess := staticcall(gas, _from, add(calldata, 0x20), mload(calldata), calldata, 0x20)
                if callSuccess {
                    tokenOwner := mload(calldata)
                }
            }
            if(callSuccess == true) {
                require(tokenOwner >> 224 != ERC998_MAGIC_VALUE);
            }
            require(tokenOwnerToOperators[_from][msg.sender] || approvedAddress == msg.sender);
        }

        // clear approval
        if (approvedAddress != address(0)) {
            delete rootOwnerAndTokenIdToApprovedAddress[_from][_tokenId];
            emit Approval(_from, address(0), _tokenId);
        }
    }

    function _transferFrom(address _from, address _to, uint256 _tokenId) internal {
        // first remove the token from the owner list of owned tokens
        uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
        uint256 lastTokenId = ownedTokens[_from][lastTokenIndex];
        if (lastTokenId != _tokenId) {
            // replace the _tokenId in the list of ownedTokens with the
            // last token id in the list. Make sure ownedTokensIndex gets updated
            // with the new position of the last token id as well.
            uint256 tokenIndex = ownedTokensIndex[_tokenId];
            ownedTokens[_from][tokenIndex] = lastTokenId;
            ownedTokensIndex[lastTokenId] = tokenIndex;
        }

        // resize ownedTokens array (automatically deletes the last array entry)
        ownedTokens[_from].length--;

        // transfer token
        tokenIdToTokenOwner[_tokenId].tokenOwner = _to;
        
        // add token to the new owner's list of owned tokens
        ownedTokensIndex[_tokenId] = ownedTokens[_to].length;
        ownedTokens[_to].push(_tokenId);

        emit Transfer(_from, _to, _tokenId);
    }

    function approve(address _approved, uint256 _tokenId) external {
        address tokenOwner = tokenIdToTokenOwner[_tokenId].tokenOwner;
        require(tokenOwner != address(0));
        address rootOwner = address(rootOwnerOf(_tokenId));
        require(rootOwner == msg.sender || tokenOwnerToOperators[rootOwner][msg.sender]);

        rootOwnerAndTokenIdToApprovedAddress[rootOwner][_tokenId] = _approved;
        emit Approval(rootOwner, _approved, _tokenId);
    }

    function getApproved(uint256 _tokenId) public view returns (address)  {
        address rootOwner = address(rootOwnerOf(_tokenId));
        return rootOwnerAndTokenIdToApprovedAddress[rootOwner][_tokenId];
    }

    function setApprovalForAll(address _operator, bool _approved) external {
        require(_operator != address(0));
        tokenOwnerToOperators[msg.sender][_operator] = _approved;
        emit ApprovalForAll(msg.sender, _operator, _approved);
    }

    function isApprovedForAll(address _owner, address _operator) external view returns (bool)  {
        require(_owner != address(0));
        require(_operator != address(0));
        return tokenOwnerToOperators[_owner][_operator];
    }

    function _tokenOwnerOf(uint256 _tokenId) internal view returns (address tokenOwner, uint256 parentTokenId, bool isParent) {
        tokenOwner = tokenIdToTokenOwner[_tokenId].tokenOwner;
        require(tokenOwner != address(0));
        parentTokenId = tokenIdToTokenOwner[_tokenId].parentTokenId;
        if (parentTokenId > 0) {
            isParent = true;
            parentTokenId--;
        }
        else {
            isParent = false;
        }
        return (tokenOwner, parentTokenId, isParent);
    }

    
    function tokenOwnerOf(uint256 _tokenId) external view returns (bytes32 tokenOwner, uint256 parentTokenId, bool isParent) {
        address tokenOwnerAddress = tokenIdToTokenOwner[_tokenId].tokenOwner;
        require(tokenOwnerAddress != address(0));
        parentTokenId = tokenIdToTokenOwner[_tokenId].parentTokenId;
        if (parentTokenId > 0) {
            isParent = true;
            parentTokenId--;
        }
        else {
            isParent = false;
        }
        return (ERC998_MAGIC_VALUE << 224 | bytes32(tokenOwnerAddress), parentTokenId, isParent);
    }

    // Use Cases handled:
    // Case 1: Token owner is this contract and no parent tokenId.
    // Case 2: Token owner is this contract and token
    // Case 3: Token owner is top-down composable
    // Case 4: Token owner is an unknown contract
    // Case 5: Token owner is a user
    // Case 6: Token owner is a bottom-up composable
    // Case 7: Token owner is ERC721 token owned by top-down token
    // Case 8: Token owner is ERC721 token owned by unknown contract
    // Case 9: Token owner is ERC721 token owned by user
    function rootOwnerOf(uint256 _tokenId) public view returns (bytes32 rootOwner) {
        address rootOwnerAddress = tokenIdToTokenOwner[_tokenId].tokenOwner;
        require(rootOwnerAddress != address(0));
        uint256 parentTokenId = tokenIdToTokenOwner[_tokenId].parentTokenId;
        bool isParent = parentTokenId > 0;
        if (isParent) {
            parentTokenId--;
        }

        if((rootOwnerAddress == address(this))) {
            do {
                if(isParent == false) {
                    // Case 1: Token owner is this contract and no token.
                    // This case should not happen.
                    return ERC998_MAGIC_VALUE << 224 | bytes32(rootOwnerAddress);
                }
                else {
                    // Case 2: Token owner is this contract and token
                    (rootOwnerAddress, parentTokenId, isParent) = _tokenOwnerOf(parentTokenId);
                }
            } while(rootOwnerAddress == address(this));
            _tokenId = parentTokenId;
        }

        bytes memory calldata;
        bool callSuccess;

        if (isParent == false) {

            // success if this token is owned by a top-down token
            // 0xed81cdda == rootOwnerOfChild(address, uint256)
            calldata = abi.encodeWithSelector(0xed81cdda, address(this), _tokenId);
            assembly {
                callSuccess := staticcall(gas, rootOwnerAddress, add(calldata, 0x20), mload(calldata), calldata, 0x20)
                if callSuccess {
                    rootOwner := mload(calldata)
                }
            }
            if(callSuccess == true && rootOwner >> 224 == ERC998_MAGIC_VALUE) {
                // Case 3: Token owner is top-down composable
                return rootOwner;
            }
            else {
                // Case 4: Token owner is an unknown contract
                // Or
                // Case 5: Token owner is a user
                return ERC998_MAGIC_VALUE << 224 | bytes32(rootOwnerAddress);
            }
        }
        else {

            // 0x43a61a8e == rootOwnerOf(uint256)
            calldata = abi.encodeWithSelector(0x43a61a8e, parentTokenId);
            assembly {
                callSuccess := staticcall(gas, rootOwnerAddress, add(calldata, 0x20), mload(calldata), calldata, 0x20)
                if callSuccess {
                    rootOwner := mload(calldata)
                }
            }
            if (callSuccess == true && rootOwner >> 224 == ERC998_MAGIC_VALUE) {
                // Case 6: Token owner is a bottom-up composable
                // Or
                // Case 2: Token owner is top-down composable
                return rootOwner;
            }
            else {
                // token owner is ERC721
                address childContract = rootOwnerAddress;
                //0x6352211e == "ownerOf(uint256)"
                calldata = abi.encodeWithSelector(0x6352211e, parentTokenId);
                assembly {
                    callSuccess := staticcall(gas, rootOwnerAddress, add(calldata, 0x20), mload(calldata), calldata, 0x20)
                    if callSuccess {
                        rootOwnerAddress := mload(calldata)
                    }
                }
                require(callSuccess);

                // 0xed81cdda == rootOwnerOfChild(address,uint256)
                calldata = abi.encodeWithSelector(0xed81cdda, childContract, parentTokenId);
                assembly {
                    callSuccess := staticcall(gas, rootOwnerAddress, add(calldata, 0x20), mload(calldata), calldata, 0x20)
                    if callSuccess {
                        rootOwner := mload(calldata)
                    }
                }
                if(callSuccess == true && rootOwner >> 224 == ERC998_MAGIC_VALUE) {
                    // Case 7: Token owner is ERC721 token owned by top-down token
                    return rootOwner;
                }
                else {
                    // Case 8: Token owner is ERC721 token owned by unknown contract
                    // Or
                    // Case 9: Token owner is ERC721 token owned by user
                    return ERC998_MAGIC_VALUE << 224 | bytes32(rootOwnerAddress);
                }
            }
        }
    }

    // List of all Land Tokens assigned to an address.
    function tokensOfOwner(address _owner) external view returns(uint256[] ownerTokens) {
        return ownedTokens[_owner];
    }

    /////////////////////////////////////////////////////////////////////////////
    //
    // ERC721MetadataImpl
    //
    /////////////////////////////////////////////////////////////////////////////

    function tokenURI(uint256 _tokenId) external view returns (string) {
        require (exists(_tokenId));
        return _appendUintToString(tokenURIBase, _tokenId);
    }

    function name() external view returns (string) {
        return name_;
    }

    function symbol() external view returns (string) {
        return symbol_;
    }

    function _appendUintToString(string inStr, uint v) private pure returns (string str) {
        uint maxlength = 100;
        bytes memory reversed = new bytes(maxlength);
        uint i = 0;
        while (v != 0) {
            uint remainder = v % 10;
            v = v / 10;
            reversed[i++] = byte(48 + remainder);
        }
        bytes memory inStrb = bytes(inStr);
        bytes memory s = new bytes(inStrb.length + i);
        uint j;
        for (j = 0; j < inStrb.length; j++) {
            s[j] = inStrb[j];
        }
        for (j = 0; j < i; j++) {
            s[j + inStrb.length] = reversed[i - 1 - j];
        }
        str = string(s);
    }

    /////////////////////////////////////////////////////////////////////////////
    //
    // ERC721EnumerableImpl
    //
    /////////////////////////////////////////////////////////////////////////////

    function exists(uint256 _tokenId) public view returns (bool) {
        return _tokenId < tokenCount;
    }
 
    function totalSupply() external view returns (uint256) {
        return tokenCount;
    }

    function tokenOfOwnerByIndex(address _tokenOwner, uint256 _index) external view returns (uint256 tokenId) {
        require(_index < ownedTokens[_tokenOwner].length);
        return ownedTokens[_tokenOwner][_index];
    }

    function tokenByIndex(uint256 _index) external view returns (uint256 tokenId) {
        require(_index < tokenCount);
        return _index;
    }

    function _mint(address _to, uint256 _tokenId) internal {
        require (_to != address(0));
        require (tokenIdToTokenOwner[_tokenId].tokenOwner == address(0));
        tokenIdToTokenOwner[_tokenId].tokenOwner = _to;
        ownedTokensIndex[_tokenId] = ownedTokens[_to].length;
        ownedTokens[_to].push(_tokenId);
        tokenCount++;

        emit Transfer(address(0), _to, _tokenId);
    }

    /////////////////////////////////////////////////////////////////////////////
    //
    // ERC998 Bottom-Up implementation (extenstion of ERC-721)
    //
    /////////////////////////////////////////////////////////////////////////////

    function _removeChild(address _fromContract, uint256 _fromTokenId, uint256 _tokenId) internal {
        uint256 lastChildTokenIndex = parentToChildTokenIds[_fromContract][_fromTokenId].length - 1;
        uint256 lastChildTokenId = parentToChildTokenIds[_fromContract][_fromTokenId][lastChildTokenIndex];

        if (_tokenId != lastChildTokenId) {
            uint256 currentChildTokenIndex = tokenIdToChildTokenIdsIndex[_tokenId];
            parentToChildTokenIds[_fromContract][_fromTokenId][currentChildTokenIndex] = lastChildTokenId;
            tokenIdToChildTokenIdsIndex[lastChildTokenId] = currentChildTokenIndex;
        }
        parentToChildTokenIds[_fromContract][_fromTokenId].length--;
    }

    function _transferChild(address _from, address _toContract, uint256 _toTokenId, uint256 _tokenId) internal {
        tokenIdToTokenOwner[_tokenId].parentTokenId = _toTokenId.add(1);
        uint256 index = parentToChildTokenIds[_toContract][_toTokenId].length;
        parentToChildTokenIds[_toContract][_toTokenId].push(_tokenId);
        tokenIdToChildTokenIdsIndex[_tokenId] = index;

        _transferFrom(_from, _toContract, _tokenId);
        
        require(ERC721(_toContract).ownerOf(_toTokenId) != address(0));
        emit TransferToParent(_toContract, _toTokenId, _tokenId);
    }

    function _removeFromToken(address _fromContract, uint256 _fromTokenId, address _to, uint256 _tokenId) internal {
        require(_fromContract != address(0));
        require(_to != address(0));
        require(tokenIdToTokenOwner[_tokenId].tokenOwner == _fromContract);
        uint256 parentTokenId = tokenIdToTokenOwner[_tokenId].parentTokenId;
        require(parentTokenId != 0);
        require(parentTokenId - 1 == _fromTokenId);

        // authenticate
        address rootOwner = address(rootOwnerOf(_tokenId));
        address approvedAddress = rootOwnerAndTokenIdToApprovedAddress[rootOwner][_tokenId];
        require(rootOwner == msg.sender || tokenOwnerToOperators[rootOwner][msg.sender] || approvedAddress == msg.sender);

        // clear approval
        if (approvedAddress != address(0)) {
            delete rootOwnerAndTokenIdToApprovedAddress[rootOwner][_tokenId];
            emit Approval(rootOwner, address(0), _tokenId);
        }

        tokenIdToTokenOwner[_tokenId].parentTokenId = 0;

        _removeChild(_fromContract, _fromTokenId, _tokenId);
        emit TransferFromParent(_fromContract, _fromTokenId, _tokenId);
    }

    function transferFromParent(address _fromContract, uint256 _fromTokenId, address _to, uint256 _tokenId, bytes _data) public {
        _removeFromToken(_fromContract, _fromTokenId, _to, _tokenId);
        delete tokenIdToChildTokenIdsIndex[_tokenId];
        _transferFrom(_fromContract, _to, _tokenId);
        require(_checkAndCallSafeTransfer(_fromContract, _to, _tokenId, _data));
    }

    function transferToParent(address _from, address _toContract, uint256 _toTokenId, uint256 _tokenId, bytes _data) public {
        _transferFromOwnerCheck(_from, _toContract, _tokenId);
        _transferChild(_from, _toContract, _toTokenId, _tokenId);
    }

    function transferAsChild(address _fromContract, uint256 _fromTokenId, address _toContract, uint256 _toTokenId, uint256 _tokenId, bytes _data) external {
        _removeFromToken(_fromContract, _fromTokenId, _toContract, _tokenId);
        _transferChild(_fromContract, _toContract, _toTokenId, _tokenId);
    }

    /////////////////////////////////////////////////////////////////////////////
    //
    // ERC998 Bottom-Up Enumerable Implementation
    //
    /////////////////////////////////////////////////////////////////////////////

    function totalChildTokens(address _parentContract, uint256 _parentTokenId) public view returns (uint256) {
        return parentToChildTokenIds[_parentContract][_parentTokenId].length;
    }

    function childTokenByIndex(address _parentContract, uint256 _parentTokenId, uint256 _index) public view returns (uint256) {
        require(parentToChildTokenIds[_parentContract][_parentTokenId].length > _index);
        return parentToChildTokenIds[_parentContract][_parentTokenId][_index];
    }
}


contract CryptoRomeControl {

    // Emited when contract is upgraded or ownership changed
    event ContractUpgrade(address newContract);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    // Has control of (most) contract elements
    address public ownerPrimary;
    address public ownerSecondary;

    // Address of owner wallet to transfer funds
    address public ownerWallet;
    address public cryptoRomeWallet;

    // Contracts that need access for gameplay
    // (state = 1 means access is active, state = 0 means disabled)
    mapping(address => uint8) public otherOperators;

    // Improvement contract is the only authorized address that can modify 
    // existing land data (ex. when player purchases a land improvement). No one else can
    // modify land - even owners of this contract
    address public improvementContract;

    // Tracks if contract is paused or not. If paused, most actions are blocked
    bool public paused = false;

    constructor() public {
        ownerPrimary = msg.sender;
        ownerSecondary = msg.sender;
        ownerWallet = msg.sender;
        cryptoRomeWallet = msg.sender;
    }

    modifier onlyOwner() {
        require (msg.sender == ownerPrimary || msg.sender == ownerSecondary);
        _;
    }

    modifier anyOperator() {
        require (
            msg.sender == ownerPrimary ||
            msg.sender == ownerSecondary ||
            otherOperators[msg.sender] == 1
        );
        _;
    }

    modifier onlyOtherOperators() {
        require (otherOperators[msg.sender] == 1);
        _;
    }

    modifier onlyImprovementContract() {
        require (msg.sender == improvementContract);
        _;
    }

    function setPrimaryOwner(address _newOwner) external onlyOwner {
        require (_newOwner != address(0));
        emit OwnershipTransferred(ownerPrimary, _newOwner);
        ownerPrimary = _newOwner;
    }

    function setSecondaryOwner(address _newOwner) external onlyOwner {
        require (_newOwner != address(0));
        emit OwnershipTransferred(ownerSecondary, _newOwner);
        ownerSecondary = _newOwner;
    }

    function setOtherOperator(address _newOperator, uint8 _state) external onlyOwner {
        require (_newOperator != address(0));
        otherOperators[_newOperator] = _state;
    }

    function setImprovementContract(address _improvementContract) external onlyOwner {
        require (_improvementContract != address(0));
        emit OwnershipTransferred(improvementContract, _improvementContract);
        improvementContract = _improvementContract;
    }

    function transferOwnerWalletOwnership(address newWalletAddress) onlyOwner external {
        require(newWalletAddress != address(0));
        ownerWallet = newWalletAddress;
    }

    function transferCryptoRomeWalletOwnership(address newWalletAddress) onlyOwner external {
        require(newWalletAddress != address(0));
        cryptoRomeWallet = newWalletAddress;
    }

    modifier whenNotPaused() {
        require(!paused);
        _;
    }

    modifier whenPaused {
        require(paused);
        _;
    }

    function pause() public onlyOwner whenNotPaused {
        paused = true;
    }

    function unpause() public onlyOwner whenPaused {
        paused = false;
    }

    function withdrawBalance() public onlyOwner {
        ownerWallet.transfer(address(this).balance);
    }
}

contract CryptoRomeLandComposableNFT is ERC998ERC721BottomUpToken, CryptoRomeControl {
    using SafeMath for uint256;

    // Set in case the contract needs to be updated
    address public newContractAddress;

    struct LandInfo {
        uint256 landType;  // 0-4  unit, plot, village, town, city (unit unused)
        uint256 landImprovements; 
        uint256 askingPrice;
    }

    mapping(uint256 => LandInfo) internal tokenIdToLand;

    // for sale state of all tokens. tokens map to bits. 0 = not for sale; 1 = for sale
    // 256 token states per index of this array
    uint256[] internal allLandForSaleState;

    // landType => land count
    mapping(uint256 => uint256) internal landTypeToCount;

    // total number of villages in existence is 50000 (no more can be created)
    uint256 constant internal MAX_VILLAGES = 50000;

    constructor () public {
        paused = true;
        name_ = "CryptoRome-Land-NFT";
        symbol_ = "CRLAND";
    }

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

    function getLandTypeCount(uint256 _landType) public view returns (uint256) {
        return landTypeToCount[_landType];
    }

    function setTokenURI(string _tokenURI) external anyOperator {
        tokenURIBase = _tokenURI;
    }

    function setNewAddress(address _v2Address) external onlyOwner {
        require (_v2Address != address(0));
        newContractAddress = _v2Address;
        emit ContractUpgrade(_v2Address);
    }

    /////////////////////////////////////////////////////////////////////////////
    // Get Land
    //   Token Owner: Address of the token owner
    //   Parent Token Id: If parentTokenId is > 0, then this land
    //      token is owned by another token (i.e. it is attached bottom-up).
    //      parentTokenId is the id of the owner token, and tokenOwner
    //      address (the first parameter) is the ERC721 contract address of the  
    //      parent token. If parentTokenId == 0, then this land token is owned
    //      by a user address.
    //   Land Types: village=1, town=2, city=3
    //   Land Improvements: improvements and upgrades
    //      to each land NFT are coded into a single uint256 value
    //   Asking Price (in wei): 0 if land is not for sale
    /////////////////////////////////////////////////////////////////////////////
    function getLand(uint256 _tokenId) external view
        returns (
            address tokenOwner,
            uint256 parentTokenId,
            uint256 landType,
            uint256 landImprovements,
            uint256 askingPrice
        ) {
        TokenOwner storage owner = tokenIdToTokenOwner[_tokenId];
        LandInfo storage land = tokenIdToLand[_tokenId];

        parentTokenId = owner.parentTokenId;
        if (parentTokenId > 0) {
            parentTokenId--;
        }
        tokenOwner = owner.tokenOwner;
        parentTokenId = owner.parentTokenId;
        landType = land.landType;
        landImprovements = land.landImprovements;
        askingPrice = land.askingPrice;
    }

    /////////////////////////////////////////////////////////////////////////////
    // Create Land NFT
    //   Land Types: village=1, town=2, city=3
    //   Land Improvements: improvements and upgrades
    //      to each land NFT are the coded into a uint256 value
    /////////////////////////////////////////////////////////////////////////////
    function _createLand (address _tokenOwner, uint256 _landType, uint256 _landImprovements) internal returns (uint256 tokenId) {
        require(_tokenOwner != address(0));
        require(landTypeToCount[1] < MAX_VILLAGES);
        tokenId = tokenCount;

        LandInfo memory land = LandInfo({
            landType: _landType,  // 1-3  village, town, city
            landImprovements: _landImprovements,
            askingPrice: 0
        });
        
        // map new tokenId to the newly created land      
        tokenIdToLand[tokenId] = land;
        landTypeToCount[_landType]++;

        if (tokenId % 256 == 0) {
            // create new land sale state entry in storage
            allLandForSaleState.push(0);
        }

        _mint(_tokenOwner, tokenId);

        return tokenId;
    }
    
    function createLand (address _tokenOwner, uint256 _landType, uint256 _landImprovements) external anyOperator whenNotPaused returns (uint256 tokenId) {
        return _createLand (_tokenOwner, _landType, _landImprovements);
    }

    ////////////////////////////////////////////////////////////////////////////////
    // Land Improvement Data
    //   This uint256 land "dna" value describes all improvements and upgrades 
    //   to a piece of land. After land token distribution, only the Improvement
    //   Contract can ever update or modify the land improvement data of a piece
    //   of land (contract owner cannot modify land).
    //
    // For villages, improvementData is a uint256 value containing village
    // improvement data with the following slot bit mapping
    //     0-31:     slot 1 improvement info
    //     32-63:    slot 2 improvement info
    //     64-95:    slot 3 improvement info
    //     96-127:   slot 4 improvement info
    //     128-159:  slot 5 improvement info
    //     160-191:  slot 6 improvement info
    //     192-255:  reserved for additional land information
    //
    // Each 32 bit slot in the above structure has the following bit mapping
    //     0-7:      improvement type (index to global list of possible types)
    //     8-14:     upgrade type 1 - level 0-99  (0 for no upgrade present)
    //     15-21:    upgrade type 2 - level 0-99  (0 for no upgrade present)
    //     22:       upgrade type 3 - 1 if upgrade present, 0 if not (no leveling)
    ////////////////////////////////////////////////////////////////////////////////
    function getLandImprovementData(uint256 _tokenId) external view returns (uint256) {
        return tokenIdToLand[_tokenId].landImprovements;
    }

    function updateLandImprovementData(uint256 _tokenId, uint256 _newLandImprovementData) external whenNotPaused onlyImprovementContract {
        require(_tokenId <= tokenCount);
        tokenIdToLand[_tokenId].landImprovements = _newLandImprovementData;
    }

    /////////////////////////////////////////////////////////////////////////////
    // Land Compose/Decompose functions
    //   Towns are composed of 3 Villages
    //   Cities are composed of 3 Towns
    /////////////////////////////////////////////////////////////////////////////

    // Attach three child land tokens onto a parent land token (ex. 3 villages onto a town).
    // This function is called when the parent does not exist yet, so create parent land token first
    // Ownership of the child lands transfers from the existing owner (sender) to the parent land token
    function composeNewLand(uint256 _landType, uint256 _childLand1, uint256 _childLand2, uint256 _childLand3) external whenNotPaused returns(uint256) {
        uint256 parentTokenId = _createLand(msg.sender, _landType, 0);
        return composeLand(parentTokenId, _childLand1, _childLand2, _childLand3);
    }

    // Attach three child land tokens onto a parent land token (ex. 3 villages into a town).
    // All three children and an existing parent need to be passed into this function.
    // Ownership of the child lands transfers from the existing owner (sender) to the parent land token
    function composeLand(uint256 _parentLandId, uint256 _childLand1, uint256 _childLand2, uint256 _childLand3) public whenNotPaused returns(uint256) {
        require (tokenIdToLand[_parentLandId].landType == 2 || tokenIdToLand[_parentLandId].landType == 3);
        uint256 validChildLandType = tokenIdToLand[_parentLandId].landType.sub(1);
        require(tokenIdToLand[_childLand1].landType == validChildLandType &&
                tokenIdToLand[_childLand2].landType == validChildLandType &&
                tokenIdToLand[_childLand3].landType == validChildLandType);

        // transfer ownership of child land tokens to parent land token
        transferToParent(tokenIdToTokenOwner[_childLand1].tokenOwner, address(this), _parentLandId, _childLand1, "");
        transferToParent(tokenIdToTokenOwner[_childLand2].tokenOwner, address(this), _parentLandId, _childLand2, "");
        transferToParent(tokenIdToTokenOwner[_childLand3].tokenOwner, address(this), _parentLandId, _childLand3, "");

        // if this contract is owner of the parent land token, transfer ownership to msg.sender
        if (tokenIdToTokenOwner[_parentLandId].tokenOwner == address(this)) {
            _transferFrom(address(this), msg.sender, _parentLandId);
        }

        return _parentLandId;
    }

    // Decompose a parent land back to it's attached child land token components (ex. a town into 3 villages).
    // The existing owner of the parent land becomes the owner of the three child tokens
    // This contract takes over ownership of the parent land token (for later reuse)
    // Loop to remove and transfer all land tokens in case other land tokens are attached.
    function decomposeLand(uint256 _tokenId) external whenNotPaused {
        uint256 numChildren = totalChildTokens(address(this), _tokenId);
        require (numChildren > 0);

        // it is lower gas cost to remove children starting from the end of the array
        for (uint256 numChild = numChildren; numChild > 0; numChild--) {
            uint256 childTokenId = childTokenByIndex(address(this), _tokenId, numChild-1);

            // transfer ownership of underlying lands to msg.sender
            transferFromParent(address(this), _tokenId, msg.sender, childTokenId, "");
        }

        // transfer ownership of parent land back to this contract owner for reuse
        _transferFrom(msg.sender, address(this), _tokenId);
    }

    /////////////////////////////////////////////////////////////////////////////
    // Sale functions
    /////////////////////////////////////////////////////////////////////////////
    function _updateSaleData(uint256 _tokenId, uint256 _askingPrice) internal {
        tokenIdToLand[_tokenId].askingPrice = _askingPrice;
        if (_askingPrice > 0) {
            // Item is for sale - set bit
            allLandForSaleState[_tokenId.div(256)] = allLandForSaleState[_tokenId.div(256)] | (1 << (_tokenId % 256));
        } else {
            // Item is no longer for sale - clear bit
            allLandForSaleState[_tokenId.div(256)] = allLandForSaleState[_tokenId.div(256)] & ~(1 << (_tokenId % 256));
        }
    }

    function sellLand(uint256 _tokenId, uint256 _askingPrice) public whenNotPaused {
        require(tokenIdToTokenOwner[_tokenId].tokenOwner == msg.sender);
        require(tokenIdToTokenOwner[_tokenId].parentTokenId == 0);
        require(_askingPrice > 0);
        // Put the land token on the market
        _updateSaleData(_tokenId, _askingPrice);
    }

    function cancelLandSale(uint256 _tokenId) public whenNotPaused {
        require(tokenIdToTokenOwner[_tokenId].tokenOwner == msg.sender);
        // Take the land token off the market
        _updateSaleData(_tokenId, 0);
    }

    function purchaseLand(uint256 _tokenId) public whenNotPaused payable {
        uint256 price = tokenIdToLand[_tokenId].askingPrice;
        require(price <= msg.value);

        // Take the land token off the market
        _updateSaleData(_tokenId, 0);

        // Marketplace fee
        uint256 marketFee = computeFee(price);
        uint256 sellerProceeds = msg.value.sub(marketFee);
        cryptoRomeWallet.transfer(marketFee);

        // Return excess payment to sender
        uint256 excessPayment = msg.value.sub(price);
        msg.sender.transfer(excessPayment);

        // Transfer proceeds to seller. Sale was removed above before this transfer()
        // to guard against reentrancy attacks
        tokenIdToTokenOwner[_tokenId].tokenOwner.transfer(sellerProceeds);
        // Transfer token to buyer
        _transferFrom(tokenIdToTokenOwner[_tokenId].tokenOwner, msg.sender, _tokenId);
    }

    function getAllForSaleStatus() external view returns(uint256[]) {
        // return uint256[] bitmap values up to max tokenId (for ease of querying from UI for marketplace)
        //   index 0 of the uint256 holds first 256 land token status; index 1 is next 256 land tokens, etc
        //   value of 1 = For Sale; 0 = Not for Sale
        return allLandForSaleState;
    }

    function computeFee(uint256 amount) internal pure returns(uint256) {
        // 3% marketplace fee, most of which will be distributed to the Caesar and Senators of CryptoRome
        return amount.mul(3).div(100);
    }
}

contract CryptoRomeLandDistribution is CryptoRomeControl {
    using SafeMath for uint256;

    // Set in case the contract needs to be updated
    address public newContractAddress;

    CryptoRomeLandComposableNFT public cryptoRomeLandNFTContract;
    ImprovementGeneration public improvementGenContract;
    uint256 public villageInventoryPrice;
    uint256 public numImprovementsPerVillage;

    uint256 constant public LOWEST_VILLAGE_INVENTORY_PRICE = 100000000000000000; // 0.1 ETH

    constructor (address _cryptoRomeLandNFTContractAddress, address _improvementGenContractAddress) public {
        require (_cryptoRomeLandNFTContractAddress != address(0));
        require (_improvementGenContractAddress != address(0));

        paused = true;

        cryptoRomeLandNFTContract = CryptoRomeLandComposableNFT(_cryptoRomeLandNFTContractAddress);
        improvementGenContract = ImprovementGeneration(_improvementGenContractAddress);

        villageInventoryPrice = LOWEST_VILLAGE_INVENTORY_PRICE;
        numImprovementsPerVillage = 3;
    }

    function setNewAddress(address _v2Address) external onlyOwner {
        require (_v2Address != address(0));
        newContractAddress = _v2Address;
        emit ContractUpgrade(_v2Address);
    }

    function setCryptoRomeLandNFTContract(address _cryptoRomeLandNFTContract) external onlyOwner {
        require (_cryptoRomeLandNFTContract != address(0));
        cryptoRomeLandNFTContract = CryptoRomeLandComposableNFT(_cryptoRomeLandNFTContract);
    }

    function setImprovementGenContract(address _improvementGenContractAddress) external onlyOwner {
        require (_improvementGenContractAddress != address(0));
        improvementGenContract = ImprovementGeneration(_improvementGenContractAddress);
    }

    function setVillageInventoryPrice(uint256 _price) external onlyOwner {
        require(_price >= LOWEST_VILLAGE_INVENTORY_PRICE);
        villageInventoryPrice = _price;
    }

    function setNumImprovementsPerVillage(uint256 _numImprovements) external onlyOwner {
        require(_numImprovements <= 6);
        numImprovementsPerVillage = _numImprovements;
    }

    function purchaseFromVillageInventory(uint256 _num) external whenNotPaused payable {
        uint256 price = villageInventoryPrice.mul(_num);
        require (msg.value >= price);
        require (_num > 0 && _num <= 50);

        // Marketplace fee
        uint256 marketFee = computeFee(price);
        cryptoRomeWallet.transfer(marketFee);

        // Return excess payment to sender
        uint256 excessPayment = msg.value.sub(price);
        msg.sender.transfer(excessPayment);

        for (uint256 i = 0; i < _num; i++) {
            // create a new village w/ random improvements and transfer the NFT to caller
            _createVillageWithImprovementsFromInv(msg.sender);
        }
    }

    function computeFee(uint256 amount) internal pure returns(uint256) {
        // 3% marketplace fee, most of which will be distributed to the Caesar and Senators of CryptoRome
        return amount.mul(3).div(100);
    }

    function batchIssueLand(address _toAddress, uint256[] _landType) external onlyOwner {
        require (_toAddress != address(0));
        require (_landType.length > 0);

        for (uint256 i = 0; i < _landType.length; i++) {
            issueLand(_toAddress, _landType[i]);
        }
    }

    function batchIssueVillages(address _toAddress, uint256 _num) external onlyOwner {
        require (_toAddress != address(0));
        require (_num > 0);

        for (uint256 i = 0; i < _num; i++) {
            _createVillageWithImprovements(_toAddress);
        }
    }

    function issueLand(address _toAddress, uint256 _landType) public onlyOwner returns (uint256) {
        require (_toAddress != address(0));

        return _createLandWithImprovements(_toAddress, _landType);
    }

    function batchCreateLand(uint256[] _landType) external onlyOwner {
        require (_landType.length > 0);

        for (uint256 i = 0; i < _landType.length; i++) {
            // land created is owned by this contract for staging purposes
            // (must later use transferTo or batchTransferTo)
            _createLandWithImprovements(address(this), _landType[i]);
        }
    }

    function batchCreateVillages(uint256 _num) external onlyOwner {
        require (_num > 0);

        for (uint256 i = 0; i < _num; i++) {
            // land created is owned by this contract for staging purposes
            // (must later use transferTo or batchTransferTo)
            _createVillageWithImprovements(address(this));
        }
    }

    function createLand(uint256 _landType) external onlyOwner {
        // land created is owned by this contract for staging purposes
        // (must later use transferTo or batchTransferTo)
        _createLandWithImprovements(address(this), _landType);
    }

    function batchTransferTo(uint256[] _tokenIds, address _to) external onlyOwner {
        require (_tokenIds.length > 0);
        require (_to != address(0));

        for (uint256 i = 0; i < _tokenIds.length; ++i) {
            // transfers staged land out of this contract to the owners
            cryptoRomeLandNFTContract.transferFrom(address(this), _to, _tokenIds[i]);
        }
    }

    function transferTo(uint256 _tokenId, address _to) external onlyOwner {
        require (_to != address(0));

        // transfers staged land out of this contract to the owners
        cryptoRomeLandNFTContract.transferFrom(address(this), _to, _tokenId);
    }

    function issueVillageWithImprovementsForPromo(address _toAddress, uint256 numImprovements) external onlyOwner returns (uint256) {
        uint256 landImprovements = improvementGenContract.genInitialResourcesForVillage(numImprovements, false);
        return cryptoRomeLandNFTContract.createLand(_toAddress, 1, landImprovements);
    }

    function _createVillageWithImprovementsFromInv(address _toAddress) internal returns (uint256) {
        uint256 landImprovements = improvementGenContract.genInitialResourcesForVillage(numImprovementsPerVillage, true);
        return cryptoRomeLandNFTContract.createLand(_toAddress, 1, landImprovements);
    }

    function _createVillageWithImprovements(address _toAddress) internal returns (uint256) {
        uint256 landImprovements = improvementGenContract.genInitialResourcesForVillage(3, false);
        return cryptoRomeLandNFTContract.createLand(_toAddress, 1, landImprovements);
    }

    function _createLandWithImprovements(address _toAddress, uint256 _landType) internal returns (uint256) {
        require (_landType > 0 && _landType < 4);

        if (_landType == 1) {
            return _createVillageWithImprovements(_toAddress);
        } else if (_landType == 2) {
            uint256 village1TokenId = _createLandWithImprovements(address(this), 1);
            uint256 village2TokenId = _createLandWithImprovements(address(this), 1);
            uint256 village3TokenId = _createLandWithImprovements(address(this), 1);
            uint256 townTokenId = cryptoRomeLandNFTContract.createLand(_toAddress, 2, 0);
            cryptoRomeLandNFTContract.composeLand(townTokenId, village1TokenId, village2TokenId, village3TokenId);
            return townTokenId;
        } else if (_landType == 3) {
            uint256 town1TokenId = _createLandWithImprovements(address(this), 2);
            uint256 town2TokenId = _createLandWithImprovements(address(this), 2);
            uint256 town3TokenId = _createLandWithImprovements(address(this), 2);
            uint256 cityTokenId = cryptoRomeLandNFTContract.createLand(_toAddress, 3, 0);
            cryptoRomeLandNFTContract.composeLand(cityTokenId, town1TokenId, town2TokenId, town3TokenId);
            return cityTokenId;
        }
    }
}

interface RandomNumGeneration {
    function getRandomNumber(uint256 seed) external returns (uint256);
}

contract ImprovementGeneration is CryptoRomeControl {
    using SafeMath for uint256;
    
    // Set in case the contract needs to be updated
    address public newContractAddress;

    RandomNumGeneration public randomNumberSource; 
    uint256 public rarityValueMax;
    uint256 public latestPseudoRandomNumber;
    uint8 public numResourceImprovements;

    mapping(uint8 => uint256) private improvementIndexToRarityValue;

    constructor () public {
        // Starting Improvements
        // improvement => rarity value (lower number = higher rarity) 
        improvementIndexToRarityValue[1] = 256;  // Wheat
        improvementIndexToRarityValue[2] = 256;  // Wood
        improvementIndexToRarityValue[3] = 128;  // Grapes
        improvementIndexToRarityValue[4] = 128;  // Stone
        improvementIndexToRarityValue[5] = 64;   // Clay
        improvementIndexToRarityValue[6] = 64;   // Fish
        improvementIndexToRarityValue[7] = 32;   // Horse
        improvementIndexToRarityValue[8] = 16;   // Iron
        improvementIndexToRarityValue[9] = 8;    // Marble
        // etc --> More can be added in the future

        // max resource improvement types is 63
        numResourceImprovements = 9;
        rarityValueMax = 952;
    }

    function setNewAddress(address _v2Address) external onlyOwner {
        require (_v2Address != address(0));
        newContractAddress = _v2Address;
        emit ContractUpgrade(_v2Address);
    }

    function setRandomNumGenerationContract(address _randomNumberGenAddress) external onlyOwner {
        require (_randomNumberGenAddress != address(0));
        randomNumberSource = RandomNumGeneration(_randomNumberGenAddress);
    }

    function genInitialResourcesForVillage(uint256 numImprovements, bool useRandomInput) external anyOperator returns(uint256) {
        require(numImprovements <= 6);
        uint256 landImprovements;

        // each improvement takes up one village slot (max 6 slots)
        for (uint256 i = 0; i < numImprovements; i++) {
            uint8 newImprovement = generateImprovement(useRandomInput);
            // each slot is a 32 bit section in the 256 bit landImprovement value
            landImprovements |= uint256(newImprovement) << (32*i);
        }
        
        return landImprovements;
    }

    function generateImprovement(bool useRandomSource) public anyOperator returns (uint8 newImprovement) {     
        // seed does not need to be anything super fancy for initial improvement generation for villages...
        // players will not be performing that operation, so this should be random enough
        uint256 seed = latestPseudoRandomNumber.add(now);
        if (useRandomSource) {
            // for cases where players are generating land (i.e. after initial distribution of villages), there
            // will need to be a better source of randomness
            seed = randomNumberSource.getRandomNumber(seed);
        }
        
        latestPseudoRandomNumber = addmod(uint256(blockhash(block.number-1)), seed, rarityValueMax);
        
        // do lookup for the improvement
        newImprovement = lookupImprovementTypeByRarity(latestPseudoRandomNumber);
    }

    function lookupImprovementTypeByRarity(uint256 rarityNum) public view returns (uint8 improvementType) {
        uint256 rarityIndexValue;
        for (uint8 i = 1; i <= numResourceImprovements; i++) {
            rarityIndexValue += improvementIndexToRarityValue[i];
            if (rarityNum < rarityIndexValue) {
                return i;
            }
        }
        return 0;
    }

    function addNewResourceImprovementType(uint256 rarityValue) external onlyOwner {
        require(rarityValue > 0);
        require(numResourceImprovements < 63);

        numResourceImprovements++;
        rarityValueMax += rarityValue;
        improvementIndexToRarityValue[numResourceImprovements] = rarityValue;
    }

    function updateImprovementRarityValue(uint256 rarityValue, uint8 improvementIndex) external onlyOwner {
        require(rarityValue > 0);
        require(improvementIndex <= numResourceImprovements);

        rarityValueMax -= improvementIndexToRarityValue[improvementIndex];
        rarityValueMax += rarityValue;
        improvementIndexToRarityValue[improvementIndex] = rarityValue;
    }
}

    Contract ABI  
[{"constant":true,"inputs":[{"name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_parentContract","type":"address"},{"name":"_parentTokenId","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"childTokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_approved","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newWalletAddress","type":"address"}],"name":"transferCryptoRomeWalletOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenOwner","type":"address"},{"name":"_landType","type":"uint256"},{"name":"_landImprovements","type":"uint256"}],"name":"createLand","outputs":[{"name":"tokenId","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAllForSaleStatus","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenOwner","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"tokenId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cryptoRomeWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"rootOwnerOf","outputs":[{"name":"rootOwner","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"setPrimaryOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"tokenId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_fromContract","type":"address"},{"name":"_fromTokenId","type":"uint256"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transferFromParent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"newContractAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"otherOperators","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenOwner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_v2Address","type":"address"}],"name":"setNewAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_landType","type":"uint256"},{"name":"_childLand1","type":"uint256"},{"name":"_childLand2","type":"uint256"},{"name":"_childLand3","type":"uint256"}],"name":"composeNewLand","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"purchaseLand","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"name":"ownerTokens","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_parentContract","type":"address"},{"name":"_parentTokenId","type":"uint256"}],"name":"totalChildTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenOwnerOf","outputs":[{"name":"tokenOwner","type":"bytes32"},{"name":"parentTokenId","type":"uint256"},{"name":"isParent","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"decomposeLand","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ownerWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ownerPrimary","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_askingPrice","type":"uint256"}],"name":"sellLand","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_landType","type":"uint256"}],"name":"getLandTypeCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getLandImprovementData","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_fromContract","type":"address"},{"name":"_fromTokenId","type":"uint256"},{"name":"_toContract","type":"address"},{"name":"_toTokenId","type":"uint256"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transferAsChild","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_parentLandId","type":"uint256"},{"name":"_childLand1","type":"uint256"},{"name":"_childLand2","type":"uint256"},{"name":"_childLand3","type":"uint256"}],"name":"composeLand","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ownerSecondary","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newWalletAddress","type":"address"}],"name":"transferOwnerWalletOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isCryptoRomeLandComposableNFT","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"setSecondaryOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"improvementContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOperator","type":"address"},{"name":"_state","type":"uint8"}],"name":"setOtherOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_improvementContract","type":"address"}],"name":"setImprovementContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenURI","type":"string"}],"name":"setTokenURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_newLandImprovementData","type":"uint256"}],"name":"updateLandImprovementData","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"cancelLandSale","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getLand","outputs":[{"name":"tokenOwner","type":"address"},{"name":"parentTokenId","type":"uint256"},{"name":"landType","type":"uint256"},{"name":"landImprovements","type":"uint256"},{"name":"askingPrice","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_toContract","type":"address"},{"name":"_toTokenId","type":"uint256"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transferToParent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newContract","type":"address"}],"name":"ContractUpgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_toContract","type":"address"},{"indexed":true,"name":"_toTokenId","type":"uint256"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"TransferToParent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_fromContract","type":"address"},{"indexed":true,"name":"_fromTokenId","type":"uint256"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"TransferFromParent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_tokenOwner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":true,"name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_tokenOwner","type":"address"},{"indexed":true,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]

  Contract Creation Code Switch To Opcodes View
60806040526011805460a060020a60ff02191690553480156200002157600080fd5b50600b60209081527f6fc4fe54b7713e8c3beb98c1633f1a7c51390dad7f13255e19999c5edaf38b65805460ff1990811660019081179092557f58dbcb8b42477ba587235ed21c9227789266bd956417ae5420ec8c31552e276280548216831790557f392a5f45591c4d9c05a109aeb535f975c0e2d81925e3ac029c52e6ec2139a20b80548216831790557f9ea35b7873c8b046fb963897c29b313fe2a41ca6b497dee659b16c91e3b8a50280548216831790557fff2ba62c5c6f4e0b72ee7054c587fbb2ff1ec14aa579cbc64a86f76ec6cb296e80548216831790557f8318b539000000000000000000000000000000000000000000000000000000006000527f9e33802b94a5b5ebfeaa1630ee645e08a3449bd86e190a9ecd7ced7baf89913280549091169091179055600c8054600160a060020a031990811633908117909255600d8054821683179055600e8054821683179055600f805490911690911790556011805460a060020a60ff021916740100000000000000000000000000000000000000001790556040805180820190915260138082527f43727970746f526f6d652d4c616e642d4e46540000000000000000000000000091909201908152620001f191600891906200023f565b506040805180820190915260068082527f43524c414e440000000000000000000000000000000000000000000000000000602090920191825262000238916009916200023f565b50620002e4565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200028257805160ff1916838001178555620002b2565b82800160010185558215620002b2579182015b82811115620002b257825182559160200191906001019062000295565b50620002c0929150620002c4565b5090565b620002e191905b80821115620002c05760008155600101620002cb565b90565b61314780620002f46000396000f30060806040526004361061028f5763ffffffff60e060020a60003504166301ffc9a78114610294578063051847d5146102df57806306fdde0314610318578063081812fc146103a2578063095ea7b3146103d65780630b1ad18d146103fc57806318160ddd1461041d5780631e1e3c5b14610432578063216a55431461045957806323b872dd146104be5780632f745c59146104e857806337efa3971461050c5780633f4ba83a1461052157806342842e0e1461053657806343a61a8e1461056057806343bad081146105785780634f558e79146105995780634f6ccce7146105b15780635c975abb146105c95780635e3e2687146105de5780635fd8c710146106575780636352211e1461066c5780636af04a57146106845780636eccc6a31461069957806370a08231146106d057806371587988146106f15780637fcdcb9a146107125780638009d5d7146107335780638456cb591461073e5780638462151c146107535780638600f2ec1461077457806389885a591461079857806390b62297146107d05780639335dcb7146107e857806395910d46146107fd57806395d89b4114610812578063a22cb46514610827578063ae9409031461084d578063b5f4968c14610868578063b88d4fde14610880578063bd2f37ba146108b9578063c0a899f2146108d1578063c87b56dd14610911578063cfef941b14610929578063d00155001461094a578063d16d9f411461095f578063d1ce65ab14610980578063d52e7f9314610995578063d621c878146109b6578063d8bbe8cf146109cb578063dbd1a08e146109f2578063e0df5b6f14610a13578063e11304f914610a33578063e87596c014610a4e578063e985e9c514610a66578063f02dd53f14610a8d578063f50acfa014610ada575b600080fd5b3480156102a057600080fd5b506102cb7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610b51565b604080519115158252519081900360200190f35b3480156102eb57600080fd5b50610306600160a060020a0360043516602435604435610b85565b60408051918252519081900360200190f35b34801561032457600080fd5b5061032d610bf7565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036757818101518382015260200161034f565b50505050905090810190601f1680156103945780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103ae57600080fd5b506103ba600435610c8e565b60408051600160a060020a039092168252519081900360200190f35b3480156103e257600080fd5b506103fa600160a060020a0360043516602435610cca565b005b34801561040857600080fd5b506103fa600160a060020a0360043516610da6565b34801561042957600080fd5b50610306610e0b565b34801561043e57600080fd5b50610306600160a060020a0360043516602435604435610e11565b34801561046557600080fd5b5061046e610e89565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104aa578181015183820152602001610492565b505050509050019250505060405180910390f35b3480156104ca57600080fd5b506103fa600160a060020a0360043581169060243516604435610ee0565b3480156104f457600080fd5b50610306600160a060020a0360043516602435610f11565b34801561051857600080fd5b506103ba610f6c565b34801561052d57600080fd5b506103fa610f7b565b34801561054257600080fd5b506103fa600160a060020a0360043581169060243516604435610fe1565b34801561056c57600080fd5b5061030660043561101e565b34801561058457600080fd5b506103fa600160a060020a0360043516611360565b3480156105a557600080fd5b506102cb6004356113ff565b3480156105bd57600080fd5b50610306600435611406565b3480156105d557600080fd5b506102cb611419565b3480156105ea57600080fd5b50604080516020601f6084356004818101359283018490048402850184019095528184526103fa94600160a060020a0381358116956024803596604435909316956064359536959460a4949391909101919081908401838280828437509497506114299650505050505050565b34801561066357600080fd5b506103fa61146d565b34801561067857600080fd5b506103ba6004356114d8565b34801561069057600080fd5b506103ba611502565b3480156106a557600080fd5b506106ba600160a060020a0360043516611511565b6040805160ff9092168252519081900360200190f35b3480156106dc57600080fd5b50610306600160a060020a0360043516611526565b3480156106fd57600080fd5b506103fa600160a060020a0360043516611559565b34801561071e57600080fd5b506103066004356024356044356064356115f0565b6103fa600435611632565b34801561074a57600080fd5b506103fa61177e565b34801561075f57600080fd5b5061046e600160a060020a03600435166117e9565b34801561078057600080fd5b50610306600160a060020a0360043516602435611855565b3480156107a457600080fd5b506107b060043561187d565b604080519384526020840192909252151582820152519081900360600190f35b3480156107dc57600080fd5b506103fa600435611908565b3480156107f457600080fd5b506103ba611996565b34801561080957600080fd5b506103ba6119a5565b34801561081e57600080fd5b5061032d6119b4565b34801561083357600080fd5b506103fa600160a060020a03600435166024351515611a15565b34801561085957600080fd5b506103fa600435602435611a98565b34801561087457600080fd5b50610306600435611b0a565b34801561088c57600080fd5b506103fa600160a060020a0360048035821691602480359091169160443591606435908101910135611b1c565b3480156108c557600080fd5b50610306600435611b6e565b3480156108dd57600080fd5b506103fa60048035600160a060020a039081169160248035926044351691606435916084359160a435918201910135611b83565b34801561091d57600080fd5b5061032d600435611ba4565b34801561093557600080fd5b50610306600435602435604435606435611c52565b34801561095657600080fd5b506103ba611deb565b34801561096b57600080fd5b506103fa600160a060020a0360043516611dfa565b34801561098c57600080fd5b506102cb611e5f565b3480156109a157600080fd5b506103fa600160a060020a0360043516611e64565b3480156109c257600080fd5b506103ba611f03565b3480156109d757600080fd5b506103fa600160a060020a036004351660ff60243516611f12565b3480156109fe57600080fd5b506103fa600160a060020a0360043516611f82565b348015610a1f57600080fd5b506103fa6004803560248101910135612021565b348015610a3f57600080fd5b506103fa600435602435612078565b348015610a5a57600080fd5b506103fa6004356120ca565b348015610a7257600080fd5b506102cb600160a060020a036004358116906024351661210f565b348015610a9957600080fd5b50610aa560043561216a565b60408051600160a060020a03909616865260208601949094528484019290925260608401526080830152519081900360a00190f35b348015610ae657600080fd5b50604080516020601f6084356004818101359283018490048402850184019095528184526103fa94600160a060020a0381358116956024803590921695604435956064359536959460a494939101919081908401838280828437509497506121ce9650505050505050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000908152600b602052604090205460ff1690565b600160a060020a03831660009081526005602090815260408083208584529091528120548210610bb457600080fd5b600160a060020a03841660009081526005602090815260408083208684529091529020805483908110610be357fe5b906000526020600020015490509392505050565b60088054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c835780601f10610c5857610100808354040283529160200191610c83565b820191906000526020600020905b815481529060010190602001808311610c6657829003601f168201915b505050505090505b90565b600080610c9a8361101e565b600160a060020a038082166000908152600460209081526040808320888452909152902054169250905050919050565b600081815260016020526040812054600160a060020a031690811515610cef57600080fd5b610cf88361101e565b9050600160a060020a038116331480610d345750600160a060020a038116600090815260076020908152604080832033845290915290205460ff165b1515610d3f57600080fd5b600160a060020a0381811660008181526004602090815260408083208884529091528082208054600160a060020a031916948916948517905551869392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b600c54600160a060020a0316331480610dc95750600d54600160a060020a031633145b1515610dd457600080fd5b600160a060020a0381161515610de957600080fd5b600f8054600160a060020a031916600160a060020a0392909216919091179055565b60005490565b600c54600090600160a060020a0316331480610e375750600d54600160a060020a031633145b80610e5457503360009081526010602052604090205460ff166001145b1515610e5f57600080fd5b60115460a060020a900460ff1615610e7657600080fd5b610e818484846121e5565b949350505050565b60606014805480602002602001604051908101604052809291908181526020018280548015610c8357602002820191906000526020600020905b815481526020019060010190808311610ec3575050505050905090565b600160a060020a038216301415610ef657600080fd5b610f018383836122e6565b610f0c8383836124d0565b505050565b600160a060020a0382166000908152600260205260408120548210610f3557600080fd5b600160a060020a0383166000908152600260205260409020805483908110610f5957fe5b9060005260206000200154905092915050565b600f54600160a060020a031681565b600c54600160a060020a0316331480610f9e5750600d54600160a060020a031633145b1515610fa957600080fd5b60115460a060020a900460ff161515610fc157600080fd5b6011805474ff000000000000000000000000000000000000000019169055565b610fec8383836122e6565b610ff78383836124d0565b611013838383602060405190810160405280600081525061264c565b1515610f0c57600080fd5b600081815260016020526040812054600160a060020a031681806060818085151561104857600080fd5b600088815260016020819052604082200154955085119350831561106e57600019909401935b600160a060020a0386163014156110e4575b8315156110ba577fcd740db500000000000000000000000000000000000000000000000000000000600160a060020a038716179650611355565b6110c3856127c0565b91975095509350600160a060020a0386163014156110e057611080565b8497505b8315156111b4576040805130602482015260448082018b905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561115c57825196505b6001821515148015611177575060e060020a870463cd740db5145b1561118157611355565b7fcd740db500000000000000000000000000000000000000000000000000000000600160a060020a038716179650611355565b60408051602480820188905282518083039091018152604490910190915260208181018051600160e060020a03167f43a61a8e00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561121f57825196505b600182151514801561123a575060e060020a870463cd740db5145b1561124457611355565b5060408051602480820187905282518083039091018152604490910190915260208181018051600160e060020a03167f6352211e00000000000000000000000000000000000000000000000000000000178152825192945087928591845afa915081156112b057825195505b8115156112bc57600080fd5b60408051600160a060020a0383166024820152604480820188905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561115c57825196506001821515148015611177575060e060020a870463cd740db51415611181575b505050505050919050565b600c54600160a060020a03163314806113835750600d54600160a060020a031633145b151561138e57600080fd5b600160a060020a03811615156113a357600080fd5b600c54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c8054600160a060020a031916600160a060020a0392909216919091179055565b6000541190565b60008054821061141557600080fd5b5090565b60115460a060020a900460ff1681565b61143585858585612818565b60008281526006602052604081205561144f8584846124d0565b61145b8584848461264c565b151561146657600080fd5b5050505050565b600c54600160a060020a03163314806114905750600d54600160a060020a031633145b151561149b57600080fd5b600e54604051600160a060020a0390911690303180156108fc02916000818181858888f193505050501580156114d5573d6000803e3d6000fd5b50565b600081815260016020526040812054600160a060020a03168015156114fc57600080fd5b92915050565b601254600160a060020a031681565b60106020526000908152604090205460ff1681565b6000600160a060020a038216151561153d57600080fd5b50600160a060020a031660009081526002602052604090205490565b600c54600160a060020a031633148061157c5750600d54600160a060020a031633145b151561158757600080fd5b600160a060020a038116151561159c57600080fd5b60128054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b601154600090819060a060020a900460ff161561160c57600080fd5b611618338760006121e5565b905061162681868686611c52565b91505b50949350505050565b60115460009081908190819060a060020a900460ff161561165257600080fd5b60008581526013602052604090206002015493503484111561167357600080fd5b61167e8560006129f1565b61168784612ad0565b9250611699348463ffffffff612af416565b600f54604051919350600160a060020a03169084156108fc029085906000818181858888f193505050501580156116d4573d6000803e3d6000fd5b506116e5348563ffffffff612af416565b604051909150339082156108fc029083906000818181858888f19350505050158015611715573d6000803e3d6000fd5b50600085815260016020526040808220549051600160a060020a039091169184156108fc02918591818181858888f1935050505015801561175a573d6000803e3d6000fd5b5060008581526001602052604090205461146690600160a060020a031633876124d0565b600c54600160a060020a03163314806117a15750600d54600160a060020a031633145b15156117ac57600080fd5b60115460a060020a900460ff16156117c357600080fd5b6011805474ff0000000000000000000000000000000000000000191660a060020a179055565b600160a060020a03811660009081526002602090815260409182902080548351818402810184019094528084526060939283018282801561184957602002820191906000526020600020905b815481526020019060010190808311611835575b50505050509050919050565b600160a060020a03919091166000908152600560209081526040808320938352929052205490565b60008181526001602052604081205481908190600160a060020a03168015156118a557600080fd5b60008581526001602081905260408220015493508311156118d05760001990920191600191506118d5565b600091505b600160a060020a03167fcd740db50000000000000000000000000000000000000000000000000000000017949193509150565b6011546000908190819060a060020a900460ff161561192657600080fd5b6119303085611855565b92506000831161193f57600080fd5b8291505b60008211156119855761195a308560018503610b85565b9050611979308533846020604051908101604052806000815250611429565b60001990910190611943565b6119903330866124d0565b50505050565b600e54600160a060020a031681565b600c54600160a060020a031681565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c835780601f10610c5857610100808354040283529160200191610c83565b600160a060020a0382161515611a2a57600080fd5b336000818152600760209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b60115460a060020a900460ff1615611aaf57600080fd5b600082815260016020526040902054600160a060020a03163314611ad257600080fd5b6000828152600160208190526040909120015415611aef57600080fd5b60008111611afc57600080fd5b611b0682826129f1565b5050565b60009081526015602052604090205490565b611b278585856122e6565b611b328585856124d0565b61145b85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375061264c945050505050565b60009081526013602052604090206001015490565b611b8f87878786612818565b611b9b87868686612b12565b50505050505050565b6060611baf826113ff565b1515611bba57600080fd5b600a8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526114fc9390929091830182828015611c475780601f10611c1c57610100808354040283529160200191611c47565b820191906000526020600020905b815481529060010190602001808311611c2a57829003601f168201915b505050505083612c5d565b601154600090819060a060020a900460ff1615611c6e57600080fd5b60008681526013602052604090205460021480611c9957506000868152601360205260409020546003145b1515611ca457600080fd5b600086815260136020526040902054611cc490600163ffffffff612af416565b60008681526013602052604090205490915081148015611cf1575060008481526013602052604090205481145b8015611d0a575060008381526013602052604090205481145b1515611d1557600080fd5b6000858152600160209081526040808320548151928301909152918152611d4b91600160a060020a0316903090899089906121ce565b6000848152600160209081526040808320548151928301909152918152611d8191600160a060020a0316903090899088906121ce565b6000838152600160209081526040808320548151928301909152918152611db791600160a060020a0316903090899087906121ce565b600086815260016020526040902054600160a060020a0316301415611de157611de13033886124d0565b5093949350505050565b600d54600160a060020a031681565b600c54600160a060020a0316331480611e1d5750600d54600160a060020a031633145b1515611e2857600080fd5b600160a060020a0381161515611e3d57600080fd5b600e8054600160a060020a031916600160a060020a0392909216919091179055565b600190565b600c54600160a060020a0316331480611e875750600d54600160a060020a031633145b1515611e9257600080fd5b600160a060020a0381161515611ea757600080fd5b600d54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600d8054600160a060020a031916600160a060020a0392909216919091179055565b601154600160a060020a031681565b600c54600160a060020a0316331480611f355750600d54600160a060020a031633145b1515611f4057600080fd5b600160a060020a0382161515611f5557600080fd5b600160a060020a03919091166000908152601060205260409020805460ff191660ff909216919091179055565b600c54600160a060020a0316331480611fa55750600d54600160a060020a031633145b1515611fb057600080fd5b600160a060020a0381161515611fc557600080fd5b601154604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360118054600160a060020a031916600160a060020a0392909216919091179055565b600c54600160a060020a03163314806120445750600d54600160a060020a031633145b8061206157503360009081526010602052604090205460ff166001145b151561206c57600080fd5b610f0c600a8383613045565b60115460a060020a900460ff161561208f57600080fd5b601154600160a060020a031633146120a657600080fd5b6000548211156120b557600080fd5b60009182526013602052604090912060010155565b60115460a060020a900460ff16156120e157600080fd5b600081815260016020526040902054600160a060020a0316331461210457600080fd5b6114d58160006129f1565b6000600160a060020a038316151561212657600080fd5b600160a060020a038216151561213b57600080fd5b50600160a060020a03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6000818152600160208181526040808420601390925283209181015491839182918291908286111561219e57600019909501945b8154600192830154825493830154600290930154600160a060020a039092169a9099509297509095509350915050565b6121d98585846122e6565b61146685858585612b12565b60006121ef6130bf565b600160a060020a038516151561220457600080fd5b600160005260156020527f27739e4bb5e6f8b5e4b57a047dca8767cc9b982a011081e086cbb0dfa9de818d5461c3501161223d57600080fd5b5050600080546040805160608101825285815260208082018681528284018681528587526013835284872084518155915160018084019190915590516002909201919091558786526015909152919093208054909101905590610100820615156122d4576014805460018101825560009182527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec01555b6122de8583612e2c565b509392505050565b600080806060600160a060020a038716151561230157600080fd5b600160a060020a038616151561231657600080fd5b600085815260016020526040902054600160a060020a0388811691161461233c57600080fd5b600085815260016020819052604090912001541561235957600080fd5b600160a060020a0380881660008181526004602090815260408083208a84529091529020549091169450331461245d575060408051306024820152604480820187905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825183918a5afa915081156123f657805192505b600182151514156124185760e060020a830463cd740db5141561241857600080fd5b600160a060020a038716600090815260076020908152604080832033845290915290205460ff16806124525750600160a060020a03841633145b151561245d57600080fd5b600160a060020a03841615611b9b57600160a060020a03871660008181526004602090815260408083208984529091528082208054600160a060020a0319169055518792907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a450505050505050565b600160a060020a038316600090815260026020526040812054819081906124fe90600163ffffffff612af416565b600160a060020a03871660009081526002602052604090208054919450908490811061252657fe5b9060005260206000200154915083821415156125935750600083815260036020908152604080832054600160a060020a0389168452600290925290912080548391908390811061257257fe5b60009182526020808320909101929092558381526003909152604090208190555b600160a060020a03861660009081526002602052604090208054906125bc9060001983016130e1565b5060008481526001602081815260408084208054600160a060020a031916600160a060020a038b8116918217909255808652600280855283872080548c895260038752858920819055918652958101865594865292852090930188905551879391928a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050505050565b60008061265885612ef2565b15156126675760019150611629565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b838110156126fa5781810151838201526020016126e2565b50505050905090810190601f1680156127275780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561274957600080fd5b505af115801561275d573d6000803e3d6000fd5b505050506040513d602081101561277357600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f150b7a0200000000000000000000000000000000000000000000000000000000149695505050505050565b600081815260016020526040812054600160a060020a031690808215156127e657600080fd5b600084815260016020819052604082200154925082111561280d5750600019016001612811565b5060005b9193909250565b60008080600160a060020a038716151561283157600080fd5b600160a060020a038516151561284657600080fd5b600084815260016020526040902054600160a060020a0388811691161461286c57600080fd5b60008481526001602081905260409091200154925082151561288d57600080fd5b6000198301861461289d57600080fd5b6128a68461101e565b600160a060020a0380821660008181526004602090815260408083208a8452909152902054929450911691503314806129025750600160a060020a038216600090815260076020908152604080832033845290915290205460ff165b806129155750600160a060020a03811633145b151561292057600080fd5b600160a060020a0381161561298b57600160a060020a03821660008181526004602090815260408083208884529091528082208054600160a060020a0319169055518692907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a45b6000848152600160208190526040822001556129a8878786612efa565b6040805185815290518791600160a060020a038a16917f3c619d5b30fb8431c0c0094f4485f1859d63f222f36cc2104cc13e56c2b993d39181900360200190a350505050505050565b6000828152601360205260408120600201829055811115612a6e57610100820660020a6014612a288461010063ffffffff612fdb16565b81548110612a3257fe5b600091825260209091200154176014612a538461010063ffffffff612fdb16565b81548110612a5d57fe5b600091825260209091200155611b06565b610100820660020a196014612a8b8461010063ffffffff612fdb16565b81548110612a9557fe5b600091825260209091200154166014612ab68461010063ffffffff612fdb16565b81548110612ac057fe5b6000918252602090912001555050565b60006114fc6064612ae884600363ffffffff612ffe16565b9063ffffffff612fdb16565b60008083831115612b0457600080fd5b5050808203805b5092915050565b6000612b2583600163ffffffff61303316565b6000838152600160208181526040808420830194909455600160a060020a03881683526005815283832087845281528383208054928301815583528083208201869055858352600690529190208190559050612b828585846124d0565b6000600160a060020a031684600160a060020a0316636352211e856040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b158015612bd657600080fd5b505af1158015612bea573d6000803e3d6000fd5b505050506040513d6020811015612c0057600080fd5b5051600160a060020a03161415612c1657600080fd5b6040805183815290518491600160a060020a038716917fda19c10bf4b88776cd85f9091592a44edff2d94035ec670ebd9e8356f56f887d9181900360200190a35050505050565b60408051606480825260a0820190925260609190829060009081908390819083908760208201610c8080388339019050509550600094505b8815612cf8578551600a808b049a6001880197919006955060f860020a6030870102918891908110612cc357fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612c95565b899250848351016040519080825280601f01601f191660200182016040528015612d2c578160200160208202803883390190505b509150600090505b8251811015612da4578281815181101515612d4b57fe5b90602001015160f860020a900460f860020a028282815181101515612d6c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101612d34565b5060005b84811015612e1f5785816001870303815181101515612dc357fe5b90602001015160f860020a900460f860020a028284518301815181101515612de757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101612da8565b5098975050505050505050565b600160a060020a0382161515612e4157600080fd5b600081815260016020526040902054600160a060020a031615612e6357600080fd5b60008181526001602081815260408084208054600160a060020a031916600160a060020a0388169081179091558085526002808452828620805488885260038652848820819055918552818601815586529285209092018590558354909201835590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000903b1190565b600160a060020a03831660009081526005602090815260408083208584529091528120805460001981019291829184908110612f3257fe5b906000526020600020015491508184141515612fa75750600083815260066020908152604080832054600160a060020a038916845260058352818420888552909252909120805483919083908110612f8657fe5b60009182526020808320909101929092558381526006909152604090208190555b600160a060020a03861660009081526005602090815260408083208884529091529020805490611b9b9060001983016130e1565b600080808311612fea57600080fd5b8284811515612ff557fe5b04949350505050565b6000808315156130115760009150612b0b565b5082820282848281151561302157fe5b041461302c57600080fd5b9392505050565b60008282018381101561302c57600080fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106130865782800160ff198235161785556130b3565b828001600101855582156130b3579182015b828111156130b3578235825591602001919060010190613098565b50611415929150613101565b6060604051908101604052806000815260200160008152602001600081525090565b815481835581811115610f0c57600083815260209020610f0c9181019083015b610c8b91905b8082111561141557600081556001016131075600a165627a7a723058203bac0f675bcdf51c3197b6eda1a5774c29cb9df158ccff4398ebc9bf256d99900029

   Swarm Source:
bzzr://3bac0f675bcdf51c3197b6eda1a5774c29cb9df158ccff4398ebc9bf256d9990

 

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