ARC-28: Algorand Event Log Spec Source

A methodology for structured logging by Algorand dapps.

AuthorDan Burton
Discussions-Tohttps://github.com/algorandfoundation/ARCs/issues/144
StatusFinal
TypeStandards Track
CategoryARC
Created2022-07-18
Requires 4

Algorand Event Log Spec

Abstract

Algorand dapps can use the log primitive to attach information about an application call. This ARC proposes the concept of Events, which are merely a way in which data contained in these logs may be categorized and structured.

In short: to emit an Event, a dapp calls log with ABI formatting of the log data, and a 4-byte prefix to indicate which Event it is.

Specification

Each kind of Event emitted by a given dapp has a unique 4-byte identifier. This identifier is derived from its name and the structure of its contents, like so:

Event Signature

An Event Signature is a utf8 string, comprised of: the name of the event, followed by an open paren, followed by the comma-separated names of the data types contained in the event (Types supported are the same as in ARC-4), followed by a close paren. This follows naming conventions similar to ABI signatures, but does not include the return type.

Deriving the 4-byte prefix from the Event Signature

To derive the 4-byte prefix from the Event Signature, perform the sha512/256 hash algorithm on the signature, and select the first 4 bytes of the result.

This is the same process that is used by the ABI Method Selector as specified in ARC-4.

Argument Encoding

The arguments to a tuple MUST be encoded as if they were a single ARC-4 tuple (opposed to concatenating the encoded values together). For example, an event signature foo(string,string) would contain the 4-byte prefix and a (string,string) encoded byteslice.

ARC-4 Extension

Event

An event is represented as follow:

interface Event {
  /** The name of the event */
  name: string;
  /** Optional, user-friendly description for the event */
  desc?: string;
  /** The arguments of the event, in order */
  args: Array<{
    /** The type of the argument */
    type: string;
    /** Optional, user-friendly name for the argument */
    name?: string;
    /** Optional, user-friendly description for the argument */
    desc?: string;
  }>;
}

Method

This ARC extends ARC-4 by adding an array events of type Event[] to the Method interface. Concretely, this give the following extended Method interface:

interface Method {
  /** The name of the method */
  name: string;
  /** Optional, user-friendly description for the method */
  desc?: string;
  /** The arguments of the method, in order */
  args: Array<{
    /** The type of the argument */
    type: string;
    /** Optional, user-friendly name for the argument */
    name?: string;
    /** Optional, user-friendly description for the argument */
    desc?: string;
  }>;
  /** All of the events that the method use */
  events: Event[];
  /** Information about the method's return value */
  returns: {
    /** The type of the return value, or "void" to indicate no return value. */
    type: string;
    /** Optional, user-friendly description for the return value */
    desc?: string;
  };
}

Contract

Even if events are already inside Method, the contract MUST provide an array of Events to improve readability.

interface Contract {
  /** A user-friendly name for the contract */
  name: string;
  /** Optional, user-friendly description for the interface */
  desc?: string;
  /**
   * Optional object listing the contract instances across different networks
   */
  networks?: {
    /**
     * The key is the base64 genesis hash of the network, and the value contains
     * information about the deployed contract in the network indicated by the
     * key
     */
    [network: string]: {
      /** The app ID of the deployed contract in this network */
      appID: number;
    }
  }
  /** All of the methods that the contract implements */
  methods: Method[];
  /** All of the events that the contract contains */
  events: Event[];
}

Rationale

Event logging allows a dapp to convey useful information about the things it is doing. Well-designed Event logs allow observers to more easily interpret the history of interactions with the dapp. A structured approach to Event logging could also allow for indexers to more efficiently store and serve queryable data exposed by the dapp about its history.

Reference Implementation

Sample interpretation of Event log data

An exchange dapp might emit a Swapped event with two uint64 values representing quantities of currency swapped. The event signature would be: Swapped(uint64,uint64).

Suppose that dapp emits the following log data (seen here as base64 encoded): HMvZJQAAAAAAAAAqAAAAAAAAAGQ=.

Suppose also that the dapp developers have declared that it follows this spec for Events, and have published the signature Swapped(uint64,uint64).

We can attempt to parse this log data to see if it is one of these events, as follows. (This example is written in JavaScript.)

First, we can determine the expected 4-byte prefix by following the spec above:

> { sha512_256 } = require('js-sha512')
> sig = 'Swapped(uint64,uint64)'
'Swapped(uint64,uint64)'
> hash = sha512_256(sig)
'1ccbd9254b9f2e1caf190c6530a8d435fc788b69954078ab937db9b5540d9567'
> prefix = hash.slice(0,8) // 8 nibbles = 4 bytes
'1ccbd925'

Next, we can inspect the data to see if it matches the expected format: 4 bytes for the prefix, 8 bytes for the first uint64, and 8 bytes for the next.

> b = Buffer.from('HMvZJQAAAAAAAAAqAAAAAAAAAGQ=', 'base64')
<Buffer 1c cb d9 25 00 00 00 00 00 00 00 2a 00 00 00 00 00 00 00 64>
> b.slice(0,4).toString('hex')
'1ccbd925'
> b.slice(4, 12)
<Buffer 00 00 00 00 00 00 00 2a>
> b.slice(12,20)
<Buffer 00 00 00 00 00 00 00 64>

We see that the 4-byte prefix matches the signature for Swapped(uint64,uint64), and that the rest of the data can be interpreted using the types declared for that signature. We interpret the above Event data to be: Swapped(0x2a,0x64), meaning Swapped(42,100).

Security Considerations

As specify in ARC-4, methods which have a return value MUST NOT emit an event after they log their return value.

Copyright and related rights waived via CCO.

Citation

Please cite this document as:

Dan Burton, "ARC-28: Algorand Event Log Spec," Algorand Requests for Comments, no. 28, July 2022. [Online serial]. Available: https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0028.md.