Ich versuche, eine Zeichenfolge mit web3.eth.sign() zu signieren und dann den öffentlichen Schlüssel, mit dem ich signiert habe, aus der Signatur abzurufen. Dazu verwende ich ecrecover() von ethereumjs-utils, das einen Puffer zurückgibt. Wenn ich bufferToHex() für den Puffer verwende, gibt es eine Hex-Zeichenfolge, die viel zu lang ist, um eine Adresse zu sein - 130 Zeichen einschließlich '0x'
web3.personal.unlockAccount(myAccount,pass)
msg = web3.sha3(aString)
sig = web3.eth.sign(myAccount,msg)
r = sig.slice(0, 66)
s = '0x' + sig.slice(66, 130)
v = '0x' + sig.slice(130, 132)
v = web3.toDecimal(v)
msg = ethJsUtil.toBuffer(msg)
addr = ethJsUtil.ecrecover(msg,v,r,s)
addr = ethJsUtil.bufferToHex(addr)
Ich habe den größten Teil des Codes aus der Antwort auf den Workflow zum Signieren einer Zeichenfolge mit privatem Schlüssel genommen, gefolgt von der Signaturüberprüfung mit öffentlichem Schlüssel , musste aber „msg“ in einen Puffer konvertieren, da ecrecover andernfalls einen Typfehler auslöste.
Was muss ich tun, um den Puffer von ecrecover in eine Adresse umzuwandeln?
ecrecover
gibt den öffentlichen Schlüssel zurück , Sie müssen ihn mit in eine Adresse umwandeln pubToAddress
.
pub = ethJsUtil.ecrecover(msg, v, r, s);
addrBuf = ethJsUtil.pubToAddress(pub);
addr = ethJsUtil.bufferToHex(addrBuf);
Sie können auch verwenden fromRpcSig
, um zu bekommenv, r, s
sig = web3.eth.sign(myAccount,msg)
res = ethJsUtil.fromRpcSig(sig)
pub = ethJsUtil.ecrecover(msg, res.v, res.r, res.s);
Bitte beachten Sie, dass web3.eth.sign
der Nachricht vor dem Signieren ein Präfix hinzugefügt wird (siehe JSON-RPC-Spezifikation ).
So fügen Sie es manuell hinzu:
const util = require('ethereumjs-util')
const msg = new Buffer('hello');
const sig = web3.eth.sign(web3.eth.accounts[0], '0x' + msg.toString('hex'));
const res = util.fromRpcSig(sig);
const prefix = new Buffer("\x19Ethereum Signed Message:\n");
const prefixedMsg = util.sha3(
Buffer.concat([prefix, new Buffer(String(msg.length)), msg])
);
const pubKey = util.ecrecover(prefixedMsg, res.v, res.r, res.s);
const addrBuf = util.pubToAddress(pubKey);
const addr = util.bufferToHex(addrBuf);
console.log(web3.eth.accounts[0], addr);
Auf der anderen Seite fügt testrpc (mindestens Version 3.0.5) kein solches Präfix hinzu.
Beispiel node.js + testrpc-Sitzung:
const util = require('ethereumjs-util')
const msg = web3.sha3('hello!');
const sig = web3.eth.sign(web3.eth.accounts[0], msg);
const {v, r, s} = util.fromRpcSig(sig);
const pubKey = util.ecrecover(util.toBuffer(msg), v, r, s);
const addrBuf = util.pubToAddress(pubKey);
const addr = util.bufferToHex(addrBuf);
console.log(web3.eth.accounts[0], addr);
v, r, s
Wiederherstellung geben, versuchen Sie es mit fromRpcSig
.Beispiel node.js + ethereumjs-util andere Methode zur Validierung der Signatur
const ethUtil = require("ethereumjs-util");
const inSignature = "0x...."; //user signed message
const message = "hello!";
const msgHex = ethUtil.bufferToHex(Buffer.from(message));
const msgBuffer = ethUtil.toBuffer(msgHex);
const msgHash = ethUtil.hashPersonalMessage(msgBuffer);
const signature = ethUtil.toBuffer(inSignature);
const sigParams = ethUtil.fromRpcSig(signature);
const publicKey = ethUtil.ecrecover(
msgHash,
sigParams.v,
sigParams.r,
sigParams.s
);
const sender = ethUtil.publicToAddress(publicKey);
const addr = ethUtil.bufferToHex(sender);
//now compare addr with user wallet address
if("0x<userWaller>" === addr) console.log("valid");
DappDev
Jo