Знак go - ethereum имеет другую подпись, чем nodejs эфиры - PullRequest
0 голосов
/ 08 мая 2020

Мне нужны подписи, сделанные в golang, проверяемые в nodejs и наоборот (с кошельками / закрытыми ключами ethereum). Но две библиотеки, которые я использую, дают разные результаты для подписи сообщения. Я не знаю, это потому, что я где-то ошибся или алгоритмы подписи разные. Я пробовал другие варианты, но не смог найти то, что дает одинаковые результаты с обеих сторон.

Golang код с «go - ethereum»:

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

1 Ответ

0 голосов
/ 09 мая 2020

Ребята из ethers. js нашли мою проблему. Как они там объясняют: https://github.com/ethers-io/ethers.js/issues/823#issuecomment -625953096 , функция signMessage эфиров. js использует EIP-191 с форматом personal_sign, поэтому он ставит перед сообщением префикс "\x19Ethereum Signed Message:\n".

Чтобы получить тот же результат в эфирах. js как в golang, мы должны использовать необработанный SigningKey, а не оболочку Wallet:

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"

Единственное, что нужно учитывать, это то, что последние 2 цифры этой подписи в эфирах. js не будут такими же, как golang, как в простых эфирах. js функция joinSignature использует v в конце, но golang, показанная выше, использует параметр восстановления в конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...