Skip to content
Discussions/App Development/Example Syntax of QueryContractKeyForum ↗

Example Syntax of QueryContractKey

App Development6 posts389 views2 likesLast activity Apr 2022
RI
rikotacardsOP
Apr 2022

I’m trying to grab a contract inside a trigger, I want to use queryContractKey

From the docs,
queryContractKey

: (Template a, HasKey a k, Eq k, ActionTriggerAny m, Functor m) => k → m (Optional (ContractId a, a))

Find the contract with the given key in the ACS, if present.

How do I interpret the signature, and write the correct code, below is a line from the DA market place
Some (listingServiceCid, _) <- queryContractKey @Listing.Service exchange (operator, exchange, exchange)

So is that interpreted as resultIGet <- queryContractKey @templateName something (keyval1, keyval2, keyval3)

github.com

digital-asset/da-marketplace/blob/b6bdab2084424efd3396481cde13fb3f286fcd69/daml/Tests/Clearing/Setup.daml#L89

      
        
  1. (Some expiry) <- submit issuer.customer $ exerciseCmd q122Cid AssetDescription.Expiry with party = issuer.customer
  2. (underlying::_) <- submit issuer.customer $ exerciseCmd q122Cid AssetDescription.Underlying with party = issuer.customer
  3. (mult::_) <- submit issuer.customer $ exerciseCmd q122Cid AssetDescription.Multipliers with party = issuer.customer
  4. expiry === (date 2022 Jan 1)
  5. underlying === h2oId
  6. mult === 1.0
  7. -- List a Security to trade
  8. Some (listingServiceCid, _) <- queryContractKey @Listing.Service exchange (operator, exchange, exchange)
  9. let mkMarket : Id -> Id -> Script Text
  10. mkMarket quoteId tradedId = do
  11. let
  12. symbol = quoteId.label <> tradedId.label
  13. listingType = Listing.ClearedRequest clearinghouse
  14. calendarId = "1261007448"
  15. description = quoteId.label <> " vs " <> tradedId.label
  16. tradedAssetId = tradedId
  17. quotedAssetId = quoteId

What exactly goes after @templateName, where “something” is, its not clear to me from the signature in the docs.

CO
cocreature
Apr 2022

You’re mixing up Daml Script and Daml triggers. The signature you provided is the one for triggers while the example code you’re linking to is Daml Script.

In Daml triggers, queryContractKey only takes one argument, the contract key. You also often have to specify the template type via @templatetype because multiple templates can have the same key so it cannot always be inferred. So in the end, you end up with

queryContractKey @template key

In Daml script, you also have to specify the parties you are querying at (in triggers that’s always fixed to the party your trigger is running as) so you end up with:

queryContractKey @template party key
RI
rikotacards
Apr 2022

Thanks! Yeah I figured I was getting mixed up.

So regarding the trigger docs,

queryContractKey

: (Template a, HasKey a k, Eq k, ActionTriggerAny m, Functor m) => k → m (Optional (ContractId a, a))

Find the contract with the given key in the ACS, if present.

The below signature here,

: (Template a, HasKey a k, Eq k, ActionTriggerAny m, Functor m) => k → m (Optional (ContractId a, a))

Should translate to the code below here, right?
queryContractKey @template key

I feel like I am missing something from signature → actual code.

Or take the queryContractKey from Daml scripts,
queryContractKey

: (HasCallStack, TemplateKey t k, IsParties p) => p → k → Script (Optional (ContractId t, t))

How does the above instruct me to type the below?

queryContractKey @template party key

Where is HasCallStack, TemplateKey t k, isParties?

CO
cocreature
Apr 2022

The part before => is a typeclass constraint. Those are not arguments you pass, it only constraints possible choices for the type variables, in this case for example HasKey a k requires that k is the contract key of a. The actual arguments come afterwards which for triggers is only the key k. So you know that you need to call queryContractKey key. In some cases that is already sufficient if the template type can be inferred by the compiler. However, because different templates can have the same key types this is not always possible so in those cases you want to specify the value of the type variable explicitly. That’s done by prefixing it with an @ so queryContractKey @template key.

GA
Gary_Verhaegen
Apr 2022

I’d recommend always using the @template annotation for queryContractKey, so your code doesn’t suddenly break if you add another template with the same key type.

CO
cocreature
Apr 2022
Gary_Verhaegen:

I’d recommend always using the @template annotation for queryContractKey , so your code doesn’t suddenly break if you add another template with the same key type.

That will never happen. Type inference doesn’t take into account whether there is only a single typeclass instance or multiple. Either it’s ambiguous because you’re not using the return type in a way that enforces a specific contract type regardless of whether there is only a sinlge template type with that key or you are forcing a specific type so adding another template won’t change that.

← Back to Discussions