Plutus Pioneer Program – Lecture #1

Welcome to the Plutus pioneer
program, we are very excited to have so many of you participating. I'll start by saying a couple of
things about the organization. So we have the first lecture today
thursday but the plan is to starting next week, switch to a different rhythm. So we'll have lectures coming
out on Tuesdays, and then we'll have a Q and A session, a live
Q and A session on Thursdays. And, because they ask so many of you. It's unfortunately not possible to be
as interactive as I'd like it to be. So it would be great if all of you could
use the discord server to help each other, answer questions and solve problems. I mean, we will do what we can,
my colleagues and myself to, to answer questions and help.

But with the sheer number of
participants, it's just not possible to pay as much attention to every
individual as we would like. So thank you for helping out. As for the content. So the ideas to really give a
thorough introduction to Plutus explain the underlying concepts,
look at various types of contracts. Look at how we can test contracts in
the playground or also offline, locally. Um, Talk about native tokens, how
to control minting and burning of naked tokens in Plutus. And, we also look at how to deploy
a Plutus contract and write a backend for Plutus contract. Plutus learning is not
easy, unfortunately. So, you have to be aware that the
course probably won't be easy and there are a variety of reasons for that. So one is that Plutus uses the UTXO model. I'll explain in much more detail what
that means later in this lecture. And that is different than less
intuitive than the Ethereum method for doing smart contracts. It has a lot of advantages the UTXO
model, but it also requires a new way of thinking about smart contracts.

So that's one thing and that's before
we even start with the language itself, Then of course Plutus has brand new
and still under rapid development. So probably during the time of the course
um, there will be significant changes. So we often have to update
the dependencies on the main Plutus repository. And it might be that contract state
compile at the beginning of the course won't compile any longer at the end of
towards the end of the course, because there have been some syntax changes. In addition to that
tooling is not ideal yet. So those of you who have experienced
with Haskell and know about the Haskell tooling, we noticed that in
the presence of Plutus some of the tooling is not as pleasant as you will
maybe use to being from, doing Haskell.

So Sometimes it's a bit painful. So it's, not that easy to get access
to a syntax or functions or to, to documentation from the repl for example. And it's not even very easy to,
build Plutus in the first place. So your best bet is probably using nix. You can also try Cabal
and stack or Docker. Actually the Plutus team will
provide a nice Docker image. At some point, so maybe that will
then be the easiest option, but, yeah, it's not, totally trivial to get
Plutus to compile in the first place. Then of course Plutus
is Haskell more or less. So on top of the other problems,
you first have to have a firm grip on Haskell in order to do Plutus
and obviously in the 10 weeks. Oh, of course time. I won't have time to, first do a
proper thorough Haskell course. Uh, the Haskell courses that I did in
Greece, on Barbados in Ethiopia, and then last year virtually in Mongolia,
the full time course is 10 week full time courses, 40 hours a week. And even in those courses we
didn't cover everything that you will need to, fully understand.

Plutus of course, we also covered
things that are irrelevant for Plutus. So it's not as bad as it sounds,
but nevertheless, there is a quite some Haskell that you need. And I would have time to
thoroughly explain everything. I'll try to explain the, special
concepts that you need for Plutus obviously, and whenever there is a
especially need, when I see that a lot of you are struggling with something,
then obviously I'll take the time to, to explain that topic in more detail. So, unfortunately I won't be able to
spend as much time teaching Haskell as I'd like to, because obviously I
mostly want to do Plutus, but we did record our Mongolia Haskell course.

And we have started editing the videos
and making them nicer and more concise. And what we have, we'll publish here
for you, on the discord server so that if you are struggling with Haskell and
would like an introduction, that's much slower, pace, then you can give those
videos or try, and maybe they help with, Haskell problems you might have. Another problem is that Plutus is
brand new, which of course is also very exciting, but it also means that you
and I and the Plutus team are the first people ever in the history of humanity
that write Plutus code, so if you learn another programming language and you get
stuck or have a problem, then normally you can just go to stack overflow, Google, and
often you'll be lucky and find an answer. So, because we are the first, you
won't have that option, so we have to figure it out while we go along. As for the curriculum. I'm I told you what topics I want
to cover, but I also consciously made the decision not to like
published the curriculum in advance because I want to be flexible and
be able to react to your feedback.

