Общие полезные фрагменты JavaScript для geth

В geth вы можете загрузить любой .jsфайл.

Я обнаружил это на вики, которое мне очень нравится:

function checkAllBalances() { 
  var i =0; 
  eth.accounts.forEach( function(e){
    console.log("  eth.accounts["+i+"]: " +  e + " \tbalance: " + web3.fromWei(eth.getBalance(e), "ether") + " ether"); 
    i++; 
  })
};

Вы часто используете другие? Своеобразный репозиторий «классики» или «обязательного» был бы отличным ресурсом.

Здесь я собрал все скрипты и создал из них один файл niksmac/ethereum-scripts
Итак, я не понимаю, как мы загружаем эти скрипты. Я предполагаю, что сохраняю отдельный скрипт, который хочу использовать, в виде файла .js. Но как мне загрузить его в Geth?
Он возвращает true только для меня, когда я звоню с другого терминала. Так что это работает, но не возвращает балансы

Ответы (12)

Скрипт для поиска транзакций в/из учетной записи

Применение

Найти все транзакции в/из eth.accounts[0]последних 1000 блоков:

> getTransactionsByAccount(eth.accounts[0])

Найти все транзакции в/из аккаунта DAO0xbb9bc244d798123fde783fcc1c72d3bb8c189413 между блоками 1 432 400 и 1 432 423:

> getTransactionsByAccount("0xbb9bc244d798123fde783fcc1c72d3bb8c189413", 1432400, 1432423)

Найти все транзакции в/из любой учетной записи в последних 1000 блоков:

> getTransactionsByAccount("*")


Сценарий

function getTransactionsByAccount(myaccount, startBlockNumber, endBlockNumber) {
  if (endBlockNumber == null) {
    endBlockNumber = eth.blockNumber;
    console.log("Using endBlockNumber: " + endBlockNumber);
  }
  if (startBlockNumber == null) {
    startBlockNumber = endBlockNumber - 1000;
    console.log("Using startBlockNumber: " + startBlockNumber);
  }
  console.log("Searching for transactions to/from account \"" + myaccount + "\" within blocks "  + startBlockNumber + " and " + endBlockNumber);

  for (var i = startBlockNumber; i <= endBlockNumber; i++) {
    if (i % 1000 == 0) {
      console.log("Searching block " + i);
    }
    var block = eth.getBlock(i, true);
    if (block != null && block.transactions != null) {
      block.transactions.forEach( function(e) {
        if (myaccount == "*" || myaccount == e.from || myaccount == e.to) {
          console.log("  tx hash          : " + e.hash + "\n"
            + "   nonce           : " + e.nonce + "\n"
            + "   blockHash       : " + e.blockHash + "\n"
            + "   blockNumber     : " + e.blockNumber + "\n"
            + "   transactionIndex: " + e.transactionIndex + "\n"
            + "   from            : " + e.from + "\n" 
            + "   to              : " + e.to + "\n"
            + "   value           : " + e.value + "\n"
            + "   time            : " + block.timestamp + " " + new Date(block.timestamp * 1000).toGMTString() + "\n"
            + "   gasPrice        : " + e.gasPrice + "\n"
            + "   gas             : " + e.gas + "\n"
            + "   input           : " + e.input);
        }
      })
    }
  }
}


Пример

Найти транзакции в/из eth.accounts[0]адреса:

> getTransactionsByAccount(eth.accounts[0])
Using endBlockNumber: 1864
Using startBlockNumber: 864
Searching for transactions to/from account "0xa7857047907d53a2e494d5f311b4b586dc6a96d2" within blocks 864 and 1864
Searching block 1000
  tx hash          : 0x3c3bc3c456a84e20cf0077f9aa5ce363d3b12bca18d01000a750288c2e76401e
   nonce           : 44
   blockHash       : 0xef2d15775908951fc61f9a83b53c00cf2cde4e0def93e20544f784441c6178db
   blockNumber     : 1582
   transactionIndex: 0
   from            : 0xa7857047907d53a2e494d5f311b4b586dc6a96d2
   to              : null
   value           : 0
   time            : 1470459255 Sat, 06 Aug 2016 04:54:15 GMT
   gasPrice        : 20000000000
   gas             : 24615
   input           : 0x6060604052600a8060106000396000f360606040526008565b00
  tx hash          : 0xc255cdbf477452eb8922d8230889f7cc08b9deed4695378aba3d97906071ce5f
   nonce           : 45
   blockHash       : 0x987a8214af96bb1530b97fe09da8f8168679e42c9efb4defee50800f2067d6d8
   blockNumber     : 1587
   transactionIndex: 0
   from            : 0xa7857047907d53a2e494d5f311b4b586dc6a96d2
   to              : null
   value           : 0
   time            : 1470459409 Sat, 06 Aug 2016 04:56:49 GMT
   gasPrice        : 20000000000
   gas             : 24615
   input           : 0x6060604052600a8060106000396000f360606040526008565b00
