contract Substar {
    uint160 immutable _substar_base = 0x008888888888888888888888880000000000000000;
    uint32  _star_no = 0;
    mapping (address => address) private _star_substar_base;
    mapping (address => address) private _substar_base_star;
    
    /**
     * @dev Determine whether an address is a sub-address.
     */
    function isSubstar(address substar) public pure returns(bool){
        return uint160(substar) & 0x00FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000 == _substar_base;
    }

    /**
     * @dev Get the sub-address identification base the main address.
     */
    function getSubstarBase(address star) public view returns(address){
        return _star_substar_base[star];
    }
    
    /**
     * @dev Returns the main address of the subaddress.
     */
    function getStarBySubstar(address substar) public view returns(address){
        return _substar_base_star[_fetchSubstarBase(substar)];
    }

    /**
     * @dev Get the segment identifier part of the subaddress.
     */
    function _fetchSubstarBase(address substar) internal pure returns(address){
        return address(uint160(substar) & 0x00FFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF);
    }
    
    /**
     * @dev Generate the base address of the sub-address space for the address.
     */
    function _generateSubstarBase(address star) internal virtual{
        require(!isSubstar(star), "it's substar, can not generate substar base.");
        // exists substar base?
        if(getSubstarBase(star) == address(0)){
            _star_no++;
            address substarBase = address(_substar_base | _star_no); 
            _star_substar_base[star] = substarBase;
            _substar_base_star[substarBase] = star;
        }
    }
    
    event SubstarTransfer(address indexed from, address indexed to, address indexed star, uint256 value);
}
/**
 * @dev Specify a specific address as a sub-address, so that the main address 
 * can allocate about 1 million sub-address space for application identification. 
 * 
 */
function _generateSubstarBase(address star) internal virtual{
    require(!isSubstar(star), "it's substar, can not generate substar base.");
    // exists substar base?
    if(getSubstarBase(star) == address(0)){
        _star_no++;
        address substarBase = address(_substar_base | _star_no); 
        _star_substar_base[star] = substarBase;
        _substar_base_star[substarBase] = star;
    }
}

/**
 * @dev Generate the base address of the sub-address space for the address.
 */