

Beginner's Guide to Design Patterns in DAML and Practices - Knoldus Blogs
source link: https://blog.knoldus.com/daml-design-patterns-and-practices/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Beginner’s Guide to Design Patterns in DAML
Reading Time: 6 minutes
DAML is an open-source language used to write distributed applications quickly,concisely and correctly. It runs on leading blockchain platforms like Hyperledger Sawtooth , fabric and Corda.
It is used to build smart contracts for distributed ledgers and provide us with ability to focus more on business workflow instead of the blockchain implementation.
In our previous blogs, Building Powerful Smart Contracts, Getting started with building Templates and DAML supported data types we have covered basics of DAML which will help you understand the language and need of language and also a guide to get you started with it. I would recommend you all to go through them before going forward with this blog.
In this blog we will go through DAML design patterns that we should follow while building our application.
What are Design Patterns ?
Design patterns are used to represent some of the best practices adapted by experienced software developers. A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in systems. It describes the problem, the solution, when to apply the solution, and its consequences. It also gives implementation hints and examples.
A design pattern isn’t a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations.
They help in speeding up the development process.
Here are some of the DAML design patterns we can use for building applications using DAML
- Initiate and Accept
- Multiparty Agreement
- Delegation
- Authorisation
- Locking
Initiate and Accept
This design pattern demonstrates how we can start building templates when only two parties are involved in the project. As the title suggests one party initiates the workflow by creating a proposal or an invite contract. The other party will accept, reject or renegotiate the contract.
As shown in this diagram the two cards represent two templates. The first template is the initiation template or the invite template and the other is the Accept template which the user will use to accept the invite.
Lets understand better with an example :
In this example we have two templates for Initiation and Acceptance. This example we are to issue coins to the user once the user has accepted the agreement. This code is not in complete
And is just used to give you guys an idea of the concept.
template CoinIssueProposal
with
coinAgreement: CoinIssueAgreement
where
signatory coinAgreement.issuer
controller coinAgreement.owner can
AcceptCoinProposal
: ContractId CoinIssueAgreement
do create coinAgreement
Initiate Template
The CoinIssueProposal contract has Issuer as the signatory, and Owner as the controller to the Accept choice. As we can see the choice available is of only AcceptCoinProposal but in reality different choices like reject or renegotiate are also provided.
template CoinIssueAgreement
with
issuer: Party
owner: Party
where
signatory issuer, owner
controller issuer can
nonconsuming Issue : ContractId Coin
with amount: Decimal
do create Coin with issuer; owner; amount; delegates = []
Result Contract
Once the owner exercises the AcceptCoinProposal choice on the initiate contract to express their consent, it returns a result contract representing the agreement between the two parties. In this example, the result contract is of type CoinIssueAgreement. Note, it has both issuer and owner as the signatories, implying they both need to consent to the creation of this contract. Both parties could be controllers on the result contract, depending on the business case.
Multiparty Agreement
In the previous topic we saw the best way to make the contract when only two parties are involved but in the real world multiple parties can be part of the contract. When multiple parties are involved bilateral contracts are not the way to go as no two parties can be sure if there is a conflict between their two contracts and third contract between their partners.
So what approach should we follow in that case? Let’s find out!
The Multiple Party Agreement pattern uses a Pending contract as a wrapper for the Agreement contract. Any one of the signatory parties can kick off the workflow by creating a Pending contract on the ledger, filling in themselves in all the signatory fields. The Agreement contract is not created on the ledger until all parties have agreed to the Pending contract, and replaced the initiator’s signature with their own.
template Agreement
with
signatories: [Party]
where
signatory signatories
ensure
unique signatories
-- The rest of the template to be agreed to would follow here
Agreement Contract
This represents final agreement between all the parties. It has multiple signatories.
template Pending
with
finalContract: Agreement
alreadySigned: [Party]
where
signatory alreadySigned
observer finalContract.signatories
ensure
-- Can't have duplicate signatories
unique alreadySigned
-- The parties who need to sign is the finalContract.signatories with alreadySigned filtered out
let toSign = filter (`notElem` alreadySigned) finalContract.signatories
choice Sign : ContractId Pending with
signer : Party
controller signer
do
-- Check the controller is in the toSign list, and if they are, sign the Pending contract
assert (signer `elem` toSign)
create this with alreadySigned = signer :: alreadySigned
choice Finalize : ContractId Agreement with
signer : Party
controller signer do -- Check that all the required signatories have signed Pending
assert (sort alreadySigned == sort finalContract.signatories)
create finalContract
Pending Contract
This pending contract contains the Agreement as one of the parameters so that all the parties know what they are signing for.
Here the pending contract has the list of parties which have signed the contract and the list of parties which are yet to sign the contract. Once all the parties have signed the contract using the Finalize choice. This checks that all of the signatories for the Agreement have signed the pending contract.
Delegation
This is an important design pattern because it gives one party the right to exercise a choice on behalf of another party. In the real world this is very useful because there may be many cases where somebody would like to give another person the right to exercise the choice on their behalf. For eg: when a company may give the rights to their chosen bank to hold their securities and settle transactions on their behalf.
Delegation design pattern can be implemented using:
template Coin
with
owner: Party
issuer: Party
amount: Decimal
delegates : [Party]
where
signatory issuer, owner
observer delegates
controller owner can
Transfer : ContractId TransferProposal
with newOwner: Party
do
create TransferProposal
with coin=this; newOwner
Disclose : ContractId Coin
with p : Party
do create this with delegates = p :: delegates
Pre-Condition Contract
This contract exists with the choice for Party A to delegate execution of the choice to Party B. Here the control of the choice is given to the owner who can pass the authority to another party to exercise choice on its behalf.
template CoinPoA
with
attorney: Party
principal: Party
where
signatory principal
controller principal can
WithdrawPoA
: ()
do return ()
controller attorney can
nonconsuming TransferCoin : ContractId TransferProposal with
coinId: ContractId Coin
newOwner: Party
do
exercise coinId Transfer with newOwner
Delegation Contract
Here the original coin owner is the signatory of delegation. This signatory is required to authorise the transfer choice on the coin. Attorney is the controller of the Delegation choice on the contract. Within the choice, the Principal exercises the choice Transfer on the Coin contract.Coin contracts need to be disclosed to the Attorney before they can be used in an exercise of Transfer. This can be done by adding an Attorney to Coin as an Observer. This is done using the Disclose choice in the pre-condition contract.
Authorisation
In this business world it is very important to make sure that the contracts choices are exercised by the right person. If any person who is not authorized or does not have the permission is able to exercise a choice then it’s consequences can be bad for business.
It is important to make sure that the parties are authorised to before taking part in the business transaction. This can be achieved by using an Authorised pattern model.
template CoinOwnerAuthorization
with
owner: Party
issuer: Party
where
signatory issuer
observer owner
controller issuer can
WithdrawAuthorization
: ()
do return ()
Authorisation Contract
In this example we can see that issuer is the signatory here and owner is the observer. This makes sure that the owner is an authorised person. This is a simple example, in real business use cases we can add many things.
Locking
Locking is an important concept for business contracts. In a real world scenario like in the case of the settlement process between two parties the securities under the ownership of seller need to be locked so they cannot be used for other purposes, and so should be the funds on the buyer’s account. The locked state should remain throughout the settlement Payment versus Delivery process. Once the ownership is exchanged, the lock is lifted for the new owner to have full access.
This can be achieved in three ways:
References :
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK