Skip to main content

Compare transactions

dpm trace compare shows why two things differ, whether they are two committed updates, a prepared command and an update, or a prepared command and a failed completion. Each comparison below uses the update IDs and files from the commands in this block, so run them first:

# a GOLD asset with quantity 100
dpm trace submit --submitter "$LEDGER" --act-as "$ISSUER" \
--template '#asset-tests:Asset:Asset' \
--arg issuer="$ISSUER" --arg owner="$ALICE" --arg name=GOLD --arg quantity=100

# a SILVER asset with quantity 50
dpm trace submit --submitter "$LEDGER" --act-as "$ISSUER" \
--template '#asset-tests:Asset:Asset' \
--arg issuer="$ISSUER" --arg owner="$ALICE" --arg name=SILVER --arg quantity=50

# the GOLD command, prepared and not committed
dpm trace prepare --submitter "$LEDGER" --act-as "$ISSUER" \
--template '#asset-tests:Asset:Asset' \
--arg issuer="$ISSUER" --arg owner="$ALICE" --arg name=GOLD --arg quantity=100 \
--export create.prepared.json

# the GOLD command with quantity 0, which fails and is saved as a completion file
dpm trace submit --submitter "$LEDGER" --act-as "$ISSUER" \
--template '#asset-tests:Asset:Asset' \
--arg issuer="$ISSUER" --arg owner="$ALICE" --arg name=GOLD --arg quantity=0 \
--export failed-create.completion.json

To see how two committed updates differ, pass their update IDs, the baseline first and the candidate second. Replace <gold-update-id> and <silver-update-id> with the update IDs printed by the first two commands above.

dpm trace compare <gold-update-id> <silver-update-id> \
--submitter "$LEDGER" --read-as "$ISSUER"

Output:

✗ 1 difference (1 value) kind: update-vs-update

A update 12200833d... @ offset 25 (baseline)
B update 122007af7... @ offset 28 (candidate)

Events
~ create Asset:Asset name: GOLD → SILVER, quantity: 100 → 50

Context read-as Issuer::1220e92d...89b47e sync 2026-10-19T10:07:31.035562Z

To check that the ledger committed what you prepared, compare the prepared file with the GOLD update. Use the same <gold-update-id> as above.

dpm trace compare \
--prepared create.prepared.json \
--update <gold-update-id> \
--submitter "$LEDGER" --read-as "$ISSUER"

Output:

✓ no differences kind: prepared-vs-update

A command dpm-trace-prepare... (prepared)
B update 12200833d... @ offset 25 (committed)

Events
= create Asset:Asset (4 fields match)

Context act-as Issuer::1220e92d...89b47e read-as Issuer::1220e92d...89b47e sync 2026-10-19T10:07:31.035562Z

The prepared command and the committed update match: both create the same Asset, and all four fields are equal.

To see what happened to a command that failed, compare the prepared file with the saved completion. A failed submission has no events, so the comparison tells you that it failed and why, not which event failed.

dpm trace compare \
--prepared create.prepared.json \
--completion-file failed-create.completion.json

Output:

✗ completion failed — DAML_FAILURE kind: prepared-vs-completion

A command dpm-trace-prepare... (prepared)
B completion dpm-trace-submit-... offset - DAML_FAILURE

'Interpretation error: Error: User failure: UNHANDLED_EXCEPTION/DA.Exception.PreconditionFailed:PreconditionFailed (error category 9): Template precondition violated: Asset {issuer = \'Issuer::1220e92d30a9b48e588f55405a4ab8e51a58a08d2ebd7864b58afb6082d5b489b47e\', owner = \'Alice::1220e92d30a9b48e588f55405a4ab8e51a58a08d2ebd7864b58afb6082d5b489b47e\', name = "GOLD", quantity = 0}'

Context submission 30f6ad7e-b9a0-4b6...