contract Zitetags is Owned {
    using SafeMath for uint;

    /* Initialize version number. */
    uint public version;

    /* Initialize Zer0net Db contract. */
    Zer0netDbInterface public zer0netDb;

    /* Initialize zitetag update notification/log event. */
    event ZitetagUpdate(
        bytes32 indexed zitetagId, 
        string zitetag, 
        string info
    );

    /* Constructor. */
    constructor() public {
        /* Set the version number. */
        version = now;

        /* Initialize Zer0netDb (eternal) storage database contract. */
        // NOTE We hard-code the address here, since it should never change.
        zer0netDb = Zer0netDbInterface(0xE865Fe1A1A3b342bF0E2fcB11fF4E3BCe58263af);
    }

    /**
     * @dev Only allow access to an authorized Zer0net administrator.
     */
    modifier onlyAuthBy0Admin() {
        /* Verify write access is only permitted to authorized accounts. */
        require(zer0netDb.getBool(keccak256(
            abi.encodePacked(msg.sender, '.has.auth.for.zitetags'))) == true);

        _;      // function code is inserted here
    }

    /**
     * @notice Retrieves the registration info for the given zitetag.
     * 
     * @dev Use the calculated hash to query the eternal database 
     *      for the `_zitetag` info.
     */
    function getInfo(string _zitetag) external view returns (string) {
        /* Calculate the zitetag's hash. */
        bytes32 hash = keccak256(abi.encodePacked('zitetag.', _zitetag));
        
        /* Retrieve the zitetag's info. */
        string memory info = zer0netDb.getString(hash);

        /* Return info. */
        return (info);
    }

    /**
     * @notice Set the zitetag's registration info.
     * 
     * @dev Calculate the `_zitetag` hash and use it to store the
     *      registration details in the eternal database.
     * 
     *      NOTE: JSON will be the object type for registration details.
     */
    function setInfo(
        string _zitetag, 
        string _info
    ) onlyAuthBy0Admin external returns (bool success) {
        /* Calculate the zitetag's hash. */
        bytes32 hash = keccak256(abi.encodePacked('zitetag.', _zitetag));
        
        /* Set the zitetag's info. */
        zer0netDb.setString(hash, _info);

        /* Emit event notification. */
        emit ZitetagUpdate(hash, _zitetag, _info);

        /* Return success. */
        return true;
    }

    /**
     * THIS CONTRACT DOES NOT ACCEPT DIRECT ETHER
     */
    function () public payable {
        /* Cancel this transaction. */
        revert('Oops! Direct payments are NOT permitted here.');
    }

    /**
     * Transfer Any ERC20 Token
     *
     * @notice Owner can transfer out any accidentally sent ERC20 tokens.
     *
     * @dev Provides an ERC20 interface, which allows for the recover
     *      of any accidentally sent ERC20 tokens.
     */
    function transferAnyERC20Token(
        address tokenAddress, uint tokens
    ) public onlyOwner returns (bool success) {
        return ERC20Interface(tokenAddress).transfer(owner, tokens);
    }
}
/*******************************************************************************
 *
 * @notice Zitetags Registrar Contract.
 *
 * @dev Zitetags are Namecoin (.bit) addresses that are used
 *      (similar to Twitter hashtags and traditional domain names) as a
 *      convenient alternative to users/clients when entering a 
 *      zite's Bitcoin public key.
 */
function getInfo(string _zitetag) external view returns (string) {
    /* Calculate the zitetag's hash. */
    bytes32 hash = keccak256(abi.encodePacked('zitetag.', _zitetag));
        
    /* Retrieve the zitetag's info. */
    string memory info = zer0netDb.getString(hash);

    /* Return info. */
    return (info);
}

/**
 * @notice Retrieves the registration info for the given zitetag.
 * 
 * @dev Use the calculated hash to query the eternal database 
 *      for the `_zitetag` info.
 */