Steem for Script Kiddies: Get the first block number from a given day
Here is a bash shell script to retrieve the first Steem block number from a particular day.
This has been on my "to-do list" for quite some time. There have been many times when I wanted to run a script between "day 1" and "day 2", but the Steem API calls typically want block number arguments. So, fairly often, I would abandon the project before it started because I didn't feel like dealing with the hassle of finding the relevant block numbers. So now, I'm taking that excuse away from myself.
The script takes a single argument, in the form YYYY-MM-DD. It makes use of two binary search loops because I didn't want to make any assumptions about matching the exact second that a block was produced or the 3 second cadence between blocks.
Loop 1: Searches for any block that matches the desired date.
Loop 2: Backs up from there to find the first block of the day.
So, here it is:
#!/bin/bash
STEEM_SHELL_API="https://api.steemit.com"
# Get first block from a given day
startDate=${1} ### YYYY-MM-DD
lastIrreversibleBlockNum=$(curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.get_dynamic_global_properties", "params":[], "id":1}' ${STEEM_SHELL_API} | \
jq -S .result.last_irreversible_block_num)
lastIrreversibleBlockHead=$(curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.get_block_header", "params":['${lastIrreversibleBlockNum}'], "id":1}' ${STEEM_SHELL_API})
lastTimeStamp=$(echo ${lastIrreversibleBlockHead} | jq -Sr .result.timestamp)
Top=${lastIrreversibleBlockNum}
Bottom=1 # First block ever
#
# Keep looping 'til we find any block in the right day.
#
while :
do
topDate=$(curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.get_block_header", "params":['${Top}'], "id":1}' ${STEEM_SHELL_API} | \
jq -Sr .result.timestamp | sed 's/T.*//g')
bottomDate=$(curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.get_block_header", "params":['${Bottom}'], "id":1}' ${STEEM_SHELL_API} | \
jq -Sr .result.timestamp | sed 's/T.*//g')
if [ "${topDate}" == "${bottomDate}" -o ${topDate} == $startDate -o ${bottomDate} == $startDate ]
then
if [ ${topDate} == ${startDate} ]
then
matchBlockNum=${Top}
elif [ ${bottomDate} == ${startDate} ]
then
matchBlockNum=${Bottom}
else
echo "Not found"
exit
fi
break
fi
Middle=$(( ( ${Top} + ${Bottom} ) / 2 ))
middleDate=$( curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.get_block_header", "params":['${Middle}'], "id":1}' ${STEEM_SHELL_API} | \
jq -Sr .result.timestamp | sed 's/T.*//g' )
if [[ "${middleDate}" > "${startDate}" ]]
then
Top=${Middle}
else
Bottom=${Middle}
fi
done
#
# Now back up to find the first block of the day
#
Top=${matchBlockNum}
Bottom=$(( ${matchBlockNum} - 28800 )) ### 28,800 blocks per day (20 * 60 * 24 )
while [ $(( ${Top} - ${Bottom} )) -gt 1 ]
do
topDate=$(curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.get_block_header", "params":['${Top}'], "id":1}' ${STEEM_SHELL_API} | \
jq -Sr .result.timestamp | sed 's/T.*//g')
bottomDate=$(curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.get_block_header", "params":['${Bottom}'], "id":1}' ${STEEM_SHELL_API} | \
jq -Sr .result.timestamp | sed 's/T.*//g')
middleBlock=$(( ( ${Top} + ${Bottom} ) / 2 ))
middleDate=$(curl -s --data '{"jsonrpc":"2.0", "method":"condenser_api.get_block_header", "params":['${middleBlock}'], "id":1}' ${STEEM_SHELL_API} | \
jq -Sr .result.timestamp | sed 's/T.*//g')
if [ ${middleDate} == ${startDate} ]
then
Top=${middleBlock}
else
Bottom=${middleBlock}
fi
done
matchBlockNum=${Top}
echo ${matchBlockNum}
And here's some sample output:
$ ./gfb.sh 2016-03-16
Not found
$ ./gfb.sh 2016-03-24
1
$ ./gfb.sh 2016-07-17
3259141
$ ./gfb.sh 2020-02-14
40796981
$ ./gfb.sh 2020-03-15
41658216
$ ./gfb.sh 2022-01-01
60338154
$ ./gfb.sh 2022-11-11
69328610
$ ./gfb.sh 2022-12-31
Not found
I slapped this together in a short time today, so there is basically no error checking and unfortunately, it is still somewhat slow, taking about 16 seconds to return a block number.
$ time ./gfb.sh 2019-08-25
35846311
real 0m16.610s
user 0m1.531s
sys 0m3.344s
That's better than trying to search and click my way through a block explorer, but it's still not great.
A fun challenge to the reader might be to make it faster or do the same thing in Windows Powershell.
Feel free to use this script and to make changes as desired.
Previously in Steem for script kiddies, I posted:
- Steem for script kiddies: Top N pending powerdowns
- Steem for script kiddies: SBD debt ratio
- Steem for Script Kiddies: Get the first block number from a given day
Pixabay license, source
Reminder
Visit the /promoted page and #burnsteem25 to support the inflation-fighters who are helping to enable decentralized regulation of Steem token growth.
Yes, 16 seconds seems small for an ordinary person in life, but in blocks it is a lot. Everything is relative in this world. Good luck to you!
I don't think there are any errors. I wish you a happy weekend
Good job. And things need to be done right away without postponing. I hope there are no mistakes here, but to be honest, I don't really understand this)