You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web3.js签名消息方法异常:React简易示例问题排查

签名验证地址不一致的问题修复

你的核心问题是签名和验证时对消息的处理逻辑不匹配,导致哈希值不一致,最终恢复出的签名地址和原地址对不上:

  • web3.eth.sign是以太坊钱包签名的标准方法,它会自动给传入的消息添加固定前缀:"\x19Ethereum Signed Message:\n" + 消息长度,然后再计算哈希进行签名。但你在签名时提前对原消息做了sha3哈希,相当于让web3.eth.sign对哈希后的结果又加了前缀再哈希,签名的内容和验证时处理的内容完全不匹配。
  • 验证环节你把原消息转成Hex再哈希,完全没遵循签名时的标准前缀规则,自然无法正确恢复出签名地址。

修正后的代码

import './App.css';
import Web3 from "web3/dist/web3.min.js"
import React, { useState, useEffect } from 'react';

function App() {
  const [address, setAddress] = useState('');
  const [message, setMessage] = useState('ciao');
  const [signature, setSignature] = useState('');
  const [isValid, setIsValid] = useState(false);
  const [web3, setWeb3] = useState(null);

  useEffect(() => {
    async function getWeb3() {
      if (window.ethereum) {
        const web3 = new Web3(window.ethereum);
        await window.ethereum.enable();
        const accounts = await web3.eth.getAccounts();
        setAddress(accounts[0]);
        setWeb3(web3);
      }
    }
    getWeb3();
  }, []);

  const signMessage = async () => {
    // 直接传入原始消息,让web3.eth.sign按照标准流程处理前缀和哈希
    const signature = await web3.eth.sign(message, address);
    setSignature(signature);
  };

  const verifyMessage = async () => {
    // 直接用原始消息和签名调用recover,方法会自动处理标准前缀
    const signer = web3.eth.accounts.recover(message, signature);
    // 注意地址大小写问题,统一转成小写比较
    const isMatch = signer.toLowerCase() === address.toLowerCase();
    setIsValid(isMatch);
    console.log(isMatch ? "验证通过" : "验证失败");
  };

  return (
    <div className="App">
      <header className="App-header">
        <p>Sign Message: {message}</p>
        <button onClick={signMessage}>Sign</button>
        <p>Signature: {signature}</p>
        <button onClick={verifyMessage}>Verify</button>
        <p>Is Valid: {isValid ? 'True' : 'False'}</p>
      </header>
    </div>
  );
}

export default App;

关键修正点

  1. 签名函数:移除了提前计算messageHash的步骤,直接传入原始消息给web3.eth.sign,让它按照以太坊签名标准处理前缀和哈希。
  2. 验证函数:直接用原始消息和签名调用web3.eth.accounts.recover,该方法内部会自动添加标准前缀并计算正确的哈希,恢复出签名地址。同时增加了地址大小写统一比较,避免因地址大小写格式不同导致的匹配失败。

内容的提问来源于stack exchange,提问作者xitalianx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 09:55:31