[Ethereum] Block explorer running on private network

explorersprivate-blockchain

Is there any application out there that allows me to explore the Ethereum blockchain in a private network? (something similar to what blockchain.info does to bitcoin or etherchain does to ethereum public network)

Best Answer

I don't know of any block explorer source code / application you can deploy into your private network.

Here's my scripts to check and print blocks, uncles and transactions that can be used to explore blocks in your private network.

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.

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

    with the output being:

    getMinedBlocks("0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", 1325620, 1325640);
    Searching for miner "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" within blocks 1325620 and 1325640"
    Found block 1325622
    Block number     : 1325622
     hash            : 0x06cdfceefb706514defc44a0bee28341bbb03e241a8bf8963d4c26b8a37f4309
     parentHash      : 0x2b29abc7a8cf63b40d33d8fcc6871d33e1ac1b7858d752d02f35b506981c15e3
     nonce           : 0x4f3215d189a40d32
     sha3Uncles      : 0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
     logsBloom       : 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
     transactionsRoot: 0xb7f7547bd977d3d8db65a1565035414c01058a82645cdde4b4bc00ceba0f8482
     stateRoot       : 0x10444688147ecdd6c838482141aa9d95af4816563faf05a8c6d8c0028abbb040
     miner           : 0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5
     difficulty      : 26590795561548
     totalDifficulty : 13344340377114708239
     extraData       : 0xd783010305844765746887676f312e342e32856c696e7578
     size            : 770
     gasLimit        : 4712388
     gasUsed         : 42000
     timestamp       : 1460501661
     transactions    : 0x0fba1db5d970e41aa4c7b496631eb0a3dbaf2de46c7b27fda7800ed0145c609a,0x7891df53455629cfed4240f9c8a18a1657abfc088d47a1a89a51fc8ac339a2b1
     uncles          : 
    --- transactions ---
      tx hash          : 0x0fba1db5d970e41aa4c7b496631eb0a3dbaf2de46c7b27fda7800ed0145c609a
       nonce           : 23443
       blockHash       : 0x06cdfceefb706514defc44a0bee28341bbb03e241a8bf8963d4c26b8a37f4309
       blockNumber     : 1325622
       transactionIndex: 0
       from            : 0xea674fdde714fd979de3edf0f56aa9716b898ec8
       to              : 0x77d4d32435d57cbd99afd8ff4c9a58e0302e0675
       value           : 1503349049188321300
       gasPrice        : 20000000000
       gas             : 90000
       input           : 0x
      tx hash          : 0x7891df53455629cfed4240f9c8a18a1657abfc088d47a1a89a51fc8ac339a2b1
       nonce           : 23444
       blockHash       : 0x06cdfceefb706514defc44a0bee28341bbb03e241a8bf8963d4c26b8a37f4309
       blockNumber     : 1325622
       ...
    
  • Print block with uncles mined by "0x4bb96091ee9d802ed039c4d1a5f6216f90f81b01". See https://etherscan.io/block/1325635

    getMinedBlocks("0x4bb96091ee9d802ed039c4d1a5f6216f90f81b01", 1325630, 1325640);
    
  • 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);