18.16
($-1.65%)
| 1 Gwei
// SPDX-License-Identifier: GLWTPL pragma solidity ^0.8.11; contract tmwstw_buildings{ string private token_name = "TMWSTW BUILDINGS"; string private token_symbol = "BLDS"; address private contract_creator; string private base_uri = ""; address private bob_contract; uint nukewei = 10000000000000;//for rent price division //AT START constructor(){ contract_creator = msg.sender; burnable_by_router_types[8] = true; //walls rentable_b_types[0] = true; //small ground rentable_b_types[1] = true; //big ground rentable_b_types[2] = true; //residential rentable_b_types[3] = true; //mansion rentable_b_types[5] = true; //lvr } //MAPS mapping(uint => address) private token_ownership;// Mapping from token ID to owner address mapping(address => uint256) private balance_per_owner;// Mapping owner address to token count mapping(uint => address) private approval_per_token;// Mapping from token ID to approved address mapping(address => mapping(address => bool)) private operator_approvals;// Mapping from owner to operator approvals //TYPE MAPS mapping(uint8 => bool) private burnable_by_router_types; // all b_types that are burnable without ownership via router mapping(uint8 => bool) private rentable_b_types; //all b types that can be rented out mapping(uint8 => bool) private damageable_b_types; //all b types that can be damaged //....................................PROXY function register_bob(address this_bob)public CREATOR_ONLY{ bob_contract = this_bob; } //SEND BOB to core, send GAS to router, emit request event function build_proxy_request(address build_router, uint bob_amount)public payable{ require(all_build_routers[build_router],"Bad build router"); require(bob_amount>0,"Send more BOB"); require(msg.value>0,"Send more GAS"); bool sent; bytes memory response; (sent,response) = build_router.call{value: msg.value}(""); require(sent, "Failed to send GAS"); bob(bob_contract).transferFrom(msg.sender,bob_contract, bob_amount); emit build_request_event(msg.sender,build_router,bob_amount,msg.value); } event build_request_event(address from,address b_router,uint bob_amount,uint gas_amount); //....................................BUILD_ROUTERS mapping(address => bool) private all_build_routers; //fillup claim routers array function add_or_remove_build_routers(bool this_action, address[] calldata those_addresses) public CREATOR_ONLY{ require(those_addresses.length>0,"no input"); for(uint i = 0; i < those_addresses.length; i++){ all_build_routers[those_addresses[i]] = this_action; } } //...................................BUILD/BURN functions //BUILD DATA MAPS struct build_data{ uint8 b_type; //type of building uint16 plot_id; //plot_id bool buildable_on_top; bool is_ground; bool is_double_floor; bool is_base; uint8 top_unit_shell_rotation; //random rotation of residential units uint16 mesh_id; //mesh id representing token uint8 color_id; //1-5 unit base color id uint8 color_scheme_id; //unit color scheme id bool is_damaged; //true = damaged , false = repaired uint8 style_by_claster; //store style_id by cluster uint8 extra_cluster_randomizer_1; //store extra cluster rand 1-250 for future uint8 extra_cluster_randomizer_2; uint8 extra_cluster_randomizer_3; } struct build_position_data{ int32 quat_x; //2,000,000,000x quaternion int32 quat_y; //2,000,000,000x quaternion int32 quat_z; //2,000,000,000x quaternion int32 quat_w; //2,000,000,000x quaternion int32 pos_x; //100,000x position int32 pos_y; //100,000x position int32 pos_z; //100,000x position } mapping(uint => build_position_data) private p_data_per_build;// building data mapping(uint => build_data) private data_per_building;// building data //BUILD/MINT function build( address b_owner, uint this_token_id, uint16 plot_id, uint16 mesh_id, uint8[] calldata all_uints8, bool[] calldata all_bools, int32[] calldata pos_data ) public BUILD_ROUTER_ONLY{ require(b_owner != address(0),"cant be minted to null"); require(token_ownership[this_token_id] == address(0),"token already exists"); balance_per_owner[b_owner] += 1; token_ownership[this_token_id] = b_owner; data_per_building[this_token_id].plot_id = plot_id; data_per_building[this_token_id].mesh_id = mesh_id; data_per_building[this_token_id].is_damaged = false; //ALL UINTS8 data_per_building[this_token_id].b_type = all_uints8[0]; data_per_building[this_token_id].top_unit_shell_rotation = all_uints8[1]; data_per_building[this_token_id].color_id = all_uints8[2]; data_per_building[this_token_id].color_scheme_id = all_uints8[3]; data_per_building[this_token_id].style_by_claster = all_uints8[4]; data_per_building[this_token_id].extra_cluster_randomizer_1 = all_uints8[5]; data_per_building[this_token_id].extra_cluster_randomizer_2 = all_uints8[6]; data_per_building[this_token_id].extra_cluster_randomizer_3 = all_uints8[7]; //BOOLS data_per_building[this_token_id].buildable_on_top = all_bools[0]; data_per_building[this_token_id].is_ground = all_bools[1]; data_per_building[this_token_id].is_double_floor = all_bools[2]; data_per_building[this_token_id].is_base = all_bools[3]; //POS DATA p_data_per_build[this_token_id].quat_x = pos_data[0]; p_data_per_build[this_token_id].quat_y = pos_data[1]; p_data_per_build[this_token_id].quat_z = pos_data[2]; p_data_per_build[this_token_id].quat_w = pos_data[3]; p_data_per_build[this_token_id].pos_x = pos_data[4]; p_data_per_build[this_token_id].pos_y = pos_data[5]; p_data_per_build[this_token_id].pos_z = pos_data[6]; emit Transfer(address(0), b_owner, this_token_id); emit Build_event(this_token_id); } event Build_event(uint token_id); //return available token id function get_token_id(uint id_search_start,bool is_base)public view returns(uint){ uint next_id; uint mutiplier = 1; if(is_base){ mutiplier = 100000; } for (uint i = 1; i < 10000; i++) { next_id = id_search_start + (mutiplier * i); if(token_ownership[next_id] == address(0)){ return next_id; } } } //ALL COMBINED DATA function retrieve_all_building_data(uint this_token_id)public view returns(int32[7] memory,uint8[16] memory,uint16[2] memory,uint32[2] memory, uint,address,address){ require(token_exists(this_token_id), "Token doesn't exist"); return ( [ p_data_per_build[this_token_id].quat_x, p_data_per_build[this_token_id].quat_y, p_data_per_build[this_token_id].quat_z, p_data_per_build[this_token_id].quat_w, p_data_per_build[this_token_id].pos_x, p_data_per_build[this_token_id].pos_y, p_data_per_build[this_token_id].pos_z ], [ data_per_building[this_token_id].b_type, data_per_building[this_token_id].top_unit_shell_rotation, data_per_building[this_token_id].color_id, data_per_building[this_token_id].color_scheme_id, data_per_building[this_token_id].style_by_claster, data_per_building[this_token_id].extra_cluster_randomizer_1, data_per_building[this_token_id].extra_cluster_randomizer_2, data_per_building[this_token_id].extra_cluster_randomizer_3, rent_data_by_token[this_token_id].rent_period, //end of uint8 bool_to_uint8(data_per_building[this_token_id].buildable_on_top), bool_to_uint8(data_per_building[this_token_id].is_ground), bool_to_uint8(data_per_building[this_token_id].is_double_floor), bool_to_uint8(data_per_building[this_token_id].is_base), bool_to_uint8(data_per_building[this_token_id].is_damaged), bool_to_uint8(rent_data_by_token[this_token_id].ever_listed), bool_to_uint8(rent_data_by_token[this_token_id].is_listed) ], [ data_per_building[this_token_id].plot_id, data_per_building[this_token_id].mesh_id ], [ rent_data_by_token[this_token_id].rent_price, rent_data_by_token[this_token_id].rented_until ], sale_price_per_token[this_token_id], rent_data_by_token[this_token_id].renter_address, token_ownership[this_token_id] ); } function bool_to_uint8(bool this_bool)private pure returns(uint8){ if(this_bool){ return 1; } else{ return 0; } } //BURN particular buildings via router ,like walls function burn_by_router(uint this_token_id, address burn_requester) public BUILD_ROUTER_ONLY{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_burnable_by_router(this_token_id), "Cant be burned by router"); burn_it(this_token_id,burn_requester); } //BURN buildings in ownership by owner function burn_by_owner(uint this_token_id)public{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_owner(this_token_id,msg.sender), "Wrong owner"); require(!is_in_rent(this_token_id), "Token in rent"); require(nothing_on_top(this_token_id)); require(base_has_no_nftbox(this_token_id)); burn_it(this_token_id,msg.sender); } //burn finalize function burn_it(uint this_token_id,address burn_requester)internal{ inner_approve(address(0), this_token_id); clean_rent_data(this_token_id); cleanup_sale_listing(this_token_id); balance_per_owner[burn_requester] -= 1; token_ownership[this_token_id] = address(0); emit Transfer(burn_requester, address(0), this_token_id); } //check if unit has nothing built on top function nothing_on_top(uint this_token_id)internal view returns(bool){ if(data_per_building[this_token_id].buildable_on_top){ uint top_token_id = this_token_id + 1; if(!token_exists(top_token_id)){ return true; } else{ return false; } } else{ return true; } } //check if base has nft_box on top function base_has_no_nftbox(uint this_token_id)internal view returns(bool){ if(data_per_building[this_token_id].is_base){ uint nftbox_token_id = this_token_id + 99999; if(!token_exists(nftbox_token_id)){ return true; } else{ return false; } } else{ return true; } } //check if belongs to walls function is_burnable_by_router(uint this_token_id)internal view returns(bool){ uint8 this_b_type = data_per_building[this_token_id].b_type; return burnable_by_router_types[this_b_type]; } //DAMAGE/REPAIR BUILDING function damage_repair_building(uint this_token_id,bool this_action)public BUILD_ROUTER_ONLY{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_of_damageable_type(this_token_id),"Cant be damaged/repaired"); data_per_building[this_token_id].is_damaged = this_action; emit damage_repair_event(this_token_id,this_action); } event damage_repair_event(uint token_id,bool is_damaged); function is_of_damageable_type(uint this_token_id)internal view returns(bool){ uint8 this_b_type = data_per_building[this_token_id].b_type; return damageable_b_types[this_b_type]; } ///...............................RENT FUNCTIONS struct rent_data{ bool ever_listed; //set true on first listing bool is_listed; //yes no uint32 rent_price;// max value 40000,00000 -- input in WEI converted to 1ETH/100000 (nukewei) uint8 rent_period; //rent period in days 1-250 address renter_address; //160 bits uint32 rented_until; //timestamp } mapping(uint => rent_data) private rent_data_by_token; //all rent related data //RENT LISTING function list_for_rent(uint this_token_id, uint rent_price_in_wei, uint8 rent_period_in_days)public{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_rentable(this_token_id),"Building type cant be rented"); require(is_owner(this_token_id,msg.sender), "Wrong owner"); require(rent_period_in_days>0 && rent_period_in_days<255, "Bad rent period"); require(verify_rent_price_input(rent_price_in_wei), "Bad rent price"); uint32 rent_price = uint32(rent_price_in_wei/nukewei); rent_data_by_token[this_token_id].ever_listed = true; rent_data_by_token[this_token_id].is_listed = true; rent_data_by_token[this_token_id].rent_price = rent_price; rent_data_by_token[this_token_id].rent_period = rent_period_in_days; emit rent_listing(this_token_id,rent_price_in_wei,rent_period_in_days); } //CANCEL RENT LISTING function cancel_rent_listing(uint this_token_id)public{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_rentable(this_token_id),"Building type cant be rented"); require(is_owner(this_token_id,msg.sender), "Wrong owner"); rent_data_by_token[this_token_id].is_listed = false; rent_data_by_token[this_token_id].rent_price = 0; rent_data_by_token[this_token_id].rent_period = 0; emit cancel_rent_listing_event(this_token_id); } //clean rent data on transfer or burn function clean_rent_data(uint this_token_id)internal{ if(rent_data_by_token[this_token_id].ever_listed){ bool if_is_listed = rent_data_by_token[this_token_id].is_listed; rent_data_by_token[this_token_id].ever_listed=false; rent_data_by_token[this_token_id].is_listed=false; rent_data_by_token[this_token_id].rent_price=0; rent_data_by_token[this_token_id].rent_period=0; rent_data_by_token[this_token_id].renter_address=address(0); rent_data_by_token[this_token_id].rented_until=0; if(if_is_listed){ emit cancel_rent_listing_event(this_token_id); } } } //RENT UNIT function rent_unit(uint this_token_id)public payable{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_rentable(this_token_id),"Building type cant be rented"); require(!is_in_rent(this_token_id), "Token in rent"); require(rent_data_by_token[this_token_id].is_listed, "Token not listed"); require(!is_owner(this_token_id,msg.sender), "Owner cant rent to himself"); require(rent_price_match(this_token_id,msg.value), "Wrong amount of ETC sent"); address unit_owner = token_ownership[this_token_id]; bool sent; bytes memory response; (sent,response) = unit_owner.call{value: msg.value}(""); require(sent, "Failed to send ETC"); uint8 rent_period = rent_data_by_token[this_token_id].rent_period; finalize_rent(this_token_id,msg.sender,rent_period); } //rent unit to someone forcefully function rent_to(uint this_token_id,address this_renter,uint8 rent_period_in_days) public{ require(this_renter != address(0), "Cant rent to zero"); require(this_renter != msg.sender, "Owner cant rent to himself"); require(token_exists(this_token_id), "Token doesn't exist"); require(is_rentable(this_token_id),"Building type cant be rented"); require(!is_in_rent(this_token_id), "Token in rent"); require(is_owner(this_token_id,msg.sender), "Bad ownership"); require(rent_period_in_days>0 && rent_period_in_days<255, "Bad rent period"); finalize_rent(this_token_id,this_renter,rent_period_in_days); } //internal rent finish function finalize_rent(uint this_token_id, address renter, uint8 rent_period)internal{ uint32 rent_end_time = calculate_rent_end_time(rent_period); rent_data_by_token[this_token_id].ever_listed = true; rent_data_by_token[this_token_id].rented_until = rent_end_time; rent_data_by_token[this_token_id].renter_address = renter; emit unit_rented(this_token_id, renter, rent_end_time); } event rent_listing(uint token_id,uint rent_price,uint8 rent_period); event cancel_rent_listing_event(uint token_id); event unit_rented(uint token_id, address renter_address, uint rented_until); function is_rentable(uint this_token_id) internal view returns(bool){ uint8 this_b_type = data_per_building[this_token_id].b_type; return rentable_b_types[this_b_type]; } function rent_price_match(uint this_token_id,uint this_amount)internal view returns(bool){ if(this_amount>0 && rent_data_by_token[this_token_id].rent_price>0){ uint32 nukewei_rent_price = uint32(this_amount/nukewei); if(nukewei_rent_price == rent_data_by_token[this_token_id].rent_price){ return true; } } return false; } //get end of rent timestamp function calculate_rent_end_time(uint8 rent_period) internal view returns(uint32) { uint32 time_now = uint32(block.timestamp); uint32 cur_rent_period = uint32(rent_period); uint32 rent_period_in_seconds = uint32(cur_rent_period * 24 * 60 * 60); uint32 rented_until_time = time_now + rent_period_in_seconds; return rented_until_time; } //check if token is in rent function is_in_rent(uint this_token_id)public view returns(bool){ if(rent_data_by_token[this_token_id].rented_until != 0){ uint32 time_now = uint32(block.timestamp); if(rent_data_by_token[this_token_id].rented_until > time_now){ return true; } } return false; } //check if price fits within uint32 function verify_rent_price_input(uint rent_price_in_wei)internal view returns(bool){ if(rent_price_in_wei>0){ uint price_in_nukewei = rent_price_in_wei/nukewei; //convert from wei to inner format of 1ETH/100000 if(price_in_nukewei<4000000000){ return true; } } return false; } //..............................MARKET FUNCTIONS mapping(uint => uint) private sale_price_per_token; //SALE LISTING function list_for_sale(uint this_token_id, uint sale_price) public{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_owner(this_token_id,msg.sender), "Wrong owner"); require(sale_price>0,"Bad price"); sale_price_per_token[this_token_id] = sale_price; emit sale_listing(this_token_id,sale_price); } //SALE CANCEL function cancel_sale_listing(uint this_token_id)public{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_owner(this_token_id,msg.sender), "Wrong owner"); cleanup_sale_listing(this_token_id); } //internal cancel and cleanup function cleanup_sale_listing(uint this_token_id) internal{ sale_price_per_token[this_token_id] = 0; emit cancel_sale_listing_event(this_token_id); } //BUY UNIT function buy_unit(uint this_token_id) public payable{ require(token_exists(this_token_id), "Token doesn't exist"); require(!is_owner(this_token_id,msg.sender), "Cant buy from yourself"); require(sale_price_per_token[this_token_id] > 0,"Unit not listed for sale"); require(!is_in_rent(this_token_id), "Token in rent"); require(msg.value == sale_price_per_token[this_token_id],"Sale price mismatch"); address this_token_owner = token_ownership[this_token_id]; bool sent; bytes memory response; (sent, response) = this_token_owner.call{value: msg.value}(""); require(sent, "Failed to send ETC"); transfer_token(this_token_owner,msg.sender,this_token_id); emit sale_event(this_token_id, msg.value); } event sale_listing(uint token_id,uint sale_price); event cancel_sale_listing_event(uint token_id); event sale_event(uint token_id,uint sale_price); //..............................ADD DATA FUCTIONs //add remove wall type function add_remove_router_burnable_b_types(uint8 b_type,bool is_add)public CREATOR_ONLY{ burnable_by_router_types[b_type] = is_add; } //add remove rentable types function add_remove_rentable_b_types(uint8 b_type,bool is_add)public CREATOR_ONLY{ rentable_b_types[b_type] = is_add; } //add remove damageable_b_types function add_remove_damageable_b_types(uint8 b_type,bool is_add)public CREATOR_ONLY{ damageable_b_types[b_type] = is_add; } //.............................MODIFIERS modifier CREATOR_ONLY { require(msg.sender == contract_creator,"must be creator"); _; } modifier BUILD_ROUTER_ONLY { require(all_build_routers[msg.sender],"must be build_router"); _; } //kinda ERC721 classics function name() external view returns (string memory){ return token_name; } function symbol() external view returns (string memory){ return token_symbol; } function tokenURI(uint this_token_id) external view returns (string memory){ require(token_exists(this_token_id),"Token doesn't exist"); string memory baseURI = base_uri; if(bytes(baseURI).length > 0){ string memory string_token = toString(this_token_id); return string(abi.encodePacked(baseURI, string_token)); } else{ return ""; } } function set_base_uri(string calldata this_base_uri)public CREATOR_ONLY{ base_uri = this_base_uri; } //good function balanceOf(address this_owner) external view returns (uint256){ require(this_owner != address(0), "Zero address has nothing in ownership"); return balance_per_owner[this_owner]; } //good function ownerOf(uint this_token_id) public view returns (address){ address this_owner = token_ownership[this_token_id]; require(this_owner != address(0), "Token doesn't exist"); return this_owner; } //ERC721 pack of transfers function safeTransferFrom(address from, address to, uint this_token_id) public{ safeTransferFrom(from, to, this_token_id, ""); } function safeTransferFrom(address from, address to, uint this_token_id, bytes memory ) public{ require(is_owner_or_approved(msg.sender, this_token_id),"not owner or approved"); transfer_token(from, to, this_token_id); } function transferFrom( address from,address to,uint this_token_id) public { require(is_owner_or_approved(msg.sender, this_token_id),"not owner or approved"); transfer_token(from, to, this_token_id); } //MAIN TRANSFER function transfer_token(address from,address to,uint this_token_id) internal { require(!is_in_rent(this_token_id), "Token in rent"); require(ownerOf(this_token_id) == from, "bad owner"); require(to != address(0), "no zero transfers"); inner_approve(address(0), this_token_id); // Clear approvals from the previous owner clean_rent_data(this_token_id); cleanup_sale_listing(this_token_id); balance_per_owner[from] -= 1; balance_per_owner[to] += 1; token_ownership[this_token_id] = to; emit Transfer(from, to, this_token_id); } event Transfer(address indexed from, address indexed to, uint256 indexed token_id); //APPROVALS function approve(address to, uint this_token_id) public { address owner = ownerOf(this_token_id); require(to != owner, "cant approve to owner"); require(msg.sender == owner || isApprovedForAll(owner,msg.sender), "sender is not owner nor approved for all"); inner_approve(to, this_token_id); } function inner_approve(address to, uint this_token_id) internal { if(approval_per_token[this_token_id] != to){ approval_per_token[this_token_id] = to; emit Approval(ownerOf(this_token_id), to, this_token_id); } } event Approval(address indexed owner, address indexed is_approved, uint256 indexed token_id); function setApprovalForAll(address operator, bool approved) public { require(msg.sender != operator, "cant approve to itself"); operator_approvals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } event ApprovalForAll(address indexed owner, address indexed operator, bool is_approved); //Verify STF function is_owner_or_approved(address msg_sender, uint this_token_id) internal view returns (bool) { address this_owner = ownerOf(this_token_id); return (msg_sender == this_owner || isApprovedForAll(this_owner, msg_sender) || getApproved(this_token_id) == msg_sender); } function is_owner(uint this_token_id, address requester)internal view returns (bool){ address this_owner = ownerOf(this_token_id); if(this_owner == requester){ return true; } return false; } function isApprovedForAll(address this_owner, address operator) public view returns (bool) { return operator_approvals[this_owner][operator]; } function getApproved(uint this_token_id) public view returns (address) { require(token_exists(this_token_id), "Token doesn't exist"); return approval_per_token[this_token_id]; } function token_exists(uint this_token_id) public view returns (bool) { return token_ownership[this_token_id] != address(0); } //...................................INTERFACES function supportsInterface(bytes4 interface_id) external pure returns (bool){ return interface_id == 0x80ac58cd; } function onERC721Received(address ,address ,uint256 ,bytes calldata ) external pure returns (bytes4){ return 0; } //..........................................UTILS function toString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } } contract bob{ function transferFrom(address _from, address _to, uint256 _value) public {} }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"is_approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"is_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"Build_event","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"b_router","type":"address"},{"indexed":false,"internalType":"uint256","name":"bob_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gas_amount","type":"uint256"}],"name":"build_request_event","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"cancel_rent_listing_event","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"cancel_sale_listing_event","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"},{"indexed":false,"internalType":"bool","name":"is_damaged","type":"bool"}],"name":"damage_repair_event","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rent_price","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"rent_period","type":"uint8"}],"name":"rent_listing","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sale_price","type":"uint256"}],"name":"sale_event","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sale_price","type":"uint256"}],"name":"sale_listing","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"},{"indexed":false,"internalType":"address","name":"renter_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rented_until","type":"uint256"}],"name":"unit_rented","type":"event"},{"inputs":[{"internalType":"bool","name":"this_action","type":"bool"},{"internalType":"address[]","name":"those_addresses","type":"address[]"}],"name":"add_or_remove_build_routers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"b_type","type":"uint8"},{"internalType":"bool","name":"is_add","type":"bool"}],"name":"add_remove_damageable_b_types","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"b_type","type":"uint8"},{"internalType":"bool","name":"is_add","type":"bool"}],"name":"add_remove_rentable_b_types","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"b_type","type":"uint8"},{"internalType":"bool","name":"is_add","type":"bool"}],"name":"add_remove_router_burnable_b_types","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"this_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"b_owner","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"uint16","name":"plot_id","type":"uint16"},{"internalType":"uint16","name":"mesh_id","type":"uint16"},{"internalType":"uint8[]","name":"all_uints8","type":"uint8[]"},{"internalType":"bool[]","name":"all_bools","type":"bool[]"},{"internalType":"int32[]","name":"pos_data","type":"int32[]"}],"name":"build","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"build_router","type":"address"},{"internalType":"uint256","name":"bob_amount","type":"uint256"}],"name":"build_proxy_request","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"burn_by_owner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"address","name":"burn_requester","type":"address"}],"name":"burn_by_router","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"buy_unit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"cancel_rent_listing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"cancel_sale_listing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"bool","name":"this_action","type":"bool"}],"name":"damage_repair_building","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_search_start","type":"uint256"},{"internalType":"bool","name":"is_base","type":"bool"}],"name":"get_token_id","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"this_owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"is_in_rent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"uint256","name":"rent_price_in_wei","type":"uint256"},{"internalType":"uint8","name":"rent_period_in_days","type":"uint8"}],"name":"list_for_rent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"uint256","name":"sale_price","type":"uint256"}],"name":"list_for_sale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"this_bob","type":"address"}],"name":"register_bob","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"address","name":"this_renter","type":"address"},{"internalType":"uint8","name":"rent_period_in_days","type":"uint8"}],"name":"rent_to","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"rent_unit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"retrieve_all_building_data","outputs":[{"internalType":"int32[7]","name":"","type":"int32[7]"},{"internalType":"uint8[16]","name":"","type":"uint8[16]"},{"internalType":"uint16[2]","name":"","type":"uint16[2]"},{"internalType":"uint32[2]","name":"","type":"uint32[2]"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"this_base_uri","type":"string"}],"name":"set_base_uri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interface_id","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"token_exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]