Web3j

在 Android 中使用 web3j 時出現記憶體不足異常

  • October 21, 2018

我正在嘗試將 web3j 集成到一個 android 應用程序中。但是庫在載入錢封包件時會出現 Out Of Memory 異常:

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

這是一個例外:

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

這似乎是罪魁禍首:

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

我知道可以載入憑據,因為另一個項目Ether Wallet使用 web3j 並且能夠載入相同的錢封包件。有人可以告訴我如何解決這個問題嗎?

找到了一個快速破解。在其中創建一個jniLibs文件夾/src/main並將scrypt fork 中的所有 android 文件夾添加到該jniLibs文件夾中。建造。跑

如果/當我找到一個更正確的解決方案時,我會更新。

注意:需要 gradle 0.7.2+ 才能將 jniLibs 自動添加到建構中

這仍在發生。

解密方法(org.web3j.cryptoorg.web3j.crypto呼叫生成的DerivedScryptKey()呼叫在SCrypt(org.spongycastle.crypto.generators)中生成..

這一切都歸結為數組的大小,由參數 N 初始化:

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是核心問題

引用自:https://ethereum.stackexchange.com/questions/26963