ETH Price: $1,981.21 (+0.23%)

Transaction Decoder

Block:
24466900 at Feb-16-2026 04:10:23 AM +UTC
Transaction Fee:
0.000003630384347328 ETH $0.007193
Gas Used:
101,872 Gas / 0.035636724 Gwei

Emitted Events:

1271 AdminUpgradeabilityProxy.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x000000000000000000000000f23e4e7a6b811c6ee4c34cb660ad70bfba137ea7, 0x000000000000000000000000baf3e76c064cc7c0b2bc8329b4d9d11b16b0651a, 0x000000000000000000000000000000000000000000000000000000000000174d )

Account State Difference:

  Address   Before After State Difference Code
(Titan Builder)
18.275836757788207982 Eth18.275836773671682734 Eth0.000000015883474752
0x959e104E...1A978c297
0xF23e4E7A...FBA137EA7
0.000183201005180735 Eth
Nonce: 30
0.000179570620833407 Eth
Nonce: 31
0.000003630384347328

Execution Trace

AdminUpgradeabilityProxy.23b872dd( )
  • EstateRegistry.transferFrom( _from=0xF23e4E7A6B811c6ee4C34Cb660aD70bFBA137EA7, _to=0xbaf3e76C064CC7C0b2bc8329b4d9D11B16b0651A, _tokenId=5965 )
    File 1 of 2: AdminUpgradeabilityProxy
    pragma solidity ^0.4.24;
    
    // File: node_modules/zos-lib/contracts/upgradeability/Proxy.sol
    
    /**
     * @title Proxy
     * @dev Implements delegation of calls to other contracts, with proper
     * forwarding of return values and bubbling of failures.
     * It defines a fallback function that delegates all calls to the address
     * returned by the abstract _implementation() internal function.
     */
    contract Proxy {
      /**
       * @dev Fallback function.
       * Implemented entirely in `_fallback`.
       */
      function () payable external {
        _fallback();
      }
    
      /**
       * @return The Address of the implementation.
       */
      function _implementation() internal view returns (address);
    
      /**
       * @dev Delegates execution to an implementation contract.
       * This is a low level function that doesn't return to its internal call site.
       * It will return to the external caller whatever the implementation returns.
       * @param implementation Address to delegate.
       */
      function _delegate(address implementation) internal {
        assembly {
          // Copy msg.data. We take full control of memory in this inline assembly
          // block because it will not return to Solidity code. We overwrite the
          // Solidity scratch pad at memory position 0.
          calldatacopy(0, 0, calldatasize)
    
          // Call the implementation.
          // out and outsize are 0 because we don't know the size yet.
          let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)
    
          // Copy the returned data.
          returndatacopy(0, 0, returndatasize)
    
          switch result
          // delegatecall returns 0 on error.
          case 0 { revert(0, returndatasize) }
          default { return(0, returndatasize) }
        }
      }
    
      /**
       * @dev Function that is run as the first thing in the fallback function.
       * Can be redefined in derived contracts to add functionality.
       * Redefinitions must call super._willFallback().
       */
      function _willFallback() internal {
      }
    
      /**
       * @dev fallback implementation.
       * Extracted to enable manual triggering.
       */
      function _fallback() internal {
        _willFallback();
        _delegate(_implementation());
      }
    }
    
    // File: openzeppelin-solidity/contracts/AddressUtils.sol
    
    /**
     * Utility library of inline functions on addresses
     */
    library AddressUtils {
    
      /**
       * Returns whether the target address is a contract
       * @dev This function will return false if invoked during the constructor of a contract,
       * as the code is not actually created until after the constructor finishes.
       * @param _addr address to check
       * @return whether the target address is a contract
       */
      function isContract(address _addr) internal view returns (bool) {
        uint256 size;
        // XXX Currently there is no better way to check if there is a contract in an address
        // than to check the size of the code at that address.
        // See https://ethereum.stackexchange.com/a/14016/36603
        // for more details about how this works.
        // TODO Check this again before the Serenity release, because all addresses will be
        // contracts then.
        // solium-disable-next-line security/no-inline-assembly
        assembly { size := extcodesize(_addr) }
        return size > 0;
      }
    
    }
    
    // File: node_modules/zos-lib/contracts/upgradeability/UpgradeabilityProxy.sol
    
    /**
     * @title UpgradeabilityProxy
     * @dev This contract implements a proxy that allows to change the
     * implementation address to which it will delegate.
     * Such a change is called an implementation upgrade.
     */
    contract UpgradeabilityProxy is Proxy {
      /**
       * @dev Emitted when the implementation is upgraded.
       * @param implementation Address of the new implementation.
       */
      event Upgraded(address implementation);
    
      /**
       * @dev Storage slot with the address of the current implementation.
       * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is
       * validated in the constructor.
       */
      bytes32 private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3;
    
      /**
       * @dev Contract constructor.
       * @param _implementation Address of the initial implementation.
       */
      constructor(address _implementation) public {
        assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation"));
    
        _setImplementation(_implementation);
      }
    
      /**
       * @dev Returns the current implementation.
       * @return Address of the current implementation
       */
      function _implementation() internal view returns (address impl) {
        bytes32 slot = IMPLEMENTATION_SLOT;
        assembly {
          impl := sload(slot)
        }
      }
    
      /**
       * @dev Upgrades the proxy to a new implementation.
       * @param newImplementation Address of the new implementation.
       */
      function _upgradeTo(address newImplementation) internal {
        _setImplementation(newImplementation);
        emit Upgraded(newImplementation);
      }
    
      /**
       * @dev Sets the implementation address of the proxy.
       * @param newImplementation Address of the new implementation.
       */
      function _setImplementation(address newImplementation) private {
        require(AddressUtils.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
    
        bytes32 slot = IMPLEMENTATION_SLOT;
    
        assembly {
          sstore(slot, newImplementation)
        }
      }
    }
    
    // File: node_modules/zos-lib/contracts/upgradeability/AdminUpgradeabilityProxy.sol
    
    /**
     * @title AdminUpgradeabilityProxy
     * @dev This contract combines an upgradeability proxy with an authorization
     * mechanism for administrative tasks.
     * All external functions in this contract must be guarded by the
     * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity
     * feature proposal that would enable this to be done automatically.
     */
    contract AdminUpgradeabilityProxy is UpgradeabilityProxy {
      /**
       * @dev Emitted when the administration has been transferred.
       * @param previousAdmin Address of the previous admin.
       * @param newAdmin Address of the new admin.
       */
      event AdminChanged(address previousAdmin, address newAdmin);
    
      /**
       * @dev Storage slot with the admin of the contract.
       * This is the keccak-256 hash of "org.zeppelinos.proxy.admin", and is
       * validated in the constructor.
       */
      bytes32 private constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b;
    
      /**
       * @dev Modifier to check whether the `msg.sender` is the admin.
       * If it is, it will run the function. Otherwise, it will delegate the call
       * to the implementation.
       */
      modifier ifAdmin() {
        if (msg.sender == _admin()) {
          _;
        } else {
          _fallback();
        }
      }
    
      /**
       * Contract constructor.
       * It sets the `msg.sender` as the proxy administrator.
       * @param _implementation address of the initial implementation.
       */
      constructor(address _implementation) UpgradeabilityProxy(_implementation) public {
        assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin"));
    
        _setAdmin(msg.sender);
      }
    
      /**
       * @return The address of the proxy admin.
       */
      function admin() external view ifAdmin returns (address) {
        return _admin();
      }
    
      /**
       * @return The address of the implementation.
       */
      function implementation() external view ifAdmin returns (address) {
        return _implementation();
      }
    
      /**
       * @dev Changes the admin of the proxy.
       * Only the current admin can call this function.
       * @param newAdmin Address to transfer proxy administration to.
       */
      function changeAdmin(address newAdmin) external ifAdmin {
        require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address");
        emit AdminChanged(_admin(), newAdmin);
        _setAdmin(newAdmin);
      }
    
      /**
       * @dev Upgrade the backing implementation of the proxy.
       * Only the admin can call this function.
       * @param newImplementation Address of the new implementation.
       */
      function upgradeTo(address newImplementation) external ifAdmin {
        _upgradeTo(newImplementation);
      }
    
      /**
       * @dev Upgrade the backing implementation of the proxy and call a function
       * on the new implementation.
       * This is useful to initialize the proxied contract.
       * @param newImplementation Address of the new implementation.
       * @param data Data to send as msg.data in the low level call.
       * It should include the signature and the parameters of the function to be
       * called, as described in
       * https://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector-and-argument-encoding.
       */
      function upgradeToAndCall(address newImplementation, bytes data) payable external ifAdmin {
        _upgradeTo(newImplementation);
        require(address(this).call.value(msg.value)(data));
      }
    
      /**
       * @return The admin slot.
       */
      function _admin() internal view returns (address adm) {
        bytes32 slot = ADMIN_SLOT;
        assembly {
          adm := sload(slot)
        }
      }
    
      /**
       * @dev Sets the address of the proxy admin.
       * @param newAdmin Address of the new proxy admin.
       */
      function _setAdmin(address newAdmin) internal {
        bytes32 slot = ADMIN_SLOT;
    
        assembly {
          sstore(slot, newAdmin)
        }
      }
    
      /**
       * @dev Only fall back when the sender is not the admin.
       */
      function _willFallback() internal {
        require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin");
        super._willFallback();
      }
    }

    File 2 of 2: EstateRegistry
    pragma solidity ^0.4.24;
    // File: openzeppelin-zos/contracts/introspection/ERC165.sol
    /**
     * @title ERC165
     * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
     */
    interface ERC165 {
      /**
       * @notice Query if a contract implements an interface
       * @param _interfaceId The interface identifier, as specified in ERC-165
       * @dev Interface identification is specified in ERC-165. This function
       * uses less than 30,000 gas.
       */
      function supportsInterface(bytes4 _interfaceId)
        external
        view
        returns (bool);
    }
    // File: openzeppelin-zos/contracts/token/ERC721/ERC721Basic.sol
    /**
     * @title ERC721 Non-Fungible Token Standard basic interface
     * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
     */
    contract ERC721Basic is ERC165 {
      event Transfer(
        address indexed _from,
        address indexed _to,
        uint256 indexed _tokenId
      );
      event Approval(
        address indexed _owner,
        address indexed _approved,
        uint256 indexed _tokenId
      );
      event ApprovalForAll(
        address indexed _owner,
        address indexed _operator,
        bool _approved
      );
      function balanceOf(address _owner) public view returns (uint256 _balance);
      function ownerOf(uint256 _tokenId) public view returns (address _owner);
      function exists(uint256 _tokenId) public view returns (bool _exists);
      function approve(address _to, uint256 _tokenId) public;
      function getApproved(uint256 _tokenId)
        public view returns (address _operator);
      function setApprovalForAll(address _operator, bool _approved) public;
      function isApprovedForAll(address _owner, address _operator)
        public view returns (bool);
      function transferFrom(address _from, address _to, uint256 _tokenId) public;
      function safeTransferFrom(address _from, address _to, uint256 _tokenId)
        public;
      function safeTransferFrom(
        address _from,
        address _to,
        uint256 _tokenId,
        bytes _data
      )
        public;
    }
    // File: openzeppelin-zos/contracts/token/ERC721/ERC721.sol
    /**
     * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
     * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
     */
    contract ERC721Enumerable is ERC721Basic {
      function totalSupply() public view returns (uint256);
      function tokenOfOwnerByIndex(
        address _owner,
        uint256 _index
      )
        public
        view
        returns (uint256 _tokenId);
      function tokenByIndex(uint256 _index) public view returns (uint256);
    }
    /**
     * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
     * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
     */
    contract ERC721Metadata is ERC721Basic {
      function name() external view returns (string _name);
      function symbol() external view returns (string _symbol);
      function tokenURI(uint256 _tokenId) public view returns (string);
    }
    /**
     * @title ERC-721 Non-Fungible Token Standard, full implementation interface
     * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
     */
    contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
    }
    // File: openzeppelin-zos/contracts/token/ERC721/ERC721Receiver.sol
    /**
     * @title ERC721 token receiver interface
     * @dev Interface for any contract that wants to support safeTransfers
     * from ERC721 asset contracts.
     */
    contract ERC721Receiver {
      /**
       * @dev Magic value to be returned upon successful reception of an NFT
       *  Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`,
       *  which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
       */
      bytes4 internal constant ERC721_RECEIVED = 0x150b7a02;
      /**
       * @notice Handle the receipt of an NFT
       * @dev The ERC721 smart contract calls this function on the recipient
       * after a `safetransfer`. 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 transfered
       * @param _data Additional data with no specified format
       * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
       */
      function onERC721Received(
        address _operator,
        address _from,
        uint256 _tokenId,
        bytes _data
      )
        public
        returns(bytes4);
    }
    // File: openzeppelin-zos/contracts/math/SafeMath.sol
    /**
     * @title SafeMath
     * @dev Math operations with safety checks that throw on error
     */
    library SafeMath {
      /**
      * @dev Multiplies two numbers, throws on overflow.
      */
      function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
        if (a == 0) {
          return 0;
        }
        c = a * b;
        assert(c / a == b);
        return c;
      }
      /**
      * @dev Integer division of two numbers, truncating the quotient.
      */
      function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws 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 a / b;
      }
      /**
      * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
      */
      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
      }
      /**
      * @dev Adds two numbers, throws on overflow.
      */
      function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = a + b;
        assert(c >= a);
        return c;
      }
    }
    // File: openzeppelin-zos/contracts/AddressUtils.sol
    /**
     * Utility library of inline functions on addresses
     */
    library AddressUtils {
      /**
       * Returns whether the target address is a contract
       * @dev This function will return false if invoked during the constructor of a contract,
       *  as the code is not actually created until after the constructor finishes.
       * @param addr address to check
       * @return whether the target address is a contract
       */
      function isContract(address addr) internal view returns (bool) {
        uint256 size;
        // XXX Currently there is no better way to check if there is a contract in an address
        // than to check the size of the code at that address.
        // See https://ethereum.stackexchange.com/a/14016/36603
        // for more details about how this works.
        // TODO Check this again before the Serenity release, because all addresses will be
        // contracts then.
        assembly { size := extcodesize(addr) }  // solium-disable-line security/no-inline-assembly
        return size > 0;
      }
    }
    // File: openzeppelin-zos/contracts/introspection/ERC165Support.sol
    /**
     * @title ERC165Support
     * @dev Implements ERC165 returning true for ERC165 interface identifier
     */
    contract ERC165Support is ERC165 {
      bytes4 internal constant InterfaceId_ERC165 = 0x01ffc9a7;
      /**
       * 0x01ffc9a7 ===
       *   bytes4(keccak256('supportsInterface(bytes4)'))
       */
      function supportsInterface(bytes4 _interfaceId)
        external
        view
        returns (bool) 
      {
        return _supportsInterface(_interfaceId);
      }
      function _supportsInterface(bytes4 _interfaceId)
        internal
        view
        returns (bool) 
      {
        return _interfaceId == InterfaceId_ERC165;
      }
    }
    // File: openzeppelin-zos/contracts/token/ERC721/ERC721BasicToken.sol
    /**
     * @title ERC721 Non-Fungible Token Standard basic implementation
     * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
     */
    contract ERC721BasicToken is ERC165Support, ERC721Basic {
      bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd;
      /*
       * 0x80ac58cd ===
       *   bytes4(keccak256('balanceOf(address)')) ^
       *   bytes4(keccak256('ownerOf(uint256)')) ^
       *   bytes4(keccak256('approve(address,uint256)')) ^
       *   bytes4(keccak256('getApproved(uint256)')) ^
       *   bytes4(keccak256('setApprovalForAll(address,bool)')) ^
       *   bytes4(keccak256('isApprovedForAll(address,address)')) ^
       *   bytes4(keccak256('transferFrom(address,address,uint256)')) ^
       *   bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
       *   bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
       */
      bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79;
      /*
       * 0x4f558e79 ===
       *   bytes4(keccak256('exists(uint256)'))
       */
      using SafeMath for uint256;
      using AddressUtils for address;
      // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
      // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
      bytes4 private constant ERC721_RECEIVED = 0x150b7a02;
      // Mapping from token ID to owner
      mapping (uint256 => address) internal tokenOwner;
      // Mapping from token ID to approved address
      mapping (uint256 => address) internal tokenApprovals;
      // Mapping from owner to number of owned token
      mapping (address => uint256) internal ownedTokensCount;
      // Mapping from owner to operator approvals
      mapping (address => mapping (address => bool)) internal operatorApprovals;
      /**
       * @dev Guarantees msg.sender is owner of the given token
       * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender
       */
      modifier onlyOwnerOf(uint256 _tokenId) {
        require(ownerOf(_tokenId) == msg.sender);
        _;
      }
      /**
       * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator
       * @param _tokenId uint256 ID of the token to validate
       */
      modifier canTransfer(uint256 _tokenId) {
        require(isApprovedOrOwner(msg.sender, _tokenId));
        _;
      }
      function _supportsInterface(bytes4 _interfaceId)
        internal
        view
        returns (bool)
      {
        return super._supportsInterface(_interfaceId) || 
          _interfaceId == InterfaceId_ERC721 || _interfaceId == InterfaceId_ERC721Exists;
      }
      /**
       * @dev Gets the balance of the specified address
       * @param _owner address to query the balance of
       * @return uint256 representing the amount owned by the passed address
       */
      function balanceOf(address _owner) public view returns (uint256) {
        require(_owner != address(0));
        return ownedTokensCount[_owner];
      }
      /**
       * @dev Gets the owner of the specified token ID
       * @param _tokenId uint256 ID of the token to query the owner of
       * @return owner address currently marked as the owner of the given token ID
       */
      function ownerOf(uint256 _tokenId) public view returns (address) {
        address owner = tokenOwner[_tokenId];
        require(owner != address(0));
        return owner;
      }
      /**
       * @dev Returns whether the specified token exists
       * @param _tokenId uint256 ID of the token to query the existence of
       * @return whether the token exists
       */
      function exists(uint256 _tokenId) public view returns (bool) {
        address owner = tokenOwner[_tokenId];
        return owner != address(0);
      }
      /**
       * @dev Approves another address to transfer the given token ID
       * The zero address indicates there is no approved address.
       * There can only be one approved address per token at a given time.
       * Can only be called by the token owner or an approved operator.
       * @param _to address to be approved for the given token ID
       * @param _tokenId uint256 ID of the token to be approved
       */
      function approve(address _to, uint256 _tokenId) public {
        address owner = ownerOf(_tokenId);
        require(_to != owner);
        require(msg.sender == owner || isApprovedForAll(owner, msg.sender));
        tokenApprovals[_tokenId] = _to;
        emit Approval(owner, _to, _tokenId);
      }
      /**
       * @dev Gets the approved address for a token ID, or zero if no address set
       * @param _tokenId uint256 ID of the token to query the approval of
       * @return address currently approved for the given token ID
       */
      function getApproved(uint256 _tokenId) public view returns (address) {
        return tokenApprovals[_tokenId];
      }
      /**
       * @dev Sets or unsets the approval of a given operator
       * An operator is allowed to transfer all tokens of the sender on their behalf
       * @param _to operator address to set the approval
       * @param _approved representing the status of the approval to be set
       */
      function setApprovalForAll(address _to, bool _approved) public {
        require(_to != msg.sender);
        operatorApprovals[msg.sender][_to] = _approved;
        emit ApprovalForAll(msg.sender, _to, _approved);
      }
      /**
       * @dev Tells whether an operator is approved by a given owner
       * @param _owner owner address which you want to query the approval of
       * @param _operator operator address which you want to query the approval of
       * @return bool whether the given operator is approved by the given owner
       */
      function isApprovedForAll(
        address _owner,
        address _operator
      )
        public
        view
        returns (bool)
      {
        return operatorApprovals[_owner][_operator];
      }
      /**
       * @dev Transfers the ownership of a given token ID to another address
       * Usage of this method is discouraged, use `safeTransferFrom` whenever possible
       * Requires the msg sender to be the owner, approved, or operator
       * @param _from current owner of the token
       * @param _to address to receive the ownership of the given token ID
       * @param _tokenId uint256 ID of the token to be transferred
      */
      function transferFrom(
        address _from,
        address _to,
        uint256 _tokenId
      )
        public
        canTransfer(_tokenId)
      {
        require(_from != address(0));
        require(_to != address(0));
        clearApproval(_from, _tokenId);
        removeTokenFrom(_from, _tokenId);
        addTokenTo(_to, _tokenId);
        emit Transfer(_from, _to, _tokenId);
      }
      /**
       * @dev Safely transfers the ownership of a given token ID to another address
       * If the target address is a contract, it must implement `onERC721Received`,
       * which is called upon a safe transfer, and return the magic value
       * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
       * the transfer is reverted.
       *
       * Requires the msg sender to be the owner, approved, or operator
       * @param _from current owner of the token
       * @param _to address to receive the ownership of the given token ID
       * @param _tokenId uint256 ID of the token to be transferred
      */
      function safeTransferFrom(
        address _from,
        address _to,
        uint256 _tokenId
      )
        public
        canTransfer(_tokenId)
      {
        // solium-disable-next-line arg-overflow
        safeTransferFrom(_from, _to, _tokenId, "");
      }
      /**
       * @dev Safely transfers the ownership of a given token ID to another address
       * If the target address is a contract, it must implement `onERC721Received`,
       * which is called upon a safe transfer, and return the magic value
       * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
       * the transfer is reverted.
       * Requires the msg sender to be the owner, approved, or operator
       * @param _from current owner of the token
       * @param _to address to receive the ownership of the given token ID
       * @param _tokenId uint256 ID of the token to be transferred
       * @param _data bytes data to send along with a safe transfer check
       */
      function safeTransferFrom(
        address _from,
        address _to,
        uint256 _tokenId,
        bytes _data
      )
        public
        canTransfer(_tokenId)
      {
        transferFrom(_from, _to, _tokenId);
        // solium-disable-next-line arg-overflow
        require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
      }
      /**
       * @dev Returns whether the given spender can transfer a given token ID
       * @param _spender address of the spender to query
       * @param _tokenId uint256 ID of the token to be transferred
       * @return bool whether the msg.sender is approved for the given token ID,
       *  is an operator of the owner, or is the owner of the token
       */
      function isApprovedOrOwner(
        address _spender,
        uint256 _tokenId
      )
        internal
        view
        returns (bool)
      {
        address owner = ownerOf(_tokenId);
        // Disable solium check because of
        // https://github.com/duaraghav8/Solium/issues/175
        // solium-disable-next-line operator-whitespace
        return (
          _spender == owner ||
          getApproved(_tokenId) == _spender ||
          isApprovedForAll(owner, _spender)
        );
      }
      /**
       * @dev Internal function to mint a new token
       * Reverts if the given token ID already exists
       * @param _to The address that will own the minted token
       * @param _tokenId uint256 ID of the token to be minted by the msg.sender
       */
      function _mint(address _to, uint256 _tokenId) internal {
        require(_to != address(0));
        addTokenTo(_to, _tokenId);
        emit Transfer(address(0), _to, _tokenId);
      }
      /**
       * @dev Internal function to burn a specific token
       * Reverts if the token does not exist
       * @param _tokenId uint256 ID of the token being burned by the msg.sender
       */
      function _burn(address _owner, uint256 _tokenId) internal {
        clearApproval(_owner, _tokenId);
        removeTokenFrom(_owner, _tokenId);
        emit Transfer(_owner, address(0), _tokenId);
      }
      /**
       * @dev Internal function to clear current approval of a given token ID
       * Reverts if the given address is not indeed the owner of the token
       * @param _owner owner of the token
       * @param _tokenId uint256 ID of the token to be transferred
       */
      function clearApproval(address _owner, uint256 _tokenId) internal {
        require(ownerOf(_tokenId) == _owner);
        if (tokenApprovals[_tokenId] != address(0)) {
          tokenApprovals[_tokenId] = address(0);
        }
      }
      /**
       * @dev Internal function to add a token ID to the list of a given address
       * @param _to address representing the new owner of the given token ID
       * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
       */
      function addTokenTo(address _to, uint256 _tokenId) internal {
        require(tokenOwner[_tokenId] == address(0));
        tokenOwner[_tokenId] = _to;
        ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
      }
      /**
       * @dev Internal function to remove a token ID from the list of a given address
       * @param _from address representing the previous owner of the given token ID
       * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
       */
      function removeTokenFrom(address _from, uint256 _tokenId) internal {
        require(ownerOf(_tokenId) == _from);
        ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
        tokenOwner[_tokenId] = address(0);
      }
      /**
       * @dev Internal function to invoke `onERC721Received` on a target address
       * The call is not executed if the target address is not a contract
       * @param _from address representing the previous owner of the given token ID
       * @param _to target address that will receive the tokens
       * @param _tokenId uint256 ID of the token to be transferred
       * @param _data bytes optional data to send along with the call
       * @return whether the call correctly returned the expected magic value
       */
      function checkAndCallSafeTransfer(
        address _from,
        address _to,
        uint256 _tokenId,
        bytes _data
      )
        internal
        returns (bool)
      {
        if (!_to.isContract()) {
          return true;
        }
        bytes4 retval = ERC721Receiver(_to).onERC721Received(
          msg.sender, _from, _tokenId, _data);
        return (retval == ERC721_RECEIVED);
      }
    }
    // File: zos-lib/contracts/migrations/Migratable.sol
    /**
     * @title Migratable
     * Helper contract to support intialization and migration schemes between
     * different implementations of a contract in the context of upgradeability.
     * To use it, replace the constructor with a function that has the
     * `isInitializer` modifier starting with `"0"` as `migrationId`.
     * When you want to apply some migration code during an upgrade, increase
     * the `migrationId`. Or, if the migration code must be applied only after
     * another migration has been already applied, use the `isMigration` modifier.
     * This helper supports multiple inheritance.
     * WARNING: It is the developer's responsibility to ensure that migrations are
     * applied in a correct order, or that they are run at all.
     * See `Initializable` for a simpler version.
     */
    contract Migratable {
      /**
       * @dev Emitted when the contract applies a migration.
       * @param contractName Name of the Contract.
       * @param migrationId Identifier of the migration applied.
       */
      event Migrated(string contractName, string migrationId);
      /**
       * @dev Mapping of the already applied migrations.
       * (contractName => (migrationId => bool))
       */
      mapping (string => mapping (string => bool)) internal migrated;
      /**
       * @dev Internal migration id used to specify that a contract has already been initialized.
       */
      string constant private INITIALIZED_ID = "initialized";
      /**
       * @dev Modifier to use in the initialization function of a contract.
       * @param contractName Name of the contract.
       * @param migrationId Identifier of the migration.
       */
      modifier isInitializer(string contractName, string migrationId) {
        validateMigrationIsPending(contractName, INITIALIZED_ID);
        validateMigrationIsPending(contractName, migrationId);
        _;
        emit Migrated(contractName, migrationId);
        migrated[contractName][migrationId] = true;
        migrated[contractName][INITIALIZED_ID] = true;
      }
      /**
       * @dev Modifier to use in the migration of a contract.
       * @param contractName Name of the contract.
       * @param requiredMigrationId Identifier of the previous migration, required
       * to apply new one.
       * @param newMigrationId Identifier of the new migration to be applied.
       */
      modifier isMigration(string contractName, string requiredMigrationId, string newMigrationId) {
        require(isMigrated(contractName, requiredMigrationId), "Prerequisite migration ID has not been run yet");
        validateMigrationIsPending(contractName, newMigrationId);
        _;
        emit Migrated(contractName, newMigrationId);
        migrated[contractName][newMigrationId] = true;
      }
      /**
       * @dev Returns true if the contract migration was applied.
       * @param contractName Name of the contract.
       * @param migrationId Identifier of the migration.
       * @return true if the contract migration was applied, false otherwise.
       */
      function isMigrated(string contractName, string migrationId) public view returns(bool) {
        return migrated[contractName][migrationId];
      }
      /**
       * @dev Initializer that marks the contract as initialized.
       * It is important to run this if you had deployed a previous version of a Migratable contract.
       * For more information see https://github.com/zeppelinos/zos-lib/issues/158.
       */
      function initialize() isInitializer("Migratable", "1.2.1") public {
      }
      /**
       * @dev Reverts if the requested migration was already executed.
       * @param contractName Name of the contract.
       * @param migrationId Identifier of the migration.
       */
      function validateMigrationIsPending(string contractName, string migrationId) private view {
        require(!isMigrated(contractName, migrationId), "Requested target migration ID has already been run");
      }
    }
    // File: openzeppelin-zos/contracts/token/ERC721/ERC721Token.sol
    /**
     * @title Full ERC721 Token
     * This implementation includes all the required and some optional functionality of the ERC721 standard
     * Moreover, it includes approve all functionality using operator terminology
     * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
     */
    contract ERC721Token is Migratable, ERC165Support, ERC721BasicToken, ERC721 {
      bytes4 private constant InterfaceId_ERC721Enumerable = 0x780e9d63;
      /**
       * 0x780e9d63 ===
       *   bytes4(keccak256('totalSupply()')) ^
       *   bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
       *   bytes4(keccak256('tokenByIndex(uint256)'))
       */
      bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f;
      /**
       * 0x5b5e139f ===
       *   bytes4(keccak256('name()')) ^
       *   bytes4(keccak256('symbol()')) ^
       *   bytes4(keccak256('tokenURI(uint256)'))
       */
      // Token name
      string internal name_;
      // Token symbol
      string internal symbol_;
      // 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;
      // Array with all token ids, used for enumeration
      uint256[] internal allTokens;
      // Mapping from token id to position in the allTokens array
      mapping(uint256 => uint256) internal allTokensIndex;
      // Optional mapping for token URIs
      mapping(uint256 => string) internal tokenURIs;
      /**
       * @dev Constructor function
       */
      function initialize(string _name, string _symbol) public isInitializer("ERC721Token", "1.9.0") {
        name_ = _name;
        symbol_ = _symbol;
      }
      function _supportsInterface(bytes4 _interfaceId)
        internal
        view
        returns (bool)
      {
        return super._supportsInterface(_interfaceId) || 
          _interfaceId == InterfaceId_ERC721Enumerable || _interfaceId == InterfaceId_ERC721Metadata;
      }
      /**
       * @dev Gets the token name
       * @return string representing the token name
       */
      function name() external view returns (string) {
        return name_;
      }
      /**
       * @dev Gets the token symbol
       * @return string representing the token symbol
       */
      function symbol() external view returns (string) {
        return symbol_;
      }
      /**
       * @dev Returns an URI for a given token ID
       * Throws if the token ID does not exist. May return an empty string.
       * @param _tokenId uint256 ID of the token to query
       */
      function tokenURI(uint256 _tokenId) public view returns (string) {
        require(exists(_tokenId));
        return tokenURIs[_tokenId];
      }
      /**
       * @dev Gets the token ID at a given index of the tokens list of the requested owner
       * @param _owner address owning the tokens list to be accessed
       * @param _index uint256 representing the index to be accessed of the requested tokens list
       * @return uint256 token ID at the given index of the tokens list owned by the requested address
       */
      function tokenOfOwnerByIndex(
        address _owner,
        uint256 _index
      )
        public
        view
        returns (uint256)
      {
        require(_index < balanceOf(_owner));
        return ownedTokens[_owner][_index];
      }
      /**
       * @dev Gets the total amount of tokens stored by the contract
       * @return uint256 representing the total amount of tokens
       */
      function totalSupply() public view returns (uint256) {
        return allTokens.length;
      }
      /**
       * @dev Gets the token ID at a given index of all the tokens in this contract
       * Reverts if the index is greater or equal to the total number of tokens
       * @param _index uint256 representing the index to be accessed of the tokens list
       * @return uint256 token ID at the given index of the tokens list
       */
      function tokenByIndex(uint256 _index) public view returns (uint256) {
        require(_index < totalSupply());
        return allTokens[_index];
      }
      /**
       * @dev Internal function to set the token URI for a given token
       * Reverts if the token ID does not exist
       * @param _tokenId uint256 ID of the token to set its URI
       * @param _uri string URI to assign
       */
      function _setTokenURI(uint256 _tokenId, string _uri) internal {
        require(exists(_tokenId));
        tokenURIs[_tokenId] = _uri;
      }
      /**
       * @dev Internal function to add a token ID to the list of a given address
       * @param _to address representing the new owner of the given token ID
       * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address
       */
      function addTokenTo(address _to, uint256 _tokenId) internal {
        super.addTokenTo(_to, _tokenId);
        uint256 length = ownedTokens[_to].length;
        ownedTokens[_to].push(_tokenId);
        ownedTokensIndex[_tokenId] = length;
      }
      /**
       * @dev Internal function to remove a token ID from the list of a given address
       * @param _from address representing the previous owner of the given token ID
       * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address
       */
      function removeTokenFrom(address _from, uint256 _tokenId) internal {
        super.removeTokenFrom(_from, _tokenId);
        uint256 tokenIndex = ownedTokensIndex[_tokenId];
        uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
        uint256 lastToken = ownedTokens[_from][lastTokenIndex];
        ownedTokens[_from][tokenIndex] = lastToken;
        ownedTokens[_from][lastTokenIndex] = 0;
        // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
        // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
        // the lastToken to the first position, and then dropping the element placed in the last position of the list
        ownedTokens[_from].length--;
        ownedTokensIndex[_tokenId] = 0;
        ownedTokensIndex[lastToken] = tokenIndex;
      }
      /**
       * @dev Internal function to mint a new token
       * Reverts if the given token ID already exists
       * @param _to address the beneficiary that will own the minted token
       * @param _tokenId uint256 ID of the token to be minted by the msg.sender
       */
      function _mint(address _to, uint256 _tokenId) internal {
        super._mint(_to, _tokenId);
        allTokensIndex[_tokenId] = allTokens.length;
        allTokens.push(_tokenId);
      }
      /**
       * @dev Internal function to burn a specific token
       * Reverts if the token does not exist
       * @param _owner owner of the token to burn
       * @param _tokenId uint256 ID of the token being burned by the msg.sender
       */
      function _burn(address _owner, uint256 _tokenId) internal {
        super._burn(_owner, _tokenId);
        // Clear metadata (if any)
        if (bytes(tokenURIs[_tokenId]).length != 0) {
          delete tokenURIs[_tokenId];
        }
        // Reorg all tokens array
        uint256 tokenIndex = allTokensIndex[_tokenId];
        uint256 lastTokenIndex = allTokens.length.sub(1);
        uint256 lastToken = allTokens[lastTokenIndex];
        allTokens[tokenIndex] = lastToken;
        allTokens[lastTokenIndex] = 0;
        allTokens.length--;
        allTokensIndex[_tokenId] = 0;
        allTokensIndex[lastToken] = tokenIndex;
      }
    }
    // File: openzeppelin-zos/contracts/ownership/Ownable.sol
    /**
     * @title Ownable
     * @dev The Ownable contract has an owner address, and provides basic authorization control
     * functions, this simplifies the implementation of "user permissions".
     */
    contract Ownable is Migratable {
      address public owner;
      event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
      /**
       * @dev The Ownable constructor sets the original `owner` of the contract to the sender
       * account.
       */
      function initialize(address _sender) public isInitializer("Ownable", "1.9.0") {
        owner = _sender;
      }
      /**
       * @dev Throws if called by any account other than the owner.
       */
      modifier onlyOwner() {
        require(msg.sender == owner);
        _;
      }
      /**
       * @dev Allows the current owner to transfer control of the contract to a newOwner.
       * @param newOwner The address to transfer ownership to.
       */
      function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0));
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
      }
    }
    // File: contracts/estate/IEstateRegistry.sol
    contract IEstateRegistry {
      function mint(address to, string metadata) external returns (uint256);
      function ownerOf(uint256 _tokenId) public view returns (address _owner); // from ERC721
      // Events
      event CreateEstate(
        address indexed _owner,
        uint256 indexed _estateId,
        string _data
      );
      event AddLand(
        uint256 indexed _estateId,
        uint256 indexed _landId
      );
      event RemoveLand(
        uint256 indexed _estateId,
        uint256 indexed _landId,
        address indexed _destinatary
      );
      event Update(
        uint256 indexed _assetId,
        address indexed _holder,
        address indexed _operator,
        string _data
      );
      event UpdateOperator(
        uint256 indexed _estateId,
        address indexed _operator
      );
      event UpdateManager(
        address indexed _owner,
        address indexed _operator,
        address indexed _caller,
        bool _approved
      );
      event SetLANDRegistry(
        address indexed _registry
      );
      event SetEstateLandBalanceToken(
        address indexed _previousEstateLandBalance,
        address indexed _newEstateLandBalance
      );
    }
    // File: contracts/minimeToken/IMinimeToken.sol
    interface IMiniMeToken {
    ////////////////
    // Generate and destroy tokens
    ////////////////
        /// @notice Generates `_amount` tokens that are assigned to `_owner`
        /// @param _owner The address that will be assigned the new tokens
        /// @param _amount The quantity of tokens generated
        /// @return True if the tokens are generated correctly
        function generateTokens(address _owner, uint _amount) external returns (bool);
        /// @notice Burns `_amount` tokens from `_owner`
        /// @param _owner The address that will lose the tokens
        /// @param _amount The quantity of tokens to burn
        /// @return True if the tokens are burned correctly
        function destroyTokens(address _owner, uint _amount) external returns (bool);
        /// @param _owner The address that's balance is being requested
        /// @return The balance of `_owner` at the current block
        function balanceOf(address _owner) external view returns (uint256 balance);
        event Transfer(address indexed _from, address indexed _to, uint256 _amount);
    }
    // File: contracts/estate/EstateStorage.sol
    contract LANDRegistry {
      function decodeTokenId(uint value) external pure returns (int, int);
      function updateLandData(int x, int y, string data) external;
      function setUpdateOperator(uint256 assetId, address operator) external;
      function setManyUpdateOperator(uint256[] landIds, address operator) external;
      function ping() public;
      function ownerOf(uint256 tokenId) public returns (address);
      function safeTransferFrom(address, address, uint256) public;
      function updateOperator(uint256 landId) public returns (address);
    }
    contract EstateStorage {
      bytes4 internal constant InterfaceId_GetMetadata = bytes4(keccak256("getMetadata(uint256)"));
      bytes4 internal constant InterfaceId_VerifyFingerprint = bytes4(
        keccak256("verifyFingerprint(uint256,bytes)")
      );
      LANDRegistry public registry;
      // From Estate to list of owned LAND ids (LANDs)
      mapping(uint256 => uint256[]) public estateLandIds;
      // From LAND id (LAND) to its owner Estate id
      mapping(uint256 => uint256) public landIdEstate;
      // From Estate id to mapping of LAND id to index on the array above (estateLandIds)
      mapping(uint256 => mapping(uint256 => uint256)) public estateLandIndex;
      // Metadata of the Estate
      mapping(uint256 => string) internal estateData;
      // Operator of the Estate
      mapping (uint256 => address) public updateOperator;
      // From account to mapping of operator to bool whether is allowed to update content or not
      mapping(address => mapping(address => bool)) public updateManager;
      // Land balance minime token
      IMiniMeToken public estateLandBalance;
      // Registered balance accounts
      mapping(address => bool) public registeredBalance;
    }
    // File: contracts/estate/EstateRegistry.sol
    /**
     * @title ERC721 registry of every minted Estate and their owned LANDs
     * @dev Usings we are inheriting and depending on:
     * From ERC721Token:
     *   - using SafeMath for uint256;
     *   - using AddressUtils for address;
     */
    // solium-disable-next-line max-len
    contract EstateRegistry is Migratable, IEstateRegistry, ERC721Token, ERC721Receiver, Ownable, EstateStorage {
      modifier canTransfer(uint256 estateId) {
        require(isApprovedOrOwner(msg.sender, estateId), "Only owner or operator can transfer");
        _;
      }
      modifier onlyRegistry() {
        require(msg.sender == address(registry), "Only the registry can make this operation");
        _;
      }
      modifier onlyUpdateAuthorized(uint256 estateId) {
        require(_isUpdateAuthorized(msg.sender, estateId), "Unauthorized user");
        _;
      }
      modifier onlyLandUpdateAuthorized(uint256 estateId, uint256 landId) {
        require(_isLandUpdateAuthorized(msg.sender, estateId, landId), "unauthorized user");
        _;
      }
      modifier canSetUpdateOperator(uint256 estateId) {
        address owner = ownerOf(estateId);
        require(
          isApprovedOrOwner(msg.sender, estateId) || updateManager[owner][msg.sender],
          "unauthorized user"
        );
        _;
      }
      /**
       * @dev Mint a new Estate with some metadata
       * @param to The address that will own the minted token
       * @param metadata Set an initial metadata
       * @return An uint256 representing the new token id
       */
      function mint(address to, string metadata) external onlyRegistry returns (uint256) {
        return _mintEstate(to, metadata);
      }
      /**
       * @notice Transfer a LAND owned by an Estate to a new owner
       * @param estateId Current owner of the token
       * @param landId LAND to be transfered
       * @param destinatary New owner
       */
      function transferLand(
        uint256 estateId,
        uint256 landId,
        address destinatary
      )
        external
        canTransfer(estateId)
      {
        return _transferLand(estateId, landId, destinatary);
      }
      /**
       * @notice Transfer many tokens owned by an Estate to a new owner
       * @param estateId Current owner of the token
       * @param landIds LANDs to be transfered
       * @param destinatary New owner
       */
      function transferManyLands(
        uint256 estateId,
        uint256[] landIds,
        address destinatary
      )
        external
        canTransfer(estateId)
      {
        uint length = landIds.length;
        for (uint i = 0; i < length; i++) {
          _transferLand(estateId, landIds[i], destinatary);
        }
      }
      /**
       * @notice Get the Estate id for a given LAND id
       * @dev This information also lives on estateLandIds,
       *   but it being a mapping you need to know the Estate id beforehand.
       * @param landId LAND to search
       * @return The corresponding Estate id
       */
      function getLandEstateId(uint256 landId) external view returns (uint256) {
        return landIdEstate[landId];
      }
      function setLANDRegistry(address _registry) external onlyOwner {
        require(_registry.isContract(), "The LAND registry address should be a contract");
        require(_registry != 0, "The LAND registry address should be valid");
        registry = LANDRegistry(_registry);
        emit SetLANDRegistry(registry);
      }
      function ping() external {
        registry.ping();
      }
      /**
       * @notice Return the amount of tokens for a given Estate
       * @param estateId Estate id to search
       * @return Tokens length
       */
      function getEstateSize(uint256 estateId) external view returns (uint256) {
        return estateLandIds[estateId].length;
      }
      /**
       * @notice Return the amount of LANDs inside the Estates for a given address
       * @param _owner of the estates
       * @return the amount of LANDs
       */
      function getLANDsSize(address _owner) public view returns (uint256) {
        // Avoid balanceOf to not compute an unnecesary require
        uint256 landsSize;
        uint256 balance = ownedTokensCount[_owner];
        for (uint256 i; i < balance; i++) {
          uint256 estateId = ownedTokens[_owner][i];
          landsSize += estateLandIds[estateId].length;
        }
        return landsSize;
      }
      /**
       * @notice Update the metadata of an Estate
       * @dev Reverts if the Estate does not exist or the user is not authorized
       * @param estateId Estate id to update
       * @param metadata string metadata
       */
      function updateMetadata(
        uint256 estateId,
        string metadata
      )
        external
        onlyUpdateAuthorized(estateId)
      {
        _updateMetadata(estateId, metadata);
        emit Update(
          estateId,
          ownerOf(estateId),
          msg.sender,
          metadata
        );
      }
      function getMetadata(uint256 estateId) external view returns (string) {
        return estateData[estateId];
      }
      function isUpdateAuthorized(address operator, uint256 estateId) external view returns (bool) {
        return _isUpdateAuthorized(operator, estateId);
      }
      /**
      * @dev Set an updateManager for an account
      * @param _owner - address of the account to set the updateManager
      * @param _operator - address of the account to be set as the updateManager
      * @param _approved - bool whether the address will be approved or not
      */
      function setUpdateManager(address _owner, address _operator, bool _approved) external {
        require(_operator != msg.sender, "The operator should be different from owner");
        require(
          _owner == msg.sender
          || operatorApprovals[_owner][msg.sender],
          "Unauthorized user"
        );
        updateManager[_owner][_operator] = _approved;
        emit UpdateManager(
          _owner,
          _operator,
          msg.sender,
          _approved
        );
      }
      /**
       * @notice Set Estate updateOperator
       * @param estateId - Estate id
       * @param operator - address of the account to be set as the updateOperator
       */
      function setUpdateOperator(
        uint256 estateId,
        address operator
      )
        public
        canSetUpdateOperator(estateId)
      {
        updateOperator[estateId] = operator;
        emit UpdateOperator(estateId, operator);
      }
      /**
       * @notice Set Estates updateOperator
       * @param _estateIds - Estate ids
       * @param _operator - address of the account to be set as the updateOperator
       */
      function setManyUpdateOperator(
        uint256[] _estateIds,
        address _operator
      )
        public
      {
        for (uint i = 0; i < _estateIds.length; i++) {
          setUpdateOperator(_estateIds[i], _operator);
        }
      }
      /**
       * @notice Set LAND updateOperator
       * @param estateId - Estate id
       * @param landId - LAND to set the updateOperator
       * @param operator - address of the account to be set as the updateOperator
       */
      function setLandUpdateOperator(
        uint256 estateId,
        uint256 landId,
        address operator
      )
        public
        canSetUpdateOperator(estateId)
      {
        require(landIdEstate[landId] == estateId, "The LAND is not part of the Estate");
        registry.setUpdateOperator(landId, operator);
      }
     /**
       * @notice Set many LAND updateOperator
       * @param _estateId - Estate id
       * @param _landIds - LANDs to set the updateOperator
       * @param _operator - address of the account to be set as the updateOperator
       */
      function setManyLandUpdateOperator(
        uint256 _estateId,
        uint256[] _landIds,
        address _operator
      )
        public
        canSetUpdateOperator(_estateId)
      {
        for (uint i = 0; i < _landIds.length; i++) {
          require(landIdEstate[_landIds[i]] == _estateId, "The LAND is not part of the Estate");
        }
        registry.setManyUpdateOperator(_landIds, _operator);
      }
      function initialize(
        string _name,
        string _symbol,
        address _registry
      )
        public
        isInitializer("EstateRegistry", "0.0.2")
      {
        require(_registry != 0, "The registry should be a valid address");
        ERC721Token.initialize(_name, _symbol);
        Ownable.initialize(msg.sender);
        registry = LANDRegistry(_registry);
      }
      /**
       * @notice Handle the receipt of an NFT
       * @dev The ERC721 smart contract calls this function on the recipient
       * after a `safetransfer`. 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)"))`
       */
      function onERC721Received(
        address _operator,
        address _from,
        uint256 _tokenId,
        bytes _data
      )
        public
        onlyRegistry
        returns (bytes4)
      {
        uint256 estateId = _bytesToUint(_data);
        _pushLandId(estateId, _tokenId);
        return ERC721_RECEIVED;
      }
      /**
       * @dev Creates a checksum of the contents of the Estate
       * @param estateId the estateId to be verified
       */
      function getFingerprint(uint256 estateId)
        public
        view
        returns (bytes32 result)
      {
        result = keccak256(abi.encodePacked("estateId", estateId));
        uint256 length = estateLandIds[estateId].length;
        for (uint i = 0; i < length; i++) {
          result ^= keccak256(abi.encodePacked(estateLandIds[estateId][i]));
        }
        return result;
      }
      /**
       * @dev Verifies a checksum of the contents of the Estate
       * @param estateId the estateid to be verified
       * @param fingerprint the user provided identification of the Estate contents
       */
      function verifyFingerprint(uint256 estateId, bytes fingerprint) public view returns (bool) {
        return getFingerprint(estateId) == _bytesToBytes32(fingerprint);
      }
      /**
       * @dev Safely transfers the ownership of multiple Estate IDs to another address
       * @dev Delegates to safeTransferFrom for each transfer
       * @dev Requires the msg sender to be the owner, approved, or operator
       * @param from current owner of the token
       * @param to address to receive the ownership of the given token ID
       * @param estateIds uint256 array of IDs to be transferred
      */
      function safeTransferManyFrom(address from, address to, uint256[] estateIds) public {
        safeTransferManyFrom(
          from,
          to,
          estateIds,
          ""
        );
      }
      /**
       * @dev Safely transfers the ownership of multiple Estate IDs to another address
       * @dev Delegates to safeTransferFrom for each transfer
       * @dev Requires the msg sender to be the owner, approved, or operator
       * @param from current owner of the token
       * @param to address to receive the ownership of the given token ID
       * @param estateIds uint256 array of IDs to be transferred
       * @param data bytes data to send along with a safe transfer check
      */
      function safeTransferManyFrom(
        address from,
        address to,
        uint256[] estateIds,
        bytes data
      )
        public
      {
        for (uint i = 0; i < estateIds.length; i++) {
          safeTransferFrom(
            from,
            to,
            estateIds[i],
            data
          );
        }
      }
      /**
       * @dev update LAND data owned by an Estate
       * @param estateId Estate
       * @param landId LAND to be updated
       * @param data string metadata
       */
      function updateLandData(uint256 estateId, uint256 landId, string data) public {
        _updateLandData(estateId, landId, data);
      }
      /**
       * @dev update LANDs data owned by an Estate
       * @param estateId Estate id
       * @param landIds LANDs to be updated
       * @param data string metadata
       */
      function updateManyLandData(uint256 estateId, uint256[] landIds, string data) public {
        uint length = landIds.length;
        for (uint i = 0; i < length; i++) {
          _updateLandData(estateId, landIds[i], data);
        }
      }
      function transferFrom(address _from, address _to, uint256 _tokenId)
      public
      {
        uint256 estateSize = estateLandIds[_tokenId].length;
        require(estateSize != 0, "The Estate should not be empty");
        updateOperator[_tokenId] = address(0);
        _updateEstateLandBalance(_from, _to, estateSize);
        super.transferFrom(_from, _to, _tokenId);
      }
      // check the supported interfaces via ERC165
      function _supportsInterface(bytes4 _interfaceId) internal view returns (bool) {
        // solium-disable-next-line operator-whitespace
        return super._supportsInterface(_interfaceId)
          || _interfaceId == InterfaceId_GetMetadata
          || _interfaceId == InterfaceId_VerifyFingerprint;
      }
      /**
       * @dev Internal function to mint a new Estate with some metadata
       * @param to The address that will own the minted token
       * @param metadata Set an initial metadata
       * @return An uint256 representing the new token id
       */
      function _mintEstate(address to, string metadata) internal returns (uint256) {
        require(to != address(0), "You can not mint to an empty address");
        uint256 estateId = _getNewEstateId();
        _mint(to, estateId);
        _updateMetadata(estateId, metadata);
        emit CreateEstate(to, estateId, metadata);
        return estateId;
      }
      /**
       * @dev Internal function to update an Estate metadata
       * @dev Does not require the Estate to exist, for a public interface use `updateMetadata`
       * @param estateId Estate id to update
       * @param metadata string metadata
       */
      function _updateMetadata(uint256 estateId, string metadata) internal {
        estateData[estateId] = metadata;
      }
      /**
       * @notice Return a new unique id
       * @dev It uses totalSupply to determine the next id
       * @return uint256 Representing the new Estate id
       */
      function _getNewEstateId() internal view returns (uint256) {
        return totalSupply().add(1);
      }
      /**
       * @dev Appends a new LAND id to an Estate updating all related storage
       * @param estateId Estate where the LAND should go
       * @param landId Transfered LAND
       */
      function _pushLandId(uint256 estateId, uint256 landId) internal {
        require(exists(estateId), "The Estate id should exist");
        require(landIdEstate[landId] == 0, "The LAND is already owned by an Estate");
        require(registry.ownerOf(landId) == address(this), "The EstateRegistry cannot manage the LAND");
        estateLandIds[estateId].push(landId);
        landIdEstate[landId] = estateId;
        estateLandIndex[estateId][landId] = estateLandIds[estateId].length;
        address owner = ownerOf(estateId);
        _updateEstateLandBalance(address(registry), owner, 1);
        emit AddLand(estateId, landId);
      }
      /**
       * @dev Removes a LAND from an Estate and transfers it to a new owner
       * @param estateId Current owner of the LAND
       * @param landId LAND to be transfered
       * @param destinatary New owner
       */
      function _transferLand(
        uint256 estateId,
        uint256 landId,
        address destinatary
      )
        internal
      {
        require(destinatary != address(0), "You can not transfer LAND to an empty address");
        uint256[] storage landIds = estateLandIds[estateId];
        mapping(uint256 => uint256) landIndex = estateLandIndex[estateId];
        /**
         * Using 1-based indexing to be able to make this check
         */
        require(landIndex[landId] != 0, "The LAND is not part of the Estate");
        uint lastIndexInArray = landIds.length.sub(1);
        /**
         * Get the landIndex of this token in the landIds list
         */
        uint indexInArray = landIndex[landId].sub(1);
        /**
         * Get the landId at the end of the landIds list
         */
        uint tempTokenId = landIds[lastIndexInArray];
        /**
         * Store the last token in the position previously occupied by landId
         */
        landIndex[tempTokenId] = indexInArray.add(1);
        landIds[indexInArray] = tempTokenId;
        /**
         * Delete the landIds[last element]
         */
        delete landIds[lastIndexInArray];
        landIds.length = lastIndexInArray;
        /**
         * Drop this landId from both the landIndex and landId list
         */
        landIndex[landId] = 0;
        /**
         * Drop this landId Estate
         */
        landIdEstate[landId] = 0;
        address owner = ownerOf(estateId);
        _updateEstateLandBalance(owner, address(registry), 1);
        registry.safeTransferFrom(this, destinatary, landId);
        emit RemoveLand(estateId, landId, destinatary);
      }
      function _isUpdateAuthorized(address operator, uint256 estateId) internal view returns (bool) {
        address owner = ownerOf(estateId);
        return isApprovedOrOwner(operator, estateId)
          || updateOperator[estateId] == operator
          || updateManager[owner][operator];
      }
      function _isLandUpdateAuthorized(
        address operator,
        uint256 estateId,
        uint256 landId
      )
        internal returns (bool)
      {
        return _isUpdateAuthorized(operator, estateId) || registry.updateOperator(landId) == operator;
      }
      function _bytesToUint(bytes b) internal pure returns (uint256) {
        return uint256(_bytesToBytes32(b));
      }
      function _bytesToBytes32(bytes b) internal pure returns (bytes32) {
        bytes32 out;
        for (uint i = 0; i < b.length; i++) {
          out |= bytes32(b[i] & 0xFF) >> i.mul(8);
        }
        return out;
      }
      function _updateLandData(
        uint256 estateId,
        uint256 landId,
        string data
      )
        internal
        onlyLandUpdateAuthorized(estateId, landId)
      {
        require(landIdEstate[landId] == estateId, "The LAND is not part of the Estate");
        int x;
        int y;
        (x, y) = registry.decodeTokenId(landId);
        registry.updateLandData(x, y, data);
      }
      /**
       * @dev Set a new estate land balance minime token
       * @param _newEstateLandBalance address of the new estate land balance token
       */
      function _setEstateLandBalanceToken(address _newEstateLandBalance) internal {
        require(_newEstateLandBalance != address(0), "New estateLandBalance should not be zero address");
        emit SetEstateLandBalanceToken(estateLandBalance, _newEstateLandBalance);
        estateLandBalance = IMiniMeToken(_newEstateLandBalance);
      }
       /**
       * @dev Register an account balance
       * @notice Register land Balance
       */
      function registerBalance() external {
        require(!registeredBalance[msg.sender], "Register Balance::The user is already registered");
        // Get balance of the sender
        uint256 currentBalance = estateLandBalance.balanceOf(msg.sender);
        if (currentBalance > 0) {
          require(
            estateLandBalance.destroyTokens(msg.sender, currentBalance),
            "Register Balance::Could not destroy tokens"
          );
        }
        // Set balance as registered
        registeredBalance[msg.sender] = true;
        // Get LAND balance
        uint256 newBalance = getLANDsSize(msg.sender);
        // Generate Tokens
        require(
          estateLandBalance.generateTokens(msg.sender, newBalance),
          "Register Balance::Could not generate tokens"
        );
      }
      /**
       * @dev Unregister an account balance
       * @notice Unregister land Balance
       */
      function unregisterBalance() external {
        require(registeredBalance[msg.sender], "Unregister Balance::The user not registered");
        // Set balance as unregistered
        registeredBalance[msg.sender] = false;
        // Get balance
        uint256 currentBalance = estateLandBalance.balanceOf(msg.sender);
        // Destroy Tokens
        require(
          estateLandBalance.destroyTokens(msg.sender, currentBalance),
          "Unregister Balance::Could not destroy tokens"
        );
      }
      /**
       * @dev Update account balances
       * @param _from account
       * @param _to account
       * @param _amount to update
       */
      function _updateEstateLandBalance(address _from, address _to, uint256 _amount) internal {
        if (registeredBalance[_from]) {
          estateLandBalance.destroyTokens(_from, _amount);
        }
        if (registeredBalance[_to]) {
          estateLandBalance.generateTokens(_to, _amount);
        }
      }
      /**
       * @dev Set a estate land balance minime token hardcoded because of the
       * contraint of the proxy for using an owner
       * Mainnet: 0x8568f23f343694650370fe5e254b55bfb704a6c7
       */
      function setEstateLandBalanceToken() external {
        require(estateLandBalance == address(0), "estateLandBalance was set");
        _setEstateLandBalanceToken(address(0x8568f23f343694650370fe5e254b55bfb704a6c7));
      }
    }