Sign message with web3 and verify with openzeppelin-solidity ECDSA.sol

by Rob Hitchens - B9lab   Last Updated October 19, 2019 06:28 AM - source

I'm trying to get a little example working with ECDSA.sol here:

This contract:

  1. Generate a random(ish) bytes32 (stub for a future message digest).
  2. Morph it into an EthSignedHash with keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
  3. Use ecrecover to work out who signed a message.
pragma solidity 0.5.8;

import "../../node_modules/openzeppelin-solidity/contracts/cryptography/ECDSA.sol";

contract Sigs {

    using ECDSA for bytes32;

    function rndHash() public view returns(bytes32) {
        return keccak256(abi.encodePacked(block.number));

    function ethSignedHash(bytes32 messageHash) public pure returns(bytes32) {
        return messageHash.toEthSignedMessageHash();

    function recover(bytes32 hash, bytes memory signature) public pure returns(address) {
        return hash.recover(signature);

On the client side:

  1. Conjure up a random(ish) message.
  2. Make an ethHash of the message.
  3. Sign it.
  4. Send ethHash and the signature to ecRecover and get the signer address.

I'm not sure what I'm missing. I think the original message hash should be signed and EIP-712 does the "Ethereum Signing", so I should send the "Ethereum Hash" to ecrecover (as implemented in ECDSA.sol). In any case, no combination brings any joy.

var Sigs = artifacts.require("./Junk/Sigs");

contract("Sigs", accounts => {

  var signer;

  beforeEach(async () => {
    signer = accounts[0];
    sigs = await{from: signer}); 

  it("should recover signer address.", async () =>  {

    console.log("SIGNER: ", signer);

    var random  = await sigs.rndHash({from: signer});
    var ethHash = await sigs.ethSignedHash(random);

    // four possible combinations tried for the next step :/
    var signature = await web3.eth.sign(random, signer);    // sign the random hash or the ethHash
    var recovered = await sigs.recover(ethHash, signature); // recover from the random hash or the ethHash

    console.log("random1: ", random);
    console.log("signature: ", signature);
    console.log("recovered: ", recovered);

    assert.strictEqual(recovered, signer, "The recovered signature does not match the signer.");


I'd be very grateful if someone can sort me out.

Truffle v5.0.41 (core: 5.0.41)
Solidity - 0.5.8 (solc-js)
Node v8.10.0
Web3.js v1.2.1


Related Questions

Digital Signature Prefix Version Compatibility for web3

Updated November 19, 2018 15:28 PM

I need help with signatures

Updated July 07, 2017 20:28 PM

OpenZeppelin ECRecovery does not work

Updated May 19, 2018 16:28 PM