Web3j: Different privateKey generated by Mnemonic comparing to other libraries

Created on 25 Apr 2019  路  7Comments  路  Source: web3j/web3j

To get privateKey from Mnemonic, I use: ECKeyPair.create(sha256(seed))

But it creates a different privateKey from the same mnemonic using TrustKeystore in iOS (TrustKeystore generates the correct privateKey comparing to https://iancoleman.io/bip39/)

I did some research and figure out that I need to do something with the configuration of how mnemonic is used. Can you please guide me. Thank you!

awaiting-pr

Most helpful comment

Workaround - I would appreciate a PR in web3j to encapsulate this.

Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(MnemonicUtils.generateSeed("XXXXXXX", null));
int[] path = {44 | HARDENED_BIT, 60 | HARDENED_BIT, 0 | HARDENED_BIT, 0,0};
Bip32ECKeyPair  x = Bip32ECKeyPair.deriveKeyPair(masterKeypair, path);
Credentials credentials = Credentials.create(x);
System.out.println(credentials.getAddress());

All 7 comments

Workaround - I would appreciate a PR in web3j to encapsulate this.

Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(MnemonicUtils.generateSeed("XXXXXXX", null));
int[] path = {44 | HARDENED_BIT, 60 | HARDENED_BIT, 0 | HARDENED_BIT, 0,0};
Bip32ECKeyPair  x = Bip32ECKeyPair.deriveKeyPair(masterKeypair, path);
Credentials credentials = Credentials.create(x);
System.out.println(credentials.getAddress());

Didn't mean to close it

I get the reason why, other wallets providers (mostly those who uses javascript libaray ) uses a different path compared to web3j, from my digging and observation, web3j borrowed it implementation from bitcoinj so below is the path difference :

web3j & bitcoinj -> // m/44'/60'/0'/0 (as commented in org/web3j/crypto/Bip44WalletUtils.java)
metamask, blockchain.com & other javascript based libs -> "m/44'/60'/0'/0/0"

How the test was conducted :

const ethers = require('ethers');

const mnemonic = "some phrase"
const path = "m/44'/60'/0'/0/0"
const wallet = ethers.Wallet.fromMnemonic(mnemonic,path);

console.log(wallet)

to reproduce the result install ethers (yarn add ethers)

Well, I have solved it, if you want to support metamask and other wallet, use this :

    // "m/44'/60'/0'/0/0"
    val path = intArrayOf(44 or HARDENED_BIT, 60 or HARDENED_BIT, 0 or HARDENED_BIT, 0, 0)

     val mnemonic = "some key phrase"

      val seed = MnemonicUtils.generateSeed(mnemonic,"")

        val masterKeyPair = Bip32ECKeyPair.generateKeyPair(seed)

        val bip44Keypair = Bip32ECKeyPair.deriveKeyPair(masterKeyPair, path)

        val credentials = Credentials.create(bip44Keypair)

        println(credentials.address)

Reopening because I think this can be made a lot easier to configure in web3j.

I think a PR should be made to change the default behavior of web3j to be consistent with other ethereum libraries.

It should also be super easy to configure for other use-cases.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This issue has been mentioned on Web3 Labs Community. There might be relevant details there:

https://community.web3labs.com/t/web3j-v4-8-0-released/112/1

Was this page helpful?
0 / 5 - 0 ratings