Web3js
簽署 Metamask 消息並使用 ethereumjs-utils 7.0.10 進行驗證
我試圖在後端使用 ethereumjs-util 確認簽名的 Metamask 消息,但沒有成功。
Metamask 出現在使用者面前,他們可以對消息進行簽名 - 但是在後端驗證消息時,我收到錯誤消息。
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
簽名是一個 132 字元的十六進制,以 0x 開頭
後端程式碼- 帶有 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")
後端包.json
"ethereumjs-util": "^7.0.10", "web3": "^1.3.6"
前端程式碼
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 }}); } )
前端包.json
"axios": "^0.21.1", "vue": "^3.0.0", "web3": "^1.3.6"
我已經按照我可以在網上找到的所有範例進行操作,包括使用 Metamask 簽署消息並使用 ethereumjs-utils 進行驗證,但是在工作時間之後,我一無所獲。
最終排序
前端應該是這樣的:
var message = 'data'; const messageBuffer = Buffer.from(message); const messageHash = ethUtil.hashPersonalMessage(messageBuffer); const sigDecoded = ethUtil.fromRpcSig(sig);
我最近在節點 js 中管理了這個(實際上是在一個 n8n 自定義函式中)
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())
實際上找出如何正確導入它是最複雜的!
因為 ethers.utils 沒有承諾的功能!