So if I see that a lot of you are
struggling with a certain concept, then we can spend more time on that. Or if I see that a lot of you are
very eager to learn some specific thing, then we can do that. So I want to keep it flexible and,
see how it goes and then react to feedback to make it as, as valuable
as possible for, every one of you.

One of the most important things you need
to understand in order to write Plutus smart contracts is the counting Model. That Cardano uses. And that is the E UTXO model, which is
an abbreviation for "Extended Unspent Transaction Output Model", the UTXO
model without being extended is the one that has been introduced by Bitcoin. But there are other models. Ethereum for example, use this
Account Based" model, which is what you're used to from a normal bank. Where everybody has an account
and each account has a balance. And if you transfer money from one
account to another, then the balances get updated accordingly, but that
is not how the UTXO model works. Unspent Transaction Outputs
as exactly what the name says. They are transaction outputs that is
outputs from previous transactions that happened on the blockchain
that have not yet been spent.

So let's look at an example
where we have two such UTXOs, one belonging to Alice, a 100 ADA and
another one belong to Bob 50 ADA. And as an example, let's assume that
Alice wants to send 10 ADA to Bob. So she creates a transaction and the
transaction is something that has inputs and outputs, can be an arbitrary number of
inputs and an arbitrary number of outputs. And an important thing is that you can
always only use complete UTXOs as input.

So, if she wants to send 10 ADA
to Bob, she can't simply split her existing 108 ADA into a 19 to 10 piece. She has to use the full 100 ADA as input. So by using the UTXO 100 ADA
is input to a transaction. Alice has no spent that UTXO. So it's no longer UTXO it's no
longer unspent it's been spent. And Now she can create
outputs for a transaction. So she wants to pay 10 ADA to Bob. So one output will be 10 ADA to Bob,
and then she wants her change back. So she creates a second
output of 90 ADA to herself. And so this is how, even though
you always have to consume complete UTXOs you can get your change back. So you consume the complete UTXO,
but then you create an output for the change and note that in a transaction,
the sum of the input values must equal the sum of the output values. So in this case, 100 ADA go
in and 10 plus 90 aDA go out. This is strictly speaking not true. There are two exceptions. The first exception is transaction fees. So the real blockchain for each
transaction, you have to pay fees.

So that means that the. Some of input values has to be
slightly higher than the sum of output values to accommodate for the fees. And the second exception is the
native tokens that we have on Cardano. So it's possible for transactions
to create new tokens, in which case the outputs will be higher
than the inputs or to burn tokens. In which case the inputs will be higher
than the outputs, but that is a somewhat advanced topic, how to handle minting
and burning of native tokens in Plutus. And we'll come back to
that later in the course. So for now we only look at transactions
where there's some of the input values equals the sum of the output values. So this isn't first example of
a simple transaction, and we see that the effect of a transaction
is to consume and spend transaction output and to produce new ones.

So in this example, one UTXO has been
consumed, Alice original 100 ADA UTXO, and two new ones have been created. One 90 ADA UTXO belong to Alice and
another 10 ADA UTXO belonging to Bob. Let's do one other example,
slightly more complicated one, where Alice and Bob together want
to pay 55 ADA each to Charlie. So they create a transaction together. And as inputs, Alice has no
choice, she only has one UTXO. So she uses that one. And Bob also doesn't have a choice
because, neither of his two UTXOs is a large enough to cover 55 ADA. So Bob has to use both his UTXO as input. This time we need three outputs. One, the 55 plus 55 equals 110
ADA for Charlie, and then two change outputs, one for Alice's
change and one for Bob's change.

