Steem for Script Kiddies: Get the first block number from a given day

in #script2 years ago

Here is a bash shell script to retrieve the first Steem block number from a particular day.


Calendar from pixabay

Pixabay license from StockSnap at source.

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:


Trend graph

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.

Sort:  

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)