In this blog, we will explore the Bots in DAML, we will start with basic introduction about Bots than we move to why do we need it and how we can implements Bots in our DAML Application. Before moving forward, I assume that you know basic of DAML if not then please read this blog.
What is a Bot?
A bot is a software application that is programmed to do certain tasks. Bots are automated, which means they run according to their instructions without a human user needing to start them up. Typically they do repetitive tasks, and they can do them much faster than human users could.
Why do we need Bots?
DAML is a great programming language to write a smart contract but is still new and under development. Sometimes, developers need to automate processes like the generation of action in response to a certain event (an incoming transaction, for instance). Let suppose, we want to automatically create a new contract in DAML after another contract is created or we want to archive a contract after a user performs a certain transaction. Right now, this is not possible to accomplish with just DAML itself as DAML Trigger is still under development. We need bots for this purpose which is basically an abstraction to create an automation for a DAML Ledger.
How do we Implement Bots in DAML Application?
For bot implementation, we use a python library called DAZL.
DAZL is an amazing Python library provided by Digital Asset. It provides a number of functions that enable the automation on the Ledger as it provides event listeners for the same. Suppose you want to run a certain piece of code after the execution of events related to contracts, like creation, archival, or exercise of choice, then it can easily be done using the DAZL Library.
Benefits of Bot
- Add support for third-party APIs simply by creating bots that listen to external activity.
- Works great with DABL Cloud Service.
- Portable and adjustable as per requirements.
- Quick response time.
For creating a Bot we need following files to be added in our project.
- setup.py: for adding basic info about Bot. Like the name of bot, version name and for importing dazl library.
- __init__.py: It usually just be left empty—it’s just a marker file that tells Python that a directory is a module.
- __main__.py: It contains your “main”—whatever is in there is run when you run your application.
- bot.py: It contains main function you need to perform after a particular transaction.
Directory structure
Let create a Demo Application
Now we will create a simple application where a user query for a car of selected company with limited budget. As a response company marketing team will send proposal to user. Once user select a proposal and create a Final Agreement we will use bot to archive the remaining proposal.
Application Flow
As you can see in above figure that user Accept only Maruti proposal so our bot will reject Honda request.
Main.daml
module Main where
-- MAIN_TEMPLATE_BEGIN
template CarRequest with
userName: Party
userBudget : Int
interestedCompany : [Party]
where
signatory userName
observer interestedCompany
-- MAIN_TEMPLATE_END
-- FOLLOW_BEGIN
nonconsuming choice Proposal: ContractId CarProposal with
company : Party
model : Text
price : Int
controller company
do
assert(company `elem` interestedCompany)
create CarProposal with companyName = company ,queryParty=userName, carModel = model, carPrice = price
choice NotInterested : () with
company : Party
controller company
do
assert(company `elem` interestedCompany)
return ()
template CarProposal with
companyName : Party
queryParty : Party
carModel : Text
carPrice : Int
where
signatory companyName
observer queryParty
controller queryParty can
AcceptOffer : ContractId FinalAgreement
do
create FinalAgreement with
company = companyName
user = queryParty
model = carModel
controller queryParty can
RejectOffer : ()
do
return ()
template FinalAgreement with
company :Party
user : Party
model : Text
where
signatory user
observer company
setup.py
from setuptools import setup
setup(name='bot',
version='1.0.0',
description='Car-Info Bot',
author='Knoldus Inc.',
license='Apache2',
install_requires=['dazl'],
packages=['bot'],
include_package_data=True)
bot.py
import logging
import uuid
import datetime
import time
import dazl
dazl.setup_default_logger(logging.INFO)
EPOCH = datetime.datetime.utcfromtimestamp(0)
def main():
#configure bot environment so it can connect to ledger
network = dazl.Network()
network.set_config(url='http://localhost:6865')
client = network.simple_party('Alice')
contractIdProposals = []
#creating decorator which will log as soon as client make any
#transaction
@client.ledger_ready()
def bot_ready(event):
logging.info(f'user_bot for party {client} is ready')
#decorator for storing CarProposal Id
@client.ledger_created('Main.CarProposal')
def on_message(event):
contractIdProposals.append(event.cid)
logging.info(contractIdProposals)
#decorator for rejecting remaining offer aftr user accept a
#proposal
@client.ledger_exercised('Main.CarProposal','AcceptOffer')
def final_agreement_created(event):
contractIdProposals.remove(event.cid)
for contractId in contractIdProposals:
client.submit_exercise(contractId, 'RejectOffer')
# for running bot forever
network.run_forever()
if __name__ == '__main__':
main()
If you are deploying it over dabl change bot environment configuration to
url = os.getenv('DAML_LEDGER_URL')
party = os.getenv('DAML_LEDGER_PARTY')
network = dazl.Network()
network.set_config(url=url)
client = network.aio_party(party)
you can get complete code here.
Now run application
daml start
open another terminal and move to bot folder to start our bot.
python3 bot.py
Now use navigator to test your application.
References
https://github.com/digital-asset/dazl-client
https://docs.daml.com/