So Alice paid 90, so she should
get 35 change and Bob paid 60, so we should get five change. One thing, I haven't yet explained
is under which conditions a transaction can spend a given UTXO. Obviously it wouldn't be a good
idea if any transaction could spend arbitrary UTXOs, if that
was the case, then Bob could spend Alice's money without her consent. So the way it works is by adding
signatures to transactions so far, our first example, our transaction
one, because that consumes an UTXO belong to Alice as input. Alice' signature has to be
added to the transaction. And in the second example, because the
inputs belong to both Alice and Bob, both Alice and Bob have to sign that
transaction, which incidentally is something you can't do in Daedalus so
you would have to use the Cardano CLI for complex transactions like that. Everything I've explained so far
is just about the UTXO model, not the you Extended UTXO model.

So this is all just as simple UTXO
Model and the Extended part comes in when we talk about smart contracts. So in order to understand that let's
just concentrate on one consumption offer the UTXO by an input. And as I just explained, the validation
that decides whether the transaction that this input belongs to is allowed
to consume that UTXO in the simple UTXO model relies on digital signatures. So in this case, Alice has to
sign the transaction for this consumption of the UTXO to be valid. And now the idea of the Extended UTXO
model is to make this more general. So instead of just having one condition,
namely that the appropriate signatures is present in the transaction, we
replace this by arbitrary logic, and this is where Plutus comes in. So instead of just having an address
that corresponds to a public key, and that can be verified by a signature
that um, is added to the transaction. Instead we have more general
addresses that are not. Based on public keys or the hashes
of public keys, but instead contained arbitrary logic that can decide
under which condition, this specific UTXO can be spent by a transaction.

So instead of an address going
to a public key like Alice's public key in this example, there
will be an arbitrary script, the script containing arbitrary logic. And instead of the signature in the
transaction, the input will justify that it is allowed to consume this
output with some arbitrary piece of data that we call the Redeemer. So we replace the public key address,
Alice in our example by a script, and we replace a digital signature by a Redeemer,
which is an arbitrary piece of data. Now, the next question is,
what exactly does that mean? What do we mean by arbitrary logic? In a particular it's important
to consider what information, what context this script has. So there are several options. And the one indicated in this diagram is
that all the script sees is the Redeemer. So all the information descript as in
order to decide whether it's okay for the transaction to consume this UTXO
or not is looking at the Redeemer.

And that is the, thing that
Bitcoin incidentally does. So. In Bitcoin, there are smart contracts. They are just not very smart. They are called Bitcoin script and
Bitcoin script works exactly like this. So there's a script on the UTXO side. And the Reedemer on the input side
and the script gets the Redeemer and can use the Redeemer to decide whether
it's okay to consume the UTXO or not. But that's not the only option
we can decide to give more information to the script. So, Ethereum uses a different concept,
in Ethereum the script basically can see everything, the whole blockchain,
the whole state of the blockchain.

So that's like the opposite
extreme of bitcoin. the script has very little context. All it can see is the Redeemer. In Ethereum the scripts, the solidity
scripts in Ethereum can see the complete state of the blockchain. So that enables Ethereum scripts
to be much more powerful so they can do basically everything, but
it also comes with problems because the scripts are so powerful.

It's also very difficult to predict
what a given script food do and that opens the door to all source of
security issues and, dangerous because it's very hard to predict for the
developers of an Ethereum smart contract. Um, what can possibly happen? Because they had so many possibilities. So what Cardano does is
something in the middle. So it doesn't offer such a restricted
view as Bitcoin, but also not such a, global view as Ethereum,
but instead chooses a middle way. So the script can see the whole
blockchain can see the state of the world blockchain, but it can see the whole
transaction that is being validated. So. In contrast to Bitcoin, a contrast, see
this one input, the Redeemer of this one input, but it can see that and all the
other inputs of the transaction and also all the outputs of the transaction and
the transaction itself, and the Plutus script can use that information to decide
whether it's okay to consume this output.

