Does the Daml API support all CRUD operations? It depends on who is asking.

György Balázsi
DAML Masterclass
Published in
5 min readSep 2, 2023

--

From a technical POV, we only have Create and Read (and confusingly call these collectively “update”). Businesswise, consuming exercise is like Update and Delete. This combo is also known as the UTXO model.

Photo by Håkon Grimstad on Unsplash

(I wrote about what Daml ledgers contain recently in my blog posts A Daml ledger tells a story — it’s time to show it to everyone and A Daml ledger tells a story–how does the action happen? If you are not closely familiar with the platfrom I recommend you take a peak at these pieces before reading this one.)

At an abstract level, a Daml ledger is a data storage system. All data storage systems must support the CRUD operations, where the acronym stands for Create, Read, Update and Delete, namely for data entries.

Is this true for Daml as well?

As the title indicates, the answer is yes or no, depending on whether we put the question form a business or from a technical point of view.

What does a Daml ledger (projection) contain?

Before answering the question, a small detour concerning terminology:

So far, I spoke about a “Daml ledger”, but strictly speaking, there is no such thing as a full, all-encompassing Daml ledger.

Physically only exist projections of an imaginary or “virtual” ledger. The projections are projections for certain ledger parties, and contain all the information said ledger party is privy to. (This behavior is called “need-to-know-basis privacy”.) The magic of the Daml platform is that all ledger projections behave exactly as if the all-encompassing full Daml ledger existed in reality, and the projections were derived from that.

The magic of the Daml platform is that all ledger projections behave exactly as if the all-encompassing full Daml ledger existed in reality, and the projections were derived from that.

In the rest of this blog post, I will write casually “Daml ledger”, but it always means that “a Daml ledger projection for a ledger party, pertaining to a virtual full ledger”.

Coming back to the original question: what does a ledger contain?

The answer is that a Daml ledger contains an event graph, which consists of “create” and “exercise” events as nodes, and two kinds of relationships as edges between the events:

  • “consequence” relationships pointing from top-level exercise events, requested directly by ledger partes to their consequences (in the Daml code listed as the “do” block of the choice body)
  • “consuming exercise” relationships; the edge points from the “exercise” event to the preexisting “create” event, which was “consumed” by the exercise.

I wrote about the contents of Daml ledgers in more detail in my blog post A Daml ledger tells a story–how does the action happen? In this blog post, you can see the following diagram, depicting the event graph of a simple ticket purchase use case:

The event graph of a simple ticket purchase use case

Usually we don’t use these precise expressions when we speak about the contents of a Daml ledger, but use the following abstractions:

  • By “active contract” we mean “create” events, pointing to which no consuming exercise relationship was recorded so far.
  • By “archived contract” we mean “create” events, pointing to which a consuming exercise relationship was already recorded.

“Active contract” and “archived contract” are abstractions over the details of the event graph.

The practical consequence for a contract (or “create” event) to be “archived” (or being the target of a “consuming exercise” relationship) is that it cannot be used in any way in future transactions. “Used” means here: exercise the choices contained in it, or being referenced by any transaction.

In the UTXO model we don’t have data entry Update or Delete

A Daml ledger evolves in an append-only manner. This means that no event already recorded on the ledger can be modified or deleted afterwards.

(This is true in the normal course of ledger transactions. In contrast, we have a “garbage collection” mechanism called “pruning”, done by admins, in order to delete archived contracts from the ledger for resource management and GDPR compliance.)

In particular, a consuming exercise neither deletes nor modifies its target. The “consuming exercise” relationship is recorded on the exercise event as a property specifying the contract id of its target “create” event.

This model, where a ledger can only grow, is also called the UTXO model introduced by Bitcoin. (The acronym stands for Unspent Transaction Output.) There is a substantial difference though between the Bitcoin UTXO model and the Daml ledger model: in a Daml ledger an exercise is not necessarily consuming.

Ledger update is different from data entry Update

Please note that we use the expression “update” for Daml ledgers, but its meaning is different from the data entry Update the CRUD acronym refers to.

We call collectively “ledger update” the recording of events on the ledger, reading the contents of the ledger, and even getting the ledger time. Such kind of ledger update is expressed in the Daml smart contract language by the Update monad.

Updating and deleting business objects

Business object updates are expressed on a Daml ledger as a combination of “consuming exercise” and “create” events.

A “create” event recorded on a Daml ledger expresses a certain state of a business object at a particular time.

The change of the business object state is expressed by the combination of two events and a relationship recorded on the ledger:

  • an “exercise” event together with a “consuming exercise” relationship targeting the said state, and
  • a new “create” event with the modified properties.

The two events are recorded in an atomic transaction, so for the outside world the change appears to be an update of the business object. The ordered list of events to be recorded atomically on the ledger is expressed in the “do” block of the corresponding choice body in the Daml code.

The atomicity of the ledger update is achieved in a simple way: the graph fragment expressing all the intended changes either gets appended to the ledger as a whole or nothing is appended to the ledger. (“Simple” means here simple on the surface. The mechanism of checking if all conditions hold for the update under the hood is quite involved.)

One example for such a business object “update” or state change is the transfer of the cash in the ticket purchase use case above. The “9_0. Cash” event represents the issuing of an IOU by the bank for the ticket buyer. This event gets consumed by the “11_2. Transfer” event, which is a consequence of the buyer accepting the ticket offer. The transfer event, in an atomic way, also spawns another cash creation event, this time for the event organizer, as a compensation for the purchased ticket.

The continuity of the business objects across state changes can be maintained by optional contact keys.

Business object deletions are expressed by simply recording a “consuming exercise” relationship targeting the original “create” event. This is the case in the above example with the “10_0. TicketOffer” event.

--

--