DAML: Defining Contract Models Compactly¶
As described in preceeding sections, both the integrity and privacy notions depend on a contract model, and such a model must specify:
- a set of allowed actions on the contracts, and
- the signatories, observers, and an optional agreement text associated with each contract.
The sets of allowed actions can in general be infinite. For instance, the actions in the IOU contract model considered earlier can be instantiated for an arbitrary obligor and an arbitrary owner. As enumerating all possible actions from an infinite set is infeasible, a more compact way of representing models is needed.
DAML provides exactly that: a compact representation of a contract model. Intuitively, the allowed actions are:
Create actions on all instances of DAML templates such that the template arguments satisfy the ensure clause of the template
Exercise actions on a contract instance corresponding to DAML choices on that template, with given choice arguments, such that:
- The actors match the controllers of the choice. That is, the DAML controllers define the required authorizers of the choice.
- The exercise kind matches.
- All assertions in the update block hold for the given choice arguments.
- Create, exercise and fetch statements in the DAML update block are represented as create and exercise actions in the consequences of the exercise action.
Fetch actions on a contract instance corresponding to a fetch of that instance inside of an update block. The actors must be a non-empty subset of the contract stakeholders. The actors are determined dynamically as follows: if the fetch appears in an update block of a choice ch on a contract c1, and the fetched contract ID resolves to a contract c2, then the actors are defined as the intersection of (1) the signatories of c1 union the controllers of ch with (2) the signatories of c2.
An instance of a DAML template, that is, a DAML contract or contract instance, is a triple of:
- a contract identifier
- the template identifier
- the template arguments
The signatories of a DAML contract are derived from the template arguments and the explicit signatory annotations on the contract template. The observers are also derived from the template arguments and include:
- the observers as explicitly annotated on the template
- all controllers c of every choice defined using the syntax
controller c can...(as opposed to the syntax
choice ... controller c)
For example, the following DAML template exactly describes the contract model of a simple IOU with a unit amount, shown earlier.
template MustPay with obligor : Party owner : Party where signatory obligor, owner agreement show obligor <> " must pay " <> show owner <> " one unit of value" template Iou with obligor : Party owner : Party where signatory obligor controller owner can Transfer : ContractId Iou with newOwner : Party do create Iou with obligor; owner = newOwner controller owner can Settle : ContractId MustPay do create MustPay with obligor; owner
In this example, the owner is automatically made an observer on the contract, as the
Settle choices use the
controller owner can syntax.
The template identifiers of DAML contracts are created through a content-addressing scheme. This means every DAML contract is self-describing in a sense: it constrains its stakeholder annotations and all DAML-conformant actions on itself. As a consequence, one can talk about “the” DAML contract model, as a single contract model encoding all possible instances of all possible DAML templates. This model is subaction-closed; all exercise and create actions done within an update block are also always permissible as top-level actions.