Demystifying intents

The goal of this post is to start a centralised discussion on the definition of intents and to provide the necessary context for it.

Definitions

Intents

Users initiate a state transition on the blockchain by submitting their intent. Intents are representations of user preferences that shape the initiated state transition. They are invariant across all possible state transitions, meaning that no matter what transaction gets constructed, the user’s intent will be satisfied by it. Solvers are the actors who receive user intents and match them together, constructing transactions.

Partial transactions & transactions

Partial transactions and transactions are data structures that solvers construct to satisfy users’ intents. They are designed in the resource model, in which state transitions are represented as consumed (input) and created (output) resources - atomic data units.

A partial transaction contains m input and m output resources and represent a partial state transition. Such state transition cannot be published on the blockchain itself, but is used to construct transactions. A transaction tx_i contains n_i input and n_i output resources (n_i = k_i*m, k_i \in \mathbb{N}) and is built from k_i partial transactions.

The reason why a partial transaction cannot be published on the blockchain is that they are not balanced.

Balance

Each resource has a resource type and an unsigned numeric value called quantity. When a resource is being consumed, its quantity is assumed to be negative, and when a resource is being created, the quantity is assumed to be positive. A transaction balance is the sum of the resource quantities per each resource type. A transaction is called balanced when for each resource type, the balance of the transaction equals to zero[1].

Are intents partial transactions?

Well, yes and no. Intents can be represented as partial transactions, but are not equivalent to them. Let’s take a closer look.

I. Intents = partial transactions

When the user knows exactly what they want, they simply produce a partial transaction that creates the asset they want. Now, this partial transaction is not balanced, and the solver’s goal is to find another partial transaction that is willing to give the asset away (which is expressed by consuming the asset).

II. Intents \neq partial transactions

Resource logic

Every resource has a predicate encoded into it that expresses the rules on which the resource can be consumed and created. This predicate is called a resource logic. A resource logic has a hierarchical strucutre - it might require checking other predicates in order to be satisfied.

Intents = predicates

In the case when a user doesn’t know exactly what they want[2], they can encode all possible options that would satisfy them in a predicate. The resource logic then would require this predicate to be satisfied.

To allow that kind of behaviour a special type of resources is used[3], a logic of which states that this resource can be consumed iff the intent predicate is satisfied. The user would create a resource of that type at the beginning of interaction and consume it at the end. Having this resource consumed in the transaction proves that the intent was satisfied.

In this situation an intent is encoded in a predicate, that is itself is encoded in a resource, and resources are consumed and created in partial transactions. So, the intent is carried by a partial transaction but is not equal to it.

So…what are intents?

In the first section I described intents abstractly, and in the next section described two different (complementary) ways[4] to express them in the Anoma model. To start the discussion, I propose to use a variation of the definition from the first section as the definition:

Intents are representations of user preferences that shape the initiated state transition. They are invariant across all possible state transitions, meaning that no matter what transaction gets constructed, the user’s intent will be satisfied by it.


  1. the transaction balance is checked against the balancing value. For transactions fully within the shielded pool the value is 0. ↩︎

  2. it can also be used when the user knows what they want, but using just partial transactions might be cheaper in this case ↩︎

  3. it isn’t actually special ↩︎

  4. this overview is not exhaustive, and there are other ways to express intents ↩︎

4 Likes

Hi @vveiln! I have a question: How are resources initially allocated and finally freed up?

Let’s assume that a DolphinResource or MessageResource doesn’t exist yet.
How can I create one and finally delete it? Wouldn’t this result in unbalanced transactions?

Logics may allow creating resources without “proper” balancing, i.e., balancing using dummy resources. From the taiga perspective such a transaction is balanced: dummy resources consumed to balance the creation of non-dummy resources. From the application perspective, such a transaction represents a resource creation from scratch. The same works for the consumption case (resources don’t really get deleted, just marked as invalid)

1 Like