11

Electrum 2.0 and up uses BIP0032 internally. I want to write code that generates the same addresses. I can't find any information about this online.

What BIP32 paths does it use to generate addresses?

Nick ODell
  • 29,184
  • 11
  • 69
  • 129

3 Answers3

11

It uses m/0/<n> for receiving addresses, and m/1/<n> for change addresses.

Here's some example bitcoinj code to generate receiving addresses from an extended public key.

String serialized_xpub = "xpub.....";
unsigned int address_num = 4;
NetworkParameters params = MainNetParams.get();
DeterministicKey root_xpub = DeterministicKey.deserializeB58(null, serialized_xpub, params);

DeterministicKey receiving = HDKeyDerivation.deriveChildKey(root_xpub, new ChildNumber(0, false));
DeterministicKey new_address_key = HDKeyDerivation.deriveChildKey(receiving, new ChildNumber(address_num, false));
String new_address = new_address_key.toAddress().toString();
Nick ODell
  • 29,184
  • 11
  • 69
  • 129
  • [possible duplicate?](http://bitcoin.stackexchange.com/a/36840/9382) – Wizard Of Ozzie Apr 17 '15 at 07:55
  • @WizardOfOzzie Funny thing: I saw that right after I worked it out by reading the source code. "BIP32 derivation path" is totally ungoogleable, for some reason. – Nick ODell Apr 17 '15 at 08:05
  • 5
    Just for future reference, I've been maintaining a list of deterministic wallet details, including BIP-32 derivation paths, here: https://bitcointalk.org/index.php?topic=1000544.0 – Christopher Gurnee Apr 19 '15 at 14:03
  • 1
    @ChristopherGurnee You, sir, are a gentleman and a scholar. – Nick ODell Apr 19 '15 at 18:09
  • and for multisig? http://bitcoin.stackexchange.com/questions/51989/what-bip32-derivation-path-does-electrum-use-for-multisig – joe.js Mar 09 '17 at 17:21
  • @NickODell Thanks for your answer. I also created another valid answer (to help others based on yours) using the nodejs bitcoinjs package, deriving 5 receive and change addresses. – Pedro Simões Aug 31 '17 at 15:44
4

Inspired by @NickODell answer, I created another example using nodejs that derives 5 receiving addresses and 5 change addresses.

You will need these two modules: npm install bitcoinjs-lib --save and npm install bip32-utils --save and babel for the es6 javascript code support.

import Bitcoin from 'bitcoinjs-lib';
import Bip32Utils from 'bip32-utils';

let hdNode = Bitcoin.HDNode.fromBase58('xpub...get.the.master.public.key.from.a.wallet.like.electrum...');

let receiving = hdNode.derive(0); // BIP32 m/0/<n> path (receiving addresses)
let receivingChain = new Bip32Utils.Chain(receiving);

for (var k = 0; k < 5; ++k) {
    console.log(receivingChain.get());
    receivingChain.next();
}

let change = hdNode.derive(1); // BIP32 m/1/<n> path (change addresses)
let changeChain = new Bip32Utils.Chain(change);

for (var k = 0; k < 5; ++k) {
    console.log(changeChain.get());
    changeChain.next();
}

Tested in electrum with a real wallet.

When you don't have a multiple account wallet you can use these BIP32 paths to generate addresses:

m/0/kcorresponds to the k'th keypair of the external chain of the HDW derived from master m.

m/1/k corresponds to the k'th keypair of the internal chain of the HDW derived from master m. (internal, means change and other internal uses)

But when you want to use a wallet with multiple accounts, for example, one for each customer, the paths are more like this:

m/i/0/k corresponds to the k'th keypair of the external chain of account number i of the HDW derived from master m.

m/i/1/k corresponds to the k'th keypair of the internal chain of account number i of the HDW derived from master m.

This is the default wallet layout:

Wallet structure

  • This looks like a cool bit of code, but I can't honestly say that it answers the question (there is no mention of derivation paths). This would probably be more suited as a comment linking to a github gist or something. – Jestin Aug 31 '17 at 16:34
  • 1
    Sure, you are right. The paths are in the code but not correctly commented. edited the answer. – Pedro Simões Aug 31 '17 at 17:29
3

TL;DR:

BIP32 m/0/<n> path (receiving addresses)
BIP32 m/1/<n> path (change addresses)

Some days ago I had the very same question, so I ended writing this little nodejs module that does pretty much the same that you can read on @pedro_fp_simoes' answer:

https://www.npmjs.com/package/xpub-generator You can use it as follows:

import { XPubGenerator } from 'xpub-generator';

const g = new XPubGenerator('xpub....');
g.nthReceiving(1);
g.nthChange(1);