More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 1,602 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Safe Transfer Fr... | 20619155 | 120 days ago | IN | 0 ETH | 0.00007526 | ||||
Set Approval For... | 20606403 | 121 days ago | IN | 0 ETH | 0.00004739 | ||||
Safe Transfer Fr... | 20110470 | 191 days ago | IN | 0 ETH | 0.00030461 | ||||
Set Approval For... | 19588037 | 264 days ago | IN | 0 ETH | 0.00084965 | ||||
Set Approval For... | 17473633 | 560 days ago | IN | 0 ETH | 0.00070279 | ||||
Set Approval For... | 17436051 | 565 days ago | IN | 0 ETH | 0.00140166 | ||||
Set Approval For... | 17347807 | 578 days ago | IN | 0 ETH | 0.00110663 | ||||
Set Approval For... | 16853569 | 648 days ago | IN | 0 ETH | 0.00066911 | ||||
Set Approval For... | 16853566 | 648 days ago | IN | 0 ETH | 0.00072751 | ||||
Set Approval For... | 16336250 | 720 days ago | IN | 0 ETH | 0.00109463 | ||||
Set Approval For... | 15791460 | 796 days ago | IN | 0 ETH | 0.00201559 | ||||
Transfer From | 15376362 | 858 days ago | IN | 0 ETH | 0.00040509 | ||||
Set Approval For... | 15245797 | 878 days ago | IN | 0 ETH | 0.00082151 | ||||
Set Approval For... | 15009593 | 916 days ago | IN | 0 ETH | 0.00208649 | ||||
Set Approval For... | 15008123 | 916 days ago | IN | 0 ETH | 0.0023328 | ||||
Set Approval For... | 14540210 | 992 days ago | IN | 0 ETH | 0.0024101 | ||||
Set Approval For... | 14499712 | 999 days ago | IN | 0 ETH | 0.00163929 | ||||
Set Approval For... | 14246948 | 1038 days ago | IN | 0 ETH | 0.00202964 | ||||
Set Approval For... | 14240361 | 1039 days ago | IN | 0 ETH | 0.0023032 | ||||
Set Approval For... | 14239464 | 1039 days ago | IN | 0 ETH | 0.00275545 | ||||
Set Approval For... | 14016243 | 1074 days ago | IN | 0 ETH | 0.00480116 | ||||
Set Approval For... | 13262541 | 1192 days ago | IN | 0 ETH | 0.00331794 | ||||
Set Approval For... | 13235898 | 1196 days ago | IN | 0 ETH | 0.00190526 | ||||
Set Approval For... | 13168216 | 1206 days ago | IN | 0 ETH | 0.00620096 | ||||
Set Approval For... | 13146348 | 1210 days ago | IN | 0 ETH | 0.00283221 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
6855059 | 2207 days ago | 0.097 ETH | ||||
6855059 | 2207 days ago | 0.003 ETH | ||||
6826486 | 2212 days ago | 0.097 ETH | ||||
6826486 | 2212 days ago | 0.003 ETH | ||||
6822167 | 2213 days ago | 0.097 ETH | ||||
6822167 | 2213 days ago | 0.003 ETH | ||||
6822167 | 2213 days ago | 0.097 ETH | ||||
6822167 | 2213 days ago | 0.003 ETH | ||||
6822157 | 2213 days ago | 0.194 ETH | ||||
6822157 | 2213 days ago | 0.006 ETH | ||||
6814161 | 2214 days ago | 0.21825 ETH | ||||
6814161 | 2214 days ago | 0.00675 ETH | ||||
6812095 | 2215 days ago | 0.291 ETH | ||||
6812095 | 2215 days ago | 0.009 ETH | ||||
6811750 | 2215 days ago | 0.291 ETH | ||||
6811750 | 2215 days ago | 0.009 ETH | ||||
6784515 | 2219 days ago | 0.0325 ETH | ||||
6784515 | 2219 days ago | 0.031525 ETH | ||||
6784515 | 2219 days ago | 0.000975 ETH | ||||
6780657 | 2220 days ago | 0.03395 ETH | ||||
6780657 | 2220 days ago | 0.00105 ETH | ||||
6780655 | 2220 days ago | 0.03395 ETH | ||||
6780655 | 2220 days ago | 0.00105 ETH | ||||
6707765 | 2232 days ago | 0.097 ETH | ||||
6707765 | 2232 days ago | 0.003 ETH |
Loading...
Loading
Contract Name:
CryptoRomeLandComposableNFT
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2018-09-04 */ 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 Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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
Deployed Bytecode
0x60806040526004361061028f5763ffffffff60e060020a60003504166301ffc9a78114610294578063051847d5146102df57806306fdde0314610318578063081812fc146103a2578063095ea7b3146103d65780630b1ad18d146103fc57806318160ddd1461041d5780631e1e3c5b14610432578063216a55431461045957806323b872dd146104be5780632f745c59146104e857806337efa3971461050c5780633f4ba83a1461052157806342842e0e1461053657806343a61a8e1461056057806343bad081146105785780634f558e79146105995780634f6ccce7146105b15780635c975abb146105c95780635e3e2687146105de5780635fd8c710146106575780636352211e1461066c5780636af04a57146106845780636eccc6a31461069957806370a08231146106d057806371587988146106f15780637fcdcb9a146107125780638009d5d7146107335780638456cb591461073e5780638462151c146107535780638600f2ec1461077457806389885a591461079857806390b62297146107d05780639335dcb7146107e857806395910d46146107fd57806395d89b4114610812578063a22cb46514610827578063ae9409031461084d578063b5f4968c14610868578063b88d4fde14610880578063bd2f37ba146108b9578063c0a899f2146108d1578063c87b56dd14610911578063cfef941b14610929578063d00155001461094a578063d16d9f411461095f578063d1ce65ab14610980578063d52e7f9314610995578063d621c878146109b6578063d8bbe8cf146109cb578063dbd1a08e146109f2578063e0df5b6f14610a13578063e11304f914610a33578063e87596c014610a4e578063e985e9c514610a66578063f02dd53f14610a8d578063f50acfa014610ada575b600080fd5b3480156102a057600080fd5b506102cb7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1960043516610b51565b604080519115158252519081900360200190f35b3480156102eb57600080fd5b50610306600160a060020a0360043516602435604435610b85565b60408051918252519081900360200190f35b34801561032457600080fd5b5061032d610bf7565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036757818101518382015260200161034f565b50505050905090810190601f1680156103945780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103ae57600080fd5b506103ba600435610c8e565b60408051600160a060020a039092168252519081900360200190f35b3480156103e257600080fd5b506103fa600160a060020a0360043516602435610cca565b005b34801561040857600080fd5b506103fa600160a060020a0360043516610da6565b34801561042957600080fd5b50610306610e0b565b34801561043e57600080fd5b50610306600160a060020a0360043516602435604435610e11565b34801561046557600080fd5b5061046e610e89565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104aa578181015183820152602001610492565b505050509050019250505060405180910390f35b3480156104ca57600080fd5b506103fa600160a060020a0360043581169060243516604435610ee0565b3480156104f457600080fd5b50610306600160a060020a0360043516602435610f11565b34801561051857600080fd5b506103ba610f6c565b34801561052d57600080fd5b506103fa610f7b565b34801561054257600080fd5b506103fa600160a060020a0360043581169060243516604435610fe1565b34801561056c57600080fd5b5061030660043561101e565b34801561058457600080fd5b506103fa600160a060020a0360043516611360565b3480156105a557600080fd5b506102cb6004356113ff565b3480156105bd57600080fd5b50610306600435611406565b3480156105d557600080fd5b506102cb611419565b3480156105ea57600080fd5b50604080516020601f6084356004818101359283018490048402850184019095528184526103fa94600160a060020a0381358116956024803596604435909316956064359536959460a4949391909101919081908401838280828437509497506114299650505050505050565b34801561066357600080fd5b506103fa61146d565b34801561067857600080fd5b506103ba6004356114d8565b34801561069057600080fd5b506103ba611502565b3480156106a557600080fd5b506106ba600160a060020a0360043516611511565b6040805160ff9092168252519081900360200190f35b3480156106dc57600080fd5b50610306600160a060020a0360043516611526565b3480156106fd57600080fd5b506103fa600160a060020a0360043516611559565b34801561071e57600080fd5b506103066004356024356044356064356115f0565b6103fa600435611632565b34801561074a57600080fd5b506103fa61177e565b34801561075f57600080fd5b5061046e600160a060020a03600435166117e9565b34801561078057600080fd5b50610306600160a060020a0360043516602435611855565b3480156107a457600080fd5b506107b060043561187d565b604080519384526020840192909252151582820152519081900360600190f35b3480156107dc57600080fd5b506103fa600435611908565b3480156107f457600080fd5b506103ba611996565b34801561080957600080fd5b506103ba6119a5565b34801561081e57600080fd5b5061032d6119b4565b34801561083357600080fd5b506103fa600160a060020a03600435166024351515611a15565b34801561085957600080fd5b506103fa600435602435611a98565b34801561087457600080fd5b50610306600435611b0a565b34801561088c57600080fd5b506103fa600160a060020a0360048035821691602480359091169160443591606435908101910135611b1c565b3480156108c557600080fd5b50610306600435611b6e565b3480156108dd57600080fd5b506103fa60048035600160a060020a039081169160248035926044351691606435916084359160a435918201910135611b83565b34801561091d57600080fd5b5061032d600435611ba4565b34801561093557600080fd5b50610306600435602435604435606435611c52565b34801561095657600080fd5b506103ba611deb565b34801561096b57600080fd5b506103fa600160a060020a0360043516611dfa565b34801561098c57600080fd5b506102cb611e5f565b3480156109a157600080fd5b506103fa600160a060020a0360043516611e64565b3480156109c257600080fd5b506103ba611f03565b3480156109d757600080fd5b506103fa600160a060020a036004351660ff60243516611f12565b3480156109fe57600080fd5b506103fa600160a060020a0360043516611f82565b348015610a1f57600080fd5b506103fa6004803560248101910135612021565b348015610a3f57600080fd5b506103fa600435602435612078565b348015610a5a57600080fd5b506103fa6004356120ca565b348015610a7257600080fd5b506102cb600160a060020a036004358116906024351661210f565b348015610a9957600080fd5b50610aa560043561216a565b60408051600160a060020a03909616865260208601949094528484019290925260608401526080830152519081900360a00190f35b348015610ae657600080fd5b50604080516020601f6084356004818101359283018490048402850184019095528184526103fa94600160a060020a0381358116956024803590921695604435956064359536959460a494939101919081908401838280828437509497506121ce9650505050505050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000908152600b602052604090205460ff1690565b600160a060020a03831660009081526005602090815260408083208584529091528120548210610bb457600080fd5b600160a060020a03841660009081526005602090815260408083208684529091529020805483908110610be357fe5b906000526020600020015490509392505050565b60088054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c835780601f10610c5857610100808354040283529160200191610c83565b820191906000526020600020905b815481529060010190602001808311610c6657829003601f168201915b505050505090505b90565b600080610c9a8361101e565b600160a060020a038082166000908152600460209081526040808320888452909152902054169250905050919050565b600081815260016020526040812054600160a060020a031690811515610cef57600080fd5b610cf88361101e565b9050600160a060020a038116331480610d345750600160a060020a038116600090815260076020908152604080832033845290915290205460ff165b1515610d3f57600080fd5b600160a060020a0381811660008181526004602090815260408083208884529091528082208054600160a060020a031916948916948517905551869392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b600c54600160a060020a0316331480610dc95750600d54600160a060020a031633145b1515610dd457600080fd5b600160a060020a0381161515610de957600080fd5b600f8054600160a060020a031916600160a060020a0392909216919091179055565b60005490565b600c54600090600160a060020a0316331480610e375750600d54600160a060020a031633145b80610e5457503360009081526010602052604090205460ff166001145b1515610e5f57600080fd5b60115460a060020a900460ff1615610e7657600080fd5b610e818484846121e5565b949350505050565b60606014805480602002602001604051908101604052809291908181526020018280548015610c8357602002820191906000526020600020905b815481526020019060010190808311610ec3575050505050905090565b600160a060020a038216301415610ef657600080fd5b610f018383836122e6565b610f0c8383836124d0565b505050565b600160a060020a0382166000908152600260205260408120548210610f3557600080fd5b600160a060020a0383166000908152600260205260409020805483908110610f5957fe5b9060005260206000200154905092915050565b600f54600160a060020a031681565b600c54600160a060020a0316331480610f9e5750600d54600160a060020a031633145b1515610fa957600080fd5b60115460a060020a900460ff161515610fc157600080fd5b6011805474ff000000000000000000000000000000000000000019169055565b610fec8383836122e6565b610ff78383836124d0565b611013838383602060405190810160405280600081525061264c565b1515610f0c57600080fd5b600081815260016020526040812054600160a060020a031681806060818085151561104857600080fd5b600088815260016020819052604082200154955085119350831561106e57600019909401935b600160a060020a0386163014156110e4575b8315156110ba577fcd740db500000000000000000000000000000000000000000000000000000000600160a060020a038716179650611355565b6110c3856127c0565b91975095509350600160a060020a0386163014156110e057611080565b8497505b8315156111b4576040805130602482015260448082018b905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561115c57825196505b6001821515148015611177575060e060020a870463cd740db5145b1561118157611355565b7fcd740db500000000000000000000000000000000000000000000000000000000600160a060020a038716179650611355565b60408051602480820188905282518083039091018152604490910190915260208181018051600160e060020a03167f43a61a8e00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561121f57825196505b600182151514801561123a575060e060020a870463cd740db5145b1561124457611355565b5060408051602480820187905282518083039091018152604490910190915260208181018051600160e060020a03167f6352211e00000000000000000000000000000000000000000000000000000000178152825192945087928591845afa915081156112b057825195505b8115156112bc57600080fd5b60408051600160a060020a0383166024820152604480820188905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825192955090918591895afa9150811561115c57825196506001821515148015611177575060e060020a870463cd740db51415611181575b505050505050919050565b600c54600160a060020a03163314806113835750600d54600160a060020a031633145b151561138e57600080fd5b600160a060020a03811615156113a357600080fd5b600c54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c8054600160a060020a031916600160a060020a0392909216919091179055565b6000541190565b60008054821061141557600080fd5b5090565b60115460a060020a900460ff1681565b61143585858585612818565b60008281526006602052604081205561144f8584846124d0565b61145b8584848461264c565b151561146657600080fd5b5050505050565b600c54600160a060020a03163314806114905750600d54600160a060020a031633145b151561149b57600080fd5b600e54604051600160a060020a0390911690303180156108fc02916000818181858888f193505050501580156114d5573d6000803e3d6000fd5b50565b600081815260016020526040812054600160a060020a03168015156114fc57600080fd5b92915050565b601254600160a060020a031681565b60106020526000908152604090205460ff1681565b6000600160a060020a038216151561153d57600080fd5b50600160a060020a031660009081526002602052604090205490565b600c54600160a060020a031633148061157c5750600d54600160a060020a031633145b151561158757600080fd5b600160a060020a038116151561159c57600080fd5b60128054600160a060020a038316600160a060020a0319909116811790915560408051918252517f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa4461993059181900360200190a150565b601154600090819060a060020a900460ff161561160c57600080fd5b611618338760006121e5565b905061162681868686611c52565b91505b50949350505050565b60115460009081908190819060a060020a900460ff161561165257600080fd5b60008581526013602052604090206002015493503484111561167357600080fd5b61167e8560006129f1565b61168784612ad0565b9250611699348463ffffffff612af416565b600f54604051919350600160a060020a03169084156108fc029085906000818181858888f193505050501580156116d4573d6000803e3d6000fd5b506116e5348563ffffffff612af416565b604051909150339082156108fc029083906000818181858888f19350505050158015611715573d6000803e3d6000fd5b50600085815260016020526040808220549051600160a060020a039091169184156108fc02918591818181858888f1935050505015801561175a573d6000803e3d6000fd5b5060008581526001602052604090205461146690600160a060020a031633876124d0565b600c54600160a060020a03163314806117a15750600d54600160a060020a031633145b15156117ac57600080fd5b60115460a060020a900460ff16156117c357600080fd5b6011805474ff0000000000000000000000000000000000000000191660a060020a179055565b600160a060020a03811660009081526002602090815260409182902080548351818402810184019094528084526060939283018282801561184957602002820191906000526020600020905b815481526020019060010190808311611835575b50505050509050919050565b600160a060020a03919091166000908152600560209081526040808320938352929052205490565b60008181526001602052604081205481908190600160a060020a03168015156118a557600080fd5b60008581526001602081905260408220015493508311156118d05760001990920191600191506118d5565b600091505b600160a060020a03167fcd740db50000000000000000000000000000000000000000000000000000000017949193509150565b6011546000908190819060a060020a900460ff161561192657600080fd5b6119303085611855565b92506000831161193f57600080fd5b8291505b60008211156119855761195a308560018503610b85565b9050611979308533846020604051908101604052806000815250611429565b60001990910190611943565b6119903330866124d0565b50505050565b600e54600160a060020a031681565b600c54600160a060020a031681565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c835780601f10610c5857610100808354040283529160200191610c83565b600160a060020a0382161515611a2a57600080fd5b336000818152600760209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b60115460a060020a900460ff1615611aaf57600080fd5b600082815260016020526040902054600160a060020a03163314611ad257600080fd5b6000828152600160208190526040909120015415611aef57600080fd5b60008111611afc57600080fd5b611b0682826129f1565b5050565b60009081526015602052604090205490565b611b278585856122e6565b611b328585856124d0565b61145b85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375061264c945050505050565b60009081526013602052604090206001015490565b611b8f87878786612818565b611b9b87868686612b12565b50505050505050565b6060611baf826113ff565b1515611bba57600080fd5b600a8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526114fc9390929091830182828015611c475780601f10611c1c57610100808354040283529160200191611c47565b820191906000526020600020905b815481529060010190602001808311611c2a57829003601f168201915b505050505083612c5d565b601154600090819060a060020a900460ff1615611c6e57600080fd5b60008681526013602052604090205460021480611c9957506000868152601360205260409020546003145b1515611ca457600080fd5b600086815260136020526040902054611cc490600163ffffffff612af416565b60008681526013602052604090205490915081148015611cf1575060008481526013602052604090205481145b8015611d0a575060008381526013602052604090205481145b1515611d1557600080fd5b6000858152600160209081526040808320548151928301909152918152611d4b91600160a060020a0316903090899089906121ce565b6000848152600160209081526040808320548151928301909152918152611d8191600160a060020a0316903090899088906121ce565b6000838152600160209081526040808320548151928301909152918152611db791600160a060020a0316903090899087906121ce565b600086815260016020526040902054600160a060020a0316301415611de157611de13033886124d0565b5093949350505050565b600d54600160a060020a031681565b600c54600160a060020a0316331480611e1d5750600d54600160a060020a031633145b1515611e2857600080fd5b600160a060020a0381161515611e3d57600080fd5b600e8054600160a060020a031916600160a060020a0392909216919091179055565b600190565b600c54600160a060020a0316331480611e875750600d54600160a060020a031633145b1515611e9257600080fd5b600160a060020a0381161515611ea757600080fd5b600d54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600d8054600160a060020a031916600160a060020a0392909216919091179055565b601154600160a060020a031681565b600c54600160a060020a0316331480611f355750600d54600160a060020a031633145b1515611f4057600080fd5b600160a060020a0382161515611f5557600080fd5b600160a060020a03919091166000908152601060205260409020805460ff191660ff909216919091179055565b600c54600160a060020a0316331480611fa55750600d54600160a060020a031633145b1515611fb057600080fd5b600160a060020a0381161515611fc557600080fd5b601154604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360118054600160a060020a031916600160a060020a0392909216919091179055565b600c54600160a060020a03163314806120445750600d54600160a060020a031633145b8061206157503360009081526010602052604090205460ff166001145b151561206c57600080fd5b610f0c600a8383613045565b60115460a060020a900460ff161561208f57600080fd5b601154600160a060020a031633146120a657600080fd5b6000548211156120b557600080fd5b60009182526013602052604090912060010155565b60115460a060020a900460ff16156120e157600080fd5b600081815260016020526040902054600160a060020a0316331461210457600080fd5b6114d58160006129f1565b6000600160a060020a038316151561212657600080fd5b600160a060020a038216151561213b57600080fd5b50600160a060020a03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6000818152600160208181526040808420601390925283209181015491839182918291908286111561219e57600019909501945b8154600192830154825493830154600290930154600160a060020a039092169a9099509297509095509350915050565b6121d98585846122e6565b61146685858585612b12565b60006121ef6130bf565b600160a060020a038516151561220457600080fd5b600160005260156020527f27739e4bb5e6f8b5e4b57a047dca8767cc9b982a011081e086cbb0dfa9de818d5461c3501161223d57600080fd5b5050600080546040805160608101825285815260208082018681528284018681528587526013835284872084518155915160018084019190915590516002909201919091558786526015909152919093208054909101905590610100820615156122d4576014805460018101825560009182527fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec01555b6122de8583612e2c565b509392505050565b600080806060600160a060020a038716151561230157600080fd5b600160a060020a038616151561231657600080fd5b600085815260016020526040902054600160a060020a0388811691161461233c57600080fd5b600085815260016020819052604090912001541561235957600080fd5b600160a060020a0380881660008181526004602090815260408083208a84529091529020549091169450331461245d575060408051306024820152604480820187905282518083039091018152606490910190915260208181018051600160e060020a03167fed81cdda00000000000000000000000000000000000000000000000000000000178152825183918a5afa915081156123f657805192505b600182151514156124185760e060020a830463cd740db5141561241857600080fd5b600160a060020a038716600090815260076020908152604080832033845290915290205460ff16806124525750600160a060020a03841633145b151561245d57600080fd5b600160a060020a03841615611b9b57600160a060020a03871660008181526004602090815260408083208984529091528082208054600160a060020a0319169055518792907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a450505050505050565b600160a060020a038316600090815260026020526040812054819081906124fe90600163ffffffff612af416565b600160a060020a03871660009081526002602052604090208054919450908490811061252657fe5b9060005260206000200154915083821415156125935750600083815260036020908152604080832054600160a060020a0389168452600290925290912080548391908390811061257257fe5b60009182526020808320909101929092558381526003909152604090208190555b600160a060020a03861660009081526002602052604090208054906125bc9060001983016130e1565b5060008481526001602081815260408084208054600160a060020a031916600160a060020a038b8116918217909255808652600280855283872080548c895260038752858920819055918652958101865594865292852090930188905551879391928a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050505050565b60008061265885612ef2565b15156126675760019150611629565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b838110156126fa5781810151838201526020016126e2565b50505050905090810190601f1680156127275780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561274957600080fd5b505af115801561275d573d6000803e3d6000fd5b505050506040513d602081101561277357600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f150b7a0200000000000000000000000000000000000000000000000000000000149695505050505050565b600081815260016020526040812054600160a060020a031690808215156127e657600080fd5b600084815260016020819052604082200154925082111561280d5750600019016001612811565b5060005b9193909250565b60008080600160a060020a038716151561283157600080fd5b600160a060020a038516151561284657600080fd5b600084815260016020526040902054600160a060020a0388811691161461286c57600080fd5b60008481526001602081905260409091200154925082151561288d57600080fd5b6000198301861461289d57600080fd5b6128a68461101e565b600160a060020a0380821660008181526004602090815260408083208a8452909152902054929450911691503314806129025750600160a060020a038216600090815260076020908152604080832033845290915290205460ff165b806129155750600160a060020a03811633145b151561292057600080fd5b600160a060020a0381161561298b57600160a060020a03821660008181526004602090815260408083208884529091528082208054600160a060020a0319169055518692907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925908390a45b6000848152600160208190526040822001556129a8878786612efa565b6040805185815290518791600160a060020a038a16917f3c619d5b30fb8431c0c0094f4485f1859d63f222f36cc2104cc13e56c2b993d39181900360200190a350505050505050565b6000828152601360205260408120600201829055811115612a6e57610100820660020a6014612a288461010063ffffffff612fdb16565b81548110612a3257fe5b600091825260209091200154176014612a538461010063ffffffff612fdb16565b81548110612a5d57fe5b600091825260209091200155611b06565b610100820660020a196014612a8b8461010063ffffffff612fdb16565b81548110612a9557fe5b600091825260209091200154166014612ab68461010063ffffffff612fdb16565b81548110612ac057fe5b6000918252602090912001555050565b60006114fc6064612ae884600363ffffffff612ffe16565b9063ffffffff612fdb16565b60008083831115612b0457600080fd5b5050808203805b5092915050565b6000612b2583600163ffffffff61303316565b6000838152600160208181526040808420830194909455600160a060020a03881683526005815283832087845281528383208054928301815583528083208201869055858352600690529190208190559050612b828585846124d0565b6000600160a060020a031684600160a060020a0316636352211e856040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b158015612bd657600080fd5b505af1158015612bea573d6000803e3d6000fd5b505050506040513d6020811015612c0057600080fd5b5051600160a060020a03161415612c1657600080fd5b6040805183815290518491600160a060020a038716917fda19c10bf4b88776cd85f9091592a44edff2d94035ec670ebd9e8356f56f887d9181900360200190a35050505050565b60408051606480825260a0820190925260609190829060009081908390819083908760208201610c8080388339019050509550600094505b8815612cf8578551600a808b049a6001880197919006955060f860020a6030870102918891908110612cc357fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612c95565b899250848351016040519080825280601f01601f191660200182016040528015612d2c578160200160208202803883390190505b509150600090505b8251811015612da4578281815181101515612d4b57fe5b90602001015160f860020a900460f860020a028282815181101515612d6c57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101612d34565b5060005b84811015612e1f5785816001870303815181101515612dc357fe5b90602001015160f860020a900460f860020a028284518301815181101515612de757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101612da8565b5098975050505050505050565b600160a060020a0382161515612e4157600080fd5b600081815260016020526040902054600160a060020a031615612e6357600080fd5b60008181526001602081815260408084208054600160a060020a031916600160a060020a0388169081179091558085526002808452828620805488885260038652848820819055918552818601815586529285209092018590558354909201835590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000903b1190565b600160a060020a03831660009081526005602090815260408083208584529091528120805460001981019291829184908110612f3257fe5b906000526020600020015491508184141515612fa75750600083815260066020908152604080832054600160a060020a038916845260058352818420888552909252909120805483919083908110612f8657fe5b60009182526020808320909101929092558381526006909152604090208190555b600160a060020a03861660009081526005602090815260408083208884529091529020805490611b9b9060001983016130e1565b600080808311612fea57600080fd5b8284811515612ff557fe5b04949350505050565b6000808315156130115760009150612b0b565b5082820282848281151561302157fe5b041461302c57600080fd5b9392505050565b60008282018381101561302c57600080fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106130865782800160ff198235161785556130b3565b828001600101855582156130b3579182015b828111156130b3578235825591602001919060010190613098565b50611415929150613101565b6060604051908101604052806000815260200160008152602001600081525090565b815481835581811115610f0c57600083815260209020610f0c9181019083015b610c8b91905b8082111561141557600081556001016131075600a165627a7a723058203bac0f675bcdf51c3197b6eda1a5774c29cb9df158ccff4398ebc9bf256d99900029
Swarm Source
bzzr://3bac0f675bcdf51c3197b6eda1a5774c29cb9df158ccff4398ebc9bf256d9990
Loading...
Loading
Loading...
Loading
OVERVIEW
A game of economic, political and military strategyMultichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.