Contract 0x86e4dc25259ee2191cd8ae40e1865b9f0319646c

 

TxHash Block Age From To Value [TxFee]
0x69453c6760da2169f4408fd2969736bf442ec73784670f1fe52850b069b2983472087175 days 12 hrs ago0x263b604509d6a825719859ee458b2d91fb7d330d  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000370696
0x2feb1b9d89fc9392d21b4399c7820630868186978597c4b229bc7a33db4d43fd690986760 days 20 hrs ago0x983961f34fc4cfc5eafec371cdba9d56ff8c1935  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000367242
0xee1af62077ddcecc28c60a77f5e8840c30ef0953d5072819a0fcd781ac0c6320688038265 days 18 hrs ago0x199c5c53a4b654811a6e06084d516076eb504214  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.0001088664
0x089509e04d1f6e3f152ff43c39308407eade2cc01546d4b547cbf0c6b439354a687432866 days 18 hrs ago0x199c5c53a4b654811a6e06084d516076eb504214  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000171952
0xaf4ee8867f30d48f7ad463a5bb19ab1200987e630c38b428a9a2569656348d8c687198767 days 3 hrs ago0x945730e15d90da2646b01315480cfede9c7157e1  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00031046
0x846fdf934683eec66e245a9377ef081a3fc3d4328e03d0133ff5681926493e83687198767 days 3 hrs ago0x945730e15d90da2646b01315480cfede9c7157e1  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00031046
0x954e49d118c97b531ca52c6434c3c2351af613627d39bcb598250e342f910e9c687198267 days 3 hrs ago0x945730e15d90da2646b01315480cfede9c7157e1  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xb9b1fcd640b5aa710128f88983b6abd2b83a162a5f5af70bfb75324b56625833687197867 days 3 hrs ago0x945730e15d90da2646b01315480cfede9c7157e1  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00031046
0x0fa93f05dd3013a8fa95364355e749a487a6df3a5afe348f0955a2e7e335ab2b687197567 days 3 hrs ago0x945730e15d90da2646b01315480cfede9c7157e1  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.00036452
0xb11ba857f846ed055fd7e1c531a00646792abda872f56604a28fe114268d2f5f687180467 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000177966
0xeaf01b445b2b7a9186024879e5ff17a7531febc20ec095a4bd784fb6b9a783d0687180167 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000177966
0x1942f111c9b1f8b33ad9d446b55fba4897ab7e8beb5fd69099fba5179ea46773687179967 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000177966
0x582e16f6d2ce9e48112957f9e3be83f8c84d7a712b9de8a8cc9704e638d4ec36687179967 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000177966
0x019eacc65ea1b732ee9ead26c93d00d7f5be1bce646892da14e8a4b2ca3799db687179767 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000177966
0x47dd02dbc2b2a8af81c4b0f815a95c782c4b727f88d9e46c4dfb291272afe2dc687179467 days 3 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000177966
0x484f6f45da24d71cc290ad448e04d628ad15fcbf3842da6fa068b24c7bef7990687179367 days 4 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000177966
0x5446b246fa1ff1f9c2401cbeac141d921b951fbfe7117a44384c11afd00220ec686416568 days 10 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000200828
0x611f01e43ff9f4241d10a1b7ba0084689c91873bcf2d5e0ff3244f21c9414c95686415268 days 10 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000200828
0x3b3bba6fe1cc79a6cfc3841c6e3fe6f3d776cb4fccbc2bf0610fa26eea24ad05686415268 days 10 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000200838041
0x8546e26f84a1c18866ef7d4b8178b1532e3bde1560940060ea9842500bc31b46686414968 days 10 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000200838041
0xe9e627daa48aeb8786c3b027cec5fd5351bde2bea76fb41d3a0be0969ea43e46686414568 days 10 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000200838041
0xa35627d5ac6752f0bab8c80d6ea4a30cde21c7e372e458c6475ade55f33332d9686414268 days 10 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000200838041
0x5afecb3a706b53c527ca5f2179bd341092135a35656ff54e241804e61db69117686414068 days 10 hrs ago0xc14b26c277827abe952b2859e3b660096dc50bf4  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0 Ether0.000200838041
0x75244c6efb225d069df0421531e73fc9ff865a4151408599f0cf0b4296a0c28c685505969 days 22 hrs ago0x1f3e73c7822399c705e07fc6f6aae2933264c210  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0.1 Ether0.00041001
0x1c9507c0f8db655c77a1cd6d738b0a1533606bef9e3ca9bb2b83aba49f883bb6682648674 days 16 hrs ago0xae391eb86b991b6f6985d71c2d3b0227907268ca  IN   0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0.1 Ether0.000574014
[ Download CSV Export 

Latest 25 Internal Transaction, Click here to view more Internal Transactions as a result of Contract Execution

Parent TxHash Block Age From To Value
0x75244c6efb225d069df0421531e73fc9ff865a4151408599f0cf0b4296a0c28c685505969 days 22 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x2e6236591bfa37c683ce60d6cfde40396a114ff10.097 Ether
0x75244c6efb225d069df0421531e73fc9ff865a4151408599f0cf0b4296a0c28c685505969 days 22 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.003 Ether
0x1c9507c0f8db655c77a1cd6d738b0a1533606bef9e3ca9bb2b83aba49f883bb6682648674 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x2e6236591bfa37c683ce60d6cfde40396a114ff10.097 Ether
0x1c9507c0f8db655c77a1cd6d738b0a1533606bef9e3ca9bb2b83aba49f883bb6682648674 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.003 Ether
0xf95bb088c65c83b52db7fd08399b334d857c3787ca3d2bace4562633272559ab682216775 days 9 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x2e6236591bfa37c683ce60d6cfde40396a114ff10.097 Ether
0xf95bb088c65c83b52db7fd08399b334d857c3787ca3d2bace4562633272559ab682216775 days 9 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.003 Ether
0x16853a19f35d6fd8337e97071d89b77d84a064d80cb7abc701e0788847d9155b682216775 days 9 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x2e6236591bfa37c683ce60d6cfde40396a114ff10.097 Ether
0x16853a19f35d6fd8337e97071d89b77d84a064d80cb7abc701e0788847d9155b682216775 days 9 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.003 Ether
0x03f25ee42370ddcf46e9723d7dd82bc9a880f11e6066300f20d7c8996f5f502b682215775 days 9 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x2e6236591bfa37c683ce60d6cfde40396a114ff10.194 Ether
0x03f25ee42370ddcf46e9723d7dd82bc9a880f11e6066300f20d7c8996f5f502b682215775 days 9 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.006 Ether
0xf931336a1c74215bed3d2a0028e29a3f35bbca802f5e461b72fc39b94d1f4ba5681416176 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xb04b473418b6f09e5a1f809ae2d01f14211e03ff0.21825 Ether
0xf931336a1c74215bed3d2a0028e29a3f35bbca802f5e461b72fc39b94d1f4ba5681416176 days 16 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00675 Ether
0x67a4fc68ab4cf63ae0d9d5390712fd56383512354129fe3a3fa44512e94bfe9d681209577 days 58 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x504af27f1cef15772370b7c04b5d9d593ee729f50.291 Ether
0x67a4fc68ab4cf63ae0d9d5390712fd56383512354129fe3a3fa44512e94bfe9d681209577 days 58 mins ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.009 Ether
0x4beb9d448eedccceacc274db8120f9dfc130f36c031de1d9a8f725d1fa732bfe681175077 days 2 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x504af27f1cef15772370b7c04b5d9d593ee729f50.291 Ether
0x4beb9d448eedccceacc274db8120f9dfc130f36c031de1d9a8f725d1fa732bfe681175077 days 2 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.009 Ether
0x2dad729995304ff4028d7f1776b9918ada02674b373fab5255e454126f9c2967678451581 days 14 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.0325 Ether
0x2541ecf6acc414bf1f06b77ad9ed6dc67affd12c823a21fe544d2c6d16d6bc20678451581 days 14 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0xc14b26c277827abe952b2859e3b660096dc50bf40.031525 Ether
0x2541ecf6acc414bf1f06b77ad9ed6dc67affd12c823a21fe544d2c6d16d6bc20678451581 days 14 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.000975 Ether
0x867bf84ae621a49b28449a5cf7b46cbf3586bfcd791bf3e846a814ca21878421678065782 days 5 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.033950000000000004 Ether
0x867bf84ae621a49b28449a5cf7b46cbf3586bfcd791bf3e846a814ca21878421678065782 days 5 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00105 Ether
0x0efefb355aedc5b5cbfdfe6ea52960b0e65e06eb6027b4a26b69b3a84348d103678065582 days 5 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x0a19b2ac2da8b86de5d34fcdc98f029c28b1becb0.033950000000000004 Ether
0x0efefb355aedc5b5cbfdfe6ea52960b0e65e06eb6027b4a26b69b3a84348d103678065582 days 5 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.00105 Ether
0x650d91d82a0ae1350085971866605d4f9230a0f4a7dd8a55f075283408ade253670776594 days 4 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x76fa5876ecef7cecfbe8f94566a1e7252c20bf390.097 Ether
0x650d91d82a0ae1350085971866605d4f9230a0f4a7dd8a55f075283408ade253670776594 days 4 hrs ago0x86e4dc25259ee2191cd8ae40e1865b9f0319646c0x9012c8b9fccd553ae3fbdc25719af965669dad870.003 Ether
[ Download CSV Export 
Warning: The compiled contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) Solidity Compiler Bugs.

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


Contract Source Code
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
60806040526011805460a060020a60ff02191690553480156200002157600080fd5b50600b60209081527f6fc4fe54b7713e8c3beb98c1633f1a7c51390dad7f13255e19999c5edaf38b65805460ff1990811660019081179092557f58dbcb8b42477ba587235ed21c9227789266bd956417ae5420ec8c31552e276280548216831790557f392a5f45591c4d9c05a109aeb535f975c0e2d81925e3ac029c52e6ec2139a20b80548216831790557f9ea35b7873c8b046fb963897c29b313fe2a41ca6b497dee659b16c91e3b8a50280548216831790557fff2ba62c5c6f4e0b72ee7054c587fbb2ff1ec14aa579cbc64a86f76ec6cb296e80548216831790557f8318b539000000000000000000000000000000000000000000000000000000006000527f9e33802b94a5b5ebfeaa1630ee645e08a3449bd86e190a9ecd7ced7baf89913280549091169091179055600c8054600160a060020a031990811633908117909255600d8054821683179055600e8054821683179055600f805490911690911790556011805460a060020a60ff021916740100000000000000000000000000000000000000001790556040805180820190915260138082527f43727970746f526f6d652d4c616e642d4e46540000000000000000000000000091909201908152620001f191600891906200023f565b506040805180820190915260068082527f43524c414e440000000000000000000000000000000000000000000000000000602090920191825262000238916009916200023f565b50620002e4565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200028257805160ff1916838001178555620002b2565b82800160010185558215620002b2579182015b82811115620002b257825182559160200191906001019062000295565b50620002c0929150620002c4565b5090565b620002e191905b80821115620002c05760008155600101620002cb565b90565b61314780620002f46000396000f30060806040526004361061028f5763ffffffff60e060020a60003504166301ffc9a78114610294578063051847d5146102df57806306fdde0314610318578063081812fc146103a2578063095ea7b3146103d65780630b1ad18d146103fc57806318160ddd1461041d5780631e1e3c5b14610432578063216a55431461045957806323b872dd146104be5780632f745c59146104e857806337efa3971461050c5780633f4ba83a1461052157806342842e0e1461053657806343a61a8e1461056057806343bad081146105785780634f558e79146105995780634f6ccce7146105b15780635c975abb146105c95780635e3e2687146105de5780635fd8c710146106575780636352211e1461066c5780636af04a57146106845780636eccc6a31461069957806370a08231146106d057806371587988146106f15780637fcdcb9a146107125780638009d5d7146107335780638456cb591461073e5780638462151c146107535780638600f2ec1461077457806389885a591461079857806390b62297146107d05780639335dcb7146107e857806395910d46146107fd57806395d89b4114610812578063a22cb46514610827578063ae9409031461084d578063b5f4968c14610868578063b88d4fde14610880578063bd2f37ba146108b9578063c0a899f2146108d1578063c87b56dd14610911578063cfef941b14610929578063d00155001461094a578063d16d9f411461095f578063d1ce65ab14610980578063d52e7f9314610995578063d621c878146109b6578063d8bbe8cf146109cb578063dbd1a08e146109f2578063e0df5b6f14610a13578063e11304f914610a33578063e87596c014610a4e578063e985e9c514610a66578063f02dd53f14610a8d578063f50acfa014610ada575b600080fd5b3480156102a057600080fd5b506102cb7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610b51565b604080519115158252519081900360200190f35b3480156102eb57600080fd5b50610306600160a060020a0360043516602435604435610b85565b60408051918252519081900360200190f35b34801561032457600080fd5b5061032d610bf7565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036757818101518382015260200161034f565b50505050905090810190601f1680156103945780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103ae57600080fd5b506103ba600435610c8e565b60408051600160a060020a039092168252519081900360200190f35b3480156103e257600080fd5b506103fa600160a060020a0360043516602435610cca565b005b34801561040857600080fd5b506103fa600160a060020a0360043516610da6565b34801561042957600080fd5b50610306610e0b565b34801561043e57600080fd5b50610306600160a060020a0360043516602435604435610e11565b34801561046557600080fd5b5061046e610e89565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104aa578181015183820152602001610492565b505050509050019250505060405180910390f35b3480156104ca57600080fd5b506103fa600160a060020a0360043581169060243516604435610ee0565b3480156104f457600080fd5b50610306600160a060020a0360043516602435610f11565b34801561051857600080fd5b506103ba610f6c565b34801561052d57600080fd5b506103fa610f7b565b34801561054257600080fd5b506103fa600160a060020a0360043581169060243516604435610fe1565b34801561056c57600080fd5b5061030660043561101e565b34801561058457600080fd5b506103fa600160a060020a0360043516611360565b3480156105a557600080fd5b506102cb6004356113ff565b3480156105bd57600080fd5b50610306600435611406565b3480156105d557600080fd5b506102cb611419565b3480156105ea57600080fd5b50604080516020601f6084356004818101359283018490048402850184019095528184526103fa94600160a060020a0381358116956024803596604435909316956064359536959460a4949391909101919081908401838280828437509497506114299650505050505050565b34801561066357600080fd5b506103fa61146d565b34801561067857600080fd5b506103ba6004356114d8565b34801561069057600080fd5b506103ba611502565b3480156106a557600080fd5b506106ba600160a060020a0360043516611511565b6040805160ff9092168252519081900360200190f35b3480156106dc57600080fd5b50610306600160a060020a0360043516611526565b3480156106fd57600080fd5b506103fa600160a060020a0360043516611559565b34801561071e57600080fd5b506103066004356024356044356064356115f0565b6103fa600435611632565b34801561074a57600080fd5b506103fa61177e565b34801561075f57600080fd5b5061046e600160a060020a03600435166117e9565b34801561078057600080fd5b50610306600160a060020a0360043516602435611855565b3480156107a457600080fd5b506107b060043561187d565b604080519384526020840192909252151582820152519081900360600190f35b3480156107dc57600080fd5b506103fa600435611908565b3480156107f457600080fd5b506103ba611996565b34801561080957600080fd5b506103ba6119a5565b34801561081e57600080fd5b5061032d6119b4565b34801561083357600080fd5b506103fa600160a060020a03600435166024351515611a15565b34801561085957600080fd5b506103fa600435602435611a98565b34801561087457600080fd5b50610306600435611b0a565b34801561088c57600080fd5b506103fa600160a060020a0360048035821691602480359091169160443591606435908101910135611b1c565b3480156108c557600080fd5b50610306600435611b6e565b3480156108dd57600080fd5b506103fa60048035600160a060020a039081169160248035926044351691606435916084359160a435918201910135611b83565b34801561091d57600080fd5b5061032d600435611ba4565b34801561093557600080fd5b50610306600435602435604435606435611c52565b34801561095657600080fd5b506103ba611deb565b34801561096b57600080fd5b506103fa600160a060020a0360043516611dfa565b34801561098c57600080fd5b506102cb611e5f565b3480156109a157600080fd5b506103fa600160a060020a0360043516611e64565b3480156109c257600080fd5b506103ba611f03565b3480156109d757600080fd5b506103fa600160a060020a036004351660ff60243516611f12565b3480156109fe57600080fd5b506103fa600160a060020a0360043516611f82565b348015610a1f57600080fd5b506103fa6004803560248101910135612021565b348015610a3f57600080fd5b506103fa600435602435612078565b348015610a5a57600080fd5b506103fa6004356120ca565b348015610a7257600080fd5b506102cb600160a060020a036004358116906024351661210f565b348015610a9957600080fd5b50610aa560043561216a565b60408051600160a060020a03909616865260208601949094528484019290925260608401526080830152519081900360a00190f35b348015610ae657600080fd5b50604080516020601f6084356004818101359283018490048402850184019095528184526103fa94600160a060020a0381358116956024803590921695604435956064359536959460a494939101919081908401838280828437509497506121ce9650505050505050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000908152600b602052604090205460ff1690565b600160a060020a03831660009081526005602090815260408083208584529091528120548210610bb457600080fd5b600160a060020a03841660009081526005602090815260408083208684529091529020805483908110610be357fe5b906000526020600020015490509392505050565b60088054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c835780601f10610c5857610100808354040283529160200191610c83565b820191906000526020600020905b815481529060010190602001808311610c6657829003601f168201915b505050505090505b90565b600080610c9a8361101e565b600160a060020a038082166000908152600460209081526040808320888452909152902054169250905050919050565b600081815260016020526040812054600160a060020a031690811515610cef57600080fd5b610cf88361101e565b9050600160a060020a038116331480610d345750600160a060020a038116600090815260076020908152604080832033845290915290205460ff165b1515610d3f57600080fd5b600160a060020a0381811660008181526004602090815260408083208884529091528082208054600160a060020a031916948916948517905551869392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b600c54600160a060020a0316331480610dc95750600d54600160a060020a031633145b1515610dd457600080fd5b600160a060020a0381161515610de957600080fd5b600f8054600160a060020a031916600160a060020a0392909216919091179055565b60005490565b600c54600090600160a060020a0316331480610e375750600d54600160a060020a031633145b80610e5457503360009081526010602052604090205460ff166001145b1515610e5f57600080fd5b60115460a060020a900460ff1615610e7657600080fd5b610e818484846121e5565b949350505050565b60606014805480602002602001604051908101604052809291908181526020018280548015610c8357602002820191906000526020600020905b815481526020019060010190808311610ec3575050505050905090565b600160a060020a038216301415610ef657600080fd5b610f018383836122e6565b610f0c8383836124d0565b505050565b600160a060020a0382166000908152600260205260408120548210610f3557600080fd5b600160a060020a0383166000908152600260205260409020805483908110610f5957fe5b9060005260206000200154905092915050565b600f54600160a060020a031681565b600c54600160a060020a0316331480610f9e5750600d54600160a060020a031633145b1515610fa957600080fd5b60115460a060020a900460ff161515610fc157600080fd5b6011805474ff000000000000000000000000000000000000000019169055565b610fec8383836122e6565b610ff78383836124d0565b611013838383602060405190810160405280600081525061264c565b1515610f0c57600080fd5b600081815260016020526040812054600160a060020a031681806060818085151561104857600080fd5b600088815260016020819052604082200154955085119350831561106e57600019909401935b600160a060020a0386163014156110e4575b8315156110ba577fcd740db500000000000000000000000000000000000000000000000000000000600160a060020a038716179650611355565b6110c3856127c0565b91975095509350600160a060020a0386163014156110e057611080565b8497505b8315156111b4576040805130602482015260448082018b905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561115c57825196505b6001821515148015611177575060e060020a870463cd740db5145b1561118157611355565b7fcd740db500000000000000000000000000000000000000000000000000000000600160a060020a038716179650611355565b60408051602480820188905282518083039091018152604490910190915260208181018051600160e060020a03167f43a61a8e00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561121f57825196505b600182151514801561123a575060e060020a870463cd740db5145b1561124457611355565b5060408051602480820187905282518083039091018152604490910190915260208181018051600160e060020a03167f6352211e00000000000000000000000000000000000000000000000000000000178152825192945087928591845afa915081156112b057825195505b8115156112bc57600080fd5b60408051600160a060020a0383166024820152604480820188905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561115c57825196506001821515148015611177575060e060020a870463cd740db51415611181575b505050505050919050565b600c54600160a060020a03163314806113835750600d54600160a060020a031633145b151561138e57600080fd5b600160a060020a03811615156113a357600080fd5b600c54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c8054600160a060020a031916600160a060020a0392909216919091179055565b6000541190565b60008054821061141557600080fd5b5090565b60115460a060020a900460ff1681565b61143585858585612818565b60008281526006602052604081205561144f8584846124d0565b61145b8584848461264c565b151561146657600080fd5b5050505050565b600c54600160a060020a03163314806114905750600d54600160a060020a031633145b151561149b57600080fd5b600e54604051600160a060020a0390911690303180156108fc02916000818181858888f193505050501580156114d5573d6000803e3d6000fd5b50565b600081815260016020526040812054600160a060020a03168015156114fc57600080fd5b92915050565b601254600160a060020a031681565b60106020526000908152604090205460ff1681565b6000600160a060020a038216151561153d57600080fd5b50600160a060020a031660009081526002602052604090205490565b600c54600160a060020a031633148061157c5750600d54600160a060020a031633145b151561158757600080fd5b600160a060020a038116151561159c57600080fd5b60128054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b601154600090819060a060020a900460ff161561160c57600080fd5b611618338760006121e5565b905061162681868686611c52565b91505b50949350505050565b60115460009081908190819060a060020a900460ff161561165257600080fd5b60008581526013602052604090206002015493503484111561167357600080fd5b61167e8560006129f1565b61168784612ad0565b9250611699348463ffffffff612af416565b600f54604051919350600160a060020a03169084156108fc029085906000818181858888f193505050501580156116d4573d6000803e3d6000fd5b506116e5348563ffffffff612af416565b604051909150339082156108fc029083906000818181858888f19350505050158015611715573d6000803e3d6000fd5b50600085815260016020526040808220549051600160a060020a039091169184156108fc02918591818181858888f1935050505015801561175a573d6000803e3d6000fd5b5060008581526001602052604090205461146690600160a060020a031633876124d0565b600c54600160a060020a03163314806117a15750600d54600160a060020a031633145b15156117ac57600080fd5b60115460a060020a900460ff16156117c357600080fd5b6011805474ff0000000000000000000000000000000000000000191660a060020a179055565b600160a060020a03811660009081526002602090815260409182902080548351818402810184019094528084526060939283018282801561184957602002820191906000526020600020905b815481526020019060010190808311611835575b50505050509050919050565b600160a060020a03919091166000908152600560209081526040808320938352929052205490565b60008181526001602052604081205481908190600160a060020a03168015156118a557600080fd5b60008581526001602081905260408220015493508311156118d05760001990920191600191506118d5565b600091505b600160a060020a03167fcd740db50000000000000000000000000000000000000000000000000000000017949193509150565b6011546000908190819060a060020a900460ff161561192657600080fd5b6119303085611855565b92506000831161193f57600080fd5b8291505b60008211156119855761195a308560018503610b85565b9050611979308533846020604051908101604052806000815250611429565b60001990910190611943565b6119903330866124d0565b50505050565b600e54600160a060020a031681565b600c54600160a060020a031681565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c835780601f10610c5857610100808354040283529160200191610c83565b600160a060020a0382161515611a2a57600080fd5b336000818152600760209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b60115460a060020a900460ff1615611aaf57600080fd5b600082815260016020526040902054600160a060020a03163314611ad257600080fd5b6000828152600160208190526040909120015415611aef57600080fd5b60008111611afc57600080fd5b611b0682826129f1565b5050565b60009081526015602052604090205490565b611b278585856122e6565b611b328585856124d0565b61145b85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375061264c945050505050565b60009081526013602052604090206001015490565b611b8f87878786612818565b611b9b87868686612b12565b50505050505050565b6060611baf826113ff565b1515611bba57600080fd5b600a8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526114fc9390929091830182828015611c475780601f10611c1c57610100808354040283529160200191611c47565b820191906000526020600020905b815481529060010190602001808311611c2a57829003601f168201915b505050505083612c5d565b601154600090819060a060020a900460ff1615611c6e57600080fd5b60008681526013602052604090205460021480611c9957506000868152601360205260409020546003145b1515611ca457600080fd5b600086815260136020526040902054611cc490600163ffffffff612af416565b60008681526013602052604090205490915081148015611cf1575060008481526013602052604090205481145b8015611d0a575060008381526013602052604090205481145b1515611d1557600080fd5b6000858152600160209081526040808320548151928301909152918152611d4b91600160a060020a0316903090899089906121ce565b6000848152600160209081526040808320548151928301909152918152611d8191600160a060020a0316903090899088906121ce565b6000838152600160209081526040808320548151928301909152918152611db791600160a060020a0316903090899087906121ce565b600086815260016020526040902054600160a060020a0316301415611de157611de13033886124d0565b5093949350505050565b600d54600160a060020a031681565b600c54600160a060020a0316331480611e1d5750600d54600160a060020a031633145b1515611e2857600080fd5b600160a060020a0381161515611e3d57600080fd5b600e8054600160a060020a031916600160a060020a0392909216919091179055565b600190565b600c54600160a060020a0316331480611e875750600d54600160a060020a031633145b1515611e9257600080fd5b600160a060020a0381161515611ea757600080fd5b600d54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600d8054600160a060020a031916600160a060020a0392909216919091179055565b601154600160a060020a031681565b600c54600160a060020a0316331480611f355750600d54600160a060020a031633145b1515611f4057600080fd5b600160a060020a0382161515611f5557600080fd5b600160a060020a03919091166000908152601060205260409020805460ff191660ff909216919091179055565b600c54600160a060020a0316331480611fa55750600d54600160a060020a031633145b1515611fb057600080fd5b600160a060020a0381161515611fc557600080fd5b601154604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360118054600160a060020a031916600160a060020a0392909216919091179055565b600c54600160a060020a03163314806120445750600d54600160a060020a031633145b8061206157503360009081526010602052604090205460ff166001145b151561206c57600080fd5b610f0c600a8383613045565b60115460a060020a900460ff161561208f57600080fd5b601154600160a060020a031633146120a657600080fd5b6000548211156120b557600080fd5b60009182526013602052604090912060010155565b60115460a060020a900460ff16156120e157600080fd5b600081815260016020526040902054600160a060020a0316331461210457600080fd5b6114d58160006129f1565b6000600160a060020a038316151561212657600080fd5b600160a060020a038216151561213b57600080fd5b50600160a060020a03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6000818152600160208181526040808420601390925283209181015491839182918291908286111561219e57600019909501945b8154600192830154825493830154600290930154600160a060020a039092169a9099509297509095509350915050565b6121d98585846122e6565b61146685858585612b12565b60006121ef6130bf565b600160a060020a038516151561220457600080fd5b600160005260156020527f27739e4bb5e6f8b5e4b57a047dca8767cc9b982a011081e086cbb0dfa9de818d5461c3501161223d57600080fd5b5050600080546040805160608101825285815260208082018681528284018681528587526013835284872084518155915160018084019190915590516002909201919091558786526015909152919093208054909101905590610100820615156122d4576014805460018101825560009182527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec01555b6122de8583612e2c565b509392505050565b600080806060600160a060020a038716151561230157600080fd5b600160a060020a038616151561231657600080fd5b600085815260016020526040902054600160a060020a0388811691161461233c57600080fd5b600085815260016020819052604090912001541561235957600080fd5b600160a060020a0380881660008181526004602090815260408083208a84529091529020549091169450331461245d575060408051306024820152604480820187905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825183918a5afa915081156123f657805192505b600182151514156124185760e060020a830463cd740db5141561241857600080fd5b600160a060020a038716600090815260076020908152604080832033845290915290205460ff16806124525750600160a060020a03841633145b151561245d57600080fd5b600160a060020a03841615611b9b57600160a060020a03871660008181526004602090815260408083208984529091528082208054600160a060020a0319169055518792907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a450505050505050565b600160a060020a038316600090815260026020526040812054819081906124fe90600163ffffffff612af416565b600160a060020a03871660009081526002602052604090208054919450908490811061252657fe5b9060005260206000200154915083821415156125935750600083815260036020908152604080832054600160a060020a0389168452600290925290912080548391908390811061257257fe5b60009182526020808320909101929092558381526003909152604090208190555b600160a060020a03861660009081526002602052604090208054906125bc9060001983016130e1565b5060008481526001602081815260408084208054600160a060020a031916600160a060020a038b8116918217909255808652600280855283872080548c895260038752858920819055918652958101865594865292852090930188905551879391928a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050505050565b60008061265885612ef2565b15156126675760019150611629565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b838110156126fa5781810151838201526020016126e2565b50505050905090810190601f1680156127275780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561274957600080fd5b505af115801561275d573d6000803e3d6000fd5b505050506040513d602081101561277357600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f150b7a0200000000000000000000000000000000000000000000000000000000149695505050505050565b600081815260016020526040812054600160a060020a031690808215156127e657600080fd5b600084815260016020819052604082200154925082111561280d5750600019016001612811565b5060005b9193909250565b60008080600160a060020a038716151561283157600080fd5b600160a060020a038516151561284657600080fd5b600084815260016020526040902054600160a060020a0388811691161461286c57600080fd5b60008481526001602081905260409091200154925082151561288d57600080fd5b6000198301861461289d57600080fd5b6128a68461101e565b600160a060020a0380821660008181526004602090815260408083208a8452909152902054929450911691503314806129025750600160a060020a038216600090815260076020908152604080832033845290915290205460ff165b806129155750600160a060020a03811633145b151561292057600080fd5b600160a060020a0381161561298b57600160a060020a03821660008181526004602090815260408083208884529091528082208054600160a060020a0319169055518692907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a45b6000848152600160208190526040822001556129a8878786612efa565b6040805185815290518791600160a060020a038a16917f3c619d5b30fb8431c0c0094f4485f1859d63f222f36cc2104cc13e56c2b993d39181900360200190a350505050505050565b6000828152601360205260408120600201829055811115612a6e57610100820660020a6014612a288461010063ffffffff612fdb16565b81548110612a3257fe5b600091825260209091200154176014612a538461010063ffffffff612fdb16565b81548110612a5d57fe5b600091825260209091200155611b06565b610100820660020a196014612a8b8461010063ffffffff612fdb16565b81548110612a9557fe5b600091825260209091200154166014612ab68461010063ffffffff612fdb16565b81548110612ac057fe5b6000918252602090912001555050565b60006114fc6064612ae884600363ffffffff612ffe16565b9063ffffffff612fdb16565b60008083831115612b0457600080fd5b5050808203805b5092915050565b6000612b2583600163ffffffff61303316565b6000838152600160208181526040808420830194909455600160a060020a03881683526005815283832087845281528383208054928301815583528083208201869055858352600690529190208190559050612b828585846124d0565b6000600160a060020a031684600160a060020a0316636352211e856040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b158015612bd657600080fd5b505af1158015612bea573d6000803e3d6000fd5b505050506040513d6020811015612c0057600080fd5b5051600160a060020a03161415612c1657600080fd5b6040805183815290518491600160a060020a038716917fda19c10bf4b88776cd85f9091592a44edff2d94035ec670ebd9e8356f56f887d9181900360200190a35050505050565b60408051606480825260a0820190925260609190829060009081908390819083908760208201610c8080388339019050509550600094505b8815612cf8578551600a808b049a6001880197919006955060f860020a6030870102918891908110612cc357fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612c95565b899250848351016040519080825280601f01601f191660200182016040528015612d2c578160200160208202803883390190505b509150600090505b8251811015612da4578281815181101515612d4b57fe5b90602001015160f860020a900460f860020a028282815181101515612d6c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101612d34565b5060005b84811015612e1f5785816001870303815181101515612dc357fe5b90602001015160f860020a900460f860020a028284518301815181101515612de757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101612da8565b5098975050505050505050565b600160a060020a0382161515612e4157600080fd5b600081815260016020526040902054600160a060020a031615612e6357600080fd5b60008181526001602081815260408084208054600160a060020a031916600160a060020a0388169081179091558085526002808452828620805488885260038652848820819055918552818601815586529285209092018590558354909201835590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000903b1190565b600160a060020a03831660009081526005602090815260408083208584529091528120805460001981019291829184908110612f3257fe5b906000526020600020015491508184141515612fa75750600083815260066020908152604080832054600160a060020a038916845260058352818420888552909252909120805483919083908110612f8657fe5b60009182526020808320909101929092558381526006909152604090208190555b600160a060020a03861660009081526005602090815260408083208884529091529020805490611b9b9060001983016130e1565b600080808311612fea57600080fd5b8284811515612ff557fe5b04949350505050565b6000808315156130115760009150612b0b565b5082820282848281151561302157fe5b041461302c57600080fd5b9392505050565b60008282018381101561302c57600080fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106130865782800160ff198235161785556130b3565b828001600101855582156130b3579182015b828111156130b3578235825591602001919060010190613098565b50611415929150613101565b6060604051908101604052806000815260200160008152602001600081525090565b815481835581811115610f0c57600083815260209020610f0c9181019083015b610c8b91905b8082111561141557600081556001016131075600a165627a7a723058203bac0f675bcdf51c3197b6eda1a5774c29cb9df158ccff4398ebc9bf256d99900029


   Swarm Source:
bzzr://3bac0f675bcdf51c3197b6eda1a5774c29cb9df158ccff4398ebc9bf256d9990
Block Age transaction Difficulty GasUsed Reward
Block Age Uncle Number Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.