Skip to content

Instantly share code, notes, and snippets.

@mgiachetti
Last active January 4, 2018 14:13
Show Gist options
  • Save mgiachetti/2b5355ac7ac366e4813eb75f9fa1f353 to your computer and use it in GitHub Desktop.
Save mgiachetti/2b5355ac7ac366e4813eb75f9fa1f353 to your computer and use it in GitHub Desktop.
join multiple bitcoin wallets or transactions into a single wallet
// 100,000,000 satoshi = 1 btc = 1e8 satoshi
// 100,000 satoshi = 0.001 btc = 1e5 satoshi
const bitcoin = require('bitcoinjs-lib');
const network = bitcoin.networks.bitcoin;
const blockchainInfoNetwork = network === bitcoin.networks.bitcoin ? 0 : 3; // bitcoin or testnet
const blockexplorer = require('blockchain.info/blockexplorer').usingNetwork(blockchainInfoNetwork);
const pushtx = require('blockchain.info/pushtx').usingNetwork(blockchainInfoNetwork);
// const destAddr = 'mfdC1bTbar2WVAkmSMjejyiFFp6Rtyq8vW'; // testnet
const destAddr = '';
const walletsWIF = require('./wallets.json');
const wallets = walletsWIF.map(wif => bitcoin.ECPair.fromWIF(wif, network));
const fee = 14e5;
function hasDuplicatedWallets() {
const walletDic = {};
wallets.forEach(w => walletDic[w.getAddress()] = w);
return wallets.length !== Object.keys(walletDic).length;
}
async function getInputTransactions() {
const inputs = [];
const slice = 50;
const walletDic = {};
wallets.forEach(w => walletDic[w.getAddress()] = w);
for (let i = Math.ceil(wallets.length / slice); i > 0; i--) {
const addresses = wallets.slice((i - 1) * slice, i * slice).map(w => w.getAddress());
const { txs } = await blockexplorer.getMultiAddress(addresses);
txs.forEach(tx => {
tx.out.forEach( out => {
const w = walletDic[out.addr];
if (!out.spent && w) {
inputs.push({
hash: tx.hash,
n: out.n,
wallet: w,
value: out.value,
});
}
});
});
}
return inputs;
}
async function joinWallets() {
console.log('Checking for duplicated wallets');
if (hasDuplicatedWallets()) {
console.log(`ERROR: There are duplicated wallets.`);
return;
}
console.log('Getting wallets transactions');
const inputs = await getInputTransactions();
let txb = new bitcoin.TransactionBuilder(network);
let transactionAmount = 0;
inputs.forEach( input => {
txb.addInput(input.hash, input.n);
transactionAmount += input.value;
});
console.log(`Found ${transactionAmount / 1e8} BTC`);
if (transactionAmount - fee <= 0 ) {
console.log(`ERROR: You don't have enought btc.`);
return;
}
txb.addOutput(destAddr, transactionAmount - fee);
console.log('Signing');
inputs.forEach((input, index) => {
txb.sign(index, input.wallet);
});
console.log('Building transaction');
var tx = txb.build();
console.log(`Transaction size ${tx.toHex().length / 2} bytes`);
console.log('Transfering transaction');
await pushtx.pushtx(tx.toHex());
console.log(`Success: transfered ${(transactionAmount - fee) / 1e8} BTC fee: ${fee / 1e8} BTC`);
}
joinWallets();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment