Web3.js: `web3.eth.accounts.sign` and Solidity's `ecrecover` Mismatch

Created on 14 Jul 2018  路  1Comment  路  Source: ChainSafe/web3.js

Software versions:
web3.version: '1.0.0-beta.34'
solidity version: 0.4.23

Message: 0xF7Dc813B5c746F777DD29c94b7558ADE7577064e
Signer's address: 0x78fef8c1c50cb9fd16cf505d8b30d450d6241020
Signer's private key: 6c88dfd66a3c4294e3a0243218221f4337a6faa9c6b83380ec6f3d5ede3db982

Web3 1.0.0 code

Input

web3.eth.accounts.sign(web3.utils.soliditySha3({
    t:'bytes20',
    v:'0xF7Dc813B5c746F777DD29c94b7558ADE7577064e'
}),'6c88dfd66a3c4294e3a0243218221f4337a6faa9c6b83380ec6f3d5EDE3db982')

Output

{ message: '0xa5d1ba1b6cf051fc6b0546230f9fb40a85b0ee7ff6fd98a4c9bffcc7ac4d49f1',
  messageHash: '0x00d14137f83c1af34217797a1b2730e02a6f60f61a955e7fc9f9e2d66031e983',
  v: '0x1b',
  r: '0x51e1b948a53414a1f14ff9188788a074205fd3ede9bf76bcf3dc45e75d2156ca',
  s: '0x7f413510c52f6a0e4b9c7abf2ffc69aca83583a15d0b74f8ecdc3e77bb8dcbec',
  signature: '0x51e1b948a53414a1f14ff9188788a074205fd3ede9bf76bcf3dc45e75d2156ca7f413510c52f6a0e4b9c7abf2ffc69aca83583a15d0b74f8ecdc3e77bb8dcbec1b' }

Solidity 0.4.23 code

Input

function test(bytes signature, bytes20 addr) public {
  bytes32 hash = keccak256(abi.encodePacked(
    "\x19Ethereum Signed Message:\n32",
    keccak256(abi.encodePacked(addr)))
  );
  address minedAddress = hash.recover(signature); // ECRecovery.sol recover by OpenZeppelin
  uint256 reward = checkFind(minedAddress);

  emit check(minedAddress, hash, bytes20(addr));
}

Output

"recovered": "0x941b1d54B976e2D4c01C6e2929372B0a87268D55",
"hashed": "0x00d14137f83c1af34217797a1b2730e02a6f60f61a955e7fc9f9e2d66031e983",
"addr": "0xf7dc813b5c746f777dd29c94b7558ade7577064e"

The problem here is that the hashed message, before signing, matches in both web3 and solidity. However, after the actual signature is performed, ecrecover gets an incorrect address. I've tried different combinations, but I can't manage to find where the discrepancy lies.
Any ideas? I hope I'm not missing something obvious. From what I've seen the signature API methods are a very weak spot for web3 and Ethereum.

(Feel free to test with the private key posted above. It's a throwaway.)

Most helpful comment

Silly mistake. For future reference, the private key also needs the leading 0x.

>All comments

Silly mistake. For future reference, the private key also needs the leading 0x.

Was this page helpful?
0 / 5 - 0 ratings