Now, in this example, there's only
one input, but if this transaction had more than one input, then the script
would be able to see those as well. There's one last ingredient that
Plutus scripts need in order to. Yes, powerful as expressive
as Ethereum scripts. And that is a datum, which is a piece
of data that can be associated with a UTXO in addition to the value. So at a script address, like in this
example, in addition to this 100 ADA value, that can be an arbitrary piece
of data attached, which we call datum. And with this, we can actually
mathematically prove that Plutus is at least as powerful as Ethereum. So everything, every logic you can
express in Ethereum, you can also express in this Extended UTXO model
that Cardano uses, but it has. A lot of important advantages in
comparison to the Ethereum model. So for example, in Plutus, it is
possible to, check whether a transaction will validate in your wallet before
you ever send it to the chain. So something can still go wrong. So for example, your transaction
can consume an output and then when it gets to the chain.

Somebody else has already
consumed that output. This output has already been
consumed by another transaction. You can't prevent that, but in that
case, your transaction would simply fail without you having to pay any fees. But if all the inputs are still there,
That your transaction expects, then you can be sure that the transaction
will be validated and that it will have the effect that you predicted
when you ran it in your wallet. And this is definitely not the case
in Ethereum, in the time between you constructing the transaction and it being
incorporated into the blockchain, a lot of stuff can happen concurrently and
that's unpredictable, and that can have unpredictable effects on what will happen
when your script eventually executes. So that means in Ethereum, it's
obvious possible that you have to pay gas fees for a transaction. Although the transaction eventually
fails with an error, and that is guaranteed not to happen in, Cardano. In addition to that, it's also easier to
analyze a Plutus script and to, check.

Or even proof that it is secure because
you don't have to consider the whole state of the blockchain, which is unknowable. You can concentrate on this context that
just consists of the spending transaction. So you have a much more limited scope
and that makes it much easier to, understand what a script is actually
doing and what can possibly happen or what could possibly go wrong. So this is it. That's the Extended UTXO
Model that Plutus uses. So to recapitulate in extending the
normal UTXO Model, you replace public key addresses from the normal UTXO
Model with scripts, Plutus scripts, and instead of legitimizing the consumption
of new UTXO by digital signatures. As in the simple UTXO Model
arbitrary data it's called Redeemer is used on the input side. And we also add arbitrary
custom data on the output side.

And the script has context and it
runs sees the spending transaction the transaction one in this example. So given the Redeemer and the datum and
the transaction with its other inputs and outputs, this script can run arbitrary
logic to decide whether it's okay for this transaction to consume the output or not. And that is how Plutus works. And that is of course not tied to
a specific programming language. I mean, what we have is Plutus, which
is based on Haskell, but in principle, you could use the same concept, the
same UTXO model with a completely different programming language. And we also plan to write compilers
from other programming languages to Plutus script which is sort of the
assembly language underlining Plutus. So this, in Extended UTXO Model
is different from the specific programming language we use. In this course, we will use Plutus
obviously, but the understanding the UTXO model, it's independently
valid from understanding Plutus or learning the Plutus syntax. When I planned this lecture and
the course, I first thought I, I should do it the traditional
way of starting very simple.

And maybe give a crash introduction
into a Haskell and then do some simple Plutus contracts and
slowly add more complicated stuff. But then I decided it would be more
interesting, especially for the first lecture to showcase a more interesting
contract and just demonstrate what Plutus can do, and then use that
to look at certain concepts in more detail, and explain them in more detail. So the code for this course will
be in this GitHub repository. It said input output HK and
then Plutus pioneer program. And here I have a clone of that
repository and I go into the code, week one folder and do a cabal build. In my case everything is up to date
already because I built it before. But when you clone the repository and do
it for the first time, it will probably take a couple of minutes because a lot of
Plutus libraries will have to be built. Let's have a look, a quick
look at the code so that's in source week one english auction.

