Skip to main content
replaced http://ethereum.stackexchange.com/ with https://ethereum.stackexchange.com/
Source Link
Source Link
BokkyPooBah
  • 40.4k
  • 14
  • 123
  • 193

EtherScan would be scanning the blockchain block by block and saving the data into a SQL/NoSQL database.

Following is some geth console JavaScript code to extract the account and contract addresses from the transaction executed in each block.

Process the blocks from block 0 to eth.blockNumber and keep running this code when new blocks are produced. Collect the account information in your SQL/NoSQL database for easy access to the data.

Here's the code:

function getAccounts(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 accounts 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) {
        console.log("Block: " + e.blockNumber + "\n" 
          + "  Tx#: " + e.transactionIndex + "\n"
          + "  From: " + e.from + "\n"
          + "  To: " + e.to);
        if (e.to == null) {
          var txReceipt = eth.getTransactionReceipt(e.hash);
          if (txReceipt != null && txReceipt.contractAddress != null) {
            console.log("  Contract created: " + txReceipt.contractAddress);
          }
        }
        var status = debug.traceTransaction(e.hash);
        if (status.structLogs.length > 0) {
          console.log("  Status: " + status.structLogs[status.structLogs.length-1].error);
        }
      })
    }
  }
}

Running the script against the block before and the block after the block The DAO (contract address `0xbb9bc244d798123fde783fcc1c72d3bb8c189413`) was created in produces the following result:
// TheDAO created in block 1428757
getAccounts(1428756, 1428758)
Searching for accounts within blocks 1428756 and 1428758"
Block: 1428756
  Tx#: 0
  From: 0xfb95c8d03f91bf3daede239963cc3f6392af8b89
  To: 0x31911ed12996ce70d0322dc38316123d639a72c2
Block: 1428756
  Tx#: 1
  From: 0xf713234526d4d2c94ed45d4b9aa2c65bba235bd4
  To: 0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98
Block: 1428757
  Tx#: 0
  From: 0x793ea9692ada1900fbd0b80fffec6e431fe8b391
  To: null
  Contract created: 0xbb9bc244d798123fde783fcc1c72d3bb8c189413
  Status: 
Block: 1428758
  Tx#: 0
  From: 0xfb95c8d03f91bf3daede239963cc3f6392af8b89
  To: 0x31911ed12996ce70d0322dc38316123d639a72c2
Block: 1428758
  Tx#: 1
  From: 0x936a394441d6b6baf033d2f1a0d01e0237670d50
  To: 0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98
Block: 1428758
  Tx#: 2
  From: 0x8ec8b1d38b74dece7847e3a025ae53699f08aa1f
  To: 0x91337a300e0361bddb2e377dd4e88ccb7796663d
undefined

Running the script with the block number of one of The DAO's attacker's transaction from 17/06/2016 with an error shows the error status:

// TheDAO Attack 17/06/2016 had an error in block 1720426
getAccounts(1720426, 1720426)
Searching for accounts within blocks 1720426 and 1720426"
Block: 1720426
  Tx#: 0
  From: 0x969837498944ae1dc0dcac2d0c65634c88729b2d
  To: 0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89
  Status: invalid jump destination (PUSH1) 2
Block: 1720426
  Tx#: 1
  From: 0xed059bc543141c8c93031d545079b3da0233b27f
  To: 0x8b3b3b624c3c0397d3da8fd861512393d51dcbac
  Status: 
Block: 1720426
  Tx#: 2
  From: 0xed059bc543141c8c93031d545079b3da0233b27f
  To: 0x8b3b3b624c3c0397d3da8fd861512393d51dcbac
  Status: 
Block: 1720426
  Tx#: 3
  From: 0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98
  To: 0x3b80cb7ecb50760fff3d6dec17a43857eb2661e3
Block: 1720426
  Tx#: 4
  From: 0x91337a300e0361bddb2e377dd4e88ccb7796663d
  To: 0x797d1f2d60538013574734dbd6e4ef70fd81e695
Block: 1720426
  Tx#: 5
  From: 0x91337a300e0361bddb2e377dd4e88ccb7796663d
  To: 0xf565de1874479a51d46dde81d6e9b060540e54f6
Block: 1720426
  Tx#: 6
  From: 0xea674fdde714fd979de3edf0f56aa9716b898ec8
  To: 0x92e4596507168a736c9df4da3af5a6c52e64e54e
Block: 1720426
  Tx#: 7
  From: 0x011b575ec44f36950f84d3711e3eb39059351324
  To: 0xbb9bc244d798123fde783fcc1c72d3bb8c189413
  Status: 
Block: 1720426
  Tx#: 8
  From: 0xe782e8ebe804cf9192cfe0e31302da03082f9164
  To: 0xbb9bc244d798123fde783fcc1c72d3bb8c189413
  Status: 
undefined    

The bit of code that checks the status of the transaction is described in How can the transaction status from a thrown error be detected when gas can be exactly the same as the gasUsed for a successful transaction?.