...
@KalyanKumar, я отклонил ваше редактирование, потому что true в eth.getBlock(i, true);вызове функции возвращает все объекты транзакции, поэтому вам не нужна функция карты для повторного получения объектов транзакции.
Он выглядит великолепно, за исключением того, что он ожидает минимум 1000 блоков. В моей тестовой установке их было не так много. Строка 7 должна быть startBlockNumber = Math.max(endBlockNumber - 1000,0);.
@VikramRao, есть ли причина, по которой вы не можете изменить его на менее тысячи?
@RameshPareek уверен, что вы можете выбрать размер партии. в моем случае, если предположим, что их меньше batch size(1000 в этом примере), скрипт не будет работать, и поэтому я добавил файл min.
Я думаю, это банально.
@TheOfficiousBokkyPooBah Можно ли запустить этот скрипт в Nodejs? Какую библиотеку мы можем использовать, похожую на ethобъект в вашем коде?
Как найти более 1000 аккаунтов?
Осторожно, eth.getBlockвозвращает обещание.
eth.accountsздесь не работает. Используйте eth.getAccounts(callback).

1. Майнить только когда есть транзакции!

var mining_threads = 1

function checkWork() {
    if (eth.getBlock("pending").transactions.length > 0) {
        if (eth.mining) return;
        console.log("== Pending transactions! Mining...");
        miner.start(mining_threads);
    } else {
        miner.stop(0);  // This param means nothing
        console.log("== No transactions! Mining stopped.");
    }
}

eth.filter("latest", function(err, block) { checkWork(); });
eth.filter("pending", function(err, block) { checkWork(); });

checkWork();

2. Получить некоторые данные из geth, не запуская ноду.

$ geth --exec "eth.accounts" console 2>/dev/null

["0x0000000000000000000000000000000000000000"]

3. Просмотр транзакции

function printTransaction(txHash) {
  var tx = eth.getTransaction(txHash);
  if (tx != null) {
    console.log("  tx hash          : " + tx.hash + "\n"
      + "   nonce           : " + tx.nonce + "\n"
      + "   blockHash       : " + tx.blockHash + "\n"
      + "   blockNumber     : " + tx.blockNumber + "\n"
      + "   transactionIndex: " + tx.transactionIndex + "\n"
      + "   from            : " + tx.from + "\n" 
      + "   to              : " + tx.to + "\n"
      + "   value           : " + tx.value + "\n"
      + "   gasPrice        : " + tx.gasPrice + "\n"
      + "   gas             : " + tx.gas + "\n"
      + "   input           : " + tx.input);
  }
}

4. Распечатайте детали блока

function printBlock(block) {
  console.log("Block number     : " + block.number + "\n"
    + " hash            : " + block.hash + "\n"
    + " parentHash      : " + block.parentHash + "\n"
    + " nonce           : " + block.nonce + "\n"
    + " sha3Uncles      : " + block.sha3Uncles + "\n"
    + " logsBloom       : " + block.logsBloom + "\n"
    + " transactionsRoot: " + block.transactionsRoot + "\n"
    + " stateRoot       : " + block.stateRoot + "\n"
    + " miner           : " + block.miner + "\n"
    + " difficulty      : " + block.difficulty + "\n"
    + " totalDifficulty : " + block.totalDifficulty + "\n"
    + " extraData       : " + block.extraData + "\n"
    + " size            : " + block.size + "\n"
    + " gasLimit        : " + block.gasLimit + "\n"
    + " gasUsed         : " + block.gasUsed + "\n"
    + " timestamp       : " + block.timestamp + "\n"
    + " transactions    : " + block.transactions + "\n"
    + " uncles          : " + block.uncles);
    if (block.transactions != null) {
      console.log("--- transactions ---");
      block.transactions.forEach( function(e) {
        printTransaction(e);
      })
    }
}

