Scenario results not appearing
Mod note: As of SDK 1.5.0 Scenarios have been superseded by the more powerful Daml Script. We now recommend using that for all purposes. For more information, and to learn how to use Script please check out @Andreas’ post on our blog.
I have multiple contracts that I have setup, one of them is Agent.daml for which the scenario results appear just fine, however, my Investor contract for which an agent is the signatory is not displaying scenario results, so i’m assuming, I have either setup the contract incorrectly or my scenario code is incorrect?
Here’s a screenshot
Hey @krmmalik can you copy and paste your code as text? It’ll help with addressing your issue and providing examples of how to do this. Also please include the code for the Agent and Guarantor templates.
You can have it nicely formatted by putting a line of 3 back-ticks (```) above and below the code such that:
```
template Investor with
-- The rest of the code
```
Becomes:
template Investor with
-- The rest of the code
The problem is the fragment with ...; agent.agentname = alice; .... You can see that the = is underlined in red. Same problem for guarantor. You can’t just set agent.agentname in isolation there, but need to set the agent field to a value of type Agent. You haven’t shared your Agent type, but it’ll look something like this:
submit hakan do
create Investor with
investorname = hakan
agent = Agent with
agentname = alice
...
guarantor = Guarantor with
guarantorname = [fadhim, jahan]
...
It appears that the scenario does not appear because your code does not compile.
Notice the squiggly line under the = sign in agent.agentname = alice.
What does the compiler tell you there?
Hey @krmmalik can you copy and paste your code as text? It’ll help with addressing your issue and providing examples of how to do this. Also please include the code for the Agent and Guarantor templates.
You can have it nicely formatted by putting a line of 3 back-ticks (```) above and below the code such that:
```
template Investor with
-- The rest of the code
```Becomes:
template Investor with -- The rest of the code
This advice will make it much easier for the forum contributors to help you. ![]()
Investor template
module Investor where
import Agent
import Proposal
import Guarantor
-- MAIN_TEMPLATE_BEGIN
template Investor with
agent: Agent
proposal: Proposal
guarantor: Guarantor
investorname: Party
where
signatory investorname
observer agent.agentname, guarantor.guarantorname
-- MAIN_TEMPLATE_END
key agent.agentname: Party
maintainer key
-- RUN_SCENARIO --
exampleinvestor =
scenario do
-- Creates each party
hakan <- getParty "Hakan"
alice <- getParty "Alice"
fadhim <- getParty "Fadhim"
jahan <- getParty "Jahan"
-- Creates an instance of the Investor contract, authorized by "Hakan"
submit hakan do
create Investor
--
with investorname = hakan; agent.agentname = alice; guarantor.guarantorname = [Fadhim, Jahan]
-- END_SCENARIO --
Agent.daml
module Agent where
-- MAIN_TEMPLATE_BEGIN
template Agent with
agentname: Party
guarantors: [Party]
where
signatory agentname
observer guarantors
-- MAIN_TEMPLATE_END
key agentname: Party
maintainer key
-- VOUCH_BEGIN
nonconsuming choice Choose: ContractId Agent with
selectPeopleThatVouch: Party
controller agentname
do
assertMsg "You cannot vouch for yourself" (selectPeopleThatVouch /= agentname)
assertMsg "You cannot follow the same user twice" (notElem selectPeopleThatVouch guarantors)
archive self
create this with guarantors = selectPeopleThatVouch :: guarantors
-- VOUCH_END
-- RUN_SCENARIO --
example =
scenario do
-- Creates each party
alice <- getParty "Alice"
fadhim <- getParty "Fadhim"
jahan <- getParty "Jahan"
-- Creates an instance of the Agent contract, authorized by "Alice"
submit alice do
create Agent
--
with agentname = alice; guarantors = [fadhim, jahan]
-- END_SCENARIO --
Guarantor.daml
module Guarantor where
-- MAIN_TEMPLATE_BEGIN
template Guarantor with
guarantorname: Party
where
signatory guarantorname
-- RUN_SCENARIO --
gexample =
scenario do
-- Creates each party
fadhim <- getParty "Fadhim"
-- Creates an instance of the Guarntor contract, authorized by "Fadhim"
submit fadhim do
create Guarantor
--
with guarantorname = fadhim
-- END_SCENARIO --
Thank you.
It tells me parser error
/Users/khurammalik/DevTree/Qirad Agent Network/app/daml/Investor.daml:38:52: error:
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let x = 5' instead of 'x = 5'
Oh I see what you mean. Ok, let me try this and report back
The problem is the fragment
with ...; agent.agentname = alice; .... You can see that the=is underlined in red. Same problem forguarantor. You can’t just setagent.agentnamein isolation there, but need to set theagentfield to a value of typeAgent. You haven’t shared yourAgenttype, but it’ll look something like this:submit hakan do create Investor with investorname = hakan agent = Agent with agentname = alice ... guarantor = Guarantor with guarantorname = [fadhim, jahan] ...
I’m still getting a parser error.
This is the code i put together
-- RUN_SCENARIO --
exampleinvestor =
scenario do
-- Creates each party
hakan <- getParty "Hakan"
alice <- getParty "Alice"
fadhim <- getParty "Fadhim"
jahan <- getParty "Jahan"
-- Creates an instance of the Investor contract, authorized by "Hakan"
submit hakan do
create Investor with
investorname = hakan
agent = Agent with
agentname = alice
guarantor = Guarantor with
guarantorname = [fadhim, jahan]
-- END_SCENARIO --
Changing the indentation in places fixes some errors but not all so I’m wondering if this is an indentation issue?
Indentation is very important in Daml, but it’s not just the indentation here. Your definition of Agent requires a list of Partys called guarantors which is missing in your snippet. The Investor also requires a Guarantor, which has a single Party field, not a list. So here’s a version with correct indentation (I’ve set all the code in a single file and removed the choices for simplicity):
module Main where
template Investor with
agent: Agent
guarantor: Guarantor
investorname: Party
where
signatory investorname
observer agent.agentname, guarantor.guarantorname
key agent.agentname: Party
maintainer key
template Agent with
agentname: Party
guarantors: [Party]
where
signatory agentname
observer guarantors
key agentname: Party
maintainer key
template Guarantor with
guarantorname: Party
where
signatory guarantorname
exampleinvestor =
scenario do
hakan <- getParty "Hakan"
alice <- getParty "Alice"
fadhim <- getParty "Fadhim"
jahan <- getParty "Jahan"
submit hakan do
create Investor with
investorname = hakan
guarantor = Guarantor with guarantorname = jahan
agent = Agent with agentname = alice; guarantors = [fadhim]
return ()
Now, the indentation is correct, and I have added a return () at the end to get the right type for the scenario, but you’ll see this s still failing. The remaining error is that the Investor template is declaring a non-signatory maintainer for its key. Key maintainers have to be signatories. The error message read:
Scenario execution failed on commit at Main:34:5:
0: create of Main:Investor at DA.Internal.Prelude:373:26
failed due to that some parties are maintainers but not signatories: 'Alice'
and a solution here would be to make the agent.agentname party the signatory (and also therefore submit as Alice):
module Main where
template Investor with
agent: Agent
guarantor: Guarantor
investorname: Party
where
signatory agent.agentname
observer agent.agentname, guarantor.guarantorname
key agent.agentname: Party
maintainer key
template Agent with
agentname: Party
guarantors: [Party]
where
signatory agentname
observer guarantors
key agentname: Party
maintainer key
template Guarantor with
guarantorname: Party
where
signatory guarantorname
exampleinvestor =
scenario do
hakan <- getParty "Hakan"
alice <- getParty "Alice"
fadhim <- getParty "Fadhim"
jahan <- getParty "Jahan"
submit alice do
create Investor with
investorname = hakan
guarantor = Guarantor with guarantorname = jahan
agent = Agent with agentname = alice; guarantors = [fadhim]
return ()
As a final note, I would point you to my previous explanation of the differences between contracts, contract IDs and contract payloads. It’s obviously a bit of a preliminary code snippet here, but it seems like at least some of your templates should really just be data declarations.
Thank you so much @Gary_Verhaegen . I will try this hopefully tomorrow and get back to you.
The thing about the data declarations was going to be my next question a little later down the line. For now, I set up individual templates just to get the hang of putting templates together in DAML but I did wonder if I needed to modularise things so much so I’m glad you’ve brought it up already. I’m doing a presentation on Qirad today so won’t get a chance to work on this code today but will definitely come back and take a look at the snippet as well as the explanations you have linked. That will be very handy.
Thank you once again.
OK, I see my original mistake now as you say, the fact that I was supplying a list when it requires a single argument and also using a key other than a signatory, so now i have fixed those (although I changed the signatory to investorname because in reality only the investor should be able to issue that contract).
The scenario still isn’t running I am afraid(?)
submit hakan do
create Investor with
investorname = hakan
agent = Agent with
agentname = alice; guarantors = [fadhim]
guarantor = Guarantor with
guarantorname = jahan
return()
Still getting a parser error. It is a copy of your code in the sense that i typed it out line by line (to make sure I am able to understand the code being produced) apart from the fact that i used the investorname as signatory and therefore left Hakan to submit the contract.
I slightly changed the indentation to put guarantor and guarantorname on the same indentation level as agent (because they are parameters to the Investor template). Also notice that return is slightly mis-indented (not sure whether that’s just an error copying the code).
submit hakan do
create Investor with
investorname = hakan
agent = Agent with
agentname = alice; guarantors = [fadhim]
guarantor = Guarantor with
guarantorname = jahan
return()
If I apply this to the code I copied from above I now see an authorization error (that you can explore more thoroughly by clicking on Scenario results and having a look at the error).
Does this help you?
I’m afraid that gave me a whole whirlwind of errors
/Users/khurammalik/DevTree/Qirad Agent Network/app/daml/Investor.daml:35:14: error:
• Constructor ‘Investor’ does not have the required strict field(s): proposal
• In the first argument of ‘create’, namely
‘Investor
{investorname = hakan,
agent = Agent {agentname = alice, guarantors = [fadhim]},
guarantor = Guarantor {guarantorname = jahan}}’
In a stmt of a 'do' block:
create
Investor
{investorname = hakan,
agent = Agent {agentname = alice, guarantors = [fadhim]},
guarantor = Guarantor {guarantorname = jahan}}
In the second argument of ‘submit’, namely
‘do create
Investor
{investorname = hakan,
agent = Agent {agentname = alice, guarantors = [...]},
guarantor = Guarantor {guarantorname = jahan}}
return ()’
Can you double check? It works for me (modulo the authorization error).
Here is the full code for your convenience.
module Main where
template Investor with
agent: Agent
guarantor: Guarantor
investorname: Party
where
signatory agent.agentname
observer agent.agentname, guarantor.guarantorname
key agent.agentname: Party
maintainer key
template Agent with
agentname: Party
guarantors: [Party]
where
signatory agentname
observer guarantors
key agentname: Party
maintainer key
template Guarantor with
guarantorname: Party
where
signatory guarantorname
exampleinvestor =
scenario do
hakan <- getParty "Hakan"
alice <- getParty "Alice"
fadhim <- getParty "Fadhim"
jahan <- getParty "Jahan"
submit hakan do
create Investor with
investorname = hakan
agent = Agent with
agentname = alice; guarantors = [fadhim]
guarantor = Guarantor with
guarantorname = jahan
return()
Hi @krmmalik,
The Proposal template was not part of the code you shared, so in my code snippet I simply removed the proposal field from Investor. Apologies for forgetting to mention that.
In order for your code to work without removing that field, you will have to add a Proposal payload to the create Investor call. Without seeing the Proposal template I cannot give you much more guidance here.
ok, I have it working!
Thank you everyone in this thread especially @Gary_Verhaegen, I really appreciate your patience and the time you’ve spent in helping me walk through this. This trial and error has been much more valuable to me than the documentation alone – even the interactive tutorials and examples.
OK, so now for my next question since it was touched upon in this thread already.
In reality, the actual part of the contract in Qirad is really only the Proposal. The rest are in fact just entities/parties. There is a contract between the agents and the guarantors (that is actually supposed to be a group of agents that vouch for each other so their job as agents and guarantors are interchangeable), so my question is now regards the data declaration part you pointed out and the fact that I could do this all in one file, or at least most of it.
The way I see it, I have an agent contract and then a proposal contract and the rest are just data declarations. Would this be the right way to look at it?
And potentially I should still put both templates into one file as well anyway?
I am coming from a non-coding background so the data declarations explanation was a little hard for me to grasp so I’m going to try to revisit it and re-understand but conceptually I think I understand what you’re saying.
Hi @krmmalik,
Struggling through building your own application is always going to be much more enlightening than reading documentation or following in predetermined footsteps. That said, if you do have any suggestion for improving either the documentation or the tutorials, we’re always happy to receive those.
Regarding data modelling, there are a few key concepts at play.
A data declaration is the primary way to define a composite data structure in Daml. That is, any time you think two (or more) pieces of information should be consider “together”, the go-to solution for that is data. You want to store information about a person?
data Person = Person with age: Int, name: Text
A template is a representation of a contract. When you define a template, Daml will automatically create for you an equivalent data declaration, which I will refer to in the following as a contract payload. The template defines what kind of contracts you can store on the ledger; contracts are always on the ledger and never in your code. However, you can read data from the ledger and store a copy in your code in the form of a contract payload.
The issue is that the existence of a piece of data in your code that happens to have the right shape to be the payload of a contract in no way indicates the existence of a contract with corresponding data on the ledger.
There is also, in the general case, no guarantee that, for a given contract that exists on the ledger, there is no other contract with the exact same payload. (Contract keys are an exception to that.) If you want to refer to a specific contract (on the ledger) from your code, you need to use a reference to that contract, which we call a contract ID. There is no way, in Daml code, to create a contract ID from nothing, so when you have a contract ID there is a good chance there was, at some point, a contract with that ID on the ledger. You can, from your Daml code, verify the existence of that contract and get the corresponding payload (fetch).
The issue I was pointing out in your code is that you seem to be using template declarations to define, say, Agent, but then you only use the Agent data type, with no relation to the ledger.
Specifically, in:
template Agent with
agentname: Party
where
signatory agentname
template Investor with
agent: Agent
investorname: Party
where
signatory investorname
the field agent in Investor is of the data type that corresponds to the payload that a contract of type Agent could have, but does not necessarily correspond to any Agent contract on the ledger, so you may believe you have a lot more consistency guarantees than you actually do.
Is this any clearer? I guess the main point of confusion I can see here is that there are multiple “namespaces” at play, i.e. the data type Agent is only tangentially related to the template type Agent. This ambiguity is very useful in practice once you understand how all the pieces fit together, but I can see how it could be an obstacle to getting to that understanding in the first place.
Thank you for this very detailed explanation @Gary_Verhaegen . I really appreciate this.
It’s improved my understand for sure, but I think I’ll get to more grips with it in practice. It has definitely made me reconsider the design of my data model and made me more aware of other considerations I need to have that I didn’t realise before.
I’ll open up a separate thread regards my feedback on documentation etc and I must stress this is purely constructive feedback and not intended as a criticism.

