How to sign hashes with ethers.js v6 to get the signer with solidity

I have tried several ways of signing hashes with ethers.js which from front returns the signer correctly but in the contract deployed two years ago it is not able to pull the same signer.

This is the contract functións:

 function notarizeWithSign(bytes32 hash, bytes memory sig) public {
    require(hash != keccak256(abi.encodePacked("")), "hash vacio");
    require(records[hash] == address(0), "Documento ya notariado");
    require(notarizedAddress == msg.sender, "Usted no es el notario");
    require(notarizedAddress == recoverSigner(prefixed(hash), sig), "Documento no firmado por el notario");
    records[hash] = msg.sender;
    timestamps[hash] = block.timestamp;

    emit LogNotarized(hash, msg.sender, block.timestamp);
  }

  function recoverSigner(bytes32 message, bytes memory sig) internal pure returns (address) {
        (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);

        return ecrecover(message, v, r, s);
    }

    /// signature methods.
    function splitSignature(bytes memory sig)
        internal
        pure
        returns (
            uint8 v,
            bytes32 r,
            bytes32 s
        )
    {
        require(sig.length == 65);

        assembly {
            // first 32 bytes, after the length prefix.
            r := mload(add(sig, 32))
            // second 32 bytes.
            s := mload(add(sig, 64))
            // final byte (first byte of the next 32 bytes).
            v := byte(0, mload(add(sig, 96)))
        }

        return (v, r, s);
    }

    /// builds a prefixed hash to mimic the behavior of eth_sign.
    function prefixed(bytes32 hash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

This is one of the signature forms that works in front, the address address matches recoveredAddress, but the contract does not return the same result

 // Obtener la cuenta del usuario
        const signer = await provider.getSigner();
        const address = await signer.getAddress();
     

        const hash = ethers.hashMessage(inputData);
        // Firma directamente el string (dato en bruto)
        const signature = await signer.signMessage(hash);
      

        // Verificar la firma (obtener la dirección del firmante) sobre el string original
        const recoveredAddress = ethers.verifyMessage(hash, signature);

The solutions I have found are from ethers.js v5:

They ask to use the arraify function which is now non-existent in v6.

A common case is to sign a hash. In this case, if the hash is a string, it must be converted to an array first, using the arrayify utility function.

What is the way to sign with ethers.js so that my contract can correctly get the signer?

I have found a way for the contract to accept the signature:

Generation of the hash with the data as a string:

  const hashFromEthers = ethers.keccak256(ethers.toUtf8Bytes(inputData));

We generate the signature as follows:

 const address = await signer.getAddress();
     

        // const hash = ethers.hashMessage(inputData);
        // Firma directamente el string (dato en bruto)
        // const signature = await signer.signMessage(hashHook);
      const signature = await window.ethereum.request({
        method: "personal_sign",
        params: [hashFromEthers , address],
      });

If we send this data, the signature and the hash to the contract, it properly retrieves the signer. But now, on my front end, if I check the signer it tells me it doesn't match using the verifyMessage:

     const recoveredAddress = ethers.verifyMessage(hashFromEthers, signature);

I don't quite understand what is going on.

If I use the ethers signature method it properly retrieves the signer in front but in solidity it gives me another address.

If I use the “personal_sign” method of the metamask, in front ethers does not properly retrieve the signer, but in solidity, it does it properly.

Considering that I would like to have contracts that verify signatures, what is the right way to do all this with ethers.js v6?

Do I have to update the signature retrieval form in the contracts?

Why are there these discrepancies between recovery with ethers and with solidity?

I would appreciate any clarification.