Web3js – How to Asynchronously Query the Blockchain Using Filters

filtersqueryweb3js

This question is related to this one or this one. There is a tutorial here that shows some filtering examples but it doesn't get into transaction level granularity. Can we query the block chain by transaction and process specific transactions asynchronously?

For example, this code goes through blocks starting and ending with a given block number and displays each transaction to or from a given address:

function getTransactionsByAccounts(myaccount, startBlockNumber, endBlockNumber) {

  console.log("Searching for transactions to/from account \"" + myaccount + "\" within blocks "  + startBlockNumber + " and " + endBlockNumber + "\"");

  for (var i = startBlockNumber; i <= endBlockNumber; i++) {

    var block = eth.getBlock(i, true);
    if (block != null && block.transactions != null) {
      block.transactions.forEach( function(e) {
        if (myaccount == "*" || myaccount == e.from || myaccount == e.to) {
          console.log("  tx hash          : " + e.hash + "\n"
            + "   nonce           : " + e.nonce + "\n"
            + "   blockHash       : " + e.blockHash + "\n"
            + "   blockNumber     : " + e.blockNumber + "\n"
            + "   transactionIndex: " + e.transactionIndex + "\n"
            + "   from            : " + e.from + "\n" 
            + "   to              : " + e.to + "\n"
            + "   value           : " + e.value + "\n"
            + "   gasPrice        : " + e.gasPrice + "\n"
            + "   gas             : " + e.gas + "\n"
            + "   input           : " + e.input);

            // Do something asynchronously with the transaction:
            call_async_method(e); // <== HOW CAN WE ADD THIS AS A PROMISE?
        }
      })
    }
  }
}

How can we process a transaction asynchronously (as shown in the code)? possibly using promises and the filters defined in web3.js.

Best Answer

Unfortunately, there is no filter provided to parse the confirmed transactions without going through a block first i.e., you can trigger a filter (and execute call_async_method()) whenever there is a latest block: eth.getBlock("latest"), but there is no such function for a transaction.

That said, if you're operating on a private blockchain (you trust all the nodes) and believe that all the initiated transactions will successfully be added to the blockchain, you can create filters to react upon eth.pendingTransactions so that the actions like call_async_method() will be performed immediately without waiting for the transactions to get confirmed and added to the blockchain. However, at a later time, you should always check if these transactions are indeed confirmed.

This is not an ideal or recommended solution and contradicts with the fundamental principles of blockchain, but you can test and check if it's suitable for your use case.

Edit: Fast way to scan blocks for transactions on an account. This is an asynchronous scanner with 200 threads: https://ethereum.stackexchange.com/a/7184/2460

Source code here.

Related Topic