Hi @krmmalik,
First off, I really encourage you to use Script
instead of Scenario
. It may feel a little bit more restrictive (because it is!), but it is much closer in its API to the way external applications would interact with your Daml application.
With that out of the way, here is a slightly modified version of the default daml new
template:
module Main where
import Daml.Script
type AssetId = ContractId Asset
template Asset
with
issuer : Party
owner : Party
name : Text
where
ensure name /= ""
signatory issuer
controller owner can
Give : AssetId
with
newOwner : Party
do
create this with
owner = newOwner
setup : Script ()
setup = script do
alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")
aliceTV <- submit alice do
createCmd Asset with
issuer = alice
owner = alice
name = "TV"
bobsTV <- submit alice do
exerciseCmd aliceTV Give with newOwner = bob
bobs_assets <- query @Asset bob
alices_assets <- query @Asset alice
-- They can both see the asset, Alice because she is the signatory, Bob because he is the controller of a choice
assert $ bobs_assets == [(bobsTV, Asset with issuer = alice, owner = bob, name = "TV")]
assert $ alices_assets == [(bobsTV, Asset with issuer = alice, owner = bob, name = "TV")]
return ()
By default, a script
will fail if you try to do an operation on the ledger that fails with submit
(or if an operation succeeds with submitMustFail
). This is often enough, but sometimes you want a more direct inspection of the state of the ledger. For these cases, you can use the query
family of functions (docs here).
The syntax is slightly unusual, as you have to explicitly provide the type of template your are querying for. That is, query @A p
will fetch all the contracts on the ledger that are visible to party p
and are of the template type A
.
The return type is a list of pairs, where the first item is a contract ID and the second item is a contract payload. You do not need to make a separate data
declaration to represent contract payloads; one is automatically derived for you by the compiler from the corresponding template
declaration. This is why, in the snippet above, I can directly construct an Asset
payload in the arguments to assert
.
The data
declarations automatically derived from template
declarations always derive Show
and Eq
instances, meaning they can be compared for equality (and, in scripts and scenarios, printed with debug
).
So the short answer is, in the general case, you do not need to create data
declarations just to test the contents of the ledger.