5. Проверьте все балансы

function checkAllBalances() { 
 var i =0; 
 eth.accounts.forEach( function(e){
    console.log("  eth.accounts["+i+"]: " +  e + " \tbalance: " +    web3.fromWei(eth.getBalance(e), "ether") + " ether"); 
  i++; 
 })
};

Источники

  1. https://github.com/ethereum/go-ethereum/wiki/битчин-трюки
  2. https://эфириум.stackexchange.com/a/2928/259
@Nikhil M. Я пробовал пример, который вы привели для «Мой, только когда есть транзакции!» Но я не могу использовать команду "miner.start(2)". Похоже, мне нужна какая-то библиотека, но ее точно нет в web3.js. Заранее спасибо.
@Сушант, какая ошибка?
checkWork() ненадежен. Иногда я наблюдаю, что есть ожидающие транзакции, но майнинг не начинается. Например, eth.getBlock("ожидание").transactions.length == 0, eth.pendingTransactions.length == 3, но eth.mining == false
@sinoTrinity, это старый скрипт, не стесняйтесь улучшать его по мере необходимости.
Может сменить на eth.getBlock("pending").transactions.length > 0 || eth.pendingTransactions.length > 0? Хотя я этого не проверял.
Последняя версия github.com/ethereum/go-ethereum/wiki/bitchin-tricks доступна с идентификатором коммита 34cfee511a49cb3a01a51380be18212f20a01933. В текущей версии этого файла нет.

Скрипт для поиска ненулевого количества транзакций в диапазоне блоков

(Обновление от 22.04.2016)

Вот скрипт для проверки количества транзакций между начальным номером блока и конечным номером блока:

function checkTransactionCount(startBlockNumber, endBlockNumber) {
  console.log("Searching for non-zero transaction counts between blocks "  + startBlockNumber + " and " + endBlockNumber);

  for (var i = startBlockNumber; i <= endBlockNumber; i++) {
    var block = eth.getBlock(i);
    if (block != null) {
      if (block.transactions != null && block.transactions.length != 0) {
        console.log("Block #" + i + " has " + block.transactions.length + " transactions")
      }
    }
  }
}

Запуск скриптов для блоков с 1 по 46146 показывает следующие результаты - транзакций нет!:

> checkTransactionCount(1, 46146)
Searching for non-zero transaction counts between blocks 1 and 46146
undefined

Давайте проверим, что скрипт работает как положено:

> eth.blockNumber
1382234
> checkTransactionCount(1382224, 1382234)
Searching for non-zero transaction counts between blocks 1382224 and 1382234
Block #1382224 has 4 transactions
Block #1382225 has 2 transactions
Block #1382226 has 4 transactions
Block #1382227 has 6 transactions
Block #1382228 has 17 transactions
Block #1382231 has 2 transactions
Block #1382234 has 1 transactions
undefined

Есть некоторые транзакции, включенные в 46147 до 46200:

> checkTransactionCount(46147, 46200)
Searching for non-zero transaction counts between blocks 46147 and 46200
Block #46147 has 1 transactions
Block #46169 has 1 transactions
Block #46170 has 1 transactions
Block #46194 has 1 transactions
undefined
Осторожно, eth.getBlock возвращает обещание.

Скрипт для поиска добытых блоков и дядей + список транзакций

Вот мои скрипты для проверки и печати блоков, дядей и транзакций. Первоначально это было написано как ответ на вопрос Как узнать, стал ли отправленный блок дядей? .

Я перечислил их отдельно для облегчения чтения. Если вы собираетесь использовать его в geth, вы, вероятно, захотите объединить следующие 5 функций в один файл для удобного копирования и вставки в gethконсоль. И просто удалите поле, которое вам не нужно видеть.

транзакция печати (txHash)

function printTransaction(txHash) {
  var tx = eth.getTransaction(txHash);
  if (tx != null) {
    console.log("  tx hash          : " + tx.hash + "\n"
      + "   nonce           : " + tx.nonce + "\n"
      + "   blockHash       : " + tx.blockHash + "\n"
      + "   blockNumber     : " + tx.blockNumber + "\n"
      + "   transactionIndex: " + tx.transactionIndex + "\n"
      + "   from            : " + tx.from + "\n" 
      + "   to              : " + tx.to + "\n"
      + "   value           : " + tx.value + "\n"
      + "   gasPrice        : " + tx.gasPrice + "\n"
      + "   gas             : " + tx.gas + "\n"
      + "   input           : " + tx.input);
  }
}

