contract ResolverContenthashSignerENS {

    /* public constant contractVersion */
    uint64 public constant CONTRACT_VERSION = (
        (4 << 32) + /* major */
        (1 << 16) + /* minor */
        0 /* bugfix */
    );

    bytes4 constant CONTENTHASH_INTERFACE_ID = 0xbc1c58d1;

    event ContenthashChanged(bytes hash);

    struct Signature {
        uint8 v;
        bytes32 r;
        bytes32 s;
    }

    struct Record {
        uint64 version;
        bytes contenthash;
    }

    address signer; /* signer address */

    Record record;

    /**
     * Constructor.
     * @param signerAddr The signer address.
     */
    constructor(address signerAddr) public {
        signer = signerAddr;
    }

    /**
     * Sets the contenthash associated with an ENS node.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param hash The contenthash to set
     */
    /*
    function setContenthash(bytes32 node, bytes calldata hash) external {
        require(
            false,
            "Function call not supported"
        );
    }
    */

    /**
     * Returns the contenthash associated with an ENS node.
     * @param node The ENS node to query.
     * @return The associated contenthash.
     */
    function contenthash(bytes32 node) external view returns (bytes memory) {
        return record.contenthash;
    }

    /**
     * Returns true if the resolver implements the interface specified by the provided hash.
     * @param interfaceID The ID of the interface to check for.
     * @return True if the contract implements the requested interface.
     */
    function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
        return interfaceID == CONTENTHASH_INTERFACE_ID;
    }

    /**
     * Sets the contenthash associated with an ENS node using a prebuild signature.
     * May be called by anyone with a valid signature.
     * @param hash The contenthash to set
     * @param version The version (which is part of the signature)
     * @param signature The signature over the keccak256(hash, version)
     */
    function setContenthashBySignature (
        bytes memory hash,
        uint64 version,
        Signature memory signature
    ) public
    {
        require(
            signer == verify(
                keccak256(
                    abi.encodePacked(
                        hash,
                        version
                    )
                ),
                signature
            ),
            "Invalid signature"
        );

        // update only if new version is higher than current version
        if (version > record.version) {
            record.contenthash = hash;
            record.version = version;
            emit ContenthashChanged(hash);
        }
    }

    /* internal functions */

    function verify(
        bytes32 _message,
        Signature memory signature
    ) internal pure returns (address)
    {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        bytes32 prefixedHash = keccak256(
            abi.encodePacked(
                prefix,
                _message
            )
        );
        return ecrecover(
            prefixedHash,
            signature.v,
            signature.r,
            signature.s
        );
    }

}
/*
 interface ENS {
 
 // Logged when the owner of a node assigns a new owner to a subnode.
 event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
 
 // Logged when the owner of a node transfers ownership to a new account.
 event Transfer(bytes32 indexed node, address owner);
 
 // Logged when the resolver for a node changes.
 event NewResolver(bytes32 indexed node, address resolver);
 
 // Logged when the TTL of a node changes
 event NewTTL(bytes32 indexed node, uint64 ttl);
 
 
 function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external;
 function setResolver(bytes32 node, address resolver) external;
 function setOwner(bytes32 node, address owner) external;
 function setTTL(bytes32 node, uint64 ttl) external;
 function owner(bytes32 node) external view returns (address);
 function resolver(bytes32 node) external view returns (address);
 function ttl(bytes32 node) external view returns (uint64);
 }
 */
function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
    return interfaceID == CONTENTHASH_INTERFACE_ID;
}

/**
 * Returns true if the resolver implements the interface specified by the provided hash.
 * @param interfaceID The ID of the interface to check for.
 * @return True if the contract implements the requested interface.
 */