Node.js go以太坊标志提供与nodejs以太不同的标志

Node.js go以太坊标志提供与nodejs以太不同的标志,node.js,cryptography,go-ethereum,Node.js,Cryptography,Go Ethereum,我需要在golang制作的签名,可在nodejs中验证,反之,需要以太坊钱包/私钥。 但是我使用的两个库为消息签名提供了不同的结果。我不知道是因为我在某个地方犯了错误,还是因为签名算法不同。我尝试了其他的选择,但找不到在双方都有相同结果的东西 go ethereum的Golang代码: package main import ( "bytes" "crypto/ecdsa" "fmt" "github.com/ethereum/go-ethereum/comm

我需要在golang制作的签名,可在nodejs中验证,反之,需要以太坊钱包/私钥。 但是我使用的两个库为消息签名提供了不同的结果。我不知道是因为我在某个地方犯了错误,还是因为签名算法不同。我尝试了其他的选择,但找不到在双方都有相同结果的东西

go ethereum的Golang代码:

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
}
使用以太网的nodejs代码:

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

ethers.js的人发现了我的问题。正如他们在那里解释的那样:,ethers.js的signMessage函数使用EIP-191和personal_sign格式,因此它在消息前面加上\x19Ethereum签名消息:\n

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

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"

唯一要考虑的事情是,在ESES.JS中这个签名的最后2个数字与Galang-JS不一样,因为Eth.JS CouthSo签署函数在结尾使用V,但是上面所示的Galang1使用了恢复参数。