And, I don't expect you to understand any
of that, I just want to show you that it's reasonably long contract, but not too bad. So let's see. Right. So it has a 368 lines. And we see it builds so that's good. So it compiles. Now I want to take this code and run
it on the playground, but I don't want to use the, official playground
that's public on the web, because that is a bit outdated by now. That's from end of January and
Plutus has evolved since then. So I want to start a local playground
server and try this contract on there. And for that, it's important that
I use the correct version that this repository is also using. So we can check that we look into the
cabal project file uh, here is the reference to the Plutus repository. And here we see this tag. So, now I'm in a local clone of the Plutus
repository and I can check with git log that this take here that I have checked
out the right commit corresponding to the one specified in my cabal project file.

So now in order to start the
playground server, I need a nix shell. So I'll start nix shell, and
it takes a bit to set that up. And actually I need a second one. So I have another tab here in
the same repository and I'll start nix shell there as well. Let's switch back to the first tab. Okay. There's my nix shell. Now I changed into the Plutus
playground client folder. And there I know in this nix shell
have the Plutus playground server command available, which will start the
playground server as the name suggests. So this should be running now
and it's running on port 8080. Now we switched to the other tab,
there also changed into this plutus playground client folder and do
npm run start there to start the client that talks to the server. Now the client is running and
that is running at localhost 8009. Now I open my browser and go
to this address localhost 8009.

And if all goes well then the
editor, the code editor should open. Um, there can be some example contract
there, which we can delete and now we can just copy paste the code from, the
Plutus pioneer program into this editor. So I just opened this in a text
editor and copy everything. And paste it here in the editor. There's one thing we have to do in order
for it to compile in my Plutus pioneer project, I edit a proper Haskell module
header, but the playground doesn't expect that it expects code without the header,
because it adds its own wrapper around it to, actually run it in the playground.

So I delete this module header, then
I press compile and have to wait a bit and it should compile because I made
sure that I'm not running it against the exact same version of Plutus that
I also did the cabal build against. Now we can switch to the simulate tab. There we have simulated wallets
and can script, invocations of the contract and see what happens. So by default, they are two
wallets, but to make it more interesting I add a third one. And this example script I've
wrote is an auction script.

And the idea is that somebody
can auction a non fungible token. So we have a simulated one here T
but, the way it's set up by default is that every wallet would get 10
Lovelace and 10 coins of this token. And then of course there
would be 30 coins in total. So it wouldn't be non fungible to
simulate a non fungible token, I give the first wallet exactly one
coin and the other too zero of this. So now it's really basically non
fungibility only exists exactly once. And the idea is to use this contract. So that wallet one can have
an auction, run an auction for this non fungible token. Okay. And in my contract, I defined three
endpoints start bid and close.

So these three come from this
contract, the pay to wallet is always there by default in the
playground to do a simple transfer of Lovelace from one wallet to another. So we can now add actions. And see later than when we press evaluate
how that gets evaluated in the simulated blockchain that the playground provides. So we set up the auction with start,
and then we can enter parameters.

So the first parameter get slot
is the deadline of the auction. So the idea is that bidding only
happens until a specific specified deadline until a specified slot. And after that the auction is over. So for example, I can put slot 20 here. The second parameter is the minimal bid. So probably, I mean, at least in a real
scenario the, the seller of the token once at least a certain amount of Lovelace. And if nobody's willing to bid that
minimum amount, then the auction just fails and the seller gets his token back.

So just as an example,
let's put three here. Of course, three Lovelace is, a
very tiny amount of money, but it's just easier to, keep the number
small.To see what's going on. If they are not too many zeros in
a realistic scenario, they would put many, more zeros of course. And the next to parameters in the
start endpoint of the contract specify the token that sold. So we have to specify this token T
here and in Cardano native tokens, the token is specified by two things. The currency symbol, which we will talk
about a lot more later in this course and the token name and for some arbitrary
reasons, the currency symbol in this case is 66 and the token name is T. Right, so this will now start the
auction, then we can also insert wait actions so that nothing
happens for a couple of slots.

