I wrote a little tool on JS which generate addresses with unique postfixes.
It derives addresses from bip39 mnemonic and uses increments of bip44 derivation path.
What surprised me is that the total number of these addresses is somehow limited to 1225 (I ran increments into 1M, but the unique addresses dwindle out at about 20k), instead of expected 3364 (58^2).
Can anyone expain why this is the case?
const bitcoin = require('bitcoinjs-lib');
const bip32 = require('bip32');
const bip39 = require('bip39');
const EventEmitter = require('events');
var eventEmitter = new EventEmitter()
function db() {
var knex = require('knex')({
client: 'mysql',
connection: {
host : '127.0.0.1',
user : 'root',
password : 'pw',
database : 'btckeygen'
}
});
return knex;
}
function getAddress (node, network) {
return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address
}
var knex = db();
const dpath = "m/44'/0'/0'";
eventEmitter.on('eIteration', function(i){
if ( i % 1000 == 0 )
console.log(i);
if ( i < 1000000 )
syncLoop(i + 1);
else
process.exit(0);
});
const mnemonic = 'gesture large void donate enroll demise about fade arrest romance knock breeze melody card another';
const seed = bip39.mnemonicToSeed(mnemonic)
const root = bip32.fromSeed(seed)
const string = root.toBase58()
console.log('BIP32 Root: ' + string);
const bip44xprv = root.derivePath(dpath)
const bip44xpub = bip44xprv.neutered().toBase58();
console.log('Account xprv: ' + bip44xprv.toBase58());
console.log('Account xpub: ' + bip44xpub);
const bip32xprv = root.derivePath(dpath + "/0")
const bip32xpub = bip32xprv.neutered().toBase58();
console.log('BIP32 xprv: ' + bip32xprv.toBase58());
console.log('BIP32 xpub: ' + bip32xpub);
function syncLoop(i) {
const dpathi = dpath + "/0/" + i ;
const child = root.derivePath(dpathi)
const addr = getAddress(child, bitcoin.networks.mainnet);
//console.log('Child' + i + ' Address: ' + addr);
const prv = child.privateKey.toString('hex');
const pub = child.publicKey.toString('hex');
var search = addr.substr(-2);
knex
.select('address')
.from('keystore')
.where(knex.raw('RIGHT(??, 2) = ?', ['address', `${search}`]))
.then(function (result) {
if ( !result || result.length == 0 ) {
//console.log(result);
//console.log(this.path);
knex.insert({derivation_path: this.path, address: this.address, pub: this.pub, prv: this.prv})
.returning('id')
.into('keystore')
.then(function (id) {
console.log(id);
})
.catch(function(e) {
console.error(e);
});
}
eventEmitter.emit('eIteration', this.i)
}.bind({path:dpathi, address:addr, pub:pub, prv:prv, i:i})
)
.catch(function(e) {
console.error(e);
});
}
syncLoop(0);