rpchedera-hashgraphhedera

How can I obtain a block number programmatically on Hedera?


I understand from HIP-415: Introduction Of Blocks, that Hedera now has blocks, and they're based on timestamps of the transactions being grouped together into "record files" which are an artefact of how they are ingested into the Hedera mirror nodes (from the Hedera consensus nodes). Essentially all transactions that are inside the same record file are considered to be in the same block as well, and these blocks are produced approximately every 2 seconds.

Is there a way that I can convert a date (timestamp) into a block number? My objective is to be able to invoke eth_getBlockByNumber, and I need work out the first parameter for that RPC request based on timestamp.

curl -s -X POST \
    -H 'Content-Type: application/json' \
    -d '{"jsonrpc":"2.0","id":"2","method":"eth_getBlockByNumber","params":[MY_BLOCK_NUM, false]}' \
    http://localhost:7546

(Need to work out MY_BLOCK_NUM in the ^ command above.)

For example, here's block 4507206, which corresponds to the record file 2023-05-10T08_27_52.012122604Z.rcd.gz, and contains all transactions between 08:27:52.0121 and 08:27:53.7004 in UTC today. Suppose I did not know both what the block number was, or what the record file was. I only have a single timestamp, and I want to find the corresponding block number from it. How can I do this (programmatically)?


Solution

  • First, get the Unix timestamp for the date and time that you need. Use the -u flag if you want to specify the date/ time in UTC (otherwise default to the timezone on your computer). ​

    TIMESTAMP=$(date -u -j -f "%F %T" "2023-05-10 08:27:52" "+%s")
    

    ​ (Sample result: 1683707272)

    Next, make an API request to the Hedera mirror node API:

    curl -s "https://testnet.mirrornode.hedera.com/api/v1/blocks?limit=1&order=asc&timestamp=gte:${TIMESTAMP}" | jq
    

    ​ We repeat the same command as above, but this time extract the blocknumber out of the full response object using a jq path. ​

    BLOCKNUM=$( curl -s "https://testnet.mirrornode.hedera.com/api/v1/blocks?limit=1&order=asc&timestamp=gte:${TIMESTAMP}" | jq ".blocks[].number" )
    

    ​ (Sample result: 4507206)

    And that's all, you now have your block number!

    But let's go one step further to demonstrate that this block number can be used outside of the Hedera mirror node APIs (which are custom, and specific to Hedera).

    Let's use this value in JSON-RPC, and obtain the block from there!

    Convert that block number to hexadecimal using printf. ​

    BLOCKNUMHEX=$( printf "0x%x\n" ${BLOCKNUM} )​
    

    ​ (Sample result: 0x44c646)

    Make a JSON-RPC request to an instance of hedera-json-rpc-relay. If you have one running locally, the endpoint is exposed at http://localhost:7546 by default. If you don't have that running, there are other options. ​

    curl -s -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":"2","method":"eth_getBlockByNumber","params":["'"${BLOCKNUMHEX}"'", false]}' http://localhost:7546 | jq ".result"