Let me try to illustrate these concepts with an example drawn from the Daml Finance library.
These work similarly to what you would expect from interfaces in object-oriented programming:
- an interface defines a set of methods and choices
- a template that implements an interface needs to provide the implementation of the corresponding methods
- when writing Daml code, we can access the choices via the interface
As an example, consider the setup in the picture below
We have two contracts on the ledger
Both templates implement the Base holding interface, which gives access to the
Only the Fungible holding implements the Fungible interface, which gives access to the
Assume now that you want to write a new Daml template where the
owner of a holding can claim a prize if the
amount they hold is greater than
You want to write generic code that works for both C1 and C2, given that they both have an
owner field. Specifically, you can write your template to work for any contract implementing the Base holding interface (which gives access to
amount fields via the
GetView choice). In order to do that, we need a way to reference this set of templates: an interface ContractId.
Your new template will look as follows:
nonconsuming choice Claim : ContractId Prize
ctrl : Party
holdingCid : ContractId Base.I -- any contract that implements the base holding interface
view <- exercise holdingCid GetView
assert view.owner == ctrl
if view.amount > 100 then create Prize with ... else abort ""
Finally, an interface view is just a special method which
- must be defined for each interface
- must return a serializable object
The reason why views are useful is explained in my post above.
I hope this helps you get a better understanding of the mechanics of interfaces in Daml. If you find this example useful, we could consider adding it to the Daml Finance documentation. I also encourage you to have a look at the Daml Finance getting started tutorial in case you haven’t done so.