печатьБлок(блок)

function printBlock(block) {
  console.log("Block number     : " + block.number + "\n"
    + " hash            : " + block.hash + "\n"
    + " parentHash      : " + block.parentHash + "\n"
    + " nonce           : " + block.nonce + "\n"
    + " sha3Uncles      : " + block.sha3Uncles + "\n"
    + " logsBloom       : " + block.logsBloom + "\n"
    + " transactionsRoot: " + block.transactionsRoot + "\n"
    + " stateRoot       : " + block.stateRoot + "\n"
    + " miner           : " + block.miner + "\n"
    + " difficulty      : " + block.difficulty + "\n"
    + " totalDifficulty : " + block.totalDifficulty + "\n"
    + " extraData       : " + block.extraData + "\n"
    + " size            : " + block.size + "\n"
    + " gasLimit        : " + block.gasLimit + "\n"
    + " gasUsed         : " + block.gasUsed + "\n"
    + " timestamp       : " + block.timestamp + "\n"
    + " transactions    : " + block.transactions + "\n"
    + " uncles          : " + block.uncles);
    if (block.transactions != null) {
      console.log("--- transactions ---");
      block.transactions.forEach( function(e) {
        printTransaction(e);
      })
    }
}

printUncle(блок, uncleNumber, дядя)

function printUncle(block, uncleNumber, uncle) {
  console.log("Block number     : " + block.number + " , uncle position: " + uncleNumber + "\n"
    + " Uncle number    : " + uncle.number + "\n"
    + " hash            : " + uncle.hash + "\n"
    + " parentHash      : " + uncle.parentHash + "\n"
    + " nonce           : " + uncle.nonce + "\n"
    + " sha3Uncles      : " + uncle.sha3Uncles + "\n"
    + " logsBloom       : " + uncle.logsBloom + "\n"
    + " transactionsRoot: " + uncle.transactionsRoot + "\n"
    + " stateRoot       : " + uncle.stateRoot + "\n"
    + " miner           : " + uncle.miner + "\n"
    + " difficulty      : " + uncle.difficulty + "\n"
    + " totalDifficulty : " + uncle.totalDifficulty + "\n"
    + " extraData       : " + uncle.extraData + "\n"
    + " size            : " + uncle.size + "\n"
    + " gasLimit        : " + uncle.gasLimit + "\n"
    + " gasUsed         : " + uncle.gasUsed + "\n"
    + " timestamp       : " + uncle.timestamp + "\n"
    + " transactions    : " + uncle.transactions + "\n");
}

getMinedBlocks (майнер, startBlockNumber, endBlockNumber)

Если startBlockNumberне указано, по умолчанию будут использоваться последние 10 000 блоков. Сканирование занимает некоторое время, поэтому уменьшите это число до 1000, чтобы сократить время сканирования.

Если endBlockNumberне указано, по умолчанию будет использоваться последний номер блока.

function getMinedBlocks(miner, startBlockNumber, endBlockNumber) {
  if (endBlockNumber == null) {
    endBlockNumber = eth.blockNumber;
    console.log("Using endBlockNumber: " + endBlockNumber);
  }
  if (startBlockNumber == null) {
    startBlockNumber = endBlockNumber - 10000;
    console.log("Using startBlockNumber: " + startBlockNumber);
  }
  console.log("Searching for miner \"" + miner + "\" within blocks "  + startBlockNumber + " and " + endBlockNumber + "\"");

  for (var i = startBlockNumber; i <= endBlockNumber; i++) {
    if (i % 1000 == 0) {
      console.log("Searching block " + i);
    }
    var block = eth.getBlock(i);
    if (block != null) {
      if (block.miner == miner || miner == "*") {
        console.log("Found block " + block.number);
        printBlock(block);
      }
      if (block.uncles != null) {
        for (var j = 0; j < 2; j++) {
          var uncle = eth.getUncle(i, j);
          if (uncle != null) {
            if (uncle.miner == miner || miner == "*") {
              console.log("Found uncle " + block.number + " uncle " + j);
              printUncle(block, j, uncle);
            }
          }          
        }
      }
    }
  }
}

