2

I have a rather large list of accounts (HD wallets) I want to sweep into one.

They've all been imported into geth, and all have the same password.

I wrote a script to do this in node but get this error:

Error: Insufficient funds for gas * price + value

Here is the node script:

//web3
var Web3 = require('web3');
var web3 = new Web3();

//starting index... main account is 0... don't sweep that one ^.^
var startSweep = 1;

//account shell
var accounts = [];

//transaction cost... i think?
var gas = 21000;

//geth stuff
var sys = require('util');
var exec = require('child_process').execSync;
function puts(error, stdout, stderr) { sys.puts(stdout) };

//connect to node
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));

//get accounts
var accounts = web3.eth.accounts;

//set default account for gas
web3.eth.defaultAccount = accounts[0];

//loop through accounts and sweep balances
for(var x = startSweep; x<accounts.length; x++){
    //get current account balance
    var balance = web3.eth.getBalance(accounts[x]);

    //if balance is greater than 0 lets transfer... 
    if(balance > gas){
        //command to unlock account 
        var execCommand = 'geth --exec "personal.unlockAccount(eth.accounts['+x+'], \'password\', 1000)" attach';
        console.log(execCommand);

        //execute command
        exec(execCommand, puts);
        console.log(' Unlocked account ' + accounts[x] + ' with a balance of ' + balance + '! ' + 'TRANSFERING!');
        var transaction = {
            "to" : accounts[0],
            "from" : accounts[x],
            "value" : balance - gas,
            "gas": gas
        };

        //send transaction
        web3.eth.sendTransaction(transaction);
        console.log('Sent transaction from : '+ accounts[x]);
    }
}

I read that the cost of a transaction was 21000, but I get that error.... So I just kept bumping the gas up until I received the error:

Error: Exceeds block gas limit

So I guess I'm doing something wrong. Any suggestions?

  • Is it possible that one or more of the accounts don't have enough in them to cover the cost of the transaction? (i.e. balance < 21000) – Richard Horrocks Jul 31 '16 at 20:36
  • I'm running a test with only three accounts right now, they all have balances greater than 21000. It is my understanding that the gas will come from the main account anyways (index 0) which has a few eth in it. Someone please correct me if i'm wrong here though. – rxb Jul 31 '16 at 20:38
  • I may have accidently deleted your comment @RichardHorrocks. sorry! – rxb Jul 31 '16 at 21:06
  • Sorry, that was me. As per the deleted comment, you need to take into account the gas price, as well as the amount of gas. In which case value: balance - (gas * gas price), as per ethereum.stackexchange.com/a/5766/52. Also see ether.fund/tool/calculator – Richard Horrocks Jul 31 '16 at 21:17
  • After some cowboy-esque edits I accidentally set gas to 210,000. I reset it back to 21000 and everything works as it should. I will update OP with the modified code in case it can help someone. Thanks @RichardHorrocks – rxb Aug 1 '16 at 0:14
3

I was not calculating the gas correctly. Here is the updated code in case anyone wants to do something similar.

//web3
var Web3 = require('web3');
var web3 = new Web3();

//starting index... main account is 0... don't sweep that one ^.^
var startSweep = 1;

//account shell
var accounts = [];

//transaction cost.
var gas = 21000;

//geth stuff
var sys = require('util');
var exec = require('child_process').execSync;
function puts(error, stdout, stderr) { sys.puts(stdout) };

//connect to node
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));

//current gas price
var gasPrice = web3.eth.gasPrice.toNumber();

//get accounts
var accounts = web3.eth.accounts;

//set default account
web3.eth.defaultAccount = accounts[0];

//loop through accounts and sweep balances
for(var x = startSweep; x<accounts.length; x++){
    //get current account balance
    var balance = web3.eth.getBalance(accounts[x]);
    //see if this is worth sending ^.^
    var balanceMinusFee = balance - (gas * gasPrice);
    if(balanceMinusFee > 0){
        //command to unlock account 
        var execCommand = 'geth --exec "personal.unlockAccount(eth.accounts['+x+'], \'password\', 1000)" attach';
        console.log(execCommand);

        //execute command
        exec(execCommand, puts);
        console.log(' Unlocked account ' + accounts[x] + ' with a balance of ' + balanceMinusFee + '! ' + 'TRANSFERING!');
        var transaction = {
            "to" : accounts[0],
            "from" : accounts[x],
            "value" : balanceMinusFee,
            "gas": gas
        };

        //send transaction
        web3.eth.sendTransaction(transaction);
        console.log('Sent transaction from : '+ accounts[x]);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.