So that's just wait for one slot to
give it time to, to set everything up. And now bidding can start, let's say
wallet two and three, both want to bid for this token, let's say wallet two
is faster and one bids three lovelace. So wallet two invokes the bid
endpoint, this takes three parameters, the first to specify the token. So that will be the same
as here, the 66 and the T. And the third is to bid. So, we specified a minimum bid of three. So let's say that wallet two is willing
to bid to give this minimum bid so after that, let's insert another wait action. Now let wallet three also make a bid. Same parameters as before, so 66 and T and
now the bid, so obviously the bid must be higher than three for it to be successful. So let's say five. That's another wait action. And let's say that these two
bids are the only two bids are the only bids in the auction. So now we wait until slot
20 until the deadline. So now the auction is over and
now anybody can invoke the close endpoint to settle the auction.

So if it was successful, if there was
a bid at least as high as the minimum bid, then after the deadline is reached
and close as quart, the seller could, should get the bid, the highest bit
and the buyer, the person that made the highest bid should get the token. And if the auction failed because
nobody was bidding, then the seller should get his token back. So it doesn't really matter who invokes
that, but, wallet two would have no incentive to invoke the clause action. It's only wallet one and wallet three
that once something, wallet one wants the bit and wallet three wants the token. So it doesn't matter if you can, for
example, say that wallet one invokes close and this as parameter just
takes the token so the 66 and the T. So all these parameters and the endpoints
are defined and specified in the Haskell code that I briefly showed you earlier. So I'm not sure whether we need
another wait action, but we can just add one, one slot just to be safe.

Okay. And now if you're happy with this scenario
or the simulated scenario we can push the evaluate button and wait a bit. So now. The blockchain is simulated and
these, wallets are simulated and their transactions. Okay. And it seems to have worked and now
we get the simulator view where we see every transaction that happened. So it seems there were five
transactions that happened. The first one is, not one that
we specified by our actions. That's the Genesis transaction,
the very first transaction that sets everything in motion. And that distributes the
initial funds to the, wallets. So the Genesis transaction,
especially it has no inputs. So the money basically gets comes
out of thin air and we see the total available money into the system, in
the simulator system is 30 Lovelace and this one simulate non fungible token. And it, this transaction has three
outputs to the three wallets and each of the three wallets gets 10 Lovelace. And the first wallet gets the token
as we specified in the previous tab. Okay. Let's look at the first transaction. That should be the one where wallet one
sets the auction in motion by calling the start endpoint of the contract.

So this has one input and two outputs. The input is the only
UTXO the wallet one has. So even though it's two different
tokens, Lovelace and the T, they sit combined in one UTXO. And as we discussed earlier, when
I explained the UTXO Model, UTXOs always have to be consumed completely. So this whole UTXO is input to the
transaction, but then that can be changed output as is the case here. So, we didn't add any fees to our auction. So these 10 Lovelace that
wallet one has is change. So the first output is changed where
the 10 Lovelace go back to the wallet. And the second output is more
interesting and here for the first time we encounter script address. So these wallet one, wallet two, wallet
three are just ordinary public key addresses, but now the second output
of this transaction goes to a script and that script is the one I defined
in the code, the auction script. So in this example, you only have
one script, only one smart contract that handles all the scenarios to
starting the bidding and the closing.

And we see that the value at that script
output is the token, so after this transaction, the starting of the auction,
the token is locked in the script. And as we know from the introduction
to (E)UTXO there can also be datum and the actually is datum, but that
is not visible in this, display. Okay. So now the auction is set up. So let's look at the next transaction
that happened, that is when wallet two makes a bid of three ADA.

