I have an Ethereum Dapp, which requires the user to sign a transaction to prove their identity. The app uses web3.eth.personal.sign(nonce, coinbase)... to sign a nonce generated in my back end.

It seems that signing with only Metamask, and signing with Ledger Nano on Metamask produce different hashes. So my question is:

Is there a difference in how ledger signs transactions compared to web3.eth.personal.sign?

  • 2
    Having this same problem. My Nano X is producing a signature that I can't verify locally. I can make transactions on ethereum, but for whatever reason when I try to write code to verify the javascript + mm + ledger generated signature, on the server side (php), it fails to verify. Something to do with the recovery value (last byte) Oct 17, 2021 at 8:12
  • 1
    I'm having the same issue with my Nano S. Did you figure anything out?
    – Chin Leung
    Nov 10, 2021 at 20:48

1 Answer 1


I have this same problem and fixed it by replacing the v inside ledger signature curve:

def adapt_ledger(vrs):
  new_v = vrs[0]
  if new_v == 0:
    new_v = 27
  if new_v == 1:
    new_v = 28
  return (new_v, vrs[1], vrs[2])

Somehow ledger used 0 and 1 instead of 27-31.

I lost the source to this solution but I found it in a discussion somewhere. Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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