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

以太坊上验证ZenGo MPC协议签名失败求助

解决ZenGo MPC签名在以太坊验证无效的问题

以下是几个直接的排查和解决方向:

1. 检查s值是否符合EIP-2规范

以太坊要求签名的s值必须小于secp256k1曲线阶的一半(n/2 = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0)。

  • 你提供的s十六进制为0x01ca2ac83a124629d9fb194019c2c674a79520b00dbfd7216d3a952807eb500b,计算后确认它小于n/2,这一步没问题;但后续遇到其他签名时,若s大于n/2,必须用n - s替换原s值。

2. 确认签名的哈希前缀匹配

ZenGo签名的消息哈希必须和以太坊验证时使用的完全一致:

  • 如果是签名普通消息,以太坊会自动添加前缀:"\x19Ethereum Signed Message:\n" + 消息长度 + 原始消息,再对拼接后的内容做keccak256哈希。要确保ZenGo是对这个带前缀的哈希签名,而非原始消息的哈希。
  • 如果是签名交易,必须严格遵循EIP-155的交易结构,包含链ID、nonce、gasPrice等字段,哈希计算要符合以太坊交易编码规则。

3. 修正Solidity验证的参数格式

转换签名参数

将你提供的r、s、recid转换为Solidity可用格式:

  • r十六进制:0xd4804232e10807ca5662de737e72248abd1775902064b687098568e5d1a41c71
  • s十六进制:0x01ca2ac83a124629d9fb194019c2c674a79520b00dbfd7216d3a952807eb500b
  • v值:普通消息签名时,v = recid + 27(你的recid为0,所以v=27);EIP-155交易签名时,v = recid + 35 + 2 * chainId(比如链ID为1时,v=35或36)。

示例Solidity验证代码

用ecrecover直接验证:

pragma solidity ^0.8.0;

contract SignatureVerifier {
    function verify(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s,
        address expectedSigner
    ) public pure returns (bool) {
        address recovered = ecrecover(hash, v, r, s);
        return recovered == expectedSigner;
    }
}

用OpenZeppelin的ECDSA库简化验证:

pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

contract SignatureVerifier {
    using ECDSA for bytes32;

    function verify(
        bytes32 hash,
        bytes memory signature,
        address expectedSigner
    ) public pure returns (bool) {
        return hash.recover(signature) == expectedSigner;
    }
}

注意:signature参数是r(32字节) + s(32字节) + v(1字节)拼接后的bytes数据。

4. 验证公钥到地址的转换

先将你提供的压缩公钥转换为以太坊地址,确认是否和预期签名者地址一致:

  • 压缩公钥十六进制:0x02fb15ead8ede3b8a453421285467d84f93e91ba417b96d5a1c05e561978f582f8
  • 地址计算示例(Node.js):
    const keccak256 = require('keccak256');
    const pubKey = Buffer.from('fb15ead8ede3b8a453421285467d84f93e91ba417b96d5a1c05e561978f582f8', 'hex');
    const address = '0x' + keccak256(pubKey).slice(-20).toString('hex');
    // 用此地址对比ecrecover返回的地址
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:12:50