Example Syntax of QueryContractKey

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)

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

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

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?

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.

1 Like

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.

1 Like