DAML is a powerful open sourced language crceated to write distributed applications quickly, concisely and correctly.
It is functional and designed to support distributed business workflow thereby helping a developer to focus more on programming business processes by cutting down the amount of time he would spend on dealing with encryption and blockchain.
With the help of previous blogs, Build Powerful Smart Contracts and Getting started with building Templates , we can understand the benefits of using DAML to build smart contracts and get a kick start tutorial to build templates using it.
In this blog, we will walk through the different data types supported by DAML and how can we achieve rich data schemas for our ledger using them.
Native Types
We already know few data types from the previous blogs, eg, Party, Text. The other supported data types in DAML are as follows:
Native Data Type | Description | Example |
Text | Stores a unicode character | native_text = scenario do alice <- getParty “Alice” bob <- getParty “Bob” let my_text = “Alice” assert (my_text == “Alice”) |
ContractId | Stores a reference to a contract | ContractId Alice Stores a reference to a contract of type Alice. |
Int | Stores signed 64-bit integers | native_types = scenario do alice <- getParty “Alice” bob <- getParty “Bob” let my_int = -123 assert (-my_int == 123) |
Decimal | Stores fixed-point number with 28 digits before and 10 digits after the decimal point. | native_types = scenario do alice <- getParty “Alice” bob <- getParty “Bob” let my_dec = 0.001 : Decimal assert (1000.0 * my_dec == 1.0) |
Bool | Stores True or False | native_types = scenario do alice <- getParty “Alice” bob <- getParty “Bob” let my_bool = False assert(not my_bool) |
Date | Stores a date | import DA.Date native_types = scenario do alice <- getParty “Alice” bob <- getParty “Bob” let my_date = date 2020 Jan 01 assert (addDays my_date 1 == date 2020 Jan 02) |
Time | Stores absolute UTC time | import DA.Timeimport DA.Date native_types = scenario do alice <- getParty “Alice” bob <- getParty “Bob” let my_date = date 2020 Jan 01my_time = time my_date 00 00 00 |
RelTime | Stores a difference in time | import DA.Timeimport DA.Date native_types = scenario do alice <- getParty “Alice” bob <- getParty “Bob” let my_date = date 2020 Jan 01my_time = time my_date 00 00 00 my_rel_time = hours 24 assert (addRelTime my_time my_rel_time == time (addDays my_date 1) 00 00 00) |
Assembling Types
DAML’s type system provides us number of ways to assemble these native types into much more expressive structures.
Tuples:
In DAML, you can group values in a generic way. For example, A key-value pair with a Text key and an Int value can be represented as a two-tuple of type (Text, Int)
import DA.Tuple tuple_test = scenario do let key_value = ("Employee_A", 1) assert (fst my_key_value == "Employee_A") assert (snd my_key_value == 1) assert (my_key_value._1 == "Employee_A") assert (my_key_value._2 == 1)
Lists
DAML is a static and strongly typed language, thus it only supports creating a list with a single type parameter.
import DA.List list_test = scenario do let emp_list = [1,2,3] assert (head emp_list == 1)
Records
Records are named tuples with named fields. They are declared as,
data T = C here, T is the type name and C is the data constructor
For example,
data Coordinate = Coordinate with
x, y, z : Decimal
record_test = scenario do
let
my_coord = Coordinate with
x = 1.0
y = 2.0
z = 3.0
assert (my_coord.x == 1.0)
Manipulating Data
All data in DAML is immutable, meaning once a value is created, it will never change. But, you create new values based on old ones with the changes needed. For instance,
manipulation_records = scenario do
let
old_record = Record with
my_txt = "Old Record"
my_int = 2
-- new record
new_record = old_record with
my_int = 3
assert (old_record.my_int == 2)
assert (new_record == old_record)
Here, new_record is a copy of old_record with the field my_int changed.
Contract Keys
In DAML, contract models often have multiple templates that reference each other. For example, we may want to store user’s bank and account information on separate contracts and not an individual cash balance contract with both account and bank information.
Just like data, contracts are also immutable in DAML and can only be created and archived.
The below example shows a contract model where Account is split out into a separate template and referenced by ContractId.
data Bank = Bank with party : Party address: Text telephone : Text deriving (Eq, Show) template Account with accountant : Party owner : Party number : Text bank : Bank where signatory accountant data Cash = Cash with currency : Text amount : Decimal deriving (Eq, Show) template CashBalance with accountant : Party cash : Cash account : ContractId Account where signatory accountant
You are now all set to define data schemas for the ledger and create richer smart contracts!