Ich brauche Hilfe bei der Überprüfung der Ethereum-Adresse. Ich folge dem Tutorial zum Signieren und Validieren der Ethereum-Adresse. GitHub-Code . Ich bin verwirrt über mein tatsächliches Ergebnis der Adresse, nachdem ich gelaufen bin, loginContractInstance.recoverAddr.call(addr, fixed_msg_sha, v_decimal, r,s, function(err, actual) {
weil es null zurückgibt.
Hier ist mein Backend-Code unten,
// Unlock account before the login attempt
web3.personal.unlockAccount(req.body.address, req.body.password, 100, function(error, unlocked) {
console.log(`>>>>> Login - User is unlocked: ${unlocked}`);
if (unlocked) {
// Signing/ Encryption
const addr = req.body.address;
const msg = req.body.password;
const hex_msg = '0x' + toHex(msg);
let signature = web3.eth.sign(addr, hex_msg);
console.log(`address -----> ${addr}`);
console.log(`msg ---------> ${msg}`);
console.log(`hex(msg) ----> ${hex_msg}`);
console.log(`sig ---------> ${signature}`);
const r = signature.slice(0, 66)
const s = '0x' + signature.slice(66, 130)
const v = '0x' + signature.slice(130, 132)
const v_decimal = web3.toDecimal(v);
console.log(`r -----------> ${r}`);
console.log(`s -----------> ${s}`);
console.log(`v -----------> ${v}`);
console.log(`vd ----------> ${v_decimal}`);
// Validation/Decryption
const fixed_msg = `\x19Ethereum Signed Message:\n${msg.length}${msg}`
const fixed_msg_sha = '0x' + web3.sha3(fixed_msg)
loginContractInstance.isSigned.call(addr, fixed_msg_sha, v_decimal, r, s, function (err, signed) {
console.log(`>>>>> Login - Signature: ${signed}`);
if (signed) {
// Saving login attempt
loginContractInstance.successfulLogin.sendTransaction(req.body.address, req.body.password,
{from:'6ded1c5b448819a6cde4293e33fbe54583ef5c52', gas:200000},
function(err, transactionHash) {
if (!err) {
console.log(`>>>>> Login - login details (${addr}, ${msg}) successfully saved @ ${transactionHash}`);
console.log(`>>>>> Login - Successfully login`);
} else {
console.log(`>>>>> Login - login transaction failed: ${err}`);
}
// set primary account to mine
web3.eth.coinbase = req.body.address;
console.log(`>>>>> Login - Current User: ${web3.eth.coinbase} is logged in`);
var balanceWei = web3.eth.getBalance(req.body.address).toNumber();
var balance = web3.fromWei(balanceWei, 'ether');
res.json({
allowedLogin: true,
address: req.body.address,
balance: balance,
token: generateToken(addr)
});
});
} else {
loginContractInstance.recoverAddr.call(fixed_msg_sha, v_decimal, r,s, function(err, actual) {
console.log(`>>>>> Login - Failed login: Signature not matched:${addr} = ${actual}`);
saveFailedLoginAttempts(loginContractInstance, req, res);
});
}
});
} else {
console.log(`>>>>> Login - Failed login: User is locked`);
saveFailedLoginAttempts(loginContractInstance, req, res);
}
});
Und mein intelligenter Vertrag,
contract Login {
event LoginAttempt(address sender, string password);
address private sender;
string private password;
function successfulLogin (address _sender, string _password) public {
LoginAttempt(_sender, _password);
sender = _sender;
password = _password;
}
function failedLogin (address _sender, string _password) public {
LoginAttempt(_sender, _password);
}
function recoverAddr(bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) public pure returns (address) {
return ecrecover(msgHash, v, r, s);
}
function isSigned(address _addr, bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) public pure returns (bool) {
return ecrecover(msgHash, v, r, s) == _addr;
}
Hier ist das Ergebnis dieses Funktionsaufrufs in meiner Konsole:
Kann jemand helfen, was ich vermisse?
BEARBEITEN
Ich habe die Funktion recoverAddr.call korrigiert, um die richtige Eingabe zu verwenden. Ich habe auch herausgefunden, dass mein fixed_msg_sha
Problem ist, weil ich hinzugefügt 0x
habe const fixed_msg_sha = '0x' + web3.sha3(fixed_msg)
. Es wurde so gedruckt0x0xf348f6a3d221a5e7e851292474330ca6e6cf6ad54572ee114233ab9b9225ab4f
Jetzt hat sich das Problem dahingehend geändert, dass eine 0x-Adresse zurückgegeben wird.
Ihre Smart-Contract-Funktion:
function recoverAddr(bytes32 msgHash, uint8 v, bytes32 r, bytes32 s)
Ihr Backend-Code:
loginContractInstance.recoverAddr.call(addr, fixed_msg_sha, v_decimal, r,s, function(err, actual) {
addr
Denken Sie nicht, dass Sie als ersten Parameter übergeben wollten ?
Ich bin mir nicht sicher, warum es sich nicht über "ungültige Anzahl von Argumenten für die Soliditätsfunktion" beschwert
Ich f, Sie verwenden dies, um die Preimages zu rekonstruieren: \x19Ethereum Signed Message:\n30
` Was im Medium-Post angegeben ist. Es ist falsch, dass die richtige Byte-Zeichenfolge lautet:
\x19Ethereum Signed Message:\n32
Ich habe mir das gleiche Beispiel wie Sie angesehen und war beim ersten Experimentieren mit der Signaturüberprüfung extrem festgefahren, da es falsch ist (vielleicht war es richtig, als der Medium-Beitrag geschrieben wurde, aber nicht mehr).
Ich habe einen Vertrag geschrieben, der Ecrecover und geth-signierte Nachrichten verwendet. Sie können sich die Signaturpräfix-Erklärung hier ansehen: https://github.com/postables/Postables-Payment-Channel/blob/7d2f91bb060f80b139cab72b5fdff79d116f6210/solidity/ChannelsV4. sol#L12 und beachten Sie, dass es nicht mit dem übereinstimmt, was der Autor des Medium-Beitrags angegeben hat.
Die eigentliche Signaturprüfung findet hier statt:
Meine persönliche Präferenz zum Signieren von Nachrichten ist die Verwendung von Python Web3 + einem lokalen Geth-Knoten, wie dieses Python-Skript zeigt:
https://github.com/postables/Postables-Payment-Channel/blob/develop/python/signer.py
const fixed_msg = \x19Ethereum Signed Message:\n${msg.length}${msg}
da es einstellbarer ist.
Cristoforus Darryl Widjaya