I have been downloading blocks from EVM-based blockchains via the JSON-RPC API via eth_getBlockByNumber
. In the block there is a logsBloom
element which, if I understand this correctly, is an aggregate of the logs of every transaction in that block.
There are certain topics I want to search for, such as 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
(token transfer). If I can search the block-level logsBloom
filter for my topics in my software, then I can decide whether to go back to the blockchain to get any of the transaction-level logs and/or receipts.
I have limited API calls to my blockchain data provider, so I don't want to call eth_getLogs
or eth_getTransactionReceipt
for every single transaction on a blockchain since 99.9% of them are irrelevant to me and I simply can't send a million requests per day. I need this data historically back to genesis, so subscribing to real-time, filtered events is insufficient.
Is this possible? Can I parse and search the 256 byte block-level logsBloom
data for "any transaction in the block which emitted a specific topic/event that I am asking for"?
Best Answer
To check if a topic might be possibly included in one of the transactions in the block, you must check if 3 bits in the logs bloom are set to 1.
Let's go through the example:
Get the
keccak256
of the topic:0xada389e1fc24a8587c776340efb91b36e675792ab631816100d55df0b5cf3cbc
So from the
0xada389e1fc24a85...
we have to find 3 ByteMasks and ByteIndexes to check in the bloom logs for.We can refer to the source code, how the Bits are calculated which should be set to
1
.https://github.com/ethereum/go-ethereum/blob/793f0f9ec860f6f51e0cec943a268c10863097c7/core/types/bloom9.go#L139
And do the same thing:
And now, we can check our
logsBloom
if it matches the topic.If
bitsAreSet
isfalse
we know that none of the transactions in the block has theTransfer
log. But if it istrue
, it doesn't guarantee that theTransfer
event is present, just it could be present.