More about Contracts in DAML: Exploring Proposal-Acceptance Workflow in DAML
Introduction
In my previous work several important concepts like template, contract and transaction about DAML were introduced, with a very simple IOU demonstrating the relationship between them. We have seen how a new contract instance of the same template is created through choices. Here we make it more interesting and realistic: how two contracts are interacting with each other in DAML through choices.
DAML tutorial 6 gives us a good example, which is good for extending our previous IOU example. As it is needed to make owner as signatory (in addition to issuer), the transfer of IOU now is implemented as proposal-acceptance model, which means that one party proposes a transfer, and the other party can accept or reject it. In this case a single IOU template is not sufficient, and here we need another template supporting this.
This article follows largely the tutorial with a few modifications, followed by some illustration and flow analysis. I hope this helps us understand more the mechanism behind. Again, we are using “scenario” built in the DAML studio to simulate a sample flow.
Templates
IOU Template for Simple Transfer Model
In my previous work, the Iou only makes issuer as signatory, and the choice is Transfer. And whenever Transfer is exercised, a new IOU contract instance is created (becomes active) with new owner given, while the previous IOU contract gets archived.
IOU Template for Propose-Accept Model
To achieve the proposal-acceptance model, we first modify the Iou template by adding owner as signatory, and change the choice to ProposeTransfer. (Note that choice is reformatted for better illustration. The effect is the same.)
Choice ProposeTransfer can only be exercised by the current owner of the IOU contract instance. It will result in a contract based on template IouTransferProposal (discussed below). A new owner is required when exercising this choice. After the choice is exercised, a new contract based on template IouTransferProposal is created with this Iou and new owner given. Note this is a consuming choice, which means that this IOU will be archived after this choice is exercised. We will not lose visibility about this Iou, as it is now part of the newly created contract based on template IouTransferProposal.
IOU Transfer Proposal Template
Here is the newly created template, IouTransferProposal.
As mentioned before, a contract of IouTransferProposal requires both the IOU content we are referring to, and the new owner to whom this IOU is to be transferred. There are three choices provided in this proposal for different parties.
- The current owner of IOU can cancel the proposal.
- The new owner can reject the proposal.
- The new owner can accept the proposal.
We first take a look at choice 3, where the new owner accepts the proposal. It is logical and straightforward: a new IOU contract instance will be created and the owner is set to the new owner.
The outcome of choice 1 and 2, either the current owner cancels the proposal, or the new owner rejects it, are the same: back to original IOU. But here is the important part: it is not the original IOU contract instance, but a new one. The reason behind is that the original IOU contract instance has already been archived when ProposeTransfer is exercised (see the previous IOU session). As a result, although the IOU content is the same, this is a brand new contract instance.
We will make this observation in our demonstration.
Proposal-Acceptance Workflow
These illustrations show the proposal and acceptance of an IOU, and how IouTransferProposal contract works in between. It is assumed that 1-Bank issues and IOU and the current owner is Alice, and Alice plans to transfer this IOU to Bob.
Scenario: Simulating the Flow
As in previous work, we are using “scenario” to demonstrate the proposal-acceptance flow. Here are the steps.
We will walk through transactions one-by-one, and make observations on the state of contract instances, both active and archived.
Demonstration Flow
Step 1: 1-Bank issues an IOU of amount 100.0.
Note that both issuer and owner are the bank at this moment. This fulfils the signatory requirement of Iou as 1-Bank is creating this IOU.
Step 2: 1-Bank proposes transfer of this IOU to Alice.
When 1-Bank transfers this IOU to Alice, 1-Bank exercises ProposeTransfer on this IOU contract instance. Based on the template, this choice causes the IOU archived. A new contract instance is created based on template IouTransferProposal. Although the original IOU is archived, the content of that IOU is inside the newly created contract instance (iou.issuer
, iou.owner
and iou.amount
).
Step 3: Alice accepts this transfer proposal.
To accept this transfer proposal, Alice exercises the choice AcceptProposal on the contract instance of IouTransferProposal. According to the template design, this choice causes a new IOU created with owner set to new owner (i.e. Alice). The contract instance of IouTransferProposal is no longer needed. Choices are all consuming by default, that is, after it is exercised the current contract instance will be archived.
Step 4: Alice proposes transfer to Bob.
This is similar to Step 2. The result is to archive the current IOU and a contract instance of IouTransferProposal is created with the IOU content, waiting for choices to be exercised.
Now we show the result of three choices.
Step 5a: Before Bob exercises any choice, owner Alice can cancel the transfer proposal.
After Alice exercises CancelProposal in this proposal, a new contract instance of IOU is created, with all the same content as the previous one. Note that it is a newly created contract instance (id #4.1), not the original one (id #2.1) although the content is the same.
Step 5b: Bob rejects this transfer proposal.
After Bob exercises RejectProposal in this proposal, a new contract instance of IOU is created, with the same content as the previous one. Similar to Step 5a, it is also a newly created contract instance.
Step 5c: Bob accepts this transfer proposal.
After Bob exercises AcceptProposal in this proposal, a new contract instance of IOU is created with the owner now set to Bob.
Discussion
This proposal-acceptance is seen in our business world. Here we can address some questions about it.
In DAML implementation, once a proposal is made, the current IOU contract will be archived. It is still safe as the IOU detail is still inside the newly created IOU transfer proposal. And it also provides an option (a choice) to the current owner to cancel the proposal. As far as the current IOU owner exercises this choice before the new owner accepts it, the IOU is “recovered” as a new IOU contract instance.
Once the current owner makes the proposal, and the new owner accepts it, the current owner cannot revoke this any more. This is close to contracts in our real life, where acceptance on an offer forms certain legal binding. This is well represented in DAML as the acceptance causes immediately a change of ownership in an IOU. The current owner of an IOU must be careful when it makes a decision on the transfer.
We can further enhance this contract by incorporating more factors. For example, under what circumstances the existing owner can cancel the proposal (e.g. the proposal must be valid at least for 1 day), any limitation on the IOU detail (e.g. amount must exceed 1,000.0), at what conditions the new owner can accept it (e.g., acceptance can only be made with 24 hours), etc. It can also be modeled with DAML.
Summary
Hope this small illustration gives you more idea how a more realistic workflow for digital assets is modeled in DAML. We need more templates to achieve some specific pattern such as proposal-acceptance, and DAML provides flexibility when implementing these patterns.