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?.