Monitoring the blockchain is possibly an important part of your application on NEM. The most obvious example being monitoring activities involving your account. Two approaches are possible.
The first is polling, meaning that regularly you retrieve the last block and handle it. If your polling interval is significantly smaller than the average block generation time, you can be sure you will handle all blocks. And if your polling interval is bigger and multiple blocks have been generated between two polling, you can still request all new blocks in your handler. This approach has downsides, notably that the client is regularly sending queries, even if activity of interest to the poller occured on the blockchain. This means that the scalability of this approach is limited. But its development is very easy and might be sufficient in most cases.
The second way is subscribing to notifications from the NIS instance you connect to. This is done with websockets. This is the way it is done in the NanoWallet. This is a cleaner approach, but is a bit more complex.
The pollign approach is very easy to explain, and it translates immediately in runnable code in any language, expecially if it provides REST and JSON libraries. Here are the steps to do in a loop:
The number of seconds x we wait (the polling interval) will determine if we will handle all blocks. If it is smaller than the average generation time of a block, we can be sure that all blocks will be retrieved at least once by this code. We call this rapid polling in opposition of slow polling. An interval of 15 seconds seems safe for rapid polling.
It is quite straight-forward to translate that to code, even in a bash script using httpie and jq. Let’s see how this can be done!
First we initialise 2 variables: the monitored address, and the last block seen by the script which is set to 0 at the start of the script:
observed_address="TA6XFSJYZYAIYP7FL7X2RL63647FRMB65YC6CO3G"
last_block_analysed=0
As we will continually monitor the blockchain, our code will be wrapped in an infinite while loop:
while true; do
done
In the loop, we retrieve the last block by sending a GET query to /chain/last-block
, and save the result in variable block
:
block=$(http :7890/chain/last-block)
This will retrieve the last block in a json document. Here is an example from the mainnet chain showing the format of the document retrieved.
$ http 199.217.112.135:7890/chain/last-blockGET /chain/last-block HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Connection: keep-alive Host: 199.217.112.135:7890 User-Agent: HTTPie/0.9.8 HTTP/1.1 200 OK Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Origin: * Content-Encoding: gzip Content-Type: application/json Server: Jetty(9.2.11.v20150529) Transfer-Encoding: chunked Vary: Accept-Encoding, User-Agent { "height": 1106506, "prevBlockHash": { "data": "00f421e0b9a8c449bc37f0e19c21c5b1a1c24258eed8d347b0351ff2fe20078e" }, "signature": "96a8b050cd0ae341da7ea3aafa11a966821c2e3d0b614800a6d53fe6e5bbf5f2730c64d7f80b43898e1cb3eb0048e7a65f09bee591decfc07092d068064a7804", "signer": "8ca523bd39f350799b0cc150055b713bd7c65e9bbc94b90502c973a47730a431", "timeStamp": 67011602, "transactions": [ { "amount": 133400000000, "deadline": 67033173,