What is PyTeal?
Toggle full transcript
Hello, everyone. My name is Chris. And in this video we will kick off the PyTEAL video series by talking about what PyTEAL is and why it's one of the best ways to
build smart contracts on Algorand. Also, make sure to check out the Beaker Framework series overlaying on the top right of
this video right now to learn how Beaker wraps PyTEAL and makes writing smart contract with PyTEAL even easier. So what is PyTEAL? PyTEAL is a Python library that lets you write Algorand
smart contracts with python like syntax. I say python like syntax because PyTEAL programs are not really written with python
but are collections of PyTEAL expressions composed of other PyTEAL expressions. Now don't worry if you don't really understand what I mean here. There will be a separate video just on PyTEAL expressions.
So this is how it works under the hood. When you write your Algorand smart contract with PyTEAL you use the PyTEAL's compile program method to produce TEAL code automatically.
TEAL. This is shorthand for Transaction Execution Approval Language, and it's a low level assembly language that can be easily compiled to byte code for the Algorand Virtual
Machine to execute. Even if you write your smart contract with PyTEAL, it will greatly help you to understand how your contract works by learning about how TEAL works and what capabilities
DBM has. So be sure to check out the TEAL series that should be popping up on the top right now. Let's look at a simple counter example written with PyTEAL to get a feel of what a Python
smart contract looks like. Before we look at the code for you to follow along this video, you need to have
Docker Sandbox and PyTEAL installed and have sandbox running a local Algorand blockchain in dev mode. I will leave a link to the development environment setup video on the top right, so make
sure you have your dev environment set up before you continue. Here I have a new VS Code editor opened up with the project folder. What is PyTEAL? Before you start coding an Algorand smart contract, it's recommended
to create a python virtual environment (venv) to keep your projects separate from your operating machine. To do that, you want to open up your terminal.
Going to expand it a little. And then you want to do python -m env [space] env and that is going to create the venv folder.
Then to activate your virtual environment you want to do source venv/bin/activate.
Now if you do pip list, you can see that you're starting from a clean slate. So first thing you want to do is install PyTEAL. To do that you want to do PIP install PyTEAL.
And we did hit list again.
You can see that PyTEAL is installed. Now you're all ready to start coding. Now, for the sake of time. I'm going to use a completed example, but if you really want
to learn how to write PyTEAL smart contracts, you should follow along by coding for yourself. Now I am inside the what is PyTEAL folder and inside of it I created a counter.py
file where I'm going to write the code for my counter smart contract. And then I created a artifacts folder where all of the approval program,
clear program and my API is going to go when I compile my program. Now first thing I do is I import PyTEAL in.
And let's first look at this thing called a router. So whenever you write a PyTEAL smart contract, you want to set up the router first because this is like a command center that tells a smart contract, Hey,
you run this method when you get this kind of application call. You do this when you get a create application call and basically it handles
routing for all of the incoming application calls. Now, here inside of the router class, the first argument is going to be the name of the router. I called it Simple Counter.
And as a second argument I put in the BareCallActions. Inside of the BareCallActions, you want to specify what happens during creation, during opt in and all the other on complete application calls.
Since this is a simple example, I've only defined what happens during creation of the application. And if you look at the definition here, you can see that the rest of
the on complete actions are default to never, which means to never approve these incoming on complete application calls.
Now inside the create only, as an argument, I'm putting in this handle creation variable and you can see that I have defined that above over here and handle creation is basically
a variable that holds a PyTEAL expression. Now this PyTEAL expression is a sequence, so inside of the sequence are going to be multiple PyTEAL expressions and all of them have to go through for
this sequence to go through. And the line for what we're doing here is you're creating a global state by doing
app.globalPut. The key of the global state is called count (in bytes) and the default value of that global state will be an int value of zero.
So in other words, when we are creating this application, this is going to initialize a global state called count to zero. Great. Now, coming down here in line 16, we have an increment method and you can see that
this increment method is decorated by this router method. This decorator is registering this increment method to the router class that we have
defined up here so that the router knows when to execute this increment method. Now going inside we create a scratch bar of TEAL type that you in 64
that it's creating a temporary storage on the virtual machine that will go away afterwards. And we're assigning that to the scratchCount variable.
And this increment method is returning a PyTEAL expression in line 19. We're getting the global state count by doing app.globalGet
in there, we're storing that value in the scratch variable and then we're going to write a new value to count global state. The new value will be the value that is in the scratch variable right now
by doing scratchCount.load() and we're going to add Int(1) to that. So this is essentially going to increment the count by one.
And down here we have a read_count method. And whatever comes after the star in the parentheses is an output.
And we can see here that the read count is going to output a uint64 type. And this is returning a PyTEAL expression where output is set to
the global stage count that we get by doing at the globalGet. So that's a simple counter example written in PyTEAL.
Now down here, when I run this file, what I'm going to do is I'm going to compile the program by doing router.compile_program and I specifying the version here as version six.
This is going to spit out three values an approval program in TEAL, clear program in TEAL, and the contract ABI JSON file.
And down here I'm taking these three values and I'm going to dump those values into the file system. So if you open up a terminal and run python counter.py
that is going to write the three values into the filesystem.
So if you come to the what is Python folder and inside of the artifacts folder, we have the three files written here, the approval.teal, which is the TEAL program of the smart contract that we have written, a clear program
written in TEAL and the contract.json file, which is an API specification for the frontend.
Now let's try deploying this simple counter smart contract and calling the increment method to see if it works. To do that, I'm going to use a development tool called Dappflow.
This is a web based development tool for Algorand, and you can come to this Web site by going to dappflow.org. When I open the application and with Dappflow, you can connect to your sandbox
by going over here, clicking sandbox and save. Now, whatever you see on the Dappflow website is going to be the current state
of your sandbox blockchain. So before doing anything else, you want to create a dev wallet and come over here and click create wallet to create a developer wallet that you can use to play around with.
You can click the dispense button right here to automatically dispense ten algos to your account.
Come down here. Click the Connect wallet button and then connect to your dev wallet that you created. Now come to the ABI studio and this is where you can use to contract.json ABI file that we got before to
deploy and call your counter smart contract. To do that you want to click on import ABI, go to file, upload,
file and find the folder that you wrote your smart contract in, go to the artifacts folder and then import in the contract.json file.
And as you can see, you can see the name of the router over here and the two external methods that we have defined over here, increment and read count.
Before we call these methods. We want to create this application. To do that, come to create app, go to bare. And then here first you want to specify how much storage the smart contract uses.
Our counter example only has one global state that is a uint64 type. So we're going to have this as zero, one for global int, zero for
both local bytes and local. Then upload your approval program, upload your clear program. These are all in your artifacts folder and then click create.
Now you'll see the message application created successfully. Now let's try reading the default count value.
So I'm going to go to read count. If I click Execute, you can see that the value is set to zero now. If you quickly go back to our code, this is because during creation we have created a global state called count
and initialize it to zero. Going back to Dappflow now I'm going to click increment.
Click, execute. You can see the method executed successfully. And if you go back to read_count and execute that again, you can see that the value
updated to one. Dappflow is really great. If you want to do quick checking while you're developing your smart contract and you can use the ABI Studio to do what I just did right here, I'm going to be using Dappflow a lot in this PyTEAL video series,
so don't worry if you don't fully understand how to use it right now. Today we took our first glance at our PyTEAL is how it works under the hood
and saw a simple counter example to get a feel of what a PyTEAL program looks like, that we're going to go deeper into core PyTEAL concepts and make you a Python master by
the end of the series! So let's get started.