javacryptographyethereumbitcoinj

How to generate deterministic keys for Ethereum using Java?


I'm trying to create a deterministic wallet for Ethereum mixing BitcoinJ and Web3j. The deterministic key is generated using BitcoinJ and the Ethereum credentials using Web3j. But the address generated with the Web3j credential is not as expected.

String seedCode = "yard impulse luxury drive today throw farm pepper survey wreck glass federal";

// BitcoinJ
DeterministicSeed seed = new DeterministicSeed(seedCode, null, "", 1409478661L);
DeterministicKeyChain chain = DeterministicKeyChain.builder().seed(seed).build();
DeterministicKey key = chain.getKey(KeyPurpose.RECEIVE_FUNDS);
BigInteger privKey = key.getPrivKey();

// Web3j
Credentials credentials = Credentials.create(privKey.toString(16));
System.out.println("Address: " + credentials.getAddress());

Output: 0x2c4186d0422d0462a48c92cd559cbc30f528855b

Expected: 0x72445fcFdEB1Fff79496D7Ce66089d663Ff90E26

Where is the misunderstanding in the code?


Solution

  • By default bitcoinj uses the path m/0'/0 for the chain of keys. And most of the Ethereum solutions uses m/44'/60'/0'/0 from the BIP44 specification. That's why the result wasn't as expected when comparing to other Ethereum tools.

    The code below fix "the problem":

    String seedCode = "yard impulse luxury drive today throw farm pepper survey wreck glass federal";
    
    // BitcoinJ
    DeterministicSeed seed = new DeterministicSeed(seedCode, null, "", 1409478661L);
    DeterministicKeyChain chain = DeterministicKeyChain.builder().seed(seed).build();
    List<ChildNumber> keyPath = HDUtils.parsePath("M/44H/60H/0H/0/0");
    DeterministicKey key = chain.getKeyByPath(keyPath, true);
    BigInteger privKey = key.getPrivKey();
    
    // Web3j
    Credentials credentials = Credentials.create(privKey.toString(16));
    System.out.println(credentials.getAddress());