Skip to content

Instantly share code, notes, and snippets.

@mutatrum
Created April 16, 2020 15:59
Show Gist options
  • Save mutatrum/48af22c0f63cc1cc7d24d82a9d67e5e3 to your computer and use it in GitHub Desktop.
Save mutatrum/48af22c0f63cc1cc7d24d82a9d67e5e3 to your computer and use it in GitHub Desktop.
Using bitcoinj to derive legacy, segwit and bech32 addresses from account xpub
import org.bitcoinj.core.*;
import org.bitcoinj.crypto.*;
import org.bitcoinj.params.*;
import org.bitcoinj.script.*;
import org.junit.*;
public class BitcoinJTest
{
private static NetworkParameters params = MainNetParams.get();
@Test
public void test()
{
xpub("xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8", AddressFormat.P2SH);
}
enum AddressFormat
{
P2PKH, P2SH, BECH32,
}
private void xpub(String xpub, AddressFormat format)
{
DeterministicKey rootKey = DeterministicKey.deserializeB58(null, xpub, params);
DeterministicHierarchy hierarchy = new DeterministicHierarchy(rootKey);
DeterministicKey external = deriveNextChild(rootKey, hierarchy);
derive(hierarchy, external, format);
DeterministicKey change = deriveNextChild(rootKey, hierarchy);
derive(hierarchy, change, format);
}
private void derive(DeterministicHierarchy hierarchy, DeterministicKey chain, AddressFormat format)
{
for (int i = 0; i < 10; i++)
{
DeterministicKey key = deriveNextChild(chain, hierarchy);
Address address = getAddress(key, format);
System.out.println(key.getPath() + ": " + address);
}
}
private DeterministicKey deriveNextChild(DeterministicKey rootKey, DeterministicHierarchy hierarchy)
{
return hierarchy.deriveNextChild(rootKey.getPath(), false, false, false);
}
private Address getAddress(ECKey key, AddressFormat format)
{
switch (format)
{
case P2PKH:
return LegacyAddress.fromPubKeyHash(params, key.getPubKeyHash());
case P2SH:
// https://groups.google.com/d/msg/bitcoinj/pHv4XyMbhZo/RLAkreuBAwAJ
Script script = ScriptBuilder.createP2WPKHOutputScript(key.getPubKeyHash());
return LegacyAddress.fromScriptHash(params, Utils.sha256hash160(script.getProgram()));
case BECH32:
return SegwitAddress.fromHash(params, key.getPubKeyHash());
default:
throw new IllegalArgumentException();
}
}
}
@mutatrum
Copy link
Author

I'm not familiar with Electrum seeds, but the bip39 tool (https://iancoleman.io/bip39/) doesn't recognise those seed words. Apparently they use a different standard, as noted by https://walletsrecovery.org/.

@vurezo
Copy link

vurezo commented Feb 23, 2021

what's the code you used exactly to make that output? and email me vurezo@gmail.com with your BCH/BTC/crypto address

@mutatrum
Copy link
Author

The code is the gist. Just put the Electrum master public key zpub on line 14, with AddressType.BECH32. Run the test, that produces the output.

No need for payment, I wrote the code for myself, published for free.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment