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
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.