Issue with MultiParty Contract

Hello, I am new to Daml and building one of the design patterns in Daml and have been having trouble with one line and making parties. Can someone explain to me what I am doing wrong?

Here is the output when I run daml build or daml start

Can you share the full file, in particular the part above the line with the error?

Yeah sure, thanks for the quick response


@Konscious7 I strongly recommend pasting the text, rather than posting screenshots. For example, it is still difficult to see from your screenshots whether there is a scoping error. You can enclose code blocks between ``` lines to ensure they are not wrapped by the forum software, as explained here.

import Daml.Script

template GovermentContract
  with
    signatories: [Party]
  where
    signatory signatories
    ensure
      unique signatories

template Pending
  with
    finalContract : GovermentContract
    alreadySigned: [Party]
  where
    signatory alreadySigned
    observer finalContract.signatories
    ensure
      -- Can't have duplicate signatories
      unique alreadySigned

    -- The parties who need to sign is the finalContract.signotories with alreadySigned filtered out
    let toSign = filter (`notElem` alreadySigned) finalContract.signatories

    choice Sign : ContractId Pending with 
        signer : Party
      controller signer
        do
          -- Check the controller is in the toSign list, and if theu are, sign the Pending contract
          assert (signer `elem` toSign)
          create this with alreadySigned = signer :: alreadySigned
    
    choice Finalize : ContractId GovermentContract with
        signer : Party
      controller signer
        do
          -- Check that all the required signotories have signed Pending
          sort alreadySigned == sort finalContract.signatories
          create finalContract 

    
parties@[person1, person2, person3, person4, person5, person6] <- makePartiesFrom ["harris", "tom", "lee", "martin", "lisa", "bob"]
let finalContract = GovermentContract with signatories = parties

-- Parties cannot create a contract already signed by someone else
initialFailTest <- person1 `submitMustFail` do 
  createCmd Pending with finalContract; alreadySigned = [person1, person2]

-- Any party can create a contract a pending contract provided they list themeselves as the only signatory
pending <- person1 `submit` do
  createCmd Pending with finalContract; alreadySigned = [person1]

-- Each signatory of the finalContract can Sign the Pending contract
pending <- person2 `submit` do
  exerciseCmd pending Sign with signer = person2

pending <- person3 `submit` do
  exerciseCmd pending Sign with signer = person3

pending <- person4 `submit` do
  exerciseCmd pending Sign with signer = person4

pending <- person5 `submit` do
  exerciseCmd pending Sign with signer = person5

pending <- person6 `submit` do
  exerciseCmd pending Sign with signer = person6

-- A party can't sign the Pending contract twice
pendingFailTest <- person3 `submitMustFail` do
  exerciseCmd pending Sign with signer = person3

-- A party can't sign on behalf of someone else
pendingFailTest <- person3 `submitMustFail` do 
  exerciseCmd pending Sign with signer = person4


person1 `submit` do 
  exerciseCmd pending Finalize with signer = person1

Thanks for the advice!!

It looks like you put your script code at the top-level rather than within a single script definition. Take a look at the section on daml script in the daml intro for some examples of how to setup it up.

So I went through and added the fail_test = script do parties@[person1, person2, person3, person4, person5, person6] <- makePartiesFrom["harris", "tom", "lee", "martin", "lisa", "bob"] let finalContract = GovermentContract with signatories = parties. It don’t fix the issue but gave me more errors on the unique signatories saying they were not in scope. What determines the scope?

Can you share the full code you’re using now and the error message you’re receiving?

module Main where
import Daml.Script

template GovermentContract
  with
    signatories: [Party]
  where
    signatory signatories
    ensure
      unique signatories

template Pending
  with
    finalContract: GovermentContract
    alreadySigned: [Party]
  where
    signatory alreadySigned
    observer finalContract.signatories
    ensure
      -- Can't have duplicate signatories
      unique alreadySigned

    -- The parties who need to sign is the finalContract.signotories with alreadySigned filtered out
    let toSign = filter (`notElem` alreadySigned) finalContract.signatories

    choice Sign : ContractId Pending with 
        signer : Party
      controller signer
        do
          -- Check the controller is in the toSign list, and if theu are, sign the Pending contract
          assert (signer `elem` toSign)
          create this with alreadySigned = signer :: alreadySigned
    
    choice Finalize : ContractId GovermentContract with
        signer : Party
      controller signer
        do
          -- Check that all the required signotories have signed Pending
          assert (sort alreadySigned == sort finalContract.signatories)
          create finalContract 
          
fail_test = script do
  parties@[person1, person2, person3, person4, person5, person6] <- makePartiesFrom ["Tom", "Lee", "Mike", "Ted", "Luke", "EJ"]
  let finalContract = GovermentContract with signatories = parties

  -- Parties cannot create a contract already signed by someone else
  initialFailTest <- person1 `submitMustFail` do 
    createCmd Pending with finalContract; alreadySigned = [person1, person2]

  -- Any party can create a contract a pending contract provided they list themeselves as the only signatory
  pending <- person1 `submit` do
    createCmd Pending with finalContract; alreadySigned = [person1]

  -- Each signatory of the finalContract can Sign the Pending contract
  pending <- person2 `submit` do
    exerciseCmd pending Sign with signer = person2

  pending <- person3 `submit` do
    exerciseCmd pending Sign with signer = person3

  pending <- person4 `submit` do
    exerciseCmd pending Sign with signer = person4

  pending <- person5 `submit` do
    exerciseCmd pending Sign with signer = person5

  pending <- person6 `submit` do
    exerciseCmd pending Sign with signer = person6

  -- A party can't sign the Pending contract twice
  pendingFailTest <- person3 `submitMustFail` do
    exerciseCmd pending Sign with signer = person3

  -- A party can't sign on behalf of someone else
  pendingFailTest <- person3 `submitMustFail` do 
    exerciseCmd pending Sign with signer = person4

  person1 `submit` do 
    exerciseCmd pending Finalize with signer = person1

ERROR MESSAGE:

File:     daml/Main.daml
Hidden:   no
Range:    10:7-10:13
Source:   typecheck
Severity: DsError
Message:  daml/Main.daml:10:7: error:Variable not in scope: unique : [Party] -> Bool
File:     daml/Main.daml
Hidden:   no
Range:    21:7-21:13
Source:   typecheck
Severity: DsError
Message:  daml/Main.daml:21:7: error:Variable not in scope: unique : [Party] -> Bool
File:     daml/Main.daml
Hidden:   no
Range:    39:19-39:23
Source:   typecheck
Severity: DsError
Message:  daml/Main.daml:39:19: error:Variable not in scope: sort : [Party] -> a0
File:     daml/Main.daml
Hidden:   no
Range:    39:41-39:45
Source:   typecheck
Severity: DsError
Message:  daml/Main.daml:39:41: error:Variable not in scope: sort : [Party] -> a0
File:     daml/Main.daml
Hidden:   no
Range:    43:69-43:84
Source:   typecheck
Severity: DsError
Message: 
  daml/Main.daml:43:69: error:
  Variable not in scope: makePartiesFrom : [Text] -> Script [Party]
damlc: Error when running Shake build system:
BadDependency "GenerateDalf"

You have two issues here:

  1. First, you are missing an import to use unique and sort. To fix that add the following after the import Daml.Script line:
import DA.List (sort, unique)
  1. Second, you are missing the definition of makePartiesFrom. I assume your code is copied from the Daml patterns so you probably want the definition used there. Inlined here:
makePartiesFrom names =
  mapA allocateParty names

Just add that somewhere to your file after the imports.

You are a blessing, appreciate it !!