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)