Given this simple but wonderful Service:
import Daml.Finance.Interface.Account.Factory qualified as Account (F)
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?
Hello @jvelasco.intellecteu ,
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.