So we have this transaction and it
has two inputs, it has the script, the auction script with the token as input
and the UTXO that wallet two owns. And after what we have two outputs, the
first one is change output to wallet two. So remember wallet two wanted
to make a bid of three, so seven is change that this here. And then, you, script output
still contains the token. It is still locked in the, auction script. And it now additionally contains
this bid the three Lovelace. So this auction at this transaction
consumes this UTXO, the script UTXO and produces an output that
again goes to the auction script. And of course the code must make
sure that nothing can go wrong here. So that, for example, wallet
two contracts take the token. So the valid data, the validation
script here will make sure that this transaction only validates if there's
an output, whether token actually ends up in the script output again.

Remember in the EUTXO Model
that cardano uses, the script can see the whole transaction. So all this is visible too to the script,
so it can check that everything is well and that the token is not taking
out of the script, is put back in the output plus the bid that has been made. And now let's look at the slot three,
the next transaction, that should be where wallet three now bids five ADA. So that it's even more interesting. So the input side look similar. So the original UTXO of wallet three go
in and the UTXO lock that script with the token and the first bid the three ADA from
coming Lovelace coming from wallet two. Now the first output is the change,
which in this case is five Lovelace. The second output is
now the updated script. So the token still sits there and the
new bid the five Lovelace are there now.

And now we have a third output, we
have wallet two gets his bid back. So wallet two has now been outbid,
wallet two at a bid of three and now wallet three makes a bid of five. So by bidding five wallet three
has to pay back the original three Lovelace to the original
bidder wallet two in this example. And again, the logic in the script, the
code must make sure that all of this is handled properly so that wallet two
indeed gets the bid back and that the token is still locked in the script. And of course the code also must
check that this new bid, the five is indeed higher than the original three. Okay. And now the last transaction
is the close at slot 20 after the deadline has been reached. So let's look at that. So this only has the script, UTXO as
input with the token and the highest bid which is five in this example, and
it has two outputs so wallet one gets the five Lovelace, the highest bid.

And wallet three the bidder that
made the highest bid, gets the token and we can scroll down a
bid to see the final balances. And we see that we have
the expected result. So wallet one doesn't own
the token anymore, but has 15 Lovelace, wallet two is back to 10. It, I mean, During the bidding for a
while it only had seven, because it had made a bid of three, but it got that bid when got out bid by wallet three and
wallet three now only has five Lovelace left because it paid five to the seller,
but it's now the proud owner of the token.

We can also briefly check what
happens if something goes wrong? So for example, if wallet two
makes a bid that's too low, that's below the minimum bid and let's
say wallet three makes the same. So in this case, these two bids should
be invalid and the auction should fail. And in the end, the seller wallet
one should get the token back. So let's see. Okay. So now we see we have
only three transactions. Again, the Genesis
transaction, that's the same. The start is also the same, but now the
biddings don't happen because they are not valid because there's logic in the Haskell
or Plutus code I wrote that checks that for example, the minimum bid is respected.

And so in this case, because the
two bids were too low two ADA where the minimum bid was three, they are
not accepted into the blockchain. And then the last transaction is just
a close transaction and this is now a failed auction because there was
no bid higher than the minimum bid so it takes the script output and just
gives the token back to wallet one. So as a result we get the
same as after the Genesis. So that scenario also works, have a failed
auction that in the end, the seller gets the token back if, there was no bidder. So if we scroll down we
aslo see log messages.

And for example, here we see
bid lower than minimal bid. So that's an error message that I built
into the code that helps debugging so we see, not only that the transaction failed
but also get a reason why it failed. So there you have it, relatively complete
and relatively realistic auction written in Plutus as a Plutus smart contract. So coming briefly back to the code,
as I said before, I don't expect you to understand the code now,
but when writing a Plutus contract, it's important to realize that
there are two parts to a contract. The one part, the arguably more, the
most important part is this script that basically lives on the blockchain and that
governs which inputs can be consumed by a transaction and under what conditions.

