Incomplete Contract Payload

Is having an incomplete Contract Payload valid in DAML? Not sure if I am using the right terminology here, but basically, I have a proposal contract template. An agent issues a proposal (marked as issuer) and investors invest in the proposal. So I have investors setup as a party. (as below)

template Proposal with
    issuer: Party
    investor: Party
    projectdescription: Text
    unitsrequired: Int
  

Now my test script with this works absolutely fine in which I supply a party for the investor however, in reality when running the app, the proposal will be first offered by an issuer and then afterwards investors will agree to invest in the proposal and there will be multiple investors up to a specified total amount.

So my question is, can I leave it this way, or do I need to go down the proposal-accept pattern route where investors agree to invest?

2 Likes

You are using the right terminology, and no, it is not valid.

The meaning of the declaration above is that all four fields are available in values of type Proposal; that is, if x: Proposal, then x.investor: Party, without exception, every time. Retrieving a contract of template Proposal yields a value of record type Proposal, which has all four of these fields. All four fields are in scope for every choice’s definition, as well as metadata like signatory, observer, key.

Daml itself will simply not let you create a Proposal without all fields, even at the record level, never mind actually creating the contract.

 let proposal = Proposal with
                   issuer = alice
                   projectdescription = "foo"
                   unitsrequired = 42

Main.daml:59:18: error:
    • Constructor ‘Proposal’ does not have the required strict field(s): investor
    • In the expression:
        Proposal
          {issuer = alice, projectdescription = "foo", unitsrequired = 42}

If you write investor: Optional Party in your declaration, then you may pass investor = None when creating a Proposal. However, this will make your contracts more error-prone: it will be possible to accept proposals that have already been accepted (forgetting who has accepted them previously), and also to act as if a proposal that has not already been accepted, has been.

Optional is best used if a value is semantically optional, which does not describe your use case: a proposal does not have an investor, and an accepted proposal does, and these are different semantic entities. You will have a much better time if you follow the propose-accept pattern than if you try to fit an Optional square peg into an acceptance round hole. Much heartbreak awaits you if you try to force Optional into your use case.

3 Likes

OK thank you @Stephen . This confirms some of what I was thinking and more. Thanks again.

I shall try to go down the proposal-accept pattern route.

1 Like

Quote of the year

1 Like