Kein Glück beim Wiederherstellen des öffentlichen Schlüssels nach EIP 155

Ich versuche, die Ethereum-Transaktionssignierung zu verstehen, aber aus irgendeinem Grund kann ich die Signatur nicht überprüfen.

Ich habe ein Testkonto 0xb2c899884790aa9e256a2d4b2256ca3319e64e32, dessen öffentlicher Schlüssel lautete7ab22c376286ccb0616888217bc41ec31eafb090fb77900a3946e39eb5c7fa374c8d5fe191f8001d287e678567bc8058eb49729780d2ac9090ffccbc506a754

Ich nehme die folgende gültige Transaktion:

{
  "blockHash": "0x3deebc8e1fe36af7f1268ff077cc086c0653fe6fd67aa200608a7379390365f0",
  "blockNumber": "0x613",
  "from": "0xb2c899884790aa9e256a2d4b2256ca3319e64e32",
  "gas": "0x493e0",
  "gasPrice": "0x0",
  "hash": "0x6831112de9dc553de7bb111591cabe0c79b5af8c6395c1bc5411ca2fda539735",
  "input": "0x760a8c2a",
  "nonce": "0x5",
  "to": "0x78c215f61ed07929e0084233a3e86bc011bea132",
  "transactionIndex": "0x0",
  "value": "0x0",
  "v": "0x14c3",
  "r": "0xbddab1b3292ac1102c470d738640bbf91a56a9bbc99a6fc88250800b2b21e25b",
  "s": "0x1959b4b59d0c8552766294459912862a2ca8a62e0b64eab98a4b5be75e910cec"
}

Oder in Rohform:f8660580830493e09478c215f61ed07929e0084233a3e86bc011bea1328084760a8c2a8214c3a0bddab1b3292ac1102c470d738640bbf91a56a9bbc99a6fc88250800b2b21e25ba01959b4b59d0c8552766294459912862a2ca8a62e0b64eab98a4b5be75e910cec

Gemäß EIP 155 muss ich alle 9 Werte hashen und v=chainId (2640), r=0und ersetzen s=0. Ich komme also auf die folgenden "Signierdaten":

e60580830493e09478c215f61ed07929e0084233a3e86bc011bea1328084760a8c2a820a508080

Es ist "Signatur-Hash":

749a36ed5f7c67b1f5eb83a46b0dd6447e9ac050a3f469354fcc4691781a385c

Was, wenn es durchgeleitet wird ecrecover, den folgenden öffentlichen Schlüssel ergibt:

f1308d673d1cf8014370fffb43f36d5e866e405b2b5cecb3025bfb98ae47b18e21fa07c66b31423414c38611038c4c35387db8510757f65b7a632a2d48b0276e

Was offensichtlich nicht mit dem tatsächlichen öffentlichen Schlüssel übereinstimmt.

Was mache ich falsch?

Mein Testcode:

var ethutil = require('ethereumjs-util');
var raw = Buffer.from('f8660580830493e09478c215f61ed07929e0084233a3e86bc011bea1328084760a8c2a8214c3a0bddab1b3292ac1102c470d738640bbf91a56a9bbc99a6fc88250800b2b21e25ba01959b4b59d0c8552766294459912862a2ca8a62e0b64eab98a4b5be75e910cec','hex');
var data = ethutil.rlp.decode(raw);
var v = ethutil.bufferToInt(data[6]);
var r = data[7];
var s = data[8];
var chainId = Math.floor((v - 35) / 2);
data[6] = ethutil.intToBuffer(chainId);
data[7] = Buffer.from('');
data[8] = Buffer.from('');
var msg = ethutil.rlp.encode(data);
console.log(msg.toString('hex'));
var msgHash = ethutil.sha3(msg);
console.log(msgHash.toString('hex'));
var publicKey = ethutil.ecrecover(msgHash, (v & 1) + 27, r, s);
console.log(publicKey.toString('hex'));

Antworten (1)

Versuchen Sie, die vorletzte Zeile zu ersetzen durch:

var publicKey = ethutil.ecrecover(msgHash, (v & 1 ^ 1) + 27, r, s);

Der größte Teil Ihres Codes sieht für mich korrekt aus, aber die Parität des zweiten Arguments für ecrecover muss mit der Parität des vWerts übereinstimmen. Wenn der vWert also mit dem Wert 27 beginnt, können Sie Ihre Berechnung durchgehen und überprüfen, ob Ihr Code das zweite Argument auf 28 setzen würde. Das ist falsch und kann behoben werden, indem Sie den Wert mit 1 xoren.