This tutorial walks you through creating a v2 version of a Daml package. You’ll start with a simple template, add an optional field and a new choice, then verify that the upgrade compiles and that existing contracts work with the new code.Documentation Index
Fetch the complete documentation index at: https://docs.canton.network/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
- A working
dpminstallation with the Daml SDK - Familiarity with Daml templates and choices (Module 3)
- A text editor or Daml Studio
Step 1: Create the v1 Package
Start by scaffolding a new project. Thedpm new command creates the directory structure and a daml.yaml file:
daml/v1/daml.yaml:
daml/v1/daml/Main.daml:
The SDK also provides a built-in upgrades example template you can generate with
dpm new upgrade-demo --template upgrades-example. See the example source for details.Step 2: Create the v2 Package
Copy the package —cp -r v1 v2 — and bump the version. The package name must stay the same — this is how Daml knows it’s an upgrade:
upgrades field points to the v1 DAR. This is what tells dpm build to validate that v2 is a compatible upgrade of v1.
Now make backward-compatible changes. Add an Optional field to the record and a new choice to the template:
expiryDateis anOptionalfield with implicitNonedefault for v1 contractsRenewis a new choice (doesn’t exist in v1, so no backward-compatibility issue)
Step 3: Verify Compatibility
Build the v2 package:upgrades field in daml.yaml triggers this check — without it, dpm build compiles v2 in isolation and performs no cross-version validation. The compiler checks all the SCU rules: no removed fields, no type changes, new fields are Optional, etc.
If you’ve introduced a breaking change, the compiler will report an error telling you what rule was violated.
Step 4: Test Approximated Cross-Version Behavior
To verify the upgrade path, add a test script to the v2 package. First, add thedaml-script dependency to daml/v2/daml.yaml:
expiryDate = None) and exercises the new v2 Renew choice:
This test runs within a single package version, so it approximates rather than fully reproduces cross-version behavior. On a real ledger with both v1 and v2 DARs uploaded, the runtime handles the version resolution between actual v1 contracts and v2 code. See Testing Upgrades for strategies to test real cross-version scenarios.
Step 5: Deploy Both Versions
In a real deployment, you may have both DAR files uploaded to your validator. The order matters: upload v1 first (if not already uploaded), then v2. For new validators, they only need to upload v2 provided that it is SCU compatible with v1.What Happens Under the Hood
When a validator receives a v2 DAR:- If automatic vetting is enabled, the validator node vets the new package alongside v1. Otherwise, vetting must be manually done.
- Both packages remain active — v1 contracts aren’t affected
- When v2 code fetches a v1 contract, the runtime fills
Optionalfields withNone - When v1 code fetches a v2 contract where
Optionalfields areNone, the fetch succeeds (the fields are simply ignored) - When v1 code fetches a v2 contract where an
Optionalfield has a non-Nonevalue, the fetch fails to prevent data loss
Next Steps
- Upgrade Compatibility — Full reference of allowed and disallowed changes
- Testing Upgrades — Comprehensive upgrade testing strategies
- Deploying Upgrades — Rolling out upgrades across environments