I am wondering if there is a way to detect forks that may happen to an Ethereum chain. I looked in web3 library, but couldn't find anything.
Any idea?
I am wondering if there is a way to detect forks that may happen to an Ethereum chain. I looked in web3 library, but couldn't find anything.
Any idea?
I will caveat this twice this by saying the proposed solution is probably not the direct answer...
1) Caveat 1: This is not simply consuming an API
Basically as far as I know there is no direct API that gives you the block "tree" of the latest blockchain state. The reason for this is because this state is effectively considered ephemeral, and if you don't explicitly ask to, is removed (pruned) for the underlying DB periodically. However this data structure is maintained on most Ethereum clients, you just have to expose this structure to the JSONRPC api.
I'll give an example, on EthJ there is a constructed called BlockStore that maintains what you're looking for, you can query for blocks by number through this function call:
public synchronized List<Block> getBlocksByNumber(long number){
List<Block> result = new ArrayList<>();
if (number >= index.size()) {
return result;
}
List<BlockInfo> blockInfos = index.get((int) number);
if (blockInfos == null) {
return result;
}
for (BlockInfo blockInfo : blockInfos){
byte[] hash = blockInfo.getHash();
Block block = blocks.get(hash);
result.add(block);
}
return result;
}
This data structure inherently stores which chain is the "main" chain, and has functions to modify the current "main", therefore you could technically store this information and expose it later (again not trivial, but it is there). See the rebranch function here for details.
So to clarify, if you wanted an API to do this you would need to:
I used EthereumJ for simplicity, all Ethereum clients expose this structure.
There is probably a more technical solution than this, but I recently encountered the problem of needing to know if a chain-reorganisation occurred for a dapp I'm building which makes use of recent blocks.
The simple (yet somewhat hacky) solution I came up with was to deploy a simple contract which has a single function that returns the last few block hashes, as well as the current block number. The function could look something like this
function get_history() view external returns (uint block_number, bytes32[10] memory hashes){
for(uint i = 0; i < 10; i++){
hashes[i] = blockhash(block.number - i - 1);
}
return (block.number, hashes);
}
The length of the array can be anything up to 256, beyond that the block hashes aren't retrievable.
You can then call this function with web3.js either periodically or whenever a new block is mined. Using the return data, you can keep a record of which block hashes belong to which block number. If the function ever returns a block's hash which is different to a value you have recorded, you can be certain that a re-organisation has occurred, and trigger whatever behaviour you need.