Multiparty Looping choices

I have a snippet like this
type data = ContractId example
template example
with
data: Text
owner: Party
where
signatory owner
controller owner can
Add : data
with
data_new : Text
do
create this with
data =data_new
Transfer : data
with
new_owner : Party
do
create this with
owner = new_owner

when i run the above script for party say a,b,c with initial party being a and then the transfer is made to new party say b so now b can have the rights to add or transfer (that is looping ) but the thing is i am not able to do the transfer functionality that it is throwing an error like **requires authorizers A,B, but only A were given .**no

Note: It is not that initiate and accept just transferring the assets from one party to another and so on it has to work

Any pointer on this ?

1 Like

Hi @Sridinesh_R,

For this kind of question, it’s easier to help if you provide working code, ideally with a failing test. I’ll be assuming that your question was:

module Main where

import Daml.Script

type Data = ContractId Example

template Example
  with
    payload: Text
    owner: Party
  where
    signatory owner
    controller owner can
      Add : Data
        with
          data_new: Text
        do
          create this with payload = data_new
      Transfer: Data
        with
          new_owner: Party
        do
          create this with owner = new_owner

test = script do
  alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
  bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")

  c1 <- submit alice do
    createCmd Example with payload = "blah", owner = alice
  c2 <- submit alice do
    exerciseCmd c1 Transfer with new_owner = alice
  
  -- Why does this fail? (1)
  submitMustFail alice do
    exerciseCmd c2 Transfer with new_owner = bob

  -- Why does this fail? (2)
  submitMustFail bob do
    exerciseCmd c2 Transfer with new_owner = bob

Assuming that was your question, here’s an answer. (If that is not accurately capturing your question, please clarify.)

  1. This case fails to create the new contract, because in order to create a contract where Bob is a signatory, Bob needs to sign it! Alice simply cannot sign for Bob.
  2. This fails to even find the contract, because c2 is, as defined, only visible to Alice.

So, if we want to execute the transfer, we need the choice to have the ability to sign on behalf of Bob for the creation of the new contract, and on behalf of Alice for the (implicit) deletion of the existing contract. It also needs to be visible to both Alice and Bob. Here is one way to achieve that:

module Main where

import Daml.Script

template Example
  with
    payload: Text
    owner: Party
  where
    signatory owner
    preconsuming choice Transfer: ContractId TransferOffer
        with
          new_owner: Party
        controller owner
        do
          create TransferOffer with payload = payload, owner = owner, new_owner = new_owner

template TransferOffer
  with
    payload: Text
    owner: Party
    new_owner: Party
  where
    signatory owner
    observer new_owner
    preconsuming choice Accept: ContractId Example
      controller new_owner
      do
        create Example with owner = new_owner, payload = payload
    preconsuming choice Retract: ContractId Example
      controller owner
      do
        create Example with owner, payload


test = script do
  alice <- allocatePartyWithHint "Alice" (PartyIdHint "Alice")
  bob <- allocatePartyWithHint "Bob" (PartyIdHint "Bob")

  c1 <- submit alice do
    createCmd Example with payload = "blah", owner = alice
  c2 <- submit alice do
    -- Alice can do this because Bob is not a signatory on
    -- the TransferOffer.
    exerciseCmd c1 Transfer with new_owner = bob
  
  c3 <- submit alice do
    exerciseCmd c2 Retract

  c4 <- submit alice do
    exerciseCmd c3 Transfer with new_owner = bob
  
  submit bob do
    -- Bob can do this because:
    -- - As an observer, he can see the contract.
    -- - The contract gives him control of that choice.
    -- - He has authority to sign the new Example created by this.
    exerciseCmd c4 Accept

Hope that helps!

5 Likes

Thanks @Gary_Verhaegen It made my day :slight_smile:

3 Likes