So that has to be specified, of
course, when you write a Plutus contract, but the other part, which
is maybe equally important is that wallets have to be able to create
transactions that then will be validated. So on the one side, you have the
script that locks the UTXOs and make sure that they can only legitimately
be unlocked, but in order to actually use such a script output and, use it
as input to a transaction, the wallet must be able to create transactions
that fulfill all the conditions so that the script would be happy to allow
the transaction to consume this UTXO. So therefore they are two parts to
a Plutus contract, the one part that defines the validation that happens on the
blockchain and the other part that allows wallets to interact with this contract.

And the nice thing about Plutus is
that everything is written in Haskell and in particular the data types
can be shared amongst the two parts, the on-chain and the off-chain part. So if you briefly look at the code,
so in the beginning, for example, I define a Haskell data type that
defines an auction the address of the seller, the deadline, the minimum bid
and the token that's being auction. And you will recall that corresponds
exactly to the parameters of the start endpoint that I
showed you at the playground. So then there's some Haskell stuff,
just defining couple of data types.

And then this part here, this is
actually the logic that defines the script that lives on the chain,
the validation logic of the script. So yeah, all the conditions encoded
under which circumstances the script output can be unlocked. So this until about here, and here
actually the actual script is defined. So this auction instance is
the script, the auction script. And then from here, this
is now the wallet part. So, these three data types,
Haskell data types define the, parameters of the three endpoints. And Here are the three endpoints,
the logic of the three endpoints. So this is the logic of the start,
which constructs a transaction that starts the auction. This is the logic, the bidder endpoint
that controls how bidding works and how to construct a transaction that
can do a bid and finally, here is the logic that defines the close endpoint. The nice thing about everything being
Haskell is that the on-chain part and the off-chain part, can share code
and can reuse code, for example in the logic for the bi, at some point I have
to check that the bid is valid and in particular that, the bid is not too low.

So this is sufficient
bid function somewhere. And that uses a function min bid which
basically decides in every situation what the minimal valid bid will be. So that's defined here, up here,
but the point I'm trying to make is. This is used this, function min bid
is used, when I write the script that lives on the blockchain. But if we go down to the bid endpoint,
the min bid function is also used here because, the wallet also has to decide
whether the bid is high enough or not. It, doesn't really have to, it could
just do the bid anyway, and then the transaction would be, would fail, but
of course, it's nice if the wallet immediately checks and refuses to,
even try to create this transaction because it will fail anyway. So there are often situations like
that where logic is shared between the on-chain at the off-chain part and because
both are written in Haskell, it's very easy to, share code like this and that
also makes it much easier to keep the, on-chain and the off-chain part in sync.

Right. And, the rest is just boiler plate
that defines the endpoints here, so that, this is where the names of the
endpoints come from, start bit and close. Indeed they're just associated with,
these functions: start, bid and close. And the rest is just these last lines
are basically just for the playground in order to set up my example token. So this is this token I use as an
example, that was auction to wait. So I hope you enjoyed this walk through,
the auction contract and I excited to learn how to do things like that
or even more interesting things like that yourself during this course.

And that's the end of today's lecture. So all that remains is homework. So I've planned to give you a little
bit of homework every week so that you can practice because in learning a
programming language, it's always very important that you try it yourself. Because often, if you listen to a
lecture, even if you think you understand everything, then if you sit down and
try, just have you actually realize if there are certain things you didn't
really understand as well as you thought you did when you listened to it.

But of course we haven't
really learned anything yet. So I can't ask you to write
a simple Plutus contract. So for the first week, I would
just like to ask you to basically do what I did in this walkthrough. So clone the Plutus pioneer program
repository, get it to build with cabal build, clone the Plutus
repository, check out the right commit.

Um, get the nix shell working, start the
plutus playground server start the Plutus playground client, then copy paste the
code from the Plutus pioneer program repo into the playground and make it compile,
and then simulate some auctions scenarios. So it would be great if, all of you
could manage to get that working, because then it means that your environments
are properly set up and you're ready to take on more interesting things. So that was it for the first week. Thank you very much again, for attending
the course and talk to you next week. Thank you..

You May Also Like