Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Sign in
issue
issue
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 10
    • Issues 10
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar

新注册的用户请输入邮箱并保存,随后登录邮箱激活账号。后续可直接使用邮箱登录!

  • chainmaker
  • issueissue
  • Issues
  • #1610

Closed
Open
Opened Jun 08, 2026 by 18851838306@188518383063 of 19 tasks completed3/19 tasks

ChainMaker v3.0.0 EVM ecrecover returns zero address for valid secp256k1 recoverable signature

【问题分类】

  • bug
  • P2P网络相关(包含libp2p,liquid)
  • 链账户身份与权限相关(证书问题、public、多签投票问题)
  • 核心交易引擎相关(交易池、DAG)
  • 共识相关
  • 智能合约相关
  • 存储相关
  • SDK相关
  • 长安链CMC工具
  • 长安链管理台
  • 长安链浏览器
  • 长安链合约IDE
  • 长安链web签名插件
  • 跨链相关
  • 轻节点相关
  • 隐私计算相关
  • 密码学相关
  • 环境依赖
  • 其他补充:

【问题描述】

在 ChainMaker v3.0.0 的 EVM 合约中测试 ecrecover 时,发现对一组 65 字节 secp256k1 recoverable signature,ecrecover 始终返回零地址。

测试方式如下:

  1. 在 Solidity 合约中将签名拆分为 v/r/s
  2. 分别尝试:
    • ecrecover(hash, v, r, s)
    • ecrecover(hash, v + 27, r, s)
    • ecrecover(hash, v - 27, r, s)

测试使用合约:

pragma solidity 0.7.6;

contract EcrecoverDebug {
    event DebugResult(
        uint8 rawV,
        address rawAddr,
        address plus27Addr,
        address minus27Addr
    );

    function splitSignature(bytes memory sig)
        public
        pure
        returns (uint8 v, bytes32 r, bytes32 s)
    {
        require(sig.length == 65, "bad sig len");
        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            v := byte(0, mload(add(sig, 96)))
        }
    }

    function debugRecover(bytes32 hash, bytes memory sig)
        public
        returns (uint8 rawV, address rawAddr, address plus27Addr, address minus27Addr)
    {
        (rawV, bytes32 r, bytes32 s) = splitSignature(sig);
        rawAddr = ecrecover(hash, rawV, r, s);
        plus27Addr = ecrecover(hash, rawV + 27, r, s);
        minus27Addr = ecrecover(hash, rawV - 27, r, s);
        emit DebugResult(rawV, rawAddr, plus27Addr, minus27Addr);
    }

    function recoverRaw(bytes32 hash, bytes memory sig) public pure returns (address) {
        (uint8 v, bytes32 r, bytes32 s) = splitSignature(sig);
        return ecrecover(hash, v, r, s);
    }
}

测试参数 1:

hash:
0xf86fcb350fe0dd52c5eceef2a8a1bd1390ee06875a831075dff5d34bdaf530d5

sig:
0xd3c2126abbb1efcd64735ecb1d4078e59e5a464979d3bf0f1ac94f5b9c85e77c36a6d614ece8158a1130d7e88400d6e03c9d601f63240200b08d8980a0b0a41a01

返回结果:

[1, 0x0000000000000000000000000000000000000000,
   0x0000000000000000000000000000000000000000,
   0x0000000000000000000000000000000000000000,
   0x0000000000000000000000000000000000000000]

测试参数 2,仅将最后一个字节改为 00:

sig:
0xd3c2126abbb1efcd64735ecb1d4078e59e5a464979d3bf0f1ac94f5b9c85e77c36a6d614ece8158a1130d7e88400d6e03c9d601f63240200b08d8980a0b0a41a00

返回结果:

[0, 0x0000000000000000000000000000000000000000,
   0x0000000000000000000000000000000000000000,
   0x0000000000000000000000000000000000000000,
   0x0000000000000000000000000000000000000000]

实际结果:

  • 无论 v=0/1 还是兼容尝试 27/28,ecrecover 都返回零地址

预期结果:

  • 对于合法的 65 字节 secp256k1 recoverable signature,ecrecover 应恢复出正确地址,或与 Ethereum/geth 保持一致行为

初步怀疑与 vm-evm 中 ecRecover.go 的实现有关,关键逻辑包括:

  • v := input[63] - 27
  • recoverPubkey(append(input[64:128], v), input[:32])
  • btcec.RecoverCompact

希望协助确认:

  1. 当前 ChainMaker EVM ecrecover 是否保证与 Ethereum/geth 完全兼容
  2. 对于 r || s || v 格式的 secp256k1 recoverable signature,官方推荐输入格式是什么
  3. 该问题是否已知,后续版本是否已有修复

【相关日志文件】

当前无明显 panic.log。

【系统信息】

  • chainmaker-go version * : v3.0.0
  • OS & version * : CentOS 7
  • docker镜像 version: 暂不涉及
  • 管理台 version: 暂不涉及
  • 区块浏览器 version: 暂不涉及
  • 合约IDE version: 暂不涉及
  • web签名插件 version: 暂不涉及
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: chainmaker/issue#1610

Copyright © 2021 ChainMaker Org. All Rights Reserved. 长安链 版权所有。