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.