Web3.js – Parsing Transaction Receipt Logs

eventsjavascriptlogsreceiptsweb3js

The event parser in web3 provides a nice parsing functionality for events, and I use it for logging all events to a file, but it's very difficult to use for looking at individual events for a particular transaction for automated testing because it induces an unneeded and difficult to manage concurrency aspect when there doesn't need to be one.

When I get a transaction result with web3, I have the transaction receipt in hand and that's the perfect time to synchronously examine the result and apply pass/fail test criteria.

I would like to parse the log section of the receipt but can't find a function in web3 to do so. Does it exist?

Best Answer

Do this: You'll need to pull code from web3, and it works best if your frontend is bundled using something like webpack or browserify:

var SolidityCoder = require("web3/lib/solidity/coder.js");
var log = receipt.logs[0];
var data = SolidityCoder.decodeParams(["string", "uint"], log.data.replace("0x", ""));

In this case, we're decoding log data that contains two variables, one a string type and one a uint.

EDIT:

If you have the ABI available, you can detect which event it is related to that ABI:

var SolidityCoder = require("web3/lib/solidity/coder.js");

// You might want to put the following in a loop to handle all logs in this receipt.
var log = receipt.logs[0];
var event = null;

for (var i = 0; i < abi.length; i++) {
  var item = abi[i];
  if (item.type != "event") continue;
  var signature = item.name + "(" + item.inputs.map(function(input) {return input.type;}).join(",") + ")";
  var hash = web3.sha3(signature);
  if (hash == log.topics[0]) {
    event = item;
    break;
  }
}

if (event != null) {
  var inputs = event.inputs.map(function(input) {return input.type;});
  var data = SolidityCoder.decodeParams(inputs, log.data.replace("0x", ""));
  // Do something with the data. Depends on the log and what you're using the data for.
}