getMyMinedBlocks(startBlockNumber, endBlockNumber)

function getMyMinedBlocks(startBlockNumber, endBlockNumber) {
  getMinedBlocks(eth.accounts[0], startBlockNumber, endBlockNumber);
}

Примеры использования функции выше

Вот несколько примеров использования вышеуказанных функций в общедоступной основной сети Ethereum.

  • Блок печати, добытый "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5". См. https://etherscan.io/block/1325630

    getMinedBlocks("0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", 1325620, 1325640);
    
  • Блок печати с дядями, добытыми "0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb". См. https://etherscan.io/block/1325635

    getMinedBlocks("0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb", 1325630, 1325640);
    

    с выводом:

    > getMinedBlocks("0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb", 1325630, 1325640);
    Searching for miner "0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb" within blocks 1325630 and 1325640"
    Found uncle 1325635 uncle 0
    Block number     : 1325635 , uncle position: 0
     Uncle number    : 1325634
     hash            : 0xae03bb2d5f1fbde4e22bf79850307ab6ae7d8545a9f0de4a5f529095546308c0
     parentHash      : 0x771b46e0310666780a55b1d603648d89e7d8cc3feac20a175117b4cb7e206a75
     nonce           : 0xeff5922de2f569e8
     sha3Uncles      : 0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
     logsBloom       : 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
     transactionsRoot: 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
     stateRoot       : 0xafca80bc836c00c7eeb4b6f3254573f72d38a0738ce4793da7d5222ed6c0c5cd
     miner           : 0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb
     difficulty      : 26564802678158
     totalDifficulty : 0
     extraData       : 0x426974436c756220455448204d696e696e6720506f6f6c
     size            : 0
     gasLimit        : 4712388
     gasUsed         : 0
     timestamp       : 1460501836
     transactions    : undefined
    
  • Печатный блок с дядями. См. https://etherscan.io/block/907703

    getMinedBlocks("*", 907703, 907703);
    
  • Вывести блоки, добытые моим майнером, между блоками 1321603 и 1321605.

    getMyMinedBlocks(1321603, 1321605);
    
К вашему сведению, meta.ethereum.stackexchange.com/q/265/87
printTransactionработает для меня, но printBlockпросто возвращает undefined для каждого параметра. Block number undefined, hash undefined, parentHash undefinedи т.д. Вы просто называете это как printBlock("17020")?
printBlock(...)должен быть вызван getMinedBlocks(...). Или вы можете использоватьprintBlock(eth.getBlock(17020))

БЫСТРЫЙ способ сканирования блоков для транзакций на счете

Просмотрите исходный код Node.JS или его образец вывода .

Это асинхронный сканер, он создает 200 потоков для сканирования в поисках любых/всех транзакций, связанных с номером вашей учетной записи.

Вы можете легко изменить то, что происходит, когда ваша транзакция найдена, в настоящее время она просто выводится на консоль, чтобы вы могли ее увидеть.

Некоторые из приведенных выше ответов показали синхронный способ сканирования всех блоков в поисках транзакций, но синхронное сканирование выполняется медленно, особенно если вы подключаетесь к Geth через Интернет. Это решение быстрее при сканировании большого количества блоков.

Согласно примечаниям по ссылке выше, вы получаете около 266 блоков в секунду (4297 блоков за 16,111 секунды). Я провел некоторое тестирование четности (в отличие от geth) с помощью однопоточной программы на C++, и я довольно стабильно получал около 150-180 блоков в секунду. Так что ускорение есть, но не такое сильное, как я думал. Такое ощущение, что вы, должно быть, достигли предела способности geth доставлять блоки через RPC. Имеет ли это смысл? Вы тестировали различные ускорения с разным количеством потоков?
Я не очень много тестировал RE, изменяя количество потоков, за исключением того, что сказал, что слишком много потоков потребляют мой ЦП и на самом деле хуже, чем не слишком много потоков. Я также не пытался настроить geth для оптимальной работы в сети, что могло бы еще больше увеличить скорость. Я использовал стоковый гет с настройками по умолчанию.

Перевести ВЕСЬ баланс с одного счета на другой

