I want to write code for migrating contracts from one package to another.
As a starting point, I want to write a function which transfers a contract payload in one package, to an identical contract payload in the other package.
If the contract payload only contains primitive data types, this is simple, using double dot syntax.
If I have the following template in both the old and the new package:
template Asset
with
issuer : Party
owner : Party
name : Text
etc.
I create an upgrade package using the old and the new package as data dependency, and label the packages like this:
data-dependencies:
- ../asset-1/.daml/dist/asset1-0.0.1.dar
- ../asset-2/.daml/dist/asset2-0.0.1.dar
module-prefixes:
asset1-0.0.1: Asset1
asset2-0.0.1: Asset2
Given this, I can use double dot syntax for the migration function:
module Main where
import qualified Asset1.Main as Main1
import qualified Asset2.Main as Main2
migrate: Main1.Asset -> Main2.Asset
migrate Main1.Asset{..} = Main2.Asset{..}
But as soon as I have custom data types in the Asset contract, the double dot syntax doesn’t work.
data AssetCode = AssetCode with
name: Text
version: Int
deriving (Eq, Show)
template Asset
with
issuer : Party
owner : Party
assetCode : AssetCode
etc.
With the template above, the double dot syntax will result in an error, and I can do e.g. the following:
module Main where
import qualified Asset1.Main as Main1
import qualified Asset2.Main as Main2
transform: Main1.AssetCode -> Main2.AssetCode
transform Main1.AssetCode{..} = Main2.AssetCode{..}
-- This doesn't work
-- migrate: Main1.Asset -> Main2.Asset
-- migrate Main1.Asset{..} = Main2.Asset{..}
-- This works
migrate: Main1.Asset -> Main2.Asset
migrate Main1.Asset{..} = Main2.Asset with
assetCode = transform assetCode
..
For a complex template, which has even more custom data in several levels, this requires a lot of boilerplate code.
Is there a trick to avoid this possibly huge amount of boilerplate code?