Hi,
Given this simple but wonderful Service:
import Daml.Finance.Interface.Account.Factory qualified as Account (F)
template MyGreatService
with
operator : Party
provider : Party
customer : Party
accountFactoryCid : ContractId Account.F
Say we have one MyGreatService
active on-ledger and we need to fix the template implementing Account.F
because there’s a bug in it
. In this scenario we would not need to modify the codebase in MyGreatService
because we are using Interfaces
. However, we would have to migrate the MyGreatService
contract on-ledger because we want MyGreatService
contract to reference the fixed factory, accountFactoryCid’. 
Any ideas about how to approach a Service without having to migrate on-ledger for the scenario above?
Thanks!
Jose
2 Likes
Hello @jvelasco.intellecteu ,
if the MyGreatService
instance contains a ContractId
reference field that mutates, you indeed need to update that instance to point to the new instance. Otherwise, it will point to an inactive instance, which may cause issues.
In general, if the ContractId
mutates frequently, it is advisable to use a contract key as a field on your MyGreatService
instance instead of a ContractId
reference. This way, your MyGreatService
instance will not require updating every time the ContractId
mutates since the key of the new contract instance remains the same.
However, in case the referred to instance changes rarely, you might consider updating the ContractId
of the MyGreatService
instance (maybe it could be done in the same action the referred to instance changes). An alternative approach would be to remove the ContractId
field of MyGreateService
, and simply pass it in as argument to the choices it is part of + adding some appropriate checks (e.g. that signatories matches).
The use of interfaces has its benefits since it allows you to avoid updating the codebase of your MyGreatService
in case the implementation of the instance it refers to/makes use of changes. But in order to also not having to update the MyGreatService
instance, you would either need to use a key reference or the alternative approach ^.
For the particular case of referring to an account factory Account.F
instance, we believe that such instances typically should be rather stable and rarely mutate (at least our implementation has no consuming choices, and its functionality is limited). Therefore, it might be reasonable to actually let the MyGreatService
refer to it by ContractId
. However, we recommend to try the alternative approach of removing the ContractId
field from MyGreatService
, and instead pass it in to the choices where it is needed (thereby also checking that the provider
is the right one).
I hope that helps.
Johan
3 Likes