Konten entsperren und Transaktionen in web3.js durchführen

Diese Frage hängt mit diesem und diesem zusammen . Es hat auch eine Teilantwort hier und hier .

Im dritten Link wird das Konto mit web3.js für einen bestimmten Zeitraum entsperrt :

web3.personal.unlockAccount("0x..", "<passs>", 1000);

Der Parameter Entsperrzeitraum ist optional.

Wie kann überprüft werden, ob Konten gesperrt sind (vor Durchführung von Transaktionen)?

Hat das Entsperren eines bereits entsperrten Kontos Auswirkungen auf die Funktionalität?

Ist <pass> der private Schlüssel? Bsp. let account = self.web3.eth.accounts.privateKeyToAccount(self.config.walletPrivateKey);&self.web3.eth.personal.unlockAccount(account.address, account.privateKey, 200)
Nein, nur ein Passwort, das zum Verschlüsseln des privaten Schlüssels verwendet wird (der später bei Transaktionen verwendet wird).
Beachten Sie, dass die persönliche API veraltet ist und in der Praxis von keinem Wallet verwendet wird. Verschiedene Wallets bieten unterschiedliche Anbieter zum Signieren von Transaktionen. Weitere Informationen hier: ethereum.stackexchange.com/questions/82531/…

Antworten (4)

Derzeit gibt es in der web3 JS-API keine Methode , um zu überprüfen, ob ein Konto gesperrt ist oder nicht.

Wenn ein Konto jedoch bereits entsperrt ist, gibt es anhand des Codes kein Problem, die Entsperrung erneut aufzurufen.

// If the account address is already unlocked for a duration, TimedUnlock extends or
// shortens the active unlock timeout. If the address was previously unlocked
// indefinitely the timeout is not altered.
func (am *Manager) TimedUnlock(a Account, passphrase string, timeout time.Duration) error {

Warum betrachten wir nur TimedUnlock(), das vermutlich nur aufgerufen wird, wenn wir den dritten Parameter übergeben?

Wie Sie angemerkt haben, ist der Parameter für den Entsperrzeitraum optional. Wenn es nicht angegeben ist, rufen wir auf Unlock(), was ein Wrapper um TimedUnlock()ist, der aber 0als Zeitraum übergeben wird. Daher brauchen wir TimedUnlock()bei der Erklärung nur die Funktion zu berücksichtigen.

Ich habe ein Design, das sich ändern kann, und weiß noch nicht, welche Wahl die beste ist. Ich werde vorerst ohne Zeitsperre gehen (dies würde normalerweise das Konto auf unbestimmte Zeit entsperrt halten).
Ich würde argumentieren, dass es ein Problem gibt, ein Konto immer wieder zu entsperren, und das ist, dass das Entsperren ziemlich lange dauert (~ 3 Sekunden für mich mit dem neuesten Geth).

Hier ist eine Problemumgehung, um zu überprüfen, ob das Konto entsperrt ist. Es ist nicht sehr schön, aber in den meisten Fällen funktioniert es. Verwenden Sie es nur für Entwicklungszwecke im Testnetz oder im privaten Netz!!! Weil "dies eine tatsächliche Transaktion aussendet, für die Sie Benzin bezahlen müssen", Konten entsperren und Transaktionen in web3.js durchführen

function isAccountLocked(account) {
    try {
        web3.eth.sendTransaction({
            from: account,
            to: account,
            value: 0
        });
        return false;
    } catch (err) {
        return (err.message == "authentication needed: password or unlock");
    }
}

function unlockAccountsIfNeeded(accounts, passwords, unlock_duration_sec) {
    if (typeof(unlock_duration_sec)==='undefined') unlock_duration_sec = 300;

    for (let i = 0; i < accounts.length; i++) {
        if (isAccountLocked(accounts[i])) {
            console.log("Account " + accounts[i] + " is locked. Unlocking")
            web3.personal.unlockAccount(accounts[i], passwords[i], unlock_duration_sec);
        }
    }
}
Dies ist in der Tat nicht sehr schön, da dies eine tatsächliche Transaktion aussendet, für die Sie Benzin bezahlen müssen.
@AlexeyBarsuk nettes Skript, ich schlage vor, die Entsperrdauer hinzuzufügen (0 entsperrt, während Geth läuft) web3.personal.unlockAccount(accounts[i], passwords[i], Duration);

Sie können web3.eth.sign verwenden und prüfen, ob es fehlschlägt.

async function isUnlocked (web3, address) {
    try {
        await web3.eth.sign("", address);
    } catch (e) {
        return false;
    }
    return true;
}
Bitte geben Sie in Ihrer Antwort etwas mehr Details an. Das Bereitstellen eines Links ohne viel Kontext hilft dem OP möglicherweise nicht.
@Malone web3.eth.sign wirft „Authentifizierung erforderlich: Passwort oder Entsperren“, falls Sie nicht entsperrt sind

Dies ist eine mögliche Methode, die direkt die JSON RPC-Methode aufruft personal_listWallets:

async function listWallets() {
    try {
        const result = await sendRPC_personal_listWallets();
        console.log(typeof result);
        return result;
    } catch (e) {
        return e;
    }
}

function sendRPC_personal_listWallets() {

    return new Promise((resolve, reject) => {

        web3.currentProvider.send({ method: "personal_listWallets", params: [], jsonrpc: "2.0", id: new Date().getTime() },
            function (error, result) { if (error) { reject(error); } else { resolve(result); } });
    }
    );
}
let wallets;
listWallets().then((r) => { console.log("ID:", r.id); wallets = r.result; console.log("Accounts:", wallets); });

Beachten Sie, dass die personalAPI veraltet ist und dies in der Praxis von keinem Benutzer-Wallet implementiert wird. ethereum.stackexchange.com/questions/82531/…
@MikkoOhtamaa können Sie einen Link zu einer Benachrichtigung darüber bereitstellen, dass die personalAPI veraltet ist? Ich habe nachgesehen, alles, was ich finden konnte, ist, dass der HTTP-Anbieter hier veraltet ist - web3js.readthedocs.io/en/v1.2.11/…
Leider kann ich nach zwei Jahren nicht mehr auf Quellensuche gehen. Sie können sich jedoch auf mein Wort verlassen: Versuchen Sie nicht, es zu verwenden, es war 2015 eine schlechte Idee und ist es immer noch eine schlechte Idee.