Using a standard library module with constraints (map function)

@anthony’s answer is going in the right direction, but, as I understand it, you not only want 4 parties, you want to verify that they are 4 different parties. We’ll need two new functions for that. The first one is DA.List.unique, which is True if there are no duplicates in the given list. The second one is notElem, which is True if its first argument (type a) is not present in its second argument (type [a], or "list of a").

Using those, you could write something like:

module Main where

import Daml.Script
import qualified DA.List

template User
  with
    agent: Party
    hawalla: [Party]
  where
    ensure length hawalla >= 4 && DA.List.unique hawalla && agent `notElem` hawalla
    signatory agent

setup : Script ()
setup = script do
  alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
  h1 <- allocatePartyWithHint "1" (PartyIdHint "1")
  h2 <- allocatePartyWithHint "2" (PartyIdHint "2")
  h3 <- allocatePartyWithHint "3" (PartyIdHint "3")
  h4 <- allocatePartyWithHint "4" (PartyIdHint "4")

  aliceTV <- submitMustFail alice do
    createCmd User with
      agent = alice
      hawalla = [h1, h2, h3]

  aliceTV <- submit alice do
    createCmd User with
      agent = alice
      hawalla = [h1, h2, h3, h4]

  aliceTV <- submitMustFail alice do
    createCmd User with
      agent = alice
      hawalla = [h1, h2, h3, h3]
  
  aliceTV <- submitMustFail alice do
    createCmd User with
      agent = alice
      hawalla = [h1, h2, h3, alice]
  
  return ()

Note that:

  • This ensure clause is complex enough that I’d recommend extracting it to a separate (top-level) function.
  • There are of course other ways to achieve the same; using DA.Next.Map is an option, but it will end up being more complicated and DA.Next.Map is slated for deprecation soon so I wouldn’t spend much time exploring that option.

Final note. With this simple approach, you have 4 parties in the hawalla field, but there is no guarantee that these parties exist, nor that the people behind those parties have signed any sort of agreement. For that, you’ll need to make the entire hawalla signatory (signatory agent, hawalla achieves that), but then, before you can create a contract of type User on the ledger, you’ll need to collect the authority of every single party in the desired hawalla list. That will require a propose/accept pattern; if you’re not clear on what that is, a good starting point would be the Iou template described in the documentation. If you have not read through it yet, I actually recommend the entire Introduction to Daml series.

1 Like