Splitting Applications To Atoms

The goal of this post, well, was something different when I started writing it, but now the post analyses what applications are from multiple perspectives and how the definition could be improved.

Application spectrum

We talk about applications a lot and have different definitions for the word application. I believe it is another example of a terminology argument. We all have different opinions about what portion of the application bubble is substantial/relevant enough to be called an “application”.

Let’s define an application spectrum: let’s call eeeverything that is related to the application an application bubble. This is the rightmost bound of the spectrum [1]. The leftmost bound of the spectrum - the minimal immutable identity-defining core of an application - is the application kind. It is the application atom. On the RM level, application kind is what distinguishes one application from another. So we have a spectrum from application atom to application bubble. Different people working on Anoma use the word “application” to refer to different points of this spectrum depending on what they are working on. For example, I mostly care about the RM level, so I usually use the word application to refer to its atom.

Let’s define another distinguishable point of the spectrum that we sometimes talk about that includes the application kind and its transaction and projection functions. Let’s call it an application blueprint [2]. The application blueprint is a community- or developer-recommended interface to the application atom — a practical guide to using the application, including standard ways to construct transactions and read state.

Application dimensions

There may be many more dimensions worth talking about, but here I’ll define three:

  1. Call type. In the most abstractest model of a program, we can talk about reads and writes. A write updates the state, a read reads the state. Reads and writes may have different permissions, so it is useful to distinguish them
  2. Function ownership. We talk about applications and users. The application provides some service, the user requests some service. It can be useful to understand what a component of an application is responsible for
  3. Visibility of request. Let’s define three visibility modes:
    1. Global - the data is committed to public, it is persistent and verifiable by all participants. Read calls do not generate globally visible data, because no state is updated
    2. Selective - the user is expected to reveal the data to a selected set of agents who can store and share the data but, unlike global, recording the data is not required/expected for the correct functioning of the system. It is public but ephemeral
    3. Local - the user has full control over who sees the data

Now given these three dimensions, let’s define a table of application components and try to think what component could have / has these properties. Some of the components we have explicitly defined, some of the components are implicit and should stay such, some of the components we might want to define explicitly.

Function Call type Spectrum viewpoint Function owner Visibility of request
Oblivious projection function Read Any User Local
Projection function Read Any User Selective
Undefined Read Application blueprint User Local
Undefined Read Application blueprint User Selective
Oblivious projection function Read Application blueprint Application Local
Projection function Read Application blueprint Application Selective
Private solving Write Any User Local
Intent Write Any User Selective
Application circuit Write Application atom Application Local
Undefined Write Application atom Application Selective
Application out-of-circuit checks Write Application atom Application Global
Undefined Write Application blueprint User Local
Undefined Write Application blueprint User Selective
Undefined Write Application blueprint User Global
Private solving Write Application blueprint Application Local
Intent Write Application blueprint Application Selective
Undefined Write Application blueprint Application Global
  • The combination of application atom viewpoint and application as the function owner essentially means that the function is affecting the application kind. Otherwise the closest defined point is the application blueprint.

  • Application circuit the easiest case to consider. It is local as it allows the user to pick the visibility constraints, the application defines it and it is executed in order to write to the state.

  • Projection function allows to read the current state. Depending on the view point, it can be seen as something defined by both the application (viewpoint: application blueprint) or the user (viewpoint: application atom)

  • Transaction function is a write request that, depending on the view point, can be produced by the user or the application. I would say it is global as the data associated with the request (the transaction) is recorded.

  • Intent is a selective request that again, depending on the view point, can be constructed by the application or the user. It is selective as the data is ephemeral

  • Private solving intent is just like regular but local thanks to the associated privacy mechanism. Same way, it can be either produced by application or user, depending on the view point

  • Oblivious projection function is just like regular projection function but operates in the OMR style, allowing the user to retrieve information about the state without the responding party seeing the requested data

  • Application out-of-circuit checks. These are some checks that are managed externally, global, but are tightly associated with the application and influence the application’s identity, i.e., they are affecting the resource kind computation. The advantage is that some applications already imply some public sanity checks, and at the moment there are two suboptimal ways to handle them:

    • Include them in the circuit, which is excessive and expensive
    • Standardize them for all applications and require the executor to verify them out-of-circuit as a part of the transaction verification process

Ensuring integrity of the application out-of-circuit checks might be achieved by including the code in the application kind computation. We might even consider moving some of the generalized out-of-circuit checks to application out-of-circuit checks. For example, balance-related checks can become global. On the one hand, it allows more flexibility for the applications. On the other hand, it makes it easier for the applications to fuck something up.


  1. let’s ignore the complexity of composed application’s components for now ↩︎

  2. If you are wondering why I drop so many new terms - it is just because the old terms have different meanings for different people and I want to refer to specific meaning, not specific term. ↩︎

1 Like