1

I'm trying without success to get signed Metamask message confirmed with ethereumjs-util in the backend.

Metamask appears to the user, they can sign the message - but when the message is being verified on the back end, I get an error.

Number can only safely store up to 53 bits
at assert (project\node_modules\ethereumjs-util\node_modules\bn.js\lib\bn.js:6:21)
    at BN.toNumber (project\node_modules\ethereumjs-util\node_modules\bn.js\lib\bn.js:547:7)
    at Object.exports.bufferToInt (project\node_modules\ethereumjs-util\dist\bytes.js:148:55)
    at Object.exports.fromRpcSig (project\node_modules\ethereumjs-util\dist\signature.js:76:21)
    at project\Routes\dashboard.js:21:32 ## will mark this in backend

The signature is a 132 character hex, starting with 0x

Backend code - Node with Express

var ethUtil = require('ethereumjs-util');

var sig = req.query.sig;
console.log(sig + " length: " + sig.length);

var message = 'data';
const messageBuffer = Buffer.from(message);
const messageHash = ethUtil.hashPersonalMessage(messageBuffer);
const signatureBuffer = Buffer.from(sig);
const sigDecoded = ethUtil.fromRpcSig(signatureBuffer); ### this line is where it throws the Number can only safely store up to 53 bits error

// Recover Address
var recoveredPub = ethUtil.ecrecover(messageHash, sigDecoded.v, sigDecoded.r, sigDecoded.s)
var recoveredAddress = ethUtil.pubToAddress(recoveredPub).toString("hex")


Backend package.json

"ethereumjs-util": "^7.0.10",
"web3": "^1.3.6"

Front end code

import('eth-sig-util');
import('axios');
import(web3);
      
window.ethereum.sendAsync({ id: 1, method: 'personal_sign', params: [ web3.utils.fromUtf8("data"), window.ethereum.selectedAddress] },
    function(err, result) {
        console.log(result);
        let sig = result.result;
        axios.get("http://myhost:8000/authenticate/" , { params: { sig }});
    }
)

Front end packages.json

"axios": "^0.21.1",
"vue": "^3.0.0",
"web3": "^1.3.6"

I've followed all the examples I can find online, including Sign message with Metamask and verify with ethereumjs-utils but after working hours on this I'm getting nowhere.

2 Answers 2

1

I recently managed this in node js (inside an n8n custom function actually)

const { verifyMessage } = require('@ethersproject/wallet') // https://docs.ethers.io/v5/single-page/#/v5/api/utils/signing-key/-%23-utils-verifyMessage

const recoveredAddress = verifyMessage(signedMessage, signature).toLowerCase()
const isSignerMatching = !!(recoveredAddress === expectedAddress.toLowerCase())

actually finding out how to import it properly was the most complicated!
as ethers.utils didn't have the promised function!

0

Sorted finally

Front end should look like this:

var message = 'data';
const messageBuffer = Buffer.from(message);
const messageHash = ethUtil.hashPersonalMessage(messageBuffer);
const sigDecoded = ethUtil.fromRpcSig(sig);
1
  • i also tried to do this step by step with Buffer conversions, but the below answer is much cleaner.
    – gotjosh
    Feb 10, 2022 at 18:30

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.