/**
 * Transfer the ENTIRE BALANCE from one account to another.
 *
 * Before you call this, you must unlock your account:
 *   personal.unlockAccount(from)
 *
 * @see https://github.com/ethereum/go-ethereum/issues/1637
 * @see https://github.com/ethereum/go-ethereum/issues/2173
 */
function transferEntireBalance(from, to) {
    var gas = new BigNumber(21000);
    var price = web3.eth.gasPrice;  // current average price; or set your own
    var balance = eth.getBalance(from);
    var value = balance.minus(gas.times(price));
    if (value.greaterThan(0)) {
        var txn = eth.sendTransaction({from: from, to: to, gasPrice: price, gas: gas, value: value});
        console.log("  Transfer", from, "to", to, ":", txn);
        return txn;
    }
    console.log("  Transfer "+ from +" to "+ to +": (No funds available)");
    return null;
}

https://gist.github.com/ross-p/cfa489bb7ed7427e4498058b0d6a5984

Это рассчитывает количество газа, необходимого для совершения транзакции, затем переводит 100% средств (после стоимости газа) со fromсчета на toсчет.

После запуска этого метода на fromучетной записи останется 0 эфира.

Применение:

var txn = transferEntireBalance(from, to);
eth.getTransaction(txn);

Обновлено 19 июля 17 года: по умолчанию используются исключительно математические расчеты BigNumber и общесистемная средняя цена газа.

Хотя теоретически это может ответить на вопрос, было бы предпочтительнее включить сюда основные части ответа и предоставить ссылку для справки. Это всего 20 строк кода, просто включите их сюда.

Скрипт для получения баланса счета и включения токенов TheDAO

Вот версия checkAllBalances, которая также отображает токены TheDAO . Существует скрипт для Linux, который вы можете выполнить из командной строки в разделе Как мне распечатать баланс моей учетной записи и токены TheDAO из geth .

function padTokens(s, n) {
  var o = s.toPrecision(n);
  while (o.length < n) {
    o = " " + o;
  }
  return o;
}

function padEthers(s) {
  var o = s.toFixed(18);
  while (o.length < 27) {
    o = " " + o;
  }
  return o;
}

function checkAllBalances() { 
  var theDAOABI = [ { "type": "function", "outputs": [ { "type": "uint256", "name": "", "value": "5e+22" } ], "name": "minTokensToCreate", "inputs": [], "constant": true }, { "type": "function", "outputs": [ { "type": "uint256", "name": "", "value": "2.668900014413644230605979e+24" } ], "name": "totalSupply", "inputs": [], "constant": true }, { "type": "function", "outputs": [ { "type": "uint256", "name": "", "value": "1464426000" } ], "name": "closingTime", "inputs": [], "constant": true }, { "type": "function", "outputs": [], "name": "refund", "inputs": [], "constant": false }, { "type": "function", "outputs": [ { "type": "address", "name": "", "value": "0xda4a4626d3e16e094de3225a751aab7128e96526" } ], "name": "curator", "inputs": [], "constant": true }, { "type": "function", "outputs": [ { "type": "uint256", "name": "balance", "value": "0" } ], "name": "balanceOf", "inputs": [ { "type": "address", "name": "_owner" } ], "constant": true }, { "type": "function", "outputs": [ { "type": "uint256", "name": "_numberOfProposals", "value": "0" } ], "name": "numberOfProposals", "inputs": [], "constant": true }, { "type": "function", "outputs": [ { "type": "address", "name": "", "value": "0x807640a13483f8ac783c557fcdf27be11ea4ac7a" } ], "name": "extraBalance", "inputs": [], "constant": true }, { "type": "function", "outputs": [ { "type": "bool", "name": "", "value": true } ], "name": "isFueled", "inputs": [], "constant": true }, { "type": "function", "outputs": [ { "type": "bool", "name": "success" } ], "name": "createTokenProxy", "inputs": [ { "type": "address", "name": "_tokenHolder" } ], "constant": false }, { "type": "function", "outputs": [ { "type": "uint256", "name": "_voteID" } ], "name": "vote", "inputs": [ { "type": "uint256", "name": "_proposalID" }, { "type": "bool", "name": "_supportsProposal" } ], "constant": false }, { "type": "event", "name": "FuelingToDate", "inputs": [ { "type": "uint256", "name": "value", "indexed": false } ], "anonymous": false }, { "type": "event", "name": "ProposalAdded", "inputs": [ { "type": "uint256", "name": "proposalID", "indexed": true }, { "type": "address", "name": "recipient", "indexed": false }, { "type": "uint256", "name": "amount", "indexed": false }, { "type": "bool", "name": "newCurator", "indexed": false }, { "type": "string", "name": "description", "indexed": false } ], "anonymous": false }, { "type": "event", "name": "ProposalTallied", "inputs": [ { "type": "uint256", "name": "proposalID", "indexed": true }, { "type": "bool", "name": "result", "indexed": false }, { "type": "uint256", "name": "quorum", "indexed": false } ], "anonymous": false } ];
  var theDAOAddress = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413";
  var theDAO = eth.contract(theDAOABI).at(theDAOAddress);
  var theDAOTotal = 0; 
  var ethersTotal = 0; 

  console.log("  #     Account                                        TheDAO                      ethers");
  console.log("------- ------------------------------------------ ---------- ---------------------------");
  var i =0; 
  eth.accounts.forEach( function(e){
    var tokens = theDAO.balanceOf(e) / parseFloat(1e16);
    theDAOTotal += parseFloat(tokens);
    var ethers = web3.fromWei(eth.getBalance(e), "ether");
    ethersTotal += parseFloat(ethers);
    console.log("  " + i + "\t" + e + " " + padTokens(tokens, 10) + " " + padEthers(ethers)); 
    i++; 
  })
  console.log("------- ------------------------------------------ ---------- ---------------------------");
  console.log("  " + i + "                                               " + padTokens(theDAOTotal, 10) + " " + padEthers(ethersTotal));
}; 

