Indicate list of OR signatories

Expressing these sorts of model-constraints in DAML is always interesting. In order to allow a DAML system to scale, the DAML ledger model imposes a couple of strict limitations (system-constraints) on how you express constraints. In my experience, while this can be frustrating, thinking through and accommodating these within your design generally improves both your understanding of your business problem, and more importantly, makes your final design less brittle and more adaptable to future requirement changes.

  1. The only thing a DAML transaction knows about is what it can read from on the ledger, and the only way it can know of something on the ledger is to be explicitly told about it. This means that with exactly one exception, all constraints in DAML must be expressed existentially. The only universally quantified constraint in DAML is the key-uniqueness constraint—and even that required introducing the whole maintainer semantic and key maintenance protocol.

  2. With the single exception of key-uniqueness (again), all constraints on the creation of a new contract must be evaluated within the static-local scope of the contract itself.

Both of these ensure that a creation/exercise of a contract/choice can be evaluated and validated with reference to a bounded set of contracts

In order to permit DAML to scale to large numbers of parties, all constraints in DAML must be expressed existentially A constraint on a contracts, and that therefore the submitter can never be surprised at the result of a transaction by being informed of the presence of a contract about which they were not aware*. This is important to allow DAML to scale effectively as a distributed system.

So, to think about your problem:

  1. templates don’t have signatories, only contracts do. So for the rest of this answer I’m going to assume you want to ensure “a contract with a signatory amongst …”.

  2. Recall system-constraint 1. The only thing that DAML knows about is what it can read from the ledger. That means that this idea of “parties from which the signatories must be drawn” must exist on the ledger somehow. Note that DAML is a symmetric multi-party system. Unlike traditional architectures there is no privileged perspective, no super-user, no a priori centre (pulling on this thread ends up with us buried in post-modern deconstructionism, so I’m going to stop there).
    The result is that a DAML model (ie. template) can’t express the idea that you are privileged in anyway, that any model that can express the constraint Jean restricts contracts to “Jean, Pierre, or Paul” can also express the constraint Andrae restricts contracts to “John, Peter, or Paula”. Because to do otherwise would be to express a universal property of the ledger, and we are restricted to existential predication.

So we need to existentially model the context of our constraint. Specifically, the perspective of the predicating speaker (Jean or Andrae) must be explicitly modelled. As in all modelling this can be achieved in at least two ways, intensionally or extensionally. In my experience DAML is at its best when used intensionally so I’ll cover that first.

The intensional model is focused on behaviour and implication. We don’t model state as data, but rather as the set of behaviours (choices) and constraints on that behaviour implied by previous acts. This approach sees DAML as a means of achieving coherency of praxis in a symmetric distributed system while denying a central authority (and pulling on this thread leads into semiotic pragmatics, so again I’ll shelve it).

What this means is that if there is a contract on the ledger then there was at some point a consensus on potential acts one of which has caused the creation of this contract.

Ie. If there is a contract:

-- (Note the explicit modelling of the `predicator`, there is no implicit authority you can appeal to, there is nothing that is not on the ledger).

template OneOfN
  with
    predicator: Party
    signer: Party
  where
    signatory predicator, signer

Then there must have been the right to create this contract…

template RightToCreateOneOfN
  with
    predicator: Party
    potentialSigners: Set Party
  where
    signatory predicator

    nonconsuming choice CreateOneOfN: ContractId OneOfN
      with
        signer: Party
      controller signer
      do
        create OneOfN with predicator; signer

…which allows you to now utter the predicate: Jean requires that all OneOfN contracts within their authority must be signed by one of the specified signers. Note that the constraint itself is not modelled as data on the ledger, but as a choice, a right to act that has been authorised by whatever prior choice/right-to-act led to the creation of that contract.

Yes, intensionally it’s turtles all the way down until you get to self-authorising unilateral speech acts that therefore do not require or represent consensus.

The alternative is to model this extensionally, This represents the state of the system as data, and constraints on the system as constraints on the permitted values of that data. So naturally this has to comply with the system-constraint 2. One way of rewording constraint 1 is “All intensional constraints must only be existentially predicated”; similarly constraint 2 can be expressed: “All extensional constraints must be contract local”.

So if we want to constrain the signatory of a contract to a set of parties, that predicate must be expressed exclusively in terms of data in that contract. So:

template OneOfNLocal
  with
    signer: Party
    potentialSigners: Party
  where
    signatory signer
    ensure signatory elem potentialSigners

Now, you will immediately observe that while this constraint does encode the letter of the requirement, it falls well short of the spirit. As mentioned above, DAML prefers to be an intensional modelling language. The root of this difficulty is the lack of a central authority. So as a single-signatory template, this represents not consensus on predicated state, but rather a unilateral speech act by signer, and here we see Eco’s observation that any system that can express a truth can by necessity express a lie.

It is for this reason that ensure clauses are rare in DAML modelling; however, I didn’t want to ignore them in this discussion as there are times when this sort of constraint is appropriate — generally to guarantee preconditions on the contract’s choices (ie. a list/set is non-empty, a number is positive or non-zero; etc).

Summary: DAML is symmetric and un-centred, as such modelling must be explicit about authority, existentially predicated, and invariably intensional. This is a significant departure from traditional modelling which invariably has an implicit central authority, admits a range of universally quantified predicates, and is oriented around manipulation of extensional data — but this departure is a good thing and essential for scalable, distributed application of the resulting models.

5 Likes