`Update` in `ensure` clause

I have an ensure clause as follows -
ensure validateAllocatedCash allocatedCashCid this
Where -

validateAllocatedCash: ContractId C.Cash -> TradeProposalDVP -> Update Bool
validateAllocatedCash cashCid tradeDetails = do
cash <- fetch cashCid
pure (cash.owner == tradeDetails.buyer
&& cash.amount >= tradeDetails.tradePrice * intToDecimal tradeDetails.quantity
&& cash.currency == tradeDetails.currency)

Obviously this doesn’t work because ensure expects a Bool whereas validateAllocatedCash returns Update Bool . Is there a way I could have transactions in validateAllocatedCash instead of just pure expressions? Basically I’m looking for an equivalent of ensureA

3 Likes

The ensure clause is supposed to to hold during the entire lifetime of a contract. Currently this is enforced by checking it at contract creation and because it can only depend on the template data instead of an arbitrary Update expression this is guaranteed to never be invalidated if it holds at contract creation.

Now consider an ensureA that allows for an Update expression like the fetch in your example. This could hold at contract creation but if the contract gets archived later it will not hold anymore. For this reason we currently do not have such a construct.

If you do only want to check a condition at the time of contract creation, you might be able to create that contract from a choice and enforce the condition in that choice. One example of this are role contracts with multiple signatories and a nonconsuming choice for creating a contract. You can find more information on that pattern at https://docs.daml.com/daml/intro/6_Parties.html#use-role-contracts-for-ongoing-authorization.

2 Likes