Must controllers be signatories?

They don’t need to be observers either. Any party works. However, note that the submitting party must have seen that contract before (either by virtue of being a stakeholder or via divulgence, the latter being deprecated).

It is also worth noting that the controller … can syntax implicitly makes a party an observer, see What's the difference between controller first and choice first? - #2 by cocreature for details

Here is an example of exercising a choice C with controller b who is neither an observer nor a signatory:

module Main where

import Daml.Script

template T
  with
    a : Party
    b : Party
  where
    signatory a
    choice C : ()
      controller b
      do pure ()

template Auth
  with
    a : Party
    b : Party
  where
    signatory a, b
    choice ExC : ()
      with
        cid : ContractId T
      controller a
      do exercise cid C

test = do
  a <- allocateParty "a"
  b <- allocateParty "b"
  auth <- submitMulti [a, b] [] $ createCmd (Auth a b)
  cid <- submit a $ createCmd (T a b)
  submit a $ exerciseCmd auth (ExC cid)
3 Likes