Variable not in scope: submitMulti

So I have a next set of questions which is not around requiring further explanations on the previous as such but next on my journey forward. Admin might want to break this out into a new thread however, but it does require some repetition so i’ll repost some code to carry along the background context.

I have setup a proposal contract so a party can issue proposals and for that I need all members of the Guild to be a signatory on the issuing of the proposal.

Now rather than doing that in a drawn out explicit way, I was reading Use Case 2 in this blog post and wondering if I can use that same learning?

I know that I have set up Guild as a contract template here, but is there a way I could group the creator and members together so that I can have one entity as a signatory on my proposal contract?

I tried to follow the blog post example but while i understand it somewhat conceptually I got stuck trying to implement it in practice.

Here’s my code for the Proposal contract:

template Proposal with
    issuer: Party
    investor: Party
    projectdescription: Text
    unitsrequired: Int
    marketingcost: Int
    distributioncost: Int
    additionalcost: Int
    proposalId: Text -- Key
    item: Item

  where
    signatory issuer
    observer investor

This is where I wanted to add something like say

signatory issuer, guild

Where all the members of the Guild sign off on the proposal. Note that the issuer would have to be said member of the guild as well and there would be overlap between the issuer and members of the guild as the issuer is also a member of the guild as well anyway. Only a guild member can issue a proposal.

I know that right now I could do something like

guild: Guild

In the template

and then I could add something like

signatory issuer, guild.members

(not sure if my syntax is entirely correct here, but hopefully this demonstrates the point)

and then all the members of the guild would have to sign-off on this proposal. I don’t know if I would have to run an extra check before hand to see if that person is a member of said guild and if the guild needs to be specified beforehand but this is the general pattern I was going to follow logically speaking.

Would this be the right way to go about it? Or perhaps there is a more concise/elegant way of doing it?

This way sounds right to me, you’d just need to use the Propose and Accept pattern to make sure everyone signs the contract. If you want to make sure the issuer is a member of guild.members then you can add an ensure clause like:

ensure issuer `elem` guild.members -- can also write this as the following but it's less common: ensure elem issuer guild.members

Here the function elem is specified inline between the arguments issuer and guild.members and it returns a Bool, evaluating to True if issuer is an element of the guild.members list. Then ensure only succeeds if the boolean it receives is True if this check failed then the contract wouldn’t be allowed to be created.

Now because you’re using ensure to make sure the issuer is an element of the guild.members then you technically don’t need to specify the issuer twice so your signatory line can simply be:

signatory guild.members

One gotcha here is that any guild.member can attempt to make any member an issuer unless the issuer is careful to check that new obligations aren’t being made for them that they didn’t consent to so this will need to be handled in client-side code to check.

Here’s my full code for reference:

template Guild
  with
    members: [Party]
    owner: Party
  where
    signatory owner

template Proposal with
    issuer: Party
    investor: Party
    guild: Guild
    projectdescription: Text
    unitsrequired: Int
    marketingcost: Int
    distributioncost: Int
    additionalcost: Int
    proposalId: Text -- Key
    item: Item

  where
    signatory guild.members
    ensure issuer `elem` guild.members
    observer investor
1 Like

Thanks! I’ll try implementing this next week and report back.

1 Like

Hi @krmmalik,

This is veering a bit away from my expertise. While I know how the Daml language works “in the small”, I have not personally written any large Daml application and am thus not best placed to recommend “big” design decisions. I’ll comment as best I can, but I won’t be able to provide definite answers.

I think it’s important to clarify exactly what you want to express here. The delegation pattern in this blog post illustrates a way to give special authority to each member of a group. This is is not the same as saying every single member of the group has agreed to the decision.

In the specific example of the blog post, Alice is given authority to add people to the legal team, and then she can just go and do it. Note that:

  • She does not need to be a member of the legal team herself.
  • Other admins do not need to vet what she’s doing; there is no record of them ever agreeing to anything she does.
  • Members of the legal team do not know about each other.
  • Other team admins may not know about Alice being an admin until they observe her first admin action.
  • Other admins are not involved in nominating a new admin; this is a unilateral decision on the part of org.

Some of these can be easily changed (e.g. adding group as an observer on the GroupMember template would mean group members know about each other), but the fundamental process here is one of delegation: an authority figure (here the org party) gives a limited set of administrative powers individually to each person in a group. The group is there to facilitate the management of those administrative rights; individual members do not “act as a group”, so to speak.

The actions of Alice can only reasonably engage the responsibility of Alice herself and of org; other admins have no say in the matter.

Another point to note is that, because the blog post defines group membership as the existence of a (manager, group, member) contract on the ledger, with only manager and member as stakeholders, groups do not exist on the ledger as a separate thing and group members do not (necessarily) know about each other. This is fine for permission groups, but from what I understand of your use-case I’m not sure it’s a good fit. You probably want to be able to talk about properties of the guild as a separate thing itself.

If you wanted to say that every member of a guild can make proposals to investors on behalf of the entire guild without needing the explicit approval of other guild members, then you could use the pattern from the blog post. You would likely still need a propose/accept pattern between “the guild” and the investors, though.

2 Likes

I think it’s worth noting that there are really two “stages” of propose/accept in this process:

  1. A guild member wants to make a proposal to an investor and needs to collect the signature of other guild members.
  2. “The guild”, or a subset thereof, makes a proposal (signed by all, or “enough”, guild members) to an investor.

@anthony’s Proposal template is already the second stage of that process. The names are getting in the way a little bit here, but you’d likely want to have a ProposalProposal template made by a single member to the rest of the guild first (and that would get rid of the issuer problem mentioned by @anthony). You could work around the awkward names by using more creative (but longer) names for your templates, such as GuildMemberWantsToMakeProposal and ProposalFromGuildToInvestors. Or, well, you can probably come up with something better. The point is, because you have two levels of propose/accept, you’ll likely need at least 3 templates:

  1. The initial template created by a single guild member to collect all the signatures (we’ve discussed that one in the past).
  2. The template that represents a “signed by the guild” proposal ready to be shown to an investor, with the investor(s) as observers, used to collect investor signatures.
  3. A final template that represents the agreed upon contract, where all the guild members and all the participating investors are signatories.
2 Likes

Thanks for the great write-ups as always @Gary_Verhaegen . Experience “in the small” is very valuable to me here, although on a sidenote, it would be nice to pick the brain of someone that has worked on a large application for maybe a podcast interview or something. That would be super interesting.

Anyway, I appreciate you breaking down the differences between what I am intending and what the blog post is describing. I didn’t realise DAML allows you to be so granular about the way things are agreed and what authority is required in light of that.

I’m going to attempt the proposal-accept pattern the way you suggested over the next few days. To be honest, I did have a feeling it would have to be done in some way similar to this and it will now give me a chance to practise the proposal-accept pattern a little further.

Thanks again.

1 Like

A post was split to a new topic: Indentation error in record creation