Hourly ERC20 transfer volumn monitor page
This demo will show you how to build a real-time monitoring chart for the hourly transfer volume changes of Aave ERC20 tokens with about 100 lines of Python code. It will start pulling data from January 1, 2025, and display it in real time.
Build connection
First, we need to create the connection and set up some basic configurations:
def build_con():
con = duckdb.connect(database = "file.db")
con.execute("INSTALL blockduck FROM community;")
con.execute("LOAD blockduck;")
con.execute("set variable eth_url = 'eth/rpc/provider/url';")
con.execute("pragma blockduck_set_verbose(true);")
return conset verbose to true, so we can print more execution details.
Create table
Next, we will create internal tables corresponding to the block table function and the contract table function, which will be used to stream and materialize incremental blockchain data, thereby accelerating query performance.
# init table function and table
def init_table(con, start_block):
## create table func
con.execute("""
pragma blockduck_create_contract_event_rpc('tranfer_erc20', '{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"}');
""")
## create table eth_block if not exists
con.execute(f"""
create table if not exists eth_block as
select * from eth_blocks_rpc({start_block}, {start_block}, getvariable('eth_url'));
""")
## create table tranfer_erc20 if not exists
con.execute(f"""
create table if not exists tranfer_erc20 as
select * from eth_contract_event_rpc_tranfer_erc20(['{ERC20_CONTRACT}']::VARCHAR[], {start_block}, {start_block}, getvariable('eth_url'));
""")
## check the latest block in eth_block
latest_block_in_db = con.execute("select max(number) from eth_block").fetchone()[0]
if latest_block_in_db is not None:
start_block = latest_block_in_db + 1
return start_blockRead the lastest block number to start loading from the previous position.
Block Materialize
Next, materialize incremental blockchain data into the internal table. Every BLOCK_PER_QUERY blocks each time.
We use transaction to make sure insert into
eth_blockandtranfer_erc20is atomic.If we already catch up the latest block, sleep
RPC_INTERNALseconds and retry later.
Draw Chart
We join and aggregate these two tables to calculate the transfer amount per hour:
And then draw them in that chart.
Result
Finally, let's assemble them together!
And here is the result chart:

Full Code
Last updated