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.)
- 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.
- 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
3 Likes