Вот пример вывода:

> checkAllBalances()
  #     Account                                        TheDAO                      ethers
------- ------------------------------------------ ---------- ---------------------------
  0     0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa       1100        1.111111111111111111
  1     0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb       2200        2.222222222222222222
  2     0xcccccccccccccccccccccccccccccccccccccccc       3300        3.333333333333333333
------- ------------------------------------------ ---------- ---------------------------
  3                                                      6600        6.666666666666666666
Ссылка на "TheDAO" ( daohub.org ) не работает.

найти токены в блокчейне, любезно предоставлено https://github.com/linagee/find-ethereum-coins/blob/master/token.js

var tokenInterface = [{"type": "function","name": "name","constant": true,"inputs": [],"outputs": [{"name": "","type": "string"}]},{"type": "function","name": "decimals","constant": true,"inputs": [],"outputs": [{"name": "","type": "uint8"}]},{"type": "function","name": "balanceOf","constant": true,"inputs": [{"name": "","type": "address"}],"outputs": [{"name": "","type": "uint256"}]},{"type": "function","name": "symbol","constant": true,"inputs": [],"outputs": [{"name": "","type": "string"}]},{"type": "function","name": "transfer","constant": false,"inputs": [{"name": "_to","type": "address"},{"name": "_value","type": "uint256"}],"outputs": []},{"type": "constructor","inputs": [{"name": "_supply","type": "uint256"},{"name": "_name","type": "string"},{"name": "_decimals","type": "uint8"},{"name": "_symbol","type": "string"}]},{"name": "Transfer","type": "event","anonymous": false,"inputs": [{"indexed": true,"name": "from","type": "address"},{"indexed": true,"name": "to","type": "address"},{"indexed": false,"name": "value","type": "uint256"}]}];
TokenContract = web3.eth.contract(tokenInterface);

var lowestBlock = 474147; //November 3, 2015 - last time the ABI above was changed
var highestBlock = eth.getBlock("latest").number;
//var lowestBlock = 483325; //smaller test case with just one coin (MistCoin)
//var highestBlock = 484731; //smaller test case with just one coin (MistCoin)
for (var x=lowestBlock; x < highestBlock; x++) {
  var transactions = eth.getBlock(x).transactions;
  for (var y=0; y < transactions.length; y++) {
//    if (x % 100 == 0) { console.log("."); }
    var contractAddr = eth.getTransactionReceipt(transactions[y]).contractAddress;
    if (contractAddr != null) {
       var tokenInstance = TokenContract.at(contractAddr);
       var symbol = "";
       var decimals = "";
       var name = "";
       try {
         symbol = tokenInstance.symbol();
       } catch(err) {
       }
       try {
         decimals = tokenInstance.decimals();
       } catch(err) {
         //don't do anything here, just catch the error so program doesn't die
       }
       try {
         name = tokenInstance.name();
       } catch(err) {
         //don't do anything here, just catch the error so program doesn't die
       }
       if (symbol != null && symbol != "" && name != null && name != "") {
         console.log("-----------");
         console.log("Contract Address: " + contractAddr);
         console.log("Name: " + name);
         console.log("Symbol: " + symbol);
         console.log("Decimals: " + decimals);
         console.log("-----------");
       }
//       console.log(contractAddr);  //testing
    }
  }
//  console.log(eth.getBlock(x).transactions);  //testing
}

