Is it necessary that maintainer key always been a party?

I am trying to use data record as a maintainer key but getting following error.

/home/nishchal/Test/daml/Test.daml:23:16: error:
    • No instance for (IsParties CitizenKey)
        arising from a use of ‘toParties’
    • In the expression:
        toParties ((DA.Internal.Record.getField @"_1" key))
      In the first argument of ‘concat’, namely
        ‘[toParties ((DA.Internal.Record.getField @"_1" key))]’
      In the expression:
        concat [toParties ((DA.Internal.Record.getField @"_1" key))]typecheck

Here is my template and data record

data CitizenKey = CitizenKey with
    citizen : Party 
    id: Text
      deriving(Eq,Show)

data CitizenInfo =CitizenInfo with
    citizendetail1 : Text 
    citizendetail2 : Text 
    citizendetail3 : Text 
      deriving(Eq,Show)


template CitizenRegistration
  with
   registrationCid : CitizenKey
   registrationData : CitizenInfo
  where
    signatory registrationCid.citizen

    key (registrationCid,registrationData):(CitizenKey,CitizenInfo) 
    maintainer key._1
    
    nonconsuming choice UpdateRegistration : ContractId CitizenRegistration
      with
           newCitizenDetails : CitizenInfo

      controller  registrationCid.citizen
        do
         (oldRegistrationCid, oldRegistrationData) <- fetchByKey @CitizenRegistration (key this)
         archive oldRegistrationCid
         create CitizenRegistration with 
           registrationCid = oldRegistrationData.registrationCid 
           registrationData = newCitizenDetails
1 Like

edit: To the question in the subject, yes. Maintainers play a specific semantic role in the contract key model that may not simply be carried out by arbitrary data.

You need to tell DAML how to get the Partys from your CitizenKey.

If this is the only place, you could just write maintainer key._1.citizen.

If you generally want CitizenKey to work, you could add the missing instance. If I add this line to the file:

instance IsParties CitizenKey where

I get the error

Test.daml:63:10: error:
  • No explicit implementation for
  ‘toParties’
  • In the instance declaration for ‘IsParties CitizenKey’

So I can add

instance IsParties CitizenKey where
  toParties = ()

Now I get

Test.daml:64:15: error:
  • Couldn't match expected type ‘CitizenKey -> [Party]’
  with actual type ‘()’
  • In the expression: ()
  In an equation for ‘toParties’: toParties = ()
  In the instance declaration for ‘IsParties CitizenKey’

Now just implement that signature. There are a few ways; since what I want is “just recur on the IsParties instance for the citizen field”, I would write:

instance IsParties CitizenKey where
  toParties = toParties . citizen

But this is almost a stylistic choice at this point.

2 Likes