You need to enable JavaScript to run this app. web3.eth.personal.sign签名后ecrecover无法获取正确签名者地址
优惠活动
大模型
产品
解决方案
定价
更多

web3.eth.personal.sign签名后ecrecover无法获取正确签名者地址

问题原因
  • web3.eth.personal.sign 遵循EIP-191签名标准,签名时会自动为传入的消息添加前缀 \x19Ethereum Signed Message:\n + 消息长度,再做一次哈希运算。你当前合约直接使用原始消息哈希作为ecrecover的输入,两边哈希值不匹配,导致签名地址恢复错误。
  • 部分节点返回的签名v值为0或1,而Solidity的ecrecover要求v值为27或28,未做转换也会导致恢复失败。
解决方案1:修改Solidity合约(推荐,兼容EIP-191标准)
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;

contract Example {
    function signature(uint256 tokenId, uint8 v, bytes32 r, bytes32 s) public view returns(address) {
        // 计算原始消息哈希
        bytes32 messageHash = keccak256(abi.encodePacked(this, tokenId));
        // 拼接EIP-191标准签名前缀,32对应原始消息哈希的字节长度
        bytes32 ethSignedMessageHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", messageHash));
        // 兼容v值为0/1的情况
        if (v < 27) {
            v += 27;
        }
        return ecrecover(ethSignedMessageHash, v, r, s);
    }
}
解决方案2:修改JavaScript代码(无需修改合约,兼容旧逻辑)

如果你不想调整合约代码,可以改用无自动前缀的签名方式,和之前废弃的web3.eth.sign逻辑保持一致:

async function sign(){
    const message = 1001;
    const orgmessage = web3.eth.abi.encodeParameter('uint256',message);
    const orginal = `0xf8e81D47203A594245E36C48e151709F0C19fBe8${orgmessage.slice(2)}`;
    const hash = web3.utils.keccak256(orginal);
    const accounts = await getCurrentAccount();
    // 调用eth_sign方法,和旧逻辑完全一致,大部分钱包仍支持该方法
    const signature = await web3.eth.sign(hash, accounts);
    const sig1 = signature.slice(2);
    const r = `0x${sig1.slice(0, 64)}`;
    const s = `0x${sig1.slice(64, 128)}`;
    let v = web3.utils.toDecimal(`0x${sig1.slice(128, 130)}`);
    // 统一转换v值为27/28
    if (v < 27) v += 27;
                                        
    console.log("h",hash);
    console.log("v",v);
    console.log("r",r);
    console.log("s",s);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 17:06:06