Contract Overview
Balance: 0 Ether
Ether Value: $0
Transactions: 1508 txns
Token Tracker: CryptoRome-Land-NFT (CRLAND)
Misc:
Address Watch: Add To Watch List
Contract Creator: 0x199c5c53a4b654811a6e06084d516076eb504214at txn 0xb3a603a51f5a46eff473381c20bd8f0befa32ee17f4c5ec311c1d62303be885b
Token Balance:
 Latest 25 transactions from a total of 1508 transactions

TxHash Age From To Value [TxFee]
0x650d91d82a0ae1350085971866605d4f9230a0f4a7dd8a55f075283408ade2531 day 21 hrs ago0xc071a1945cff872d30e7f3bdfcd17eca8f46ea19  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0.1 Ether0.001394034
0x0480e12ee4adacd0687faf9e09422dc27390d8a28a295fda087b49da094ff31c2 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00031046
0xcd66ce65fe662bcdc1c458d16bcefd1057a136bc7f692d891847a2cafd7aaa2f2 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0xc9e6fd949c13b9338b8eefd283ad71f7added2175cf8ad1f4e3c1db02c8509df2 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0x44b661f5f75f2366cb9fa55431c7cafae4b795ce2066eefa1ed558decc7483af2 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00025526
0xa5142c901cdbbacc2e38bde8b6be26affbdd30030547b84e6840e8a3097dc9c42 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0xbfadd06109219d3932ca85f97dd8732b9613b981de6c23d5ce5fcb2a1e5b8b562 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0xa1025906f00282daaed36b7870bf485d8819e040481fb2588b80d98cad7be87c2 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0x9d592e2ccb314c382c1a32f16197f620f6ee8b841113c9b0dcbb0bb568ff06962 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0x758637ba7c18130857d2b9a7b03f290d291dd8a41684274fa9afa50b3f6964f52 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0x75712ef552949fc954a624ab06d7079a3c841119c7a59ba7bc77ad8f52753ca32 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0x8308c0646039d889762b0e4da3cb5127b8bedc4f82a6a7faec0524bcb79f0bba2 days 17 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00072904
0x577fb29a0f45cd3b3e8630dd6eb635dd15e8e80266103bc77c5615bfea85e0856 days 16 hrs ago0x361084af8d45e07885b31fcedcb642b9cc7b72d7  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0.0325 Ether0.000574014
0xb82da414763b0038f18dfe364fbe5fad8ff1395680050613cabc0640b6c36f037 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000251355
0xc3439936ac9e5c1e49dbcdab1daf3ab3bd4143533be7adcc3465e7b7eb032a957 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000251355
0x5bc479b0e1362d3c36803818e2f738c27101f8c6fe1312cbea1cbc2ef7dbe5dc7 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000251355
0x866e4f37f07c016fdbfea09016217f944f04645ff818cfc1ce016ce41e4dfacb7 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000251355
0x3e313a45e56b19cc7b2d665971fcc4b1923392142c7c4ecf556b91370788c94b7 days 13 hrs ago0xc78c5564333bfc50172904cdf484952e0576cfd9  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000069548
0xff4d3680b0bb9bff0098aacf26ecc36ca54c2acd508fafeb986a2a48c244a5377 days 13 hrs ago0xc78c5564333bfc50172904cdf484952e0576cfd9  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.0000983
0xeba1613c4705dc19e2e1e07cf7c199fc4557c0cf7ca454ebd7072472f8b4beb07 days 13 hrs ago0xc78c5564333bfc50172904cdf484952e0576cfd9  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00009887
0x2b02b418468196fdeca6f71cd31225fbb9d5148feb8a303b098667cd4852c2437 days 13 hrs ago0xc78c5564333bfc50172904cdf484952e0576cfd9  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00009887
0x7e37183d80db34c53ce2765b2f0e36a249582eccfe2d5bebed049917af8066b37 days 13 hrs ago0xc78c5564333bfc50172904cdf484952e0576cfd9  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000079096
0xbc4518798ad987a1d326352fd7d3b22d701f5a61f6b5e80a59dd537964d05f567 days 13 hrs ago0xc78c5564333bfc50172904cdf484952e0576cfd9  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000079096
0x12ddbe7ff0e5288d765869f6abdf337f34bab3464377ad60106ea3dab26dbd0a7 days 13 hrs ago0xc78c5564333bfc50172904cdf484952e0576cfd9  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000079096
0x6dd0e1e96a18ee2c2bad2e5f47f2276da8666eb86d64aa76c0f3ae356612efe57 days 22 hrs ago0xae391eb86b991b6f6985d71c2d3b0227907268ca  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0.05 Ether0.0007339179
[ 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
0x650d91d82a0ae1350085971866605d4f9230a0f4a7dd8a55f075283408ade25367077651 day 21 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x76fa5876ecef7cecfbe8f94566a1e7252c20bf390.097 Ether
0x650d91d82a0ae1350085971866605d4f9230a0f4a7dd8a55f075283408ade25367077651 day 21 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.003 Ether
0x577fb29a0f45cd3b3e8630dd6eb635dd15e8e80266103bc77c5615bfea85e08566782486 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.031525 Ether
0x577fb29a0f45cd3b3e8630dd6eb635dd15e8e80266103bc77c5615bfea85e08566782486 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.000975 Ether
0x6dd0e1e96a18ee2c2bad2e5f47f2276da8666eb86d64aa76c0f3ae356612efe566706357 days 22 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc78c5564333bfc50172904cdf484952e0576cfd90.0485 Ether
0x6dd0e1e96a18ee2c2bad2e5f47f2276da8666eb86d64aa76c0f3ae356612efe566706357 days 22 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.0015 Ether
0x47d2005e38eeef81ecc172457122ef2eab506694fca31e4cbf865a15aeaa3f8f66635039 days 3 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.033950000000000004 Ether
0x47d2005e38eeef81ecc172457122ef2eab506694fca31e4cbf865a15aeaa3f8f66635039 days 3 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00105 Ether
0x58ffa149c7934dd0c2a22b5cc8c790b0b7066e4aaabe9612a53a1eed0647bbac659705620 days 40 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.033950000000000004 Ether
0x58ffa149c7934dd0c2a22b5cc8c790b0b7066e4aaabe9612a53a1eed0647bbac659705620 days 40 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00105 Ether
0x1d7aac7303c565c3a797c7c668bde897546feccab808a41ab9ea1201549c24ee656523925 days 5 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xae391eb86b991b6f6985d71c2d3b0227907268ca0.019 Ether
0x96486d9c8481fd22ab193eabef8da1d827ecacd325d096311ecaffa2f971c44f656523225 days 5 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.01843 Ether
0x96486d9c8481fd22ab193eabef8da1d827ecacd325d096311ecaffa2f971c44f656523225 days 5 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00057 Ether
0xce86f3191ae717de696adeb5712b17d09bb52ad9381d04cbc9387f428cbba585652680631 days 12 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.05238 Ether
0xce86f3191ae717de696adeb5712b17d09bb52ad9381d04cbc9387f428cbba585652680631 days 12 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00162 Ether
0xa62a1918cbcfde5088084703ab59302803fc5b247bb06dddd8c6858d131c0f9e652647931 days 13 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.019 Ether
0x19670dad84840614a6d28dc41f966265362bd21e88ec123b6c3cbc73125ce348652614531 days 14 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.01843 Ether
0x19670dad84840614a6d28dc41f966265362bd21e88ec123b6c3cbc73125ce348652614531 days 14 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00057 Ether
0x5e2b57f938e250d7ba1a60a16a5e90197c08b38013736d05c0703bbf027f20ad652611031 days 14 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.02522 Ether
0x5e2b57f938e250d7ba1a60a16a5e90197c08b38013736d05c0703bbf027f20ad652611031 days 14 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00078 Ether
0x92f906ece0a5a5fd174d8020075ef1477220a6274c5564ae33841374e955252c652523331 days 18 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.01843 Ether
0x92f906ece0a5a5fd174d8020075ef1477220a6274c5564ae33841374e955252c652523331 days 18 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00057 Ether
0xf1ee91992a29d6d8e49115ac91f6cecbceccd297b25f8b1189910bd81a46f9b7651495833 days 10 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.02522 Ether
0xf1ee91992a29d6d8e49115ac91f6cecbceccd297b25f8b1189910bd81a46f9b7651495833 days 10 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00078 Ether
0x0af41e671d51d67b9ac81b1a60ab81f66d0ab6bf20e17d1fb8356a185643e3f5651495633 days 10 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.02328 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 GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.