I have the following (simplified) contract that uses ECDSA to validate message authenticity:

pragma solidity ^0.8.18;

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

contract ECDSATest {
    address public trustedSigner;

    constructor() {
      trustedSigner = msg.sender;

    function test(bytes calldata signature, string calldata message) public view returns (bool) {
        address signer = ECDSA.recover(keccak256(abi.encodePacked(message)), signature);
        return (signer == trustedSigner);

When I create signatures with Python (using Web3.py), valid signatures are recognized as expected. Here is the code on how I create signatures in Python:

message_hash = Web3.solidity_keccak(['string'], ['Hello World'])
signed_message = account.signHash(message_hash)
signature = signed_message.signature

However, I am not able to reproduce the same (valid) signature using ethers.js version 6 via NodeJS. Here I am using the following code to create a signature, but deriving the trustedSigner's address from it fails:

let messageHash = solidityPackedKeccak256(["string"], ["Hello World"]);
let signature = await trustedAccount.signMessage(getBytes(messageHash));

await myContract.connect(user1).test(getBytes(signature), "Hello World");

The account I am using to sign the messages is the same in both version. So I guess there is something wrong with how I create the signature via ethers.js. Any hint on how to do this properly?

1 Answer 1


For ethers.js version 6, the code will be slightly different:

    let signer = new ethers.SigningKey(privateKey);
    let messageHash = await ethers.solidityPackedKeccak256([ "string", "uint" ], [ message, message.length ] );
    let signature = signer.sign(messageHash);
  • thanks, this did the trick for me. What should be added is that signature.serialized needs to be passed to the smart contract, which is the concatenation of r, s and v. Dec 7, 2023 at 9:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.