首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >go-ethereum提供与nodejs ethers不同的签名

go-ethereum提供与nodejs ethers不同的签名
EN

Stack Overflow用户
提问于 2020-05-08 23:08:49
回答 1查看 762关注 0票数 1

我需要用golang制作的签名,可以在nodejs中验证,反之亦然(使用以太钱包/私钥)。但是我使用的两个库为消息签名提供了不同的结果。我不知道是因为我在什么地方犯了错,还是签名算法不同。我尝试了其他选项,但找不到在两边都能给出相同结果的东西。

Golang代码与"go-ethereum":

代码语言:javascript
复制
package main

import (
    "bytes"
    "crypto/ecdsa"
    "fmt"

    "github.com/ethereum/go-ethereum/common/hexutil"
    "github.com/ethereum/go-ethereum/crypto"
)

func main() {

    hexPrivateKey := "0xae78c8b502571dba876742437f8bc78b689cf8518356c0921393d89caaf284ce"
    dataToSign := "bou"

    privateKey, err := crypto.HexToECDSA(hexPrivateKey[2:])
    if err != nil {
        log.Fatal(err)
    }

    // keccak256 hash of the data
    dataBytes := []byte(dataToSign)
    hashData := crypto.Keccak256Hash(dataBytes)

    signatureBytes, err := crypto.Sign(hashData.Bytes(), privateKey)
    if err != nil {
        log.Fatal(err)
    }

    signature = hexutil.Encode(signatureBytes)

    fmt.Println(signature) // 0xc83d417a3b99535e784a72af0d9772c019c776aa0dfe4313c001a5548f6cf254477f5334c30da59531bb521278edc98f1959009253dda4ee9f63fe5562ead5aa00
}

带有ethers的nodejs代码:

代码语言:javascript
复制
import { ethers } from 'ethers';

let hexPrivateKey = "0xae78c8b502571dba876742437f8bc78b689cf8518356c0921393d89caaf284ce";
let dataToSign := "bou"

let wallet = new ethers.Wallet(hexPrivateKey);

// keccak256 hash of the data
let hashData = ethers.utils.id(dataToSign);

let signature = await wallet.signMessage(ethers.utils.arrayify(hashData));

console.log(signature); // 0x80512c504128c66590fc359fd1e663ec51144086beef775e4e3be14e949fdead5839d90f4789e80bb264dc90474148143b09c286d3d75ba33e20e4117bf5c2881c
EN

回答 1

Stack Overflow用户

发布于 2020-05-09 21:12:13

ethers.js的人发现了我的问题正如他们所解释的:https://github.com/ethers-io/ethers.js/issues/823#issuecomment-625953096,ethers.js的signMessage函数使用personal_sign格式的EIP-191,因此它在消息前面加上"\x19Ethereum Signed Message:\n"

为了在ethers.js中获得与golang相同的结果,我们必须使用原始的SigningKey,而不是钱包包装器:

代码语言:javascript
复制
const hexPrivateKey = "0xae78c8b502571dba876742437f8bc78b689cf8518356c0921393d89caaf284ce";
const signingKey = new ethers.utils.SigningKey(hexPrivateKey);

const signature = signingKey.signDigest(ethers.utils.id("bou"));
//{ r: '0xc83d417a3b99535e784a72af0d9772c019c776aa0dfe4313c001a5548f6cf254',
//  s: '0x477f5334c30da59531bb521278edc98f1959009253dda4ee9f63fe5562ead5aa',
//  _vs: '0x477f5334c30da59531bb521278edc98f1959009253dda4ee9f63fe5562ead5aa',
//  recoveryParam: 0,
//  v: 27 }

ethers.utils.joinSignature(signature);
// "0xc83d417a3b99535e784a72af0d9772c019c776aa0dfe4313c001a5548f6cf254477f5334c30da59531bb521278edc98f1959009253dda4ee9f63fe5562ead5aa1b"

唯一需要考虑的是,ethers.js中此签名的最后2位数字将不会与golang签名相同,因为ethers.js joinSignature函数在末尾使用v,但上面显示的golang签名在末尾使用recovery参数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61682191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档