How to..
Decode Events from Contract

How to decode unknown Events from a contract

For analytical approach or just for curiosity, it might be interesting to identify events that are emitted by a contract.

The snippets will show how to:

  1. Load all events from a specific contract
  2. Lookup an ABI definition from the event hash
  3. Decode event information using the found ABI

Load event data from specific contract

The thor-node API provides access to all emitted events at /logs/event. Looping until no events are returned, provides access to all data:

const bent = require('bent')
const NODE_URL = ""
const EVENTS_PER_PAGE = 1000
const postNode = bent(NODE_URL, 'POST', 'json')
async function fetchEvents(address) {
  let offset = 0
  do {
    const events = await postNode('/logs/event', {
      order: 'desc',
      options: {
        limit: EVENTS_PER_PAGE,
      "criteriaSet": [{ address }],
    offset += EVENTS_PER_PAGE
    if(!events.length) {
  } while (true)

An example event looks like this:

    "address": "0x0000000000000000000000000000456e65726779",
    "topics": [
    "data": "0x000000000000000000000000000000000000000000000000523986e1ffcd3400",
    "meta": {
      "blockID": "0x00e341410a38f1e1675174639b020b6515bb1e09e11a57d2bb622228d2d0c235",
      "blockNumber": 14893377,
      "blockTimestamp": 1679457330,
      "txID": "0xd0ac0a1fa26b27ada3d9ce912747c9801998689f374d940d1d44b77fa4d5e99d",
      "txOrigin": "0xe6e4b12097cd9588fcb96164cbdbcfba51bb35d3",
      "clauseIndex": 0

The first entry in the topics is a hash of the event signature that is unique for every event.

Lookup an ABI definition from event hash

The first entry of the topics (topics[0]) can be used to lookup the original ABI in a database.

B32 (opens in a new tab) is the priority source for this within the vechain ecosystem. (opens in a new tab) leverages it and sources from other ecosystems.

With the sig.api the lookup can be done:

async function signatureByTopic0(topic) {
  const [lookup] = await lookupSignature(`/${topic}?event=true`)
  if (!lookup) {
    console.error(`No signature found for topic ${topic}`)
  return lookup.abi

The same API can be used for looking up function calls and decode complete function calls with parameters.

Decode event information using the found ABI

thor-devkit (opens in a new tab) brings the ability to handling ABI and data decoding with it.

Instantiating an ABI-Event and using its decode function provides needed decoding:

const { abi } = require('thor-devkit')
const abiCoder = new abi.Event(eventAbi)
const decoded = abiCoder.decode(, event.topics)
console.log(event.meta.txID,, JSON.stringify(decoded))

Sandbox + Complete Snippet

The complete snippet is available on GitHub: (opens in a new tab)

A Sandbox version using Websockets to demonstrate decoding for live events is available here: (opens in a new tab)