Ausnahme „Nicht genügend Arbeitsspeicher“ bei Verwendung von web3j in Android

Ich versuche, web3j in eine Android-Anwendung zu integrieren. Die Bibliothek gibt jedoch beim Laden der Wallet-Datei eine Out Of Memory-Ausnahme aus:

Credentials credentials = WalletUtils.loadCredentials("password", walletFile)

Dies ist die Ausnahme:

java.lang.OutOfMemoryError: Failed to allocate a 268435468 byte allocation with 8050708 free bytes and 244MB until OOM

Das scheint der Übeltäter zu sein:

//com.lambdaworks.crypto.SCrypt#scryptJ
byte[] V  = new byte[128 * r * N]; // r: 8, N: 262144, V = byte[268435456]

Ich weiß, dass die Anmeldeinformationen geladen werden können, da ein anderes Projekt, Ether Wallet , web3j verwendet und dieselbe Wallet-Datei laden kann. Kann mir jemand sagen, wie ich das lösen kann?

Ich habe genau den gleichen Fehler erhalten, als ich versuchte, eine Brieftasche zu erstellen. In meinem Fall war das Problem useFullScrypt, dass es eingestellt wurde, um das Problem truezu falselösen. Ich hatte noch keine Zeit, das Problem zu untersuchen, aber als ich überprüfte, sind die KPF-Parameter in diesen Fällen unterschiedlich.

Antworten (2)

Habe einen schnellen Hack gefunden. Erstellen Sie einen jniLibsOrdner in /src/mainund fügen Sie alle Android-Ordner aus diesem Scrypt-Fork in den jniLibsOrdner ein. Bauen. Laufen

Ich werde mit einer korrekteren Lösung aktualisieren, wenn/wenn ich eine finde.

Hinweis: Erfordert Gradle 0.7.2+, damit die jniLibs automatisch zum Build hinzugefügt werden

Dies geschieht immer noch.

Methode decrypt ( org.web3j.crypto) ruft generiertDerivedScryptKey ( org.web3j.crypto) Aufrufe generiert in SCrypt ( org.spongycastle.crypto.generators) auf.

es kommt alles auf die Größe des Arrays an, das durch den Parameter N initialisiert wird:

WalletFile.KdfParams kdfParams = crypto.getKdfparams();
if (kdfParams instanceof WalletFile.ScryptKdfParams) {
    WalletFile.ScryptKdfParams scryptKdfParams =
                (WalletFile.ScryptKdfParams) crypto.getKdfparams();
    int dklen = scryptKdfParams.getDklen();
    int n = scryptKdfParams.getN();
    int p = scryptKdfParams.getP();
    int r = scryptKdfParams.getR();
    byte[] salt = Numeric.hexStringToByteArray(scryptKdfParams.getSalt());
    derivedKey = generateDerivedScryptKey(
                password.getBytes(Charset.forName("UTF-8")), salt, n, r, p, dklen);

N IST DAS KERNPROBLEM