Tengo esta transacción:
{
"blockHash": "0x163ad564b32bf17db9262391c2c9a5f191e4fd0b098ae5ce9d2e3e7dcde4bd70",
"blockNumber": "0x2",
"from": "0x55d40a83b8445c004df5964ce4a0e261b599c01a",
"gas": "0x76c0",
"gasPrice": "0x9184e72a000",
"hash": "0x5e97c5377da7864e5b82784c9e5335a2e075adfec3b075f5f2e5705733aacf8b",
"input": "0x",
"nonce": "0x8",
"to": "0x589724c5abf2bce219726477cf0a60fa09321380",
"transactionIndex": "0x0",
"value": "0x1",
"v": "0x1c",
"r": "0xfe084488847df1cf427f72784c4b1ba86526ed5f8ef0feb6bc51caf450d66e8b",
"s": "0x6226e5f4dd0d948b7014199faf018c27862c56faad0b49197057816dee9a7fa8"
}
Así que hice dos archivos a partir de los datos de la transacción anterior: msg (hash de transacción) y sig (r + s + v-27).
[root .eth]# hexdump -C msg
00000000 5e 97 c5 37 7d a7 86 4e 5b 82 78 4c 9e 53 35 a2 |^..7}..N[.xL.S5.|
00000010 e0 75 ad fe c3 b0 75 f5 f2 e5 70 57 33 aa cf 8b |.u....u...pW3...|
00000020
[root .eth]# hexdump -C sig
00000000 fe 08 44 88 84 7d f1 cf 42 7f 72 78 4c 4b 1b a8 |..D..}..B.rxLK..|
00000010 65 26 ed 5f 8e f0 fe b6 bc 51 ca f4 50 d6 6e 8b |e&._.....Q..P.n.|
00000020 62 26 e5 f4 dd 0d 94 8b 70 14 19 9f af 01 8c 27 |b&......p......'|
00000030 86 2c 56 fa ad 0b 49 19 70 57 81 6d ee 9a 7f a8 |.,V...I.pW.m....|
00000040 01 |.|
00000041
Luego escribí un programa en go para recuperar la clave pública:
[root@v48807 .eth]# cat recover-pk.go
package main
import (
"io/ioutil"
"fmt"
"os"
secp256k1 "github.com/ethereum/go-ethereum/crypto/secp256k1"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
msg, err := ioutil.ReadFile("msg")
check(err)
sig, err := ioutil.ReadFile("sig")
check(err)
pkbin, err := secp256k1.RecoverPubkey(msg, sig)
check(err)
f, err := os.Create("pkbin")
check(err)
defer f.Close()
n, err := f.Write(pkbin)
check(err)
fmt.Printf("wrote %d bytes\n", n)
}
Aquí hay un volcado de la clave pública resultante:
[root .eth]# hexdump -C pkbin
00000000 04 bc 63 e4 84 c2 ed 68 56 8d 20 74 b0 ff 2e a1 |..c....hV. t....|
00000010 b0 51 02 3d d9 c8 f2 4c c0 c2 5d 93 f4 14 2b bc |.Q.=...L..]...+.|
00000020 40 56 d9 4b 32 dc 1e 65 74 6b c7 0a 3e fe 2a ba |@V.K2..etk..>.*.|
00000030 db d2 e3 74 d8 ad 9c fd d1 0c f1 1b 12 74 ef df |...t.........t..|
00000040 53 |S|
00000041
El problema es que esta clave pública es diferente a la que generé en primer lugar:
[root .eth]# cat addr1/address
55d40a83b8445c004df5964ce4a0e261b599c01a
[root .eth]# hexdump -C addr1/pubo-bin
00000000 04 0c 2d 16 2c 3d 76 cd 47 de e5 84 c9 9e 08 80 |..-.,=v.G.......|
00000010 b4 f2 2a 38 3b 7e bc bb f6 cc bb 25 4a fe 01 b6 |..*8;~.....%J...|
00000020 dd 37 de ee ee b1 06 9a af 39 f0 e8 c4 6a f7 ca |.7.......9...j..|
00000030 53 01 5f 8f 73 7e 57 cc 2b 7a 61 32 35 54 e7 9c |S._.s~W.+za25T..|
00000040 26 |&|
00000041
Como puede ver, la dirección de ethereum (dirección de archivo) coincide con la que se usó para enviar el ether en la transacción al comienzo de la publicación.
Generé el par de claves así:
[root .eth]# cat genkey.sh
#!/usr/bin/env bash
openssl ecparam -name secp256k1 -genkey -noout | openssl ec -text -noout > keypair
cat keypair | grep pub -A 5 | tail -n +2 | tr -d '\n[:space:]:' | sed 's/^04//' > pub
cat keypair | grep priv -A 3 | tail -n +2 | tr -d '\n[:space:]:' | sed 's/^00//' > priv
cat pub | keccak-256sum -x -l | tr -d ' -' | tail -c 41 > address
cat priv | xxd -r -p > priv-bin
cat pub | xxd -r -p > pub-bin
#geth account import priv
Entonces, ¿cuál podría ser el problema? ¿Por qué la clave pública recuperada no coincide con la clave pública original?
Está utilizando un hash incorrecto al recuperar la clave pública. Hizo un hash de toda la transacción, incluida la firma, pero esto no tiene mucho sentido: el hash que debe firmarse no puede depender de la firma. Solo debe codificar aquellas partes de la transacción que se conocían antes de la firma: "a", "valor", "datos", "nonce", "gasolina" y "precio de la gasolina" (EIP-155 agregó "ID de cadena " a la lista). Así es como se ven estos seis valores en la codificación RLP:
// ["0x08","0x09184e72a000","0x76c0","0x589724c5abf2bce219726477cf0a60fa09321380","0x01","0x"]
0xe2088609184e72a0008276c094589724c5abf2bce219726477cf0a60fa093213800180
Aquí está el hash de lo anterior para ser chamuscado:
0x7eb00f90181255e010b43c944da6f9c7575e595467a710c0925263921ead9107
Aquí está su transacción sin procesar con firma:
0xf865088609184e72a0008276c094589724c5abf2bce219726477cf0a60fa0932
138001801ca0fe084488847df1cf427f72784c4b1ba86526ed5f8ef0feb6bc51
caf450d66e8ba06226e5f4dd0d948b7014199faf018c27862c56faad0b491970
57816dee9a7fa8
Aquí está la firma sola:
0xfe084488847df1cf427f72784c4b1ba86526ed5f8ef0feb6bc51caf450d66e8b
6226e5f4dd0d948b7014199faf018c27862c56faad0b49197057816dee9a7fa8
1c
Y aquí está la clave pública obtenida de la firma y el hash adecuado:
0x040c2d162c3d76cd47dee584c99e0880b4f22a383b7ebcbbf6ccbb254afe01b6
dd37deeeeeb1069aaf39f0e8c46af7ca53015f8f737e57cc2b7a61323554e79c
26
Por cierto, utilicé ABDK Toolkit para hacer todos estos cálculos.
usuario19510
retroceder la vida
usuario19510
gasLimit
.