Вот простой способ получить общий баланс:

function totalBalance() { 
  var x = 0
  eth.accounts.forEach( function(e) {
    x = x + parseFloat(web3.fromWei(eth.getBalance(e)), 10); 
  });
  console.log("  total balance: " + x + " ether"); 
};
Хм ... Разве это не почти то же самое, что и сценарий в вопросе?
@varm идентичен, за исключением того факта, что он суммирует все остатки на счетах, а не отображает их по отдельности. На самом деле я использовал фрагмент из вопроса и добавил это небольшое дополнение для быстрого просмотра общей суммы по всем счетам.

Эвристический поиск денежных операций по конкретному счету без обработки всей цепочки

var myAddr = '0xbb9bc244d798123fde783fcc1c72d3bb8c189413';
var currentBlock = eth.blockNumber;
var n = eth.getTransactionCount(myAddr, currentBlock);
var bal = eth.getBalance(myAddr, currentBlock);
for (var i=currentBlock; i >= 0 && (n > 0 || bal > 0); --i) {
    try {
        var block = eth.getBlock(i, true);
        if (block && block.transactions) {
            block.transactions.forEach(function(e) {
                if (myAddr == e.from) {
                    if (e.from != e.to)
                        bal = bal.plus(e.value);
                    console.log(i, e.from, e.to, e.value.toString(10));
                    --n;
                }
                if (myAddr == e.to) {
                    if (e.from != e.to)
                        bal = bal.minus(e.value);
                    console.log(i, e.from, e.to, e.value.toString(10));
                }
            });
        }
    } catch (e) { console.error("Error in block " + i, e); }
}

Как это работает?

Используя доступную информацию о текущем состоянии (количество транзакций «от» и текущий баланс), он возвращается во времени до тех пор, пока не будет найдено хотя бы такое количество транзакций «от», а затем продолжает возвращаться назад, пока баланс не достигнет 0.

Неотъемлемое ограничение заключается в том, что транзакции с нулевым значением до того, как счет был пополнен, не будут найдены.

Вот эта функция проверяет одноранговые узлы, отделяя рукопожатия от эффективных соединений:

function getPeers(flagAll) { 
  // always lists established connections
  // if flagAll is true shows handshakes also
  var i =0; 
  var flagHandshake = 0;
  var count00 = 0;
  var count01 = 0;
  var peersHandshake = new Array();
  var peersConnect = new Array();
  admin.peers.forEach( function(e){
    flagHandshake = ( e.protocols.eth == "handshake");
    if (flagHandshake) {
        peersHandshake[count01] = e.network.remoteAddress;
        count01++;
    } else {
        peersConnect[count00] = e.network.remoteAddress;
        count00++;
    }  
  })
  i = 0;
  peersConnect.forEach(function(e){
    console.log("  peersConnect["+i+"] :  [" +  e + "]" ); 
    i++; 
  })
  if (count00 == 0) {
    console.log("  No TRUE connections yet.  Try using `admin.addPeer()` to speed things up.");
  }  else {
    console.log("  Found ["+count00+"] TRUE connections.");
  } 
    
  
  if (flagAll) {
    i = 0;
    peersHandshake.forEach(function(e){
        console.log("  peersHandshake["+i+"] :  [" +  e + "]" ); 
        i++; 
    })
  }
    
};

Просто для удовольствия. Получает все блоки рекурсивно :) (не лучший способ)

 function getAllBlocks(blockNumber,res) { 
  if(blockNumber < 0) return; 
  var block = eth.getBlock(blockNumber); 
  res.push(getAllBlocks(block.number-1,res));
  return res; 
 }

getAllBlocks('latest',[])