{"id":"vqKpNpkLEGw","title":"Lesson 3: Daml Templates","description":"Daml templates are the building blocks of a Daml application. To understand templates, we first need to understand the common structure of a .Daml file. A Daml file has a module, and the module name is the same as the file name. Templates are defined in modules. A template must have at least one party. Parties exercise choices. Choices are methods or functions in a program that can take parameters, perform some task, and return a value. There are two types of choices; consuming and nonconsuming. \n\n\n00:10 Module\n00:21 Templates\n00:45 Party\n01:08 Creating a template\n02:17 Signatories\n02:47 Choices\n03:19 Contract ID\n04:34 Consuming and Nonconsuming choices\n07:24 Code conventions\n08:09 Review\n\nFor a better learning experience, sign up and enroll in this free course at: https://daml.talentlms.com/plus/catalog/courses/143","channel_name":"Digital Asset Training","published_at":"2025-02-20T00:00:00.000Z","thumbnail_url":"https://i.ytimg.com/vi/vqKpNpkLEGw/hqdefault.jpg","transcript_text":"Daml templates are the building blocks of a Daml application. To understand templates, we first need to understand the common structure of a .Daml file. A Daml file has a module, and the module name is the same as the file name. It then has all the import statements it needs, including other modules that you may create for your application. Templates are defined in modules. A template definition starts with a template keyword followed by the name of the template. Like modules, its name must start with a capital letter. The first thing inside a template is the with block that lists the parameters or the values needed when you create a contract out of this template. For each parameter in the template, the with block contains the name of the parameter and its type separated by a colon. An important parameter type in this section is party. A template must have at least one party. A party is a special data type used in the ledger to represent an individual or an entity that participates in the contractual agreement defined in the template. Then there is the where block that contains several important components defining what parties can do in the form of choices. Let's create a simple template for a bank account to demonstrate how a template works. In a module called bank service, we'll write template, bank account, and then inside it start the with block. daml.yaml is a white space aware language, so consistent formatting and indentation is required. As you can see, everything below the template declaration forms the body of the template and must be indented. Our bank account template needs two parties. Bank and account owner. Notice that we need to put the bank in here as a party because the account owners should not be able to create or archive accounts on their own. The bank is required to authorize all those bank related transactions. The third argument in this template is balance declared as a numeric two, which means a decimal value with two places after decimal. Something to note here is that while we're using numeric two, in many of the examples, decimal is a more common data type used in Daml real world applications. Our use of numeric two is mainly to get a more readable output to be displayed when we're demonstrating the code in the lessons. Next comes the where block. The first thing we need to specify is the role parties will play. In this template, we'll make the bank and the account owner both signatories as both must authorize the creation of a bank account in the owner's name. In this model, we don't wanna make the data inside a bank account contract visible to anyone other than the signatories of the contract that is the bank and the account owner. But if we did, we could specify the parties that would be able to view the data inside the contract as template observers. Now we want to create a choice. Think of choices as methods or functions in a program that can take parameters, perform some task, and return a value. We want to create a choice to deposit money in this account. So we say choice, deposit. A choice name must start with a capital letter. Then followed by a colon we have the return type. If we want to write a choice that does not return any value, then we can put empty parentheses. But in this case, we want the choice to return some reference to the contract that's been updated. At this point, it's a good time to introduce a unique data type to Daml, and that's contract id. Daml assigns a unique contract ID to every contract that is created. The contract ID is an inbuilt data type that's automatically assigned to a contract and can be used to access it. It's associated with the template from which the contract was. So the data type of the contract ID for the contract created from the bank account template will be contract ID bank account. Coming back to the deposit choice, if we want the choice to carry some parameters, then we create another with block this time for the choice variables. In this example, we want the amount to be deposited as the variable, so we specify that as amount numeric two. An important decision we have to make at this time is how should we be able to exercise this choice? We have just two parties here, and for all practical purposes, we think it is the account owner who should make deposits. So we then write controller. Account owner. As you may recall, a controller is a party that is able to exercise a particular choice on a particular contract. Controllers must be an observer, otherwise they can't see the contract to exercise the choice. Let's look at what needs to be done when the choice is exercised. The actions in a choice are written inside a do-block. In our example, we want the amount passed to the choice to be deposited to the account. In other words, we want to change the balance amount in the account. Now, if you recall, everything in the ledger is immutable, which means we can't simply change the balance value in the ledge. The only way to make that change is to archive the old entry and create a new account entry with the new value. Before we go any further, this is probably a good time to talk about types of choices. There are two types of choices; consuming and nonconsuming. Choices by default are consuming. When a consuming choice is exercised, the contract on which it is exercised is archived. If you visualize a ledger as a table, a contract is a row in that table. The deposit choice that we are creating in our bank service template is currently defined as consuming by default. So when Alice first creates an account with an initial deposit of a hundred dollars, it's stored as a row in the transaction table. When she exercises the deposit choice to add $20 to her account, there are three things that happen. First, the older row in the table is marked archived. This archival happens automatically when the type of choice is consuming. Second, a new row is created, marked as active. And third, the new contract gets a new contract id. If we want to make the deposit choice as nonconsuming, then we need to use the keyword nonconsuming in the choice definition. In that case, when Alice exercises this choice, the older row will not be marked as an active, and a new row will be added with a new balance. This isn't really what we want in this case, because now Alice's account has two active rows, which means she has two bank accounts, one with the balance of a hundred dollars, the other with the balance of $120. So we should keep the deposit as a consuming choice. There are situations where having many active records is exactly what we want, and we'll look at those later. So all we need to do is create a new contract with a new balance. We say create bank account with, followed by all the variables it needs. Bank, account owner and balance. If we had written the choices as returning nothing by giving empty parentheses above, we would have to provide an explicit return statement with empty parentheses. Instead, we choose to have it returned the contract id, so we don't need to specify the return type. Remember, the due blocks always return the result of the last expression. Our last statement is create, so we'll return the result of Create, which is contract id. Now, before we go any further, you might be thinking there has to be a better way of writing this. Well, there is, although the code here is readable and fairly easy to understand, we can make two changes to make it more concise. First, instead of saying create bank account, we can say, create this. Since we're creating something out of the same template, we're in. The keyword this refers to the data in a contract. It's also referred to as the payload. Second, we also see the variables bank and account owner are the same variables on both sides, so we can conveniently skip them, and Daml will understand the parameters that have the same name as the local variables and can be assigned their value. We've now written a simple template that has two parties and one choice for one of those parties. Let's review what we've covered. Templates are the building blocks of Daml applications, and they're written inside of modules. There are two blocks of code in a template. The with block and where block. The with block has arguments to create a contract, and the where block has several subsections. We looked at how to specify signatories, observers, and choices. Each template must have one party defined in the with block, and at least one signatory specified in the where block. Signatories are authorized to create and archive contracts. We need authorization from all signatories to create and archive a contract. Observers can't create or archive the contract, but they get to view the contract payload. The data stored in the contract choices are like methods that take arguments and return some value. You can use consuming choices, which archives the contract and nonconsuming choices, which do not archive the contract.","transcript_synced_at":"2026-10-26T03:57:33.277Z","segments":[{"start_seconds":0,"text":"Daml templates are the building blocks of a Daml application.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=0s"},{"start_seconds":5,"text":"To understand templates, we first need to understand the common structure of a .Daml file. A Daml file has a module, and the module name is the same as the file name.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=5s"},{"start_seconds":14,"text":"It then has all the import statements it needs, including other modules that you may create for your application. Templates are defined in modules.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=14s"},{"start_seconds":23,"text":"A template definition starts with a template keyword followed by the name of the template. Like modules, its name must start with a capital letter.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=23s"},{"start_seconds":31,"text":"The first thing inside a template is the with block that lists the parameters or the values needed when you create a contract out of this template.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=31s"},{"start_seconds":39,"text":"For each parameter in the template, the with block contains the name of the parameter and its type separated by a colon. An important parameter type in this section is party.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=39s"},{"start_seconds":48,"text":"A template must have at least one party.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=48s"},{"start_seconds":51,"text":"A party is a special data type used in the ledger to represent an individual or an entity that participates in the contractual agreement defined in the template.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=51s"},{"start_seconds":60,"text":"Then there is the where block that contains several important components defining what parties can do in the form of choices.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=60s"},{"start_seconds":68,"text":"Let's create a simple template for a bank account to demonstrate how a template works.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=68s"},{"start_seconds":73,"text":"In a module called bank service, we'll write template, bank account, and then inside it start the with block.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=73s"},{"start_seconds":80,"text":"daml.yaml is a white space aware language, so consistent formatting and indentation is required.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=80s"},{"start_seconds":85,"text":"As you can see, everything below the template declaration forms the body of the template and must be indented. Our bank account template needs two parties.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=85s"},{"start_seconds":95,"text":"Bank and account owner.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=95s"},{"start_seconds":97,"text":"Notice that we need to put the bank in here as a party because the account owners should not be able to create or archive accounts on their own.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=97s"},{"start_seconds":105,"text":"The bank is required to authorize all those bank related transactions.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=105s"},{"start_seconds":110,"text":"The third argument in this template is balance declared as a numeric two, which means a decimal value with two places after decimal.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=110s"},{"start_seconds":118,"text":"Something to note here is that while we're using numeric two, in many of the examples, decimal is a more common data type used in Daml real world applications.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=118s"},{"start_seconds":128,"text":"Our use of numeric two is mainly to get a more readable output to be displayed when we're demonstrating the code in the lessons.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=128s"},{"start_seconds":135,"text":"Next comes the where block. The first thing we need to specify is the role parties will play.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=135s"},{"start_seconds":140,"text":"In this template, we'll make the bank and the account owner both signatories as both must authorize the creation of a bank account in the owner's name.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=140s"},{"start_seconds":150,"text":"In this model, we don't wanna make the data inside a bank account contract visible to anyone other than the signatories of the contract that is the bank and the account owner.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=150s"},{"start_seconds":159,"text":"But if we did, we could specify the parties that would be able to view the data inside the contract as template observers. Now we want to create a choice.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=159s"},{"start_seconds":169,"text":"Think of choices as methods or functions in a program that can take parameters, perform some task, and return a value. We want to create a choice to deposit money in this account.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=169s"},{"start_seconds":179,"text":"So we say choice, deposit. A choice name must start with a capital letter. Then followed by a colon we have the return type.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=179s"},{"start_seconds":188,"text":"If we want to write a choice that does not return any value, then we can put empty parentheses.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=188s"},{"start_seconds":194,"text":"But in this case, we want the choice to return some reference to the contract that's been updated.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=194s"},{"start_seconds":199,"text":"At this point, it's a good time to introduce a unique data type to Daml, and that's contract id. Daml assigns a unique contract ID to every contract that is created.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=199s"},{"start_seconds":210,"text":"The contract ID is an inbuilt data type that's automatically assigned to a contract and can be used to access it.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=210s"},{"start_seconds":218,"text":"It's associated with the template from which the contract was. So the data type of the contract ID for the contract created from the bank account template will be contract ID bank account.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=218s"},{"start_seconds":230,"text":"Coming back to the deposit choice, if we want the choice to carry some parameters, then we create another with block this time for the choice variables.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=230s"},{"start_seconds":239,"text":"In this example, we want the amount to be deposited as the variable, so we specify that as amount numeric two.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=239s"},{"start_seconds":246,"text":"An important decision we have to make at this time is how should we be able to exercise this choice?","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=246s"},{"start_seconds":252,"text":"We have just two parties here, and for all practical purposes, we think it is the account owner who should make deposits. So we then write controller.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=252s"},{"start_seconds":261,"text":"Account owner.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=261s"},{"start_seconds":262,"text":"As you may recall, a controller is a party that is able to exercise a particular choice on a particular contract.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=262s"},{"start_seconds":268,"text":"Controllers must be an observer, otherwise they can't see the contract to exercise the choice. Let's look at what needs to be done when the choice is exercised.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=268s"},{"start_seconds":277,"text":"The actions in a choice are written inside a do-block.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=277s"},{"start_seconds":281,"text":"In our example, we want the amount passed to the choice to be deposited to the account. In other words, we want to change the balance amount in the account.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=281s"},{"start_seconds":290,"text":"Now, if you recall, everything in the ledger is immutable, which means we can't simply change the balance value in the ledge.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=290s"},{"start_seconds":297,"text":"The only way to make that change is to archive the old entry and create a new account entry with the new value.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=297s"},{"start_seconds":304,"text":"Before we go any further, this is probably a good time to talk about types of choices. There are two types of choices; consuming and nonconsuming.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=304s"},{"start_seconds":313,"text":"Choices by default are consuming.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=313s"},{"start_seconds":316,"text":"When a consuming choice is exercised, the contract on which it is exercised is archived. If you visualize a ledger as a table, a contract is a row in that table.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=316s"},{"start_seconds":327,"text":"The deposit choice that we are creating in our bank service template is currently defined as consuming by default.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=327s"},{"start_seconds":333,"text":"So when Alice first creates an account with an initial deposit of a hundred dollars, it's stored as a row in the transaction table.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=333s"},{"start_seconds":341,"text":"When she exercises the deposit choice to add $20 to her account, there are three things that happen. First, the older row in the table is marked archived.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=341s"},{"start_seconds":351,"text":"This archival happens automatically when the type of choice is consuming. Second, a new row is created, marked as active.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=351s"},{"start_seconds":359,"text":"And third, the new contract gets a new contract id.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=359s"},{"start_seconds":363,"text":"If we want to make the deposit choice as nonconsuming, then we need to use the keyword nonconsuming in the choice definition.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=363s"},{"start_seconds":370,"text":"In that case, when Alice exercises this choice, the older row will not be marked as an active, and a new row will be added with a new balance.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=370s"},{"start_seconds":379,"text":"This isn't really what we want in this case, because now Alice's account has two active rows, which means she has two bank accounts, one with the balance of a hundred dollars, the other with the balance of $120.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=379s"},{"start_seconds":390,"text":"So we should keep the deposit as a consuming choice.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=390s"},{"start_seconds":393,"text":"There are situations where having many active records is exactly what we want, and we'll look at those later. So all we need to do is create a new contract with a new balance.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=393s"},{"start_seconds":404,"text":"We say create bank account with, followed by all the variables it needs. Bank, account owner and balance.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=404s"},{"start_seconds":412,"text":"If we had written the choices as returning nothing by giving empty parentheses above, we would have to provide an explicit return statement with empty parentheses.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=412s"},{"start_seconds":422,"text":"Instead, we choose to have it returned the contract id, so we don't need to specify the return type.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=422s"},{"start_seconds":428,"text":"Remember, the due blocks always return the result of the last expression.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=428s"},{"start_seconds":433,"text":"Our last statement is create, so we'll return the result of Create, which is contract id.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=433s"},{"start_seconds":439,"text":"Now, before we go any further, you might be thinking there has to be a better way of writing this.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=439s"},{"start_seconds":444,"text":"Well, there is, although the code here is readable and fairly easy to understand, we can make two changes to make it more concise.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=444s"},{"start_seconds":452,"text":"First, instead of saying create bank account, we can say, create this. Since we're creating something out of the same template, we're in.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=452s"},{"start_seconds":461,"text":"The keyword this refers to the data in a contract. It's also referred to as the payload.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=461s"},{"start_seconds":469,"text":"Second, we also see the variables bank and account owner are the same variables on both sides, so we can conveniently skip them, and Daml will","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=469s"},{"start_seconds":478,"text":"understand the parameters that have the same name as the local variables and can be assigned their value.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=478s"},{"start_seconds":484,"text":"We've now written a simple template that has two parties and one choice for one of those parties. Let's review what we've covered.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=484s"},{"start_seconds":491,"text":"Templates are the building blocks of Daml applications, and they're written inside of modules. There are two blocks of code in a template. The with block and where block.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=491s"},{"start_seconds":500,"text":"The with block has arguments to create a contract, and the where block has several subsections. We looked at how to specify signatories, observers, and choices.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=500s"},{"start_seconds":510,"text":"Each template must have one party defined in the with block, and at least one signatory specified in the where block.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=510s"},{"start_seconds":517,"text":"Signatories are authorized to create and archive contracts. We need authorization from all signatories to create and archive a contract.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=517s"},{"start_seconds":525,"text":"Observers can't create or archive the contract, but they get to view the contract payload.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=525s"},{"start_seconds":529,"text":"The data stored in the contract choices are like methods that take arguments and return some value.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=529s"},{"start_seconds":536,"text":"You can use consuming choices, which archives the contract and nonconsuming choices, which do not archive the contract.","url":"https://www.youtube.com/watch?v=vqKpNpkLEGw&t=536s"}],"youtube_url":"https://youtube.com/watch?v=vqKpNpkLEGw","url":"https://ccpedia.xyz/videos/vqKpNpkLEGw"}