Common useful JavaScript snippets for geth

  • In geth you can loadscript any .js file.

    I discovered this one on the wiki which I like a lot:

    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++; 
      })
    };
    

    Are you using frequently other ones? A kind of repository of 'classics' or 'must-have' would be a great resource to have.

    Here i have summed up all the scripts and created a single file out of it niksmac/ethereum-scripts

    So, I don't understand how we loadscript these scripts. I am guessing I save the individual script I want to use as a .js file. But then how do I load it in Geth?

    It only return true for me when I call from another terminal. So its woking but not return balances

  • Script To Find Transactions To/From An Account

    Usage

    Find all transaction to/from eth.accounts[0] within the last 1,000 blocks:

    > getTransactionsByAccount(eth.accounts[0])
    

    Find all transaction to/from The DAO's account 0xbb9bc244d798123fde783fcc1c72d3bb8c189413 between blocks 1,432,400 and 1,432,423:

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

    Find all transaction to/from any account in the last 1000 blocks:

    > getTransactionsByAccount("*")
    


    The Script

    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);
            }
          })
        }
      }
    }
    


    Example

    Find transactions to/from eth.accounts[0] address:

    > 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, I've rejected your edit because the **true** in the `eth.getBlock(i, true);` function call returns all the transaction objects, so you don't need the map function to re-retrieve the transaction objects.

    It looks great except it expects minimum 1000 blocks. In my test setup, it did not have that many. Line 7 should be `startBlockNumber = Math.max(endBlockNumber - 1000,0);`.

    @VikramRao, Is there any reason why you can' t change it to less than thousand?

    @RameshPareek sure you can select the batch size. in my case if suppose there are less than `batch size` (1000 in this example) the script would not work and hence i added a `min`.

    I think that's trivial.

    @TheOfficiousBokkyPooBah Is it possible to run this script in a Nodejs? What lib can we use that is similar to the `eth` object in your code?

    How to find a for more than 1000 accounts?

    Caution, ```eth.getBlock``` returns a Promise.

    `eth.accounts` doesn't work here. Use `eth.getAccounts(callback)`.

  • 1. Mine only when there are transactions!

    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. Get some data from geth without starting the node.

    $ geth --exec "eth.accounts" console 2>/dev/null
    
    ["0x0000000000000000000000000000000000000000"]
    

    3. View a Transaction

    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. Print a Block's Details

    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. Check all Balances

    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++; 
     })
    };
    

    Sources

    1. https://github.com/ethereum/go-ethereum/wiki/bitchin-tricks
    2. https://ethereum.stackexchange.com/a/2928/259

    @Nikhil M. I was trying the example which you have given for "Mine only when there are transactions!" But I am unable to use command "miner.start(2)", Looks like i need some library, But for sure it's not there in web3.js. Thanks in advance.

    @Sushant what error?

    checkWork() is not reliable. Occasionally, I observe there are pending txs, but mining does not start. E.g., *eth.getBlock("pending").transactions.length == 0, eth.pendingTransactions.length == 3, but eth.mining == false*

    @sinoTrinity, its an old script, feel free to improve as required.

    Maybe change to `eth.getBlock("pending").transactions.length > 0 || eth.pendingTransactions.length > 0`? I haven't verified this, though.

    The last version of https://github.com/ethereum/go-ethereum/wiki/bitchin-tricks is available in commit id 34cfee511a49cb3a01a51380be18212f20a01933 Current version does not have that file.

  • Script To Find Non-Zero Transaction Count In A Range Of Blocks

    (Update 22/04/2016)

    Here is a script to check the number of transactions between a starting block number and an ending block number:

    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")
          }
        }
      }
    }
    

    Running the scripts for blocks 1 to 46146 shows the following results - there are no transactions!:

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

    Let's check that the script is working as expected:

    > 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
    

    There are some transaction included in 46147 to 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
    

    Caution, eth.getBlock returns a Promise.

  • Script To Find Mined Blocks And Uncles + List Transactions

    Here's my scripts to check and print blocks, uncles and transactions. This was originally written as an answer to the question How do I know if a submitted block became an uncle? .

    I've listed them separately for easier reading. If you intend to use it in geth, you would probably want to concatenate the following 5 functions into a single file for easy copy-pasting into the geth console. And just remove the field you don't need to see.

    printTransaction(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);
      }
    }
    

    printBlock(block)

    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(block, uncleNumber, uncle)

    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(miner, startBlockNumber, endBlockNumber)

    If startBlockNumber is not specified, it will default to the last 10,000 blocks. This takes some time to scan, so reduce this number to 1000 to reduce the scanning time.

    If endBlockNumber is not specified, it will default to the latest block number.

    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);
    }
    

    Examples For Using The Function Above

    Here are some examples of using the above functions on the public mainnet Ethereum network.

    • Print block mined by "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5". See https://etherscan.io/block/1325630

      getMinedBlocks("0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", 1325620, 1325640);
      
    • Print block with uncles mined by "0xf3b9d2c81f2b24b0fa0acaaa865b7d9ced5fc2fb". See https://etherscan.io/block/1325635

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

      with the output:

      > 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
      
    • Print block with uncles. See https://etherscan.io/block/907703

      getMinedBlocks("*", 907703, 907703);
      
    • Print blocks my miner has mined between blocks 1321603 and 1321605

      getMyMinedBlocks(1321603, 1321605);
      

    `printTransaction` works for me, but `printBlock` just returns **undefined** for each parameter. `Block number undefined`, `hash undefined`, `parentHash undefined` etc. Do you just call it like `printBlock("17020")`?

    `printBlock(...)` needs to be called by `getMinedBlocks(...)`. Or you can use `printBlock(eth.getBlock(17020))`

  • FAST way to scan blocks for transactions on an account

    View Node.JS source code or its sample output.

    This is an asynchronous scanner, it creates 200 threads to scan through looking for any/all transactions related to your account number.

    You can easily change what happens when your transaction is found, currently it just prints to console so you can see those.

    Some of the answers above showed a synchronous way to scan all of the blocks looking for transactions, but doing this scan synchronously is slow, especially if you're connecting to Geth over the Internet. This solution is faster at scanning large numbers of blocks.

    According to the notes at the link above you're getting about 266 blocks per second (4,297 blocks in 16.111 seconds). I've done some testing hitting parity (as opposed to geth) with a single threaded C++ program and I was getting about 150-180 blocks per second pretty consistently. So there's a speedup, but not as much as I would have thought. It feels like you must have hit the limit of geth's ability to deliver blocks via RPC. Does that make sense? Have you tested the different speedups given different numbers of threads?

    I didn't do much testing RE changing the thread counts, except to say that too many threads consumes my CPU and is actually worse than not-too-many threads. I also made no attempt to tune geth for optimal networking, which may be possible to increase the speed further. I used a stock geth with default settings.

  • Transfer the ENTIRE balance from one account to another

    /**
     * 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

    This calculates the amount of gas required to make the transaction, then it transfers 100% of the funds (after the gas cost) from the from account to the to account.

    After running this method, the from account will have 0 Ether remaining.

    Usage:

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

    Updated 19-July-17 to exclusively use BigNumber math and the system-wide average gasPrice by default.

    Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. It's only 20 lines of code, just include them here too.

  • Script To Get Account Balances And Including TheDAO Tokens

    Here's a version of checkAllBalances that also displays TheDAO tokens. There is a Linux script that you can execute from the command line at How do I print my account balances and TheDAO tokens from 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));
    }; 
    

    Here's some sample output:

    > checkAllBalances()
      #     Account                                        TheDAO                      ethers
    ------- ------------------------------------------ ---------- ---------------------------
      0     0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa       1100        1.111111111111111111
      1     0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb       2200        2.222222222222222222
      2     0xcccccccccccccccccccccccccccccccccccccccc       3300        3.333333333333333333
    ------- ------------------------------------------ ---------- ---------------------------
      3                                                      6600        6.666666666666666666
    

    The link for "TheDAO" (https://daohub.org/) is broken.

  • find tokens in the blockchain, courtesy of 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
    }
    
  • A heuristic search for monetary transactions for a specific account without processing the entire chain

    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); }
    }
    

    How does it work?

    Using the available information about the current state (number of "from" transactions and the current balance), it goes back in time until at least so many "from" transactions have been found, and then continues going back until the balance reaches 0.

    The inherent limitation is that 0-value transactions before the account was funded will not be found.

  • This here function checks peers, separating handshakes from effective connections:

    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++; 
        })
      }
        
    };
    

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM