The challenge here is that a choice body returns an Update, whereas query
returns a Script.
In it’s current form, you can not. This is because a ‘query’ depends on the state of the ledger, and in a multi-user environment this is not deterministic: we can’t control what order parties will submit transactions in. This means that it can’t be used in a distributed setup.
It’s possible to work around this by building the equivalent of an SQL index within a DAML contract, on-ledger, and then writing wrapper functions to CRUD records, that update this index. You can then use the index to lookup those contracts. I’ve seen this approach used in internal projects, but it depends on the developer being quite disciplined.
Thank you!
I think this is slightly misleading. Contract key lookups, contract fetches, … all depend on the ledger state. When we say that Daml is deterministic we mean that it’s deterministic in a given ledger state.
What makes query difficult is that it asserts a global property by giving you all contracts whereas a contract fetch or a successful lookup is local. Local properties are generally manageble in distributed systems while global properties are much more tricky Interestingly, this can be remarkably subtle, e.g., negative key lookups are a global property, you assert that the contract does not exist anywhere. That problem shows up in Canton’s contract key limitations.
Thank you, will check out the Canton reference.
From this remark I draw the conclusion that you could implement query
as an Update
equally justified as fetch
et al, you just decided not to do it.
Am I right?
Not quite, what I’m trying to say is that it wouldn’t break determinism.
You could implement it on a centralized ledger like Sandbox. However, even there it’s somewhat questionable from a performance pov: Doing a transaction query means that you do not just synchronize on the contracts that are returned by the query but also on the fact that not other contracts exist. This is very likely to lead to contention issues in practice.
In a fully distributed ledger like multi-domain canton on the other hand, you can’t even implement this type of stuff for the same reason why contract key uniueness cannot be guaranteed in that seetting so then you’re completely out of luck.
Yes, now I understand your point.