Transcripts
1. Intro: The blockchain is an
amazing technology. When I started to learn solider, there was very excited about all the opportunities are all the ideas that
I had in my head. But then I started noticing that all the courses and
all the tutorials, they teach the fundamentals while they called
some smart contract. And they're just
really scheme a little bit unfair to paste
it very quickly. That makes it difficult to
learn this language unless you have some other type
of programming experience. Because of that, I decided to make this course to help
everyone who wants to start learning how to code smart contract in the
solidity language, even without any
programming experience, we're gonna go over the
business structure of a smart contract and the
tools are simply gives us. You will learn how to use the remix IDE and how to leak
through the documentation. The main roadmap consists
in all the fundamentals. At the end of this course, you will be able to understand variables and functions, arrays, mappings, conditionals, loop,
as well as an enumerator, list AND function modifiers. Then along the way,
we would also code some more practical smart
contracts to help to solidify what you've
learned during the course, we will make a simple
storage contract, a contract that allows you to
keep track and rent a car, and even a contract
that allows you to mint and send coins to
different addresses. My name is Dave, and I hope
you will enjoy this course.
2. Lesson 1 - Remix IDE & Docs: Let's start right away. Solidity is a language
you need to know if you want to become blockchain
the middle there. Now, solidities
the language that interface with the
Ethereum Virtual Machine. And that's the software that
then is going to ultimately go and interact with
the theorem blockchain. Now, we can start learning
about solidity from the documentation
they release is actually very extensive
and very useful. You can find it at docs..org. If we explore, this website has a lot of information
that we don't have to cover right now
and it's introduction. But one thing that
I want to point out is the version
that's very important. If you go down here, you can identify every
version that they release. Right now we are
selected on latest. So we are looking at the documentation for the
latest version possible, which is this 0.80.13. This one here. If we go and look at the
other versions, for example, version in four, here, we can see that it's
actually very different. It is from a few years ago. Everything is so different, there's way less information. Now this is to highlight that
it's very important to use the latest version because
they actually change syntax. So for example, syntax that
you do you are using on version eight will know work if you're trying to compile it
with a version for compiler. And we will see more
about this later. But to go and talk
more about solidity. Solidity is a
high-level language and it is taking inspiration from C Plus Plus
Python and JavaScript. So you are already familiar with these
languages is going to greatly help you because the syntax are very similar,
especially to JavaScript. Now, where do we write solidity? We actually don't
have to install anything on the computer,
which is great. There is a great website, remix.ethereum.org, that gives you all the
tools to do everything. We can write the code, we can compile it, we can deploy it to the
blockchain and we can test it. We can test it in a
similar than environment or even on a magnet. So this is the remix IDE. Here. What is an ID? Id stands for Integrated
Development Environment. And compared to
just a regular cold that it'll gives a
little bit more tools. For example, if you're already
familiar with programming, you might know other softwares
like Atom and VS Code. Atom is considered regular code editor because
you can code, yes, it gives you
a few extra things compared to a text editor. Gives your syntax highlight
and things like that. But it doesn't give
you any extra tools. For example, VS Code. Vs code gives you a virtual
terminal where you can test yourself to
runaway and remixes. Pretty much the same
thing for solidity. It has a free irregular
interface when you click on their main icon where you can notify open files and
things like that. If we're trying to
get a new file, here is already up and it
gives us an example. Here. This is a contract. Right? Now. We can cope in
this environment. We can also choose a
compiler and compile it. And here, for example, is where the versions come
into, come into play. As well as compiling it. We can deployed and tested. Now let's talk a little bit more about the versions that I
want to cover it today. Here. Every contract, every time
you start coding solidity, you will start with
these two lines. This is a comment to identify the license of this smart
contract that you are coding. So to give a little
bit of history here and why the compiler likes to have that license identifier. And top is because the blockchain is essentially
an open source environment. And having a source where your code is coming
from is very important. If you go and look for the ESP edX license
identifier on Google is going to bring you
to the website that gives you examples of all the different licenses
that you can have. When we're gonna
call it our things. In this course,
we're going to use the MIT license because it's the most open
source. You can. If we can take this code and do absolutely whatever
you like with it. The circle line that is always going to be there
is the pragma solidity. Solidity gives the compiler the version of the code
that you're using. For example, these lines
that they have here where they have leader to equal 40416 less
than 0.9 means that these contract works with
the compiler's from version 0.4.1 up to burn in 0.9. So essentially the
last possible version. We always gonna see some
free like this or for these contrasts are we going
to write during this course? I am going to type
something a little bit different than
the first version. And I'm just gonna
leave it like this, whereas says, Actually
we did eight. This format here tells the compiler that all of the
compiler version late work. But now you're saying how
do I choose the compiler? Well, Rubrics has it
already in the interface. So if we go on to
the compiler page, you will see here
that you can pick the pilot version automatically is always peaking the 0.6.6. So many times we might
want to code like this because then it
avoids this step here. But if we want to compile with a different version,
we just selected. These works with all of
the version from eight. If we pick 0.80.13 and
compile, it should work. And indeed shows up the icon that says
recompile it correctly. Now, why I was mentioning
that is important to remember which version you're using is because if we try to compile it with a compiler that is outside of this version,
then it's not gonna work. Now this is gonna be the
main environment where we are going to be
coding our contract. But the second part that is
very good about remix is that it has a section where you can deploy it
wrong transaction. This is great because it allows
you to test the Congress immediately on either a virtual
machine or on a test net, and even using
MetaMask on the test. So it's a great tool. Now, you will see how
is the buyer here. You pick the environment
up here on top. And usually the false. So this JavaScript Virtual
Machine in loans on Oberlin, JavaScript Virtual
Machine, VM means that we are trying and testing the code in a
virtual environment. These connected from testis. If we, for example, want to use our
mathematics to try, I don't know, on
the RNC be testlet. Here I have it selected
main account by away. It's just the account
that I use for testing. Issues. Show any here. If we select the
ring B test neck, you'll see I have some
eith on the test. Then if we picked environment
of injected with three, then you will see that here
shows our brain PI network. We can even use
mathematics to deploy and try and test
our transactions. In. This system is very good for
our development then is the, pretty much the only thing
that we're gonna use. Then in addition to in addition to these
couple of things online, there are so many
good resources to learn solidity as is a
relatively new language. And it's very open source. This website here to tolerance point.com is very
good at using freely, often has a very good layout of everything that all the basic syntax that you need any shows. Many examples were many
explanations as well. So really recommend too
deep for this one too. These are the article
or website here. Blog x.com, and guys
solidarity is very good. So don't be afraid
of looking out for resources and other tutorials
it will help you learn. Today, we went through the
very basics of the language is have an idea what the
language of solidity means. And we explored a little
bit remix interface we're going to use
during this course. So in the next lesson, we're going to start
basically over recording. In the next lesson, you will code your first smart contract. We are going to go
over all the variables that we are primarily
going to use, as well as an introduction
to functions. Functions are very important in solidity or use, I use a lot. I want to introduce
them early to start having a pretty good
understanding of them. See you in the next one.
3. Lesson2 - Variables & Functions: Hi and welcome back. Today is the first
actual lesson where we will start coding and writing
something in the remix ID. We'll go over variables
and functions in Solidity. Solidity, just as
any other language has many variables available. Today we're going to
explore the syntax, the different types, and I'll show you some
pretty good example. So Let's go. Okay, let's start
looking at some code. So once you open the really exciting is always going to show up with this example contract the way right
now can just close. If we go look at the regular interface here
is pretty straightforward. We can just click
here on new file. Like any other code editor
workspaces available. And I have just created
one for these course. You can, you can
either use one of the sample environment
or make your own. It's up to you. It doesn't really
make any difference. Now, here, we'll have a
little button to create a new file or we
can create reform greatly from here, new file. And we can start with a name. So in solidity, it's a common procedure to name the file with
a capital initial. For example, we're going
to name this one here, variables, variables,
those salt. So every Solidity file is
going to have the extension. By the way, in the
description of this course, you will find the link to my GitHub repository
where you will find all of the files that we're going to
write down here, which is for many more comments. Comments usually our, not, our comments are
very good practice, but you don't want
to overdo them. And in these files
that you'll find in the repository the
way overdone just because I want to
have a way to have a static file without the video that
explains many things. Once we save the file
is going to be MTN, as we mentioned yesterday. Every solidity smart contract is always going to start
with the same two lines. The nicest certainty, fire, and the solidity, the rectum. The identifier is going to be written with the
two forward selection from the two forward slashes solidity are the
characters for comments. When you want to
comment something, you always going to start it
with the two forward slash. Here we'll do the two hormones. Pdx identifier. As we mentioned yesterday, will always gonna use. In this lesson. We
always are going to use the MIT licenses is
the most often one. Then the pragma directive
is gonna come next. And as we mentioned in the
last slide, a version. Here we'll use the
keyword pragmas solidity. And as you can see, the code editor actually
gives a suggestion. So this is a very
efficient way to cope. And you can just press
Tab and it's gonna compare it out solidity. Have the version. So in this case we're
just going to use the, all the compilers
conversion eight, so we can use the character
than the little top accent. And then 0 dot eight dot 0, and end with a semicolon. Every instruction in Solidity ends with a semicolon,
just like in JavaScript. This first instruction tells the compiler that all dead
version eight should work. So we can write, for example, if you want to code this, sorry, if you want to comment
these two have a reference for later
so you don't forget, you can do the two horror slash and thereby whatever you want, whatever you put
in the comments is now gonna be executed as code. So here for example, is say tails, the
solidity version. You will have a
reminder for later. Next, it comes to the actual contract
salt the instruction in the contract encompassed in the contract keyword
will do a contract. Then after the
keyword contradict comes the name of the contract. In solidity is also a
great practice to name the contract the
same as the file. So in this case we'll just
name it capital V, variables. Variables. The two brackets here. So every time the structures are inside the two
brackets in the contract. Now let's start talking
about variables. So just says in
any other language there are many variables are the variables
can be numbers, which in the programming
world that are commonly referred
to as integers, there can be strings that are just a
collection of characters, like letters, names, but numbers can also
be used as strings. They are just not going to
be recognized as numbers. And so you're not
gonna be able to use those numbers to do
mathematical operations. There are Boolean variables. Boolean variables is
just a true or false. So you can set up a variable
to be true or false, and that can be used to maybe trigger another
instruction later on. Solidity has an actual, actually a few special variables that are a little bit more
specific to the blockchain. So it has an address variable that only accept the
address numbers. And it has by 32, which is just strings, but is convert into bytes, and it's a little
bit more efficient. We will talk more about later. Now, let's start exploring
the first cause the syntax. So how do we write a variable, the oldest bride that
variable type first, then the name equal to a
value that can be a string, a number, or whatever
the variable is above. And then the semicolon. Now in solidity, if we only type the type and
the name like this, gonna be initialized
directly to 0. So for example, if
you want to have a integer variable that starts
at 0 when the contract is, is launched or when
the instructions com, then we'll just put
it out like that. Now let's go over
the actual syntax. So if we want to make a
variable for an integer, we're going to write something
like int, the name number. Let's call this variable
number equal ten. In this case, we just created integer
variable name number, which is equal to ten. So one thing to explain
about the equal sign here. If you are not familiar
with programming languages, equal, It's not
really a new colon, this case, unequal here is
more like an association. We are associating the number ten to the variable
called number. Now, in Solidity, numbers
have different sizes. And as you might know for from general
computer architecture, data in computers
is more than bids. And so when you have an integer
like this name, just int, it means that this variable can accept numbers with a sign that can be minus or plus
up to 256 bits. Why would you want to specify
the size of the number? Well, because in
crypto and blockchain, we've worked with very big
numbers in all your work with numbers and maybe have 18
decimals and things like that. You'll want to make sure
that the variable that you use except the right size. Now, if you know the, you are going to work
with a smaller number. You don't have to
use the 256 bits. You can use a smaller one. You can create an int where there is only
eight bits and you will the syntax that you can
have increments of eight. So you could have in aid, it can have in 16, and then you will name it another number equal
to one, for example. Now one thing that I want
to explain a little bit more is you see how
I wrote the num, the name here,
another starting with the non-capital initial
and then the next word. It's with a capital letter. This is another convention
in programming. It's called camelCase,
playing camelCase typing, where you basically make separations between
different words just from the initial. So you will see most
of the variables, most of the variable name. You will see typed in
a way similar to this, where the first word
is lowercase initial, and then it goes to the
uppercase initiative. For example, is an
integer variable. Salinity can also have another integer type that is
called an unsigned integer. N is usually the one that you will see the most insulated it. And you write it, typing you and then the name, unsigned, unsigned number. Equal 50, for example. This basically tells
us that we can only use positive numbers
in this one here, for example, int
number we can call it. We could associate
it to negative 10th and it will work just fine. But the uint8, you can
only associated with positive numbers or
unsigned numbers. Then next time, when
we mentioned earlier, it will be a Boolean. Boolean is start with
the rule keyword. We can call this one a
Boolean name equal to true. When we're going to
recall these variable, for example, in a function
later on during the contract. The function knows that this value is true and
so we can use this. Have the function do something. I don't know if the
variable Boolean is true, then write something. Next variable that we
can look at his address. Addresses are very
common in solidity. S is the way to
transfer currencies. How to work with the contrast. So same syntax. Address, my address. As we mentioned, this one
only accepts addresses. We're going to put it
between the double-quotes. Let's say I want to
use, in this case, I'm just going to use
the address that I have here in my mathematical copy. Now this variable address called My address is associated to this theorem address right here. And then later on we also will, we will also see how to, for example, have the
contract pick the others automatically when it's
deployed and reuse later. Things that is, the last
variable do not want to mention right now
is the Thirty-two. Thirty-two is a
type of variable. We can just type some
bytes, equal a string. That can be here we have a regular string. Actually, I forgot to mention the regular string that we'll
talk about that after this. So here we have a strain. As we mentioned, a string is just a collection of characters. The difference is
that in this case, buys 30 to convert
these strings in bytes. And just basically for this software is a little
bit more efficient. It's usually a good practice
because every time that your code in, in solidity, more code you have an heavier the numbers are and
the characters are, costs more gas to
use my transaction. If you can make it
better, efficient way, it's good because then you will the customers
or the contract, we will use less gas. Then this is gonna be converted in bias
and you will need to have a front-end to convert
it back into string. But anyway, the last
one actually here, it's a string type. That is just a string. And we said a string is a
collection of characters. So just this can be a word or a letter or anything
with a character. Here are the main variables that you can have in solidity. And just in a little bit
after this, we will explore. Other variables are
able to now assume a, as you may see here, these variables here are
all right in the contract, they're not inside
the functions. So these variables here are
called state variables. State variable is a variable that is available to
the entire contract. We can, for example,
call these function. Calls are called these variables perma
function without having to maybe write it down again or without
having to specify it again, because it's already available
to the entire contract. If we have variables that
are inside of function, those are called
local variables. And these variables are only available
inside the function, so you will have
to be careful with where you specify
your variables right? Now in Solidity has an extra, let's say an extra
instruction for variables because variables can be looked at from inside the smart contract or from
outside the smart contract. So when we type a variable here, let's say that we want
to write on the right. So we do int second
number equal to 20. Now we can specify
if this number can be visible from
outside the contract. So by everybody or just
inside the contract. In here between the name
and type of variable. We can add another keyword. In this case, we cannot public. And public means that this variable can
be called or can be read from outside the contract where it can be an application. It can be another contract or some other type of
software can access these variable,
read the content. In this case, you
can even modify. So everyone can see and change, which isn't always ideal. To visibility. Visibility types that we can
have internal and private. Now if we make a u
that is internal. Now these internal keyword
means that this variable can only be modified by the contract n by
the right contracts. Contract is just
another contracted is inheriting the values
from this contract that I mentioned a little
bit more about that later. Internal can only be
modified by this contract. Contract. The last one that we have available for
variables is private. Misspelled it, Let's call the private. It's a little bit
see moral, internal. But this means that the private, only exclusively this contract can modify these contracts. This means that these variable cannot be
narrowed headed by another contract or product. You could, but then the other
contract cannot change it. These are called disabilities. State can be applied to
variables and functions. When we write down our variable, we can apply a
visibility state to make sure that it does
the things that we want them to do. Now. Now that we've talked
about variables and we know how to type a variable. Let's briefly talk
about functions. Might feel like we are introducing functions
a little too early but insulated it that are very
important because you basically do everything
just with the functions. I want to start going
through them soon. When we do some finalists you understand and have an
understanding of what's going on. So let's go through the syntax. So the layout of a
regular function will be starting with the type or
with the keyword function. We always started with
the keyword function, then the name of the
function, parenthesis. The parenthesis, we can
type parameter. Parameter. A parameter in a function is simply something that will pass. The function, I
always had troubles understanding this
concept in the beginning. Let's say that we want
to make a function that takes a number and
add ten to it. Somewhat can be
somewhat useless. But it gives the example. If we take, if we
want to give you a number and then add ten, we will pass the number here. Dislocation as the parameter. When you specify a
parameter and a function, is there anything
you always want to put the parameter type? Then the parameter name. For example, let's say we want to pass in a
number and we will pull you in if you want
an unsigned integer. And then the name
of the variable. In this case, the name is not extremely
important in the sense that unless we want to pass it something that
is already known, we can just call it
whatever we want. Then after the parenthesis and the parameter will
pull the visibility state. That for functions can be just variables and it can be
public, internal, private. Then we'll have the
state mutability. Functions can do things
on the blockchain. The statement
abilities specifies what the function can do. And we have, we have
different options. We can understand usability. Usability can be pure, which means that the function does not do anything
on the blockchain. It doesn't have access to it. It does not read anything
of the blockchain, does not write anything
on the blockchain. So when would you use this? We will use these in case we are just doing
something internally. For example, this function that I mentioned
already that we pass in a number and we want
to add a number to it. There will be a pure function
because it just does all the computation internally without ever touching
the blockchain. Then another mutability
state that we have is view. View means that the function read something of
the blockchain, but it doesn't change. For example, if you want
to call a function that reads variables that we wrote, we want to take a function
you can access from outside the contract and
call it and read what this, what's in this variable
and other number, then there will be a
view function because we are reading something
off the blockchain. Then after we specify
the mutability state, we can have our return keyword. Now return is used in case you want the function
to return some type, some type of value. When you use the return, actually here is returns. And when you use the return here in the header
of the function, you will have to specify the type that you
want to return. It can be want to
return an under, then you will write
in or you it. Then after here, we'll
have the brackets. And inside the
brackets we will have the actual function console is just a general layout
syntax for a function. Here. Before we type the
actual function, I noticed that I had a few
mistakes and what I wrote before here where we
wrote this train, I realize that before I
put string as a name. So it didn't, doesn't
like that because string is a type of variable, so it will recognize it. It will expect a name, but he thinks polluted
the things that you tried to write another typing, just change the name
to something else characters or something that
is not Up type of variable. And another mistake
that I noticed was that the address was
type between coats, which will not work. Because what do you tie
between quotes like this? String is not going to use
the string as an address. So what happens if you leave, leave it like this
when you try to compile it, it's going
to give you an error. There's a pretty
good example of how re-mix can help you because it identifies everybody
tells you even volts the areas for
example, in this case. It says that the string is, the type is a string and it cannot be converted
to an address. So what do you have
to do to fix this? We just remove the quote. Now, let's continue
with the function. Type. The function. We'll start with the
function keyword. We want to make a function, as we mentioned earlier, that we pass a number
through and it gives us a value of the number
plus something else. For example, we will
name it, add a number. Always do the
camelCase conversion. We are going to
pass a parameter. We want to pass a number type. We pass our view int name. In this case, given number. Here I put an underscore
in front of the name. So one of the other
conventions in solidity is to name a parameter is used in setup variable with an underscore
in front of it. You might see it is. If
you explore our contract, That's just what it means, is just a convention
to name the parameter. Then we want this
function to be public. Because we want to access this function from
outside the blockchain. Now, this mutability is going to be pure
because this function is not going to read or change anything from
the blockchain. This is just going to
take a number the way give in to another number that
the function already has. So it does everything internal. And then this function
is going to return Ru it because we want to be
to take another number back. Now the keyword here
is returns with the S. Remember, then after the
parenthesis pace in brackets, the space in brackets after the definition of the function is just not a
conviction in solidity. If you go through the
documentation is going to explain all these
things under the style. I believe it's just a
common way to do it. Now how do we tell
the function that we want to take the number
that would give, throw them. Do sampling. First of all, we can add
another variable in it. Then let's add the
full number inside the variable can
be called value. We assign it the value of ten. Now, these uint8 inside the function, some
local variable. This can only be used inside this function if you try
to call it from outside, the function is not gonna work. There's not gonna
be able to see, to give instruction
to the function. We want to take the
value of this number here and add it to whatever
number that we pass through. So how do we do that? We type the name of the variable
that we want to change, equal to and then instructions.
So what do we want to do? We want to take value, the number that would
pass through to it, plus number semicolon. This is actual operation, mathematical operation
that is gonna be done. And then how do we tell
the function that we want to have a way to see
what the result of that is. We use the keyword return. Return. What do we want to return value? So now this function, it's going to take
a number that we give ten to it and then return the
result that we can see. Once we're complete, we're
done with this variable. We can try to compile
it and test it. So now, how do we do that? We go on the
compiler page. Here. We have to decide
what compelled to use the standard compiler that issue show up if you didn't do
anything else before it is 6.6. Well, we're using
the version eight. We will have to change
to one of the version a. I'll use 8.13. And then this button
you can compile, the file, could compile. And if everything goes right, which doesn't show up
with a little green tape, but it gives us an error. So let us see what
these iterates. And it tells you
that it expected a semicolon got brackets. So can you spot
what I miss here? Yes, it was a semicolon here. Now, these will compile
or should compile. So we're trying again,
if you don't want to go on the page and click Compile variables every time you can just do Control S, which is what I usually do. Control S, it saves it a composite and as you can see this time it is the
little green tick. That means that the compiled
correctly and there were no mistake to test it. We can go on to deploy
and run transaction page. We mentioned this previous
lesson, something about this. Test it like this. We are going to use
arbitrary environment. So we can just keep the
JavaScript VM that we have here. Who's going to give you a
bunch of accounts available. So you have all these accounts
are available for you to get to the point
contracts and test them. And each account
has a 100 ether. Will do slip the
standard 1 first. And here we can depart. If we click Deploy, we can see here in the dashboard here that
there is a green tick. That means that the control
was deployed successfully to look at what we've done here. And it's gonna show what the public is going to basically show all the public functions and variables. For example, here
we can see that we have a public number, which is a function, which is our function here. And number, we have something
else that we can see. Second number, why is that? It's because here we specify
a variable that is public. So we can see what
happens when I look, when I click here, it's going to tell me what's
inside the variable. Here. You can see it's telling me that
variable is associated. We wanted to look
at our function. Let's expand this so we
have a little bit better. What does this do? We can call this function inserting a number
here, see if it works. We said that we wanted to add a number that we'd
pass to this tab. So if I add another ten, it should give us a value of 21. We call it, we call it here, it gives us 201525 and saw these very simple
and basic example of how a function could work. Then once we read this contract, testing, if we can just destroy it and it's gonna
go back, gonna go away. And we could redeploy moment quantification report
and so on to the students. One thing that I want
to highlight here, It's here in that account. Remember that when we started, we had 108 and now we
have 99.9 something. Why is that? Remember that every
time that you make a change on the blockchain, which it can be just
even read from it. It's gonna use some gas. Remember, we specify that
our function is pure, so the function
doesn't do anything on the blockchain dysfunction
should not use gas. But we called the value from these public
state variable here. That's what it
consumed over gas. So just keep that in mind. More things you colon here
higher the gas is going to be. Now before we end the lesson, I want to mention one more type of variable that I didn't mention with all the other ones. Just because there's
a little bit more complicated and confusing, birth is going to be very, very useful for many things. These variables called a struct. Struct is a type of
variable that allows you to store multiple
variables in it. That then can be
called layer from functions and other
things. It's very useful. Now how do we call distract
is just a variable, right? So there's going to be, the syntax is gonna be
like they are variables. We'll start with the
type of variable which the type is struct name. Let's say that we want
to create a struct. Inside has names and
February colors of people. We can call this name, sorry, we can call
this truck peoples. People struct. We call it people struct. Now, conventionally
name instruct the capital letter
for the whole, for the first word. Just as a reminder there. Now, we'll have the brackets
and inside the brackets, we can type the variables
that we have inside. So we said we wanted to have a struct with the names
and February colors. Those are two strings. So we'll have string name, semicolon, and then stream. Call. Semicolon. Here, we've
just created a struct. Struct allows us to hold
this information inside. Now this struct
here doesn't have any information because we
didn't pass it through. And one of the next lessons
we're going to check or rather see how to add information to the
stretch from functions. But we can initialize this trucked pre-recorded
information. The syntax to do that is starting with the
name of the stretch. So the pupils strapped. We can do it public so we can see what information
is in there. Then we'll add the name. We're doing now is just
basically keeping our variable inside the struct with the information that
we have in there. We wanted to have a name, so let's call the variable Dave. These variable is going to have, is going to be
people's strengths. So we put the name of
the struct again to tell that this is
what's in there. And then we pass the parameters
through parentheses. There are two strings. The first one is
going to be a name. The second one is going
to be a color, orange. Let's say. Then let's not forget
the semicolon. So now we have
initialized the struts. So that means that
inside the strategies are variable called day. It has associated the
string name today, even the string color to orange. We can test it and
try to deploy it. So if you try to
deploy Control S, we see that there are no errors. We did want to take. We can go back into the
deploy page and deploy it. We can see the
successful can go check. Now we have an extra natural
variable here called Dave. If we call it, is going to
show that we have a name, variable name called Dave in it, and string variable called
or a color, orange. And we can just add more information to
this tract like this. You can copy paste it. And another one, for
example, Charlie. Let's say the Charlie's
favorite color is red. Recompile it again
with Control S, We Cubans contract
here to deploy it. We check. We have Charlie. Charlie is associated
with Charlie and red. Now this is a very inefficient
way to use a strep. And in the next lesson we will see a more
efficient way to do it. In conclusion here today, we went through the different
types of variables. We went to state and
local variables. This friend visibility states. Then we also went through
function, basic function. I wanted to go over
this mostly for the syntax and just
the basics under. In the next lesson we
will go over arrays, how we can use them in
different situations.
4. Lesson 3 - Arrays: Hello and welcome to the
lesson about a race. So today we're going to
talk about what arrays are and how we can
use them in Solidity. Here we have remakes open
and we'll start with the usual two line with the license identifier
and the solidity version. I also created a new file
here called the race in case, in case you want to
type it in a new file, otherwise you can
just type it in the variable file
that we created. What are the race?
A rays are actually a very common object
in programming, and they are essentially
just a list of elements. We can use arrays to store
multiple objects in them. It can be numbers, it can be strings. And in Solidity can
even be struct, or other types of variables
that we have. In solidity. We have two different
types of arrays. The first one is called
the fixed size array. Dynamic size array. The dynamic size. So
what's the difference? The fixed size it
has declared size. So it means that it
can only contain the specified amount of elements that we declared
in the beginning. If we declared that the arrays only made
of three elements, let's say three u, and then we cannot put four in them because it's going to give you an error
can only be three. While the dynamic size means that elements can be
either as we want them, we will explore and show a function of how to
add the elements. How do we start this contract
we're going to type, we're going to write a contract
today called the arrays. Here our control is done. Now let's look at
the syntax to write a race is a variable so we can start it just like any other variable with the
type of array that we want. So let's say that
we want to have a fixed type array
that contains for you. And we will start
with the type uint8. Then the square brackets. Square brackets is kind of the universal sign or symbol for arrays or lists in
programming languages. And then inside the
square brackets we define the fixed size. So in this case we'll put four. If we wanted to have
a dynamic size, then we wouldn't put
anything in the brackets. So you went for, we're going to declare this
one here as public so we can access from it outside the
contract, will give it a name. So let's say we wanted to
put numbers and let's call it numbers, array numbers. To put some data in it, we can just do they equal square brackets and
then we put the data, let's say that we want to put
1234 separated by commas. And so here we have it. Here we have fixed
size array that has four unsigned
integers in it. Let's say that we want to
create a string array. How will we do that? We will type string
the square brackets. Then we can put inside. Let's hit it. We want to have
another fixed one, just one element in it. There will be public again
so we can access it, will give a name
string array inside. We can just have one string
inside the double-quotes, and let's say is color yellow. This one is again another
fixed size array and can only contain one element because we specified that is only one. Let's try to code
dynamic size array. We will do that. Let us do a dynamic size
array for numbers again. So we'll do U int
because it's the type. And this time I was like
I spelled it wrong. This time we're gonna
leave the brackets empty because this is
a dynamic size array, we can change will prove
with the public again, and this is dynamic. Dynamic arrays, the name. Let's put the number ten in it. But remember that I forgot
the semicolon here. But remember that because
this is a dynamic size array, we can add how many
elements we want in it. This array, like this. Is what are called a one-dimensional array
because they only have, is only one array in there. We can also create
something that are called to the arrays, or
two-dimensional arrays. And essentially those are simply an array containing
other arrays. There are some
limits in solidity. We can make arrays with the, we're calling them nesting. We're calling this next thing. So there are nested arrays. We can nest up to 15 arrays, and they all must be
in the same type. Let's say that we want to
create dynamic array of arrays. So we create a dynamic array. So this will be the first one. And then inside we
nest other arrays. And let's say that we only
put two misspell this again. This is public. Then we call it an esteem. Now, how does this work? We just declare an array. This one, this part here
we declared an array, has two arrays in it. So how can we picture this? Here is the first array, and then it has other two
inside one, comma n2. And then these two arrays
can have numbers in them because these are
all uint8, so 123123. Here we go. Here now we have a 2D array
containing two arrays. And how can we access the
information inside the right? That's a very important
topic because we need to be able to take the information
and the data from it. So arrays are what we call index-based means
that every element inside of an array
correspond to an index. Arrays in Solidity are what
they're called zero-based. Index. Zero-based then means that the count of the
elements starts from 0. So if we take this first
right here with the UN, and it has four, if we want to access
to the arrays, we are now going to
find the number one. You're looking for
the index number one, it starts from 0, so this one will be 0, this one will be one over V2,
and this one will be three. We'll see when we
deploy the contract that we want to
access this array. If we want to take
the number one, will have to type the 0. If we want to take number two will have two type
one and so on. Now we just saw how we structure
an array and how we can, we can syntax one, but how do we add things in it? Let's say that we have these. Now this one here cannot be
addled because it's fixed. But let's say we
want to add numbers to these dynamic array here, we will have to write
a function to do that. How do we do that? We wrote a function just like we were
doing the last time. And let's call the
function add number. We'd write the function,
the function keyword, the name, and then we want to
add a number to that array. So we will need to pass
a parameter in here. We're going to pass in
the function are uint8. We called number. So underscore number because underscore because we use
it inside the function even if it doesn't really have
a difference on the name. And this function is public
so we can access from outside or we can
actually add our number. In this case, we are
now going to return it because we're not going
to put the return because we don't need to
pull any number. And if you notice, we're now going to pour
any modifier state because this function actually goes and changes something
on the blockchain. So the view and the
pure wouldn't know make your work because
if you remember, pure means that the function doesn't do anything on
the blockchain at all. And view it means
that we're only read. While in this case we are
going to actually write on it. Then the two brackets here. To add elements to arrays, we use the push method. How do we use methods is that we take the name of the array. In this case the dynamic array
dot push these the syntax. And what this does is takes the parameter that
will pass through the function and pushes
it to the array. And it's just going to
basically add the number. Next. We're going to pass the
parameter that we typed, the function name,
the function header. And that's semicolon. Here. This is a very simple function to add a number to the
original number here. Now we're ready to test it. Salt, test the contract. Now we're going to
have to compile it. Let's go check. Our compiler is the
right version first, because we're writing
solidity version eight. And we can see we have the
compiler for version eight, so we can go ahead
and compile it. Here are just press control S That's a little bit quicker. Going to deploy in
transactions section. We have our JavaScript
virtual machine on account and go
ahead and deploy it. Received the transaction
was successful, the control was deployed. Now if we explored the contract, you will see we have a
whole bunch of stuff. And that's because pretty
much every variable and function that we have here
is expressed as public. So we can see all of them. Now, let's start from
the first array, the number right here. You'll see that the name's gonna be a little bit more mixed in. I think it's just because they display them in
alphabetical order, but that doesn't really
make a difference. Let's start from the
numbers array here, which is going to
be this one here. We said that to
extract an element, we can use an index
since the arrays are indexed place and they are based on zeros starting from 0. So if we want to
extract the two here, for example, what index we're going to have to type
here will start from 01. So if we type one in numbers
array and we call that, then it's gonna show us right
here on extract the form. We're going to have
to extract 0123. If we call it. Here, we have the form.
What happens if we try to call for an
industry doesn't exist. For example, this one is fixed. A fixed size array with
only four elements. So what if we tried to
call for a fifth element? Type the four here, here's gonna give an error. It will say that the
call was not successful. Here it's not going to show anything because this one here
is from the previous call. The same thing works
for the other race. For example, the
string array here. It only has one element. So if we go look
for the next zeros, is going to show that
we have yellow in there and our dynamic array. Same thing as only one element. So if we go for 0, it's gonna have the ten. Now, the nested array
is a little bit more interesting because remember these are nesting nested array. So we have arrays into an array. And here you can see that it
is calling for two inputs, is the same principle with
the zero-based index, where the first input, it's asking basically for which
array we are looking for, if it's this one or this one. The second input is asking for the position of the actual
element that we want to see. In this case, let's
say that we want to extract the three here. We want destructive
from the first array. There will be in position 0. Then we want to extract
the third element. So 012, b two here. If we call it, here we go. We have extracted the three. And the same thing can be
done with the Ottoman. If you want to extract the file. We'll pass one here because it's the second array and 01 call. And we'll have the five. That's how you will explore
nesting nested arrays. You can see how it can become pretty complicated issue can have a maximum of
15 arrays in there, and then you have to
start calling him for 15 arrays inside other arrays. It can refer to the complicated. But let's explore and
look at our function. That's if you work. So
we design dysfunction to add an element to
the dynamic array. Let's look at here. What is a superstar happen? We're supposed to put a number
here, major transaction, and then we should be able to recall for another
number out of here, let's say that we
want to add 100. We made the transaction, were considered as
transaction was successful. Now in theory, we should have two elements in
this dynamic array. So how do we call for
lemon and number two, we're gonna have to go
and call for one here. And here from instead of ten, it should show 100, which thus, we can just keep
adding numbers as we please. Let us say 60. And then
we'll call to and saw. Now we have an, a dynamic array that has
multiple elements in it. But how do we know
how many elements? Because for this
one only has three. If we throw, if we try
to call for another one, not gonna work because it says it doesn't really
say anything actually, but it's because we don't have more than three
numbers right now. So how do we know the
length of the array? How many elements we can
write a function for that. So let's go back into the editor and let's
write another function. We can run a function
called count elements. Will count how many
elements are in the array. In this function, for example, we don't have to pass
anything because we are not trying to add elements
or anything like that. We're just trying to see how
many elements are in there. We will have public visibility because we want to access to it. Since we're not writing things, we're just reading from
it is going to be viewed. We want to receive
number back a result. So in this case it's
gonna be returns and it's going to return
a uint8. All right. Now, there is another method. We saw the push method to
add elements to an array. We can have another method to see how many
elements are in there, and that's called
the length element. The function is
also very simple. We can just make
this function that return the name of the array. So the dynamic dot length, remember dot is how
you access the methods and the semicolon
access methods, you will put the
name of the variable that you want to
access dot the method. And then we can
compile it so we can destroy these contract
controllers to compile it. And you'll see that it
works as an NADH here I want to show you something about the solidity in the
room mics idea. We said that this function only only reads from
the blockchain, so we don't need to write anything and we
can put it in view. But what happens if we don't? What happens if we
don't put View? We tried to compile it. It's going to compile it anyway, you'll see that it doesn't
give you a fatal error. The icon is orange. Basically means compiled
with a warning, say compile compilation finished
successful with warning. Remix gives you basically
suggestions about your code. For example, in this case, is able to understand
what the function does and how it
can be restricted. For example, the warning says Warning function
statement stability can be restricted to view because it understands
that these function is not writing to the
blockchain was reading. It tells you, hey, why
aren't you put it as view? And it just makes it
a little bit cleaner. Let's continue here
with the test. We are ready to deploy
now is already compiled. We're ready to deploy as deploy. And here we have these
one here now is to reset. The contract is reset
to the beginning. In the dynamic array we
only have one number. If we do count elements, gonna show one
because it says, Hey, there is only one
element in there. Let's add, add a bunch of them. Let's say we add 40. Then we add two. And we add 1 thousand. Now, we didn't keep track of how many elements are in there
or we simply don't know. We can call the function
count elements. And it doesn't look,
there are five elements. And let's say you want to
know what is the fourth one? The fourth one will be 0123. So now you can go on the dynamic array and call the element in
position number three. And this is going to take
the data element is 89. If you call position for the
element is 1000 and so on. So this is a situation that can be useful when you
have an array with many elements and
you simply want to understand which value is at a specific index.
I don't know. You'll have an array
of addresses and you know that address in the
index 25 has to do something. And then you can go and
take that index and recall the number for
the others in that case. Here was a quick
summary about arrays and how we can ride them and
how we can make them work. Next lesson is going
to be about mappings. Mappings are very, very
important element or variable in solidity because it allows us to associate values together. It's a very important lesson. See you next time.
5. Lesson 4 - Mappings: Hi and welcome back
to the basics. Today we're going to
explore mappings. Mapping is a very
important datatype in solidity and it's actually
similar to a database. In a sense, mappings are
made of qi to value. There's so you will have a key with a number associated
to a specific value. If you're thinking there
will be similar to arrays, is not quite because
as we remember, arrays start from 00 index
space while mappings or not, they started from one just
like it could be a database, the SQL, they start from one. In a way you can
see as a database, but it's on the blockchain. Looking at the basic syntax, how you will hire, we'll
call them mapping. You will start with
a keyword mapping. Then mappings parameters
are inside parenthesis. And we said that we have
a key associated to value will have to specify
what VIA what variables, what type of variables
we want to have. So let's say that we want to associate number to a string. So we will have u int
that is a number. Then the equal and bigger than. That is. It makes a narrow in this case. And the second data type, sorry, variable type
that is associated to. Then we'll need to have the visibility
state and the name. So in this case we can just
call it example semicolon. So this will be
the basic syntax. And now we can start our contract and we will call that a little
bit more examples. The contract restarts as usual
with the keyword contract. We'd call it mappings. Here we go. Now, let's put
them on wrapping up mapping. In this case, we will just use it doesn't make it the
same as the example, your Int associated to a string. But what we want to
do is that we want to associate a number, data number to a color. Let's say that we
want to have colors. You are planning to
make an app that describes and lists the player
choose different colors. So you'll want to put
it through a mapping. We can call it colors. Here we have the mapping. The mapping, obviously it's empty because we didn't
put anything in it. There are different
ways to code data, data into our mapping. One way is a special function that we haven't seen so far. It's called the
constructor function. You can write it just with
the keyword constructor, the parenthesis,
and the brackets. So what is a
constructor function? Call is defined as a special
function because it only runs once at the start of the contract when
the conduct is diploid. And so we can use
it to, for example, associated the address that deploys the contract
as the owner. Or we can use it to place
some standard data in it. And in this case, we can use it to fill up the map in one when
the contract is deployed. From here. How do we fill up a mapping? In this case, the
mapping names, colors. And mappings also are indexed, but they just don't
start from 0. So how do we define the different
key-value pairs will put the name of the mapping, the value of the key equal to the value that
is associated with. Right now we want
to have a uint8, the one associated with a color, registering that in our
case wants to be a color. Let's hit a report. Three of them will do callers. The second one, the second colors, color, sorry, the
third color, green. By convention, we want to use
double quotes for strings. This is a simple
constructor function. Then when we deploy
the contract, gonna fill up the
mapping automatically. Less try it out and
see how it works. We can compile it
with Control S. I always forget to change. The compiler virtual visits. So I'll put the last compiler
version, recompile it. It doesn't give any error. And let's go into the
course successfully. So let's, let's see
how this looks. You will see here we have our mapping called colors and we can see it
because it's public. Any receives a uint8. So let's say that
we want to recall what value is associated
to the key number two, then we'll type
two would call it. I will have yellow. We call number one,
will have read. And if we call three,
will have green. These are very, very nice way to associate
different datatypes. Right now replaced or you into
associated with a string. But we can place
string or strings, or we can place addresses
were numbers and strings. And we'll see a few of these options later during
the, during this lesson. Now, this is one way. This is one way to initialize
or fill up a mapping, but we can run a
function for it, can run a function for anything. Let's write a function that
allows us to add values, key-value pairs to the mapping. We'll start with function. We'll call it at color. In this case, we'll have to
pass a few parameters, right? We have two parameters
to pass because we want to add a key and a value. The parameters will be a uint8, though we can called index
because this will be the index of the
mapping a string. Now, this is the first
time that we see how to pass a string
through a function. Whenever we pass strings, will have to tell the function what type of memory we use. When we type memory, it means that the parameter
is going to be stored only during the calling of the function and it's
not permanently, permanently stored
on the blockchain. And this is the preferred way
because it saves gas phase. And then we'll just type the
name of the variable color. In dysfunction will pass an index number that is
going to go in this part here of the mapping and strained with a color that is gonna go on this
part of the mapping. We can make the function public. We want to call it from
outside of the contract. The principle is exactly
the same that we use here. We will type the
name of the mapping, in this case the index. Instead of hard-coding
manually a number we'll type, we'll pass in the
variable index, and it will be associated with whatever string that
we pass through. Now we can, we can combine it, Control S, compiled
correctly, that's free. Deploy it. We should have a function
available as well. Here it is. Let's see, We call the
number three again. It shows up as green. Let's say we want to add
a fourth one where we can E14 comma and then we want
to have orange instead. Then we call the
function at column. It was processed it correctly. So now if we call number four, here we have orange. And well, in this case it's just a string or we can write
really wherever we want. If I type Apple
is still going to pass the airport because
it's just a string. An interesting function
is that we can basically override the
previous contents. So let's say I
don't want to have read the number one anymore. But number one I
want to have purple. Number one, purple. That process. Now if I go look up what number one is and
how it's purple. So this is a more dynamic way to construct mappings because we can pass functions
through them right? Now. These are new way to explain it. Now let's do something
a little bit more elaborate with
mappings used to have. Another way. The interesting thing and why
it makes it so powerful is that we can associate mappings with pretty
much any variable. So we can make a mapping with
key associated to a struct. And inside the struct we can
have multiple variables. So let's say that we
are making a game, our game the works
on the blockchain where players can have cars to play with race. So let's start writing down a struct that is going to keep, going to keep track of
what cars each player has. We can have a struct name. Car will have two string
variables inside the struct, we'll have a
variable name maker, wherever we can save
the brand of the car. Austrian with the
model, the car. Though we have here we
have our strengths. So now we can, we can create a mapping
that associates player with a car. Let's say. Let's create a function. First. We'll create a mapping. Will make a mapping. For now, let's keep it simpler. We just associate number to the structure just
like we did before. We'll have a uint8. They'd gauze associated with, in this case, the
struct car like this. And then it will be public. And renaming cars. What do we do here? We are just coding that
this database that we can have is gonna have a number as an index and the
struct as a value. So whenever we call this index, these two variables
are gonna show up. Obviously now we have to make
a function to this course, to the struct enema. Now, we can call it ADKAR. Will have to pass three
parameters this time, because we will have
to pass the uint8 for the index and the two parameter from the for the struct itself. So the first one of BUN, and we can call it index again because is a good
mnemonics for us. Then we'll pass a two strings. Remember the string is mammary. We can call it underscore maker. Then we'll pass the
second string memory. Underscore model. This one is gonna be a
public function as well. Same principle of
the regular mapping. We're not gonna call
it course this time. It's the mapping this
time is named cars. Let me scroll down a little bit. Just named cars. We call out the mapping
cars where we're going to associate the index. Here. We'll have to build the struct. Struct. The structural member is
name car with a capital C. Will pass the
two-variable Maker model. Now we have made were
completed the function to fill up this mapping. Let's compile it and
test it. Deploy it. Here. Now we have the other
mapping with the ADKAR. These mapping here is empty. We didn't put
anything inside yet. If we call it cars. If recall something in cars,
not going to show anything, it just says that
there is a string, a maker in a stream name model, but there is nothing
associated with it. Let's add, gonna extend this so it makes it
a little bit easier. So let's say that the
index number one, we have a bin WWW, we'll add Albion W, and the model is three-thirds. We start transaction
and it was successful. So now if we try to, we try to read the first
position in the mapping cars, going to show that we
have our BMW and 330. Then we can add to
the Lamborghini. Transaction and number
two, and if we check it. So this is an example
of how you could use mappings to transfer or keep
track of multiple data. Now let's check something
interesting here. Obviously, on the blockchain we work with wallet addresses. Why not create a mapping? We can always use
it for the car, let's say for the cars game, where we associate instead of just an index that
we called manually, we associate an address. So we can make that we associate IP address of
whoever calls the function. To fill out warm, make a model of cars they have will have to create
another mapping for this, because we are going to create a mapping of another mapping is sort of like
an ester mapping. Let's have the mapping where the first type of variable
is going to be an address. Instead. The key is going to be an address and the values are gonna
be another mapping. The mapping is going to
be made of the struct, basically that we created. The struct is going
to have the uint8. This second mapping is going
to have inside the UN. And the car's going to
be a public mapping. We can call it player cars. Here too will have to make a function to this information. It's gonna be very
similar to the R1. We can call it a player car. The layer car. In this case, we pass again
only three parameters. We can actually just copy from here because we're
gonna be the same. Because the address
is gonna be taken automatically from
the transaction. And I'll show you in a
second how to do that. The public as well. Now how do we take the address? There is a simple
command in solidity. Will have, we want to fill up the players,
player cars mapping. So the index on this side here, the address is
going to be m as G. Sender is a new keyword
that we are seeing now, MSG center stands
for Message Center, and it basically
takes the address from the wallet that calls
a function and stores it. In this case, what we
do is that we take the address and put it here in this first
side of the mapping. Then on this other side, because we are creating
an atom mapping in it, we'll have the index. The other mapping. On this side we'll
have the struct car. Inside the car, we have
the maker, the module. Here we go. We can compile it. It worked the point of contract. Now the point here is going
to show a few more things. Will have a player cars
mapping down here. I'm not play your car. The player car has three variables because we
want to add an index here. I just started the
spot number one. We're going to add up in
W again three-thirds. If we make the transaction, we'll see that it went
through correctly. Now, because we call
these transaction, these first spot in the mapping with the BMW 330 is associated
to our address. If I go back up here and we take these datas that
we use, if we copy it, paste it here and
the player car, we can the index as well. We call it, shows that
we have been W3 30. Now, we could make it just
associated with the address. I just wanted to in this case, I just wanted to
show how we could put a mapping in
sign-on and mapping. But to make it a little
bit more functional, we could just use the address without
using the other mapping. Remember the message sender is a very important quality
because we're gonna use it a lot to associate
addresses with data. For example, if we take a matter address and tried
to pass a year, when we call it, nothing
shows up because there is nothing associated
to this address. Here are mappings. I would recommend to go read
some of the documentation in solidity about mappings because these are
a very powerful, very powerful system that
we're going to use a lot. Next lessons, we're going to go through if statement
conditionals and loops. And so these are
going to wrap up a little bit of the basic. And then after that, we're going to start
writing some smart contract that actually do something a
little bit more practical.
6. Lesson 5 - Conditionals & Loops: Hi and welcome to the lesson about conditionals and loops. Conditional statements and loops are a very important part and the bulk of making decisions and make automations
through code. So what are conditionals? Conditionals handled decisions. So basically a
conditional statement will return a true or false. And then based on
the value of return, we can trigger some other
type of instruction. Let's say that we want to
check that an address of another sign a contract is the owner of the contract before we trigger a
specific function, or in a more simpler
and abstract way. Let's say we have a variable and we want to check that the variable is bigger
than another one. For example, when you want to send coins to another address, while we will have to check that the balance is bigger than
the requested amount. So in that case then, if you have enough balance and you can trigger the
function and send coins. Let's check how we
do conditionals. In Solidity, conditionals are simply the if and
else statement. So just the regular syntax would be if some
conditions are met, then trigger something else. If they're not met,
trigger something else. Let's create a contract. Though we can call conditionals. Let's write it the same or tried the same
name on the file. Conditionals. We wrote a function in it. So let's say we want to have a function that passes a number and checks if this number is bigger or smaller than
a specific value. If he's bigger, returns true, and if it's smaller
returns false. It could be a very simple, It's a very simple function just to see how the
statement can work. We've make a function, we can call it big number. Big number. And we said we wanted
to pass a number in it so we can check it against a preset, another preset value. So it will be a uint8. And we can call it
number this function. We want to have it public because we want to access to it. This function is going
to do everything inside the function itself so
we can write it as pure. And we're going to
return something. We'll type returns. Now usually we return up to
now we just return a UN, today we're going to return a different value
because we said that conditional statements return
a true or false value. And if you remember from the, one of the first lessons, true and false
values are Booleans. He's going to return a bool. Going to return a bool variable. How do we write the code? We will start with
the keyword if. And then in the parenthesis we're going to have
the conditions. Now we want to check that
the parameter that we pass is the parameter that we pass is smaller or bigger
compared to a number. So let's say that
we want to check if the number that we pass
is bigger than five. This is just an arbitrary
number that we said. Now as an example, then we have the brackets. After the if statement. And in the brackets, we're going to type the
instructions that are going to be executed if this
condition is met, let's say the way pass
a number that is ten, the function is going to check, is ten bigger than five? Yes, and then return something. In this case, we said we
return a bool variable, we're simply going
to return true. Else is a second keyword that indicates what is
going to be a return in case the condition is
not met brackets and inside the brackets
we will return false. So what this function does, again, we pass a
parameter in it. We check if the parameter
is bigger than five, if it's true, is going to return true and it's false, it's
going to return false. And then after this, based on what we get back, we could trigger something else. For example, the number. If this function
returns true, then Call another function
or add some other data. Let's test it out.
We can compile it. Control S is going
to give me an error because I didn't change
the compiler, knew it. Let's make sure that we put
the version eight compiler. We can compile. It. Looks
like I forgot something else. Let's read through the
air or usually forget. I work a lot in Python. And Python doesn't
really use semi-colons at the end of the instruction. So I always forget,
let's try again. Now this time
compiles correctly. Let's deployed will
have on the eyes new address with deployed,
deployed successfully. And let's check what's
in the contract. Here we have a function name, big number, and accept a uint8. So if we put four, which is smaller than five, we should return false,
which indeed does. If we put seven, it
will return true. So these are very
abstract and simple way to see how these
conditionals work. But that's really just the
basic conditional statements. Now, let's talk about loops. Loops are a very important part because they allow
you to basically iterate through multiple
data all at once. And then you can combine it
with conditional statements, like if to trigger
some instructions. So let's try to do this. We want to create a
function that reads an array and count how many elements are
in it in that array. So how would we do that? We will have to start
typing an array. How do we replace the array? We type the type
of array, uint8. It's going to be
dynamic array, public. Let's call it values. We can play some values in it. Or you could just
write a function that first devalue like we made
in the previous lesson, and then maybe
counts through them. Let's just write some values and we write ten numbers in it. Now we want to have a function
that iterates through these numbers and
through these elements and count how many of
them are in there. Let us do that. We'll write a function
here that we can called numbers, count elements. This function is not gonna take any parameter because it's just a function
that does something without the, without
us inputted. Gonna be public because we
want to, we want to access it. And this one does something
on the blockchain. This one reads off
the blockchain because this array is on
the blockchain, right? This one is going to
be a view function. It's gonna return you int. Because we want to loop and
iterate through this array, count how many elements in it. And then we want to
get the number back, is going to give us back. Now this function has to
start with a variable. They keep trucks of the loops. Or rather the keep track of how of the items in the array. So this is called, this is defined usually as a count variable and it's
going to be a number. So it's gonna be a uint8. Then we can call count. We can just leave it
like this because when he starts is
initialized to 0, or you could write
count equal to 0, but we can just initialize it like this so we
see how this works. Then we have to lie
to write the loop. In this case, we're
going to use a for-loop. Four-loop basically follows
the instructions that we give and loop through how
many times we want. How we syntax that we'll
put the parentheses here. And we had to tell the, we have to tell the
loop where to start. Have a uint8. We can call AI that
could stand for index, but remember that these
numbers are arbitrary. You can write, you can call
them however you want. It will start at I equals 0. This means, Hey, start the
count of your loops from 0. And then we want to write some
sort of condition on here. Say, Hey, keep going
until something happens. In this case, we're
going to keep going until the index
of the account. The loop matches how many
elements are in the array. For this, we use a
method on the array. That is the array dot. Length. Length basically returns how
many items are in there. If we do less than
values, dot length. Then this means keep going until the index of the for loop matches how many
items are in the array. Then the point after that, after each loop will do
I plus, plus I plus, plus means at the end
of each loop adds one, add one to this count, will go through these
elements and then we add one, and then we go through
these elements and add one until we match the length. These I could also be
I equal I plus one. That's what the plus plus means. It basically means add one
to the previous count. But we can write it like this. It looks a little
bit more efficient. We'll have the
parentheses or brackets. And this is the
instruction that tells how the Loeb should work
inside this structure here. But then inside the brackets, we'll say what it does each
time it loops through. What do we want to do? We want to count how many, so we want to do that. Each time we lope throat, we add one to the count here so we can keep track of how
many elements are in there. How is that going to work? We're going to do I'm sorry. We're just going to do count. Plus, plus means add one
to whatever it is income. So if count now is
equal to three, while after the next top is
going to be four and so on. And then outside the
brackets we will return the value of count. So this means once
the loop is done, return the count was forgetting
a semicolon to, alright, let's compiler or Control S
and see if we can test it, will destroy this contract
we were deployed. And now we have a
few more elements. Here we have values, which is the array that
we, that we created. Remember how we can use
these to access the array. So let's say that we want to see one number is in position 5012345 should be six. If we put position
five, it gives us six. But now we don't know how
many elements are in there. How do we check it? We wrote a function for
that we do count element. And the loop is going
to tell us, Hey, there are ten elements in there. It's going to loop
through each one of them and keep track of it. Now if we add a few of them, redeploy the contract
and tested again. Now we have 12. There is a very simple for-loop to keep track of something. Now, let's combine a for-loop with the conditional statement. Let's say that we
still have this array, but we want to count how many of these numbers are bigger
than five, for example. Then we will run a function that combines the two of them. How do we do that? We're write the function. We can call it. Let's just call it how many. Call it how many? This function doesn't a
nozzle neither again, any parameter because it's just going to do
everything internally. It's public function, it's view because we are going
to access the array. And it's going to
return a uint8 as well. Because we want to return how many numbers are
bigger than five? You will need to define a
couple more variables again. Here. We are trying to
count something. We'll have to use another account variable
just like we did before your event and
we call it count again. And just as before, it's
going to start from 0. Then we can write the
loop, the for loop. It's gonna be pretty
much the same as before. Because we're still going to loop through all
the values in there. So we can just
copy this previous for loop that we wrote
and paste it in here. Now, we can do it in
a couple of ways. Toward the conditional
statement. We could simply take
the value of I, compare it to a hard-coded,
hard-coded condition. So we could do if, well, we'll have to
extract the content of i. The conjugal view will be what's in the
index of the array. So value, I will do so
if what's in the array, it's bigger than five. Well then do something. What do we do? We add a number here to count. Else is not gonna do anything in this case because we don't
really need to do anything else in case the value
is not bigger than five. But we are still going
to return a uint8. So we want to return
after the loop is done, we want to return the count. Not forget those here to. This function is going to
loop through the array. And if the value that reads from the array is bigger than five, is going to add it to count. So in this case, how many numbers are
bigger than 51234, 567 numbers are
bigger than five. When we call this function, we should get seven. As a result. Let's try to compile
it, see if it goes. It doesn't. What did I do here? I misspelled
the name of the array C. I typed value. Why the name of
the array values? Let's compile it again
with controllers. This time it worked. We can apply it. Let's call the function of how many numbers are
bigger than five, and here we get seven. Our conditional works. We could do it in another way because here we have
already a function, we're already up here. We already wrote a function that checks if a number
is bigger than five. So how could we use this function instead of
hard-coding it like this? Well, inside the if statement, the values, we can just pass
it through the function. The function is called
the big number. Then we just pass the value of, we just pass the value of the element in the array through
the function big number, which has already gone and check if the number
is bigger than five. If recompile it discharges
and already deployed. Let's check how many and
instead gives us seven. This is a little bit better way to do it because we could then change this function to
check however you want. Let's hit every instead of five, we want to check numbers
that are bigger than three for recompile
it and redeploy it. Then we have a bigger number because now we're checking if numbers are bigger than
three instead. Very good. Okay, So let's continue. And I introduced the last loop that I want to mention today. Before we go, I just
wanted to mention that these explanations and
I'm making are very, I know they feel very
slow, very dumbed down, but I just want to make
sure that I explained the logic of how these
parts work step-by-step. And just in case
you're following. Not familiar with this
consequent already. Programming some
other languages. These concepts are
very, very opposite, especially the for-loop structure
like this issue code in JavaScript is pretty much
the same, but there's one. I'll make sure that I cover everything step-by-step
so you'll be able to understand better when you're actually
want to use those. Now let's talk about
the while loop. So the difference
between the for loop and while loop is that
on the while loop, we just continue the loop all the way until a
specific condition is met. Let's, let's show
an example of that. We write a function that
loops until a number. Is rich in our variable. We write a function
that we called go-to 0. Go to 0 function. This function is not
really gonna get anything. It's going to be a
public function. Will be pure because
we're doing everything internally to the function
will return a uint8. How do we syntax of while loop? We'll use the keyword while and then inside
the keyword while. We don't have the instructions. Just saying this. Before
we continue with that, we will have to add a couple of variables just like
we did in the R1. So this time we can set how many times we
want the loop to go. We can just create a variable, variable U int,
though we can call it times that could stand for how many times we want to loop. And let's say that we want
the loop to go for ten times. Then we'll have
another variable. We can call how many. For example, these variables is going to keep track of how
many times the loop goes. I know this is not extra
practical in the real world, whereas this to show an
example of how this works. So what we want to do is
we want to loop ten times. We want this loop
to go all the way until these variable
times equals 0. We'll do if times is bigger
than 0, then keep looping. And then we can write
the instructions here. So how do we structured this? We want to say, we want to count how many
times will loop through, but we only want to count, we only want to loop all the way until this
one which is 0. What we'll do is that each
time there is a loop, we're going to add 12. How many, how many
variable will be, how many plus, plus. Because we want to count each
loop that we go through. And at the same time, we'll have to change the variable times
two times minus one. So basically what happens here is each time we loop through, we add one to this variable and retake
one from this variable. So basically this
is effectively with the counter of how
many loops will do. Then outside the loop, we will return the value of how many will basically check
how many times will. This could be just a very
simple function to print, determine how many times
we want to do something. We can do Control
S to compile it. We have a warning. Here, says this
declaration shadows on these the collision shadows
and exist in the question. It's because we are changing it. And but since it's just a
warning is still going to work, I just said, Hey, it's not a, it's not optimal, but
it's still going to work. Just an example to see
how the while loop works. What happens? We have
two variables here. Wonder says 101 does is 0. When we call this function, we should simply see
that the how many, because this is the only
one that we return, that how many variables
just equals ten? We can say it ten. Now if we want to loop 20
times, we can do that. Changed the variable times 20. Here shows how we
looped 20 times. Now to check that
this actually works, let's change the
conditions here. We always keep looping and all the way until
the time is equal to 0. But if each loop, instead of
taking one, Let's take two. This means that technically we should only loop ten times, even though we have
the 20 selected here. So let's try that. Redeployed. If we check it, we should just see ten, which we see ten. This was an example of
how to use a while loop. Very good. Now I want to show
you something more interesting than just
this abstract concept. We can delete all this stuff. I want to show you something with the conditional statement. Let's say that we
want to associate the address that
creates a contract to a variable so that we can
recall it later as the owner. And then we want to create
a function that checks if. A specific addresses
the owner or not. This can be useful in
case you are creating a smart contract to Mint coins
or a contract for a coin. And you create a main function. Obviously, you don't
want to have any person that acts as the contract to
be able to meet new coins. You will only have
the person that owns the contract or the entity denotes the country doing that. How can we do that? Well, first of all, we can use a constructor
function to associate the ulnar variable with the with the address that
creates the contract. So as we remembered, the constructor function is called that with the keyword
construction constructor. Remember the constructor
function is only run once when the
contract is created. We would ever
instructions in there. How can we pick the address of whoever calls these the
creation of the contract? Well, we have the
message sender. We can create a
variable named owner, will have to create it
outside the construction. So we'll create a
variable which is an address variable
called owner. We can make this one
public so we can access and see which
address is the owner. Then inside the construction, we simply associate
the variable owner with the Message Center. So MSG dot sender. In this case, as soon as
the contract is created, we have the variable owner field with the address that is
creating the contract. We already know which
addresses the owner. Now, let's create a
function to check if a specific other's calling
this function is the owner, will call the function, and we can call it is owner. We're not passing
anything through this because it reads
it automatically. And this one is going to be a public function so
we can access it. It's gonna be viewed
because we can see something from
the blockchain. And this one will return, again a ball variable because we want to check if something
is true or false. How do we check it? We
can use an if statement, will do if message senders. So MSU, those sender, if the others calling
this function is the same as the owner of the address
that isn't the owner. Here in this. In conditional statements, to check if something
equals something else, we use a double equal. As you remember in the first
lesson about the variables, we were saying that the equal we use for variables
doesn't really mean. Equal means more
like an association. This is this. While we want to check
if something is equal, then we use the double
equal, so many equals. Then what do we want to do if the message sender is
the same as this one here, then we return true. Else return false. In this case. Let's not forget the semicolons. In this case, if someone tried to call this function is not
the owner is going to give false and then
reconstruction of the system to allow these others
to do some funding, maybe not something else. Let's test it. Let's
try to compile it. Control S. I spelled returns
instead of returns. So many mistakes, even when you already know
how things work, you're still going to
make a lot of mistakes. Now we'll compile correctly. Let's check now here we
have all these addresses. This address here ending
in C4 is the other. So we'll use to deploy, deploy. It was deployed successfully. Let's check what's
in the contract. Now we have these two, these two things
that we can access. The first one here,
the second one here is the owner variable. Though we specified here. If you click on this one, we should be able to see the address that
created a contract. So we are creating CNES on C4. We say, okay, this is address
that owns the contract. And if I call the
function is owner, because we're using these
otters who should return true? Which return stroke? Now let's say that we access this function from a second
address, this one here. And then in CB2, the owner is
still the previous artists. And if we call the
function analysis false because we
are not the honor, these gonna be a very
useful structure that you'll see
often In functions. Two means coins or
maintain of t's or do something
that you don't want anybody to just be able to do. Deals was an introduction
to loops and conditionals. I know I might be a
little confusing. If you go in the
solidity documentation, you can find probably
more information that could explain and
even more examples. Next lesson is going to
be about enumerated list. And then after that,
we'll just focus on cognitive and
smart contracts.
7. Lesson 6 - Enumerated Lists: Hi and welcome to lesson six. Today we're gonna talk about enumerator list and
we'll see how we can use them to create
application that keep track of statuses. An enumerator list
simply restricts how many states
variable can have. In today's example, we'll
plan to create an app. They keep track of
doors or all adore. We can keep track of the
door to see if he's open or close and associated
to the blockchain. The syntax for a numerator list starts with the keyword enum, followed by the name that we want to give
to these variables. So we'll have the name, and then we will have a list of the variable conditions
or statuses. Between brackets. We'll have one status. We can blend one status and then another status and so on. And this means that the variables that we
call associated to these enumerator
list can only have these two statuses that we
have that we have selected. Let's start with the contract. Will start with the
usual contract, and we can call it. Let's start putting down the first variable which
we're going to create. As we mentioned,
an enumerator list to keep track of a door. We can create an enumerator
list called enum. Enum. We can call it dark condition. A convention is to use
the capital initial for enumerator list condition. Then between brackets,
we'll put the two statuses. So the first time we're going to have a
variable is closed, the doors close and open. The door is open. Enumerator list, or at least the declaration doesn't need the
semicolon at the end. So if you get use to put semi-colons than you might get an error which is easy to solve. Now after that, we can create variables that we
can use associated. It's enumerator
list that we made. So we'll start creating
a door variable. We can just call it, will start colony
the enumerator list, door condition, and then space and the name that we
want to use for the variable. In this case, we
can call it a door. Let me just change this. We can call it a door. We can do multiple things. We can create another
one for a window if we want to keep track of a
window as well, for example. Now, we need to have ways to associate this
door variable width. One of the conditions
that we have stated, we create a function for that. The function will start with
the usual keyword function, and we'll call it an open door. We don't have to pass any parameters through
the open door. Will make it public so we
can access it from outside. Here's how we change
the status of the door. The variable, we'll name the variable name
equal door condition, which is the name of the in order to list dot
one are the statuses. So in this case we can open. This is how this
function will modify whatever state is in
right now to open. And we can do the
same thing for having a function that
declares it as closed. So we have function
is only can call it close door public as well. And it will be the same thing, door equal dork
condition dot closed. Perfect. Now we have these two
functions that allow us to change the condition of the door or whatever variable that you are
keeping track off. Now how do we know what
the current condition is? I guess what we'll have to
create a function for that. Solidity is a lot of functions. So we can do a
function called Get condition is going to be public. This one we can write
it down as view, since it's gonna read something of the blockchain
is gonna read what? It's doing, it's gonna
return something as well. What is going to return? This one is gonna return the enumerator list is going to return the
condition here. We can put that is going to return the door condition
type of variable. The texts of the
function is simply going to return the door. Which means return
whatever condition variable is it. Right now? We don't know, we
don't have a way to know which condition
is the standard. We could do it as a constructor. So before should ask, alter the variables, we could
put a constructor function. Will do constructor. The constructor does. Remember the
constructor only runs once when the
quantity is created. And we can select in
which condition they're, the door is going to be solid. Say that as a standard. When the contrary is created, we want the door to
be considered open. I'm missing something out here. So we have to do is just declare that
the door will be open. Condition that open. These ensure that when
the contract is created, the door is already open. Let's try it out. We'll try to compile it. And let's see if the
compiler version is the correct one and
is not change it. Control-s to compile it
doesn't give any error. So that's a good sign. And we come here and Deploy, deploy their contract
successfully. And let's go check it. We have all these things
that we can access. Now, let's say we
want to check and make sure that the
door is actually open. So we, we assume that it is open because
the constructor is, let's use the Get condition
function. We can check. So we'll do Get
condition gives us one. So one is the second element inside the different statuses. So these are works a little bit like the arrays
0 index base. So the first element
is going to be 0, the second element
is going to be one. Sorry, It tells us one. So we know that the
door is open here. Now. We want to close it. So we call it the fashion
closed door went through. So in theory now the door
should be closed and if we call the condition
is closed again. We can use the Open
Door condition function to reopen the door and so on. This is a good way to keep track of something
on the blockchain. In the next few lessons where we actually going to
code some contracts. We're gonna see how we can, how we can tell the blockchain
and external applications. There's something changed
in this status here. These were sort of a
short lesson since there was only to cover
the enumerator list. In the next lesson, we're actually going to
code as my contract. I mean, we've been caught
in smart contracts so far, but we're going to code
as smart contract. They could have a potential
real utility in practice. And it's gonna be very simple. You're CA, will be only
a few lines are called. I'll see you in the next lesson.
8. Simple Storage: Hi, Welcome to the
single storage lesson. Today, we'll type a contract, an actual contract
that we could use for something and it's actually
very common contract. Then you can also find in
the solidity documentation, It's referred normally
as simple storage and we'll use it to
store and retrieve data. Let's start digging a little bit more into the
professional side and see how we can plan
and design contracts. Usually contracts are designed following some sort of steps. You will always have the
pregnant directive on top, then the contracts name. And then we will specify all
the data and the variables. And then we'll have
the functions. It's always this
type of structure. And so in the next videos, we're going to just work on
coordinate smart contracts. And we always going to use this type of
structure and layout. The first version that
we're going to create a simple storage contract is simply gonna be
storing a number. We're going to create
a contract that has a number variable, then a function to store the number and a function
to retrieve it, That's it. Then we're going to work
on the second version where we can plan to maybe make something that it
could be useful for a contact app where you will store and being able to retrieve
name and phone numbers. Let's start unless
they're following the structure that we mentioned. We said we always
gonna start with this solidity with the
primary directive. So that's what we
have here ready. And then we'll type
the contract name, the contract keyword, and then we call this
simple storage. Then the first part
of the contract, we said that is always
data in variables. Today we only have one variable and it's
gonna be a uint8. We can call, went too far. There. We can call user number, for example, because it's the number that
we want to store. Here. We don't associate
it to anything, so it's always initialized to 0 at first when the
contract is created. Then we need two functions, one to store it and
one to retrieve it. By now you can probably even typed those
functions by yourself. So we'll do the function
keyword will call it store, will have to pass a
number through it. I was going to be a UN
we can call number. Then this function has to be public because
we want to access it. And that's it because
this function is going to make changes
to the blockchain, because this is going to
change this variable here. Then the next step is
should be very simple. We just take our
variable user number and associated to whatever variable we pass Through the function number.
And that's it. While the second function is going to be the
function to retrieve it. We can create a function, we can call it retrieve. In this function we're
not passing any parameter because we're only looking to take a number that
is already there. It's public and view because we're going
to read something from the blockchain and it
also has to return stuff. Because we want to
return our uint8. And now we only have to make a return instruction and
we want to return what? The user number that is
stored in the contract. And that's it. In just these few lines, we created a functional
contract that actually follows a structure that you see in an actual
real smart contract. Something else we could see in an actual smart contract
will be comments. We will see something like this. If you go on the ether scan and pull up a contract from a cryptocurrency or
some other protocol, then you will see that It will see comments like this to a
close of functions obviously. In this case here
is a little bit superfluous because these
functions are very obvious. But you will see something
like this in a real contract. Function to store a number. Here, just a simple comment. And then another comment here says function to
retrieve the number. Now we can start
adding comments. A little bit of explanations. Obviously this is
all, this is pretty common and obvious to you. But let's say that you called this contract and then someone
else has to work on it. It's very good practice to leave some comments so they can
understand what's going on. Obviously don't start commenting absolutely everything
like put here. A u in variable. Here, associate the number. There will be a little
bit overdoing it. And you can actually
be a little bit confusing for people that
read it from outside, but some, some basic comments to understand
the logic behind the contract is very
good practice and I recommend to do
it when you can't. Now, the files that you
look there, you find them. The GitHub will have a lot of comments and that's
just because they are trying to explain
something that let's test this contract and
we can compile it. Control S is always. This time. I thought it was the
compiler know this time is one of the usual
mistakes that I make. Compiled correctly. We can kill them In previous
contribute we have from here, put deploy back. Here's our contract. We can store a number. Let's say we want to store 50. Then we retrieved the number 50. Very good. 100. We retrieve it on a 100. Very good. I also misspelled retrieve. This is the logic behind
these very simple contracts. Now, let's make this contract
gone a step further. Let's create a contract
that we could use to store information and maybe
related the users of an app. And we can maybe store
name and phone numbers. Let's try to do that. Trend to think before I go ahead and try to
think for a second, how could we do this? Based on what we've
learned before? We could use structs, can put different
variables together. We could use arrays, we could use mappings. In this contract, we're
going to use all of those. And so we can do things
in different ways. Now, let's, we're not going to need those anymore and those
functions here anymore. I'm gonna delete those
and the variable as well. Let's start over with the
second version of the contract. Remember, variables go on top. We'll start with the first one. We can have a struct. And thus destruct can be called people because
we want to have, I'm not sure why
it's highlighting that is kind of annoying, but we want to have multiple variables in the
related to customers or users. We want to store names
and phone number. The first variable will be a string that we can call name. The second variable
would be a uint8. We can call number. Here's our struct of
people already made. The second variable that we are going to need is an array. Because in this case, we can have an array where we
can store all this trucks. So we can recall all the informations
relates to everybody. We can have an array, though we can call
people or dynamics, so we can add things in. It will be public so we can
access it from outside. We can just call it, actually, I made a mistake here. This one we can just
call IT people and then the actual array we
call it People array. Just do that. Because we want to create an
array of structs, solve these variable here. This variable type
has to be a struct. It's people's front array. Then the next and last
function that I'm sorry, variable that we
need is a mapping. We can make a mapping. So we can associate
directly name two numbers. So the array and the strike
will be used to have a general overview of the
users that we can have. And the mapping is
going to be more like a database search type
of thing that where we can input a name and
retrieve the number. We'll start with the mapping. These mapping inside
is going to have a string because we
want to be able to input a name that is associated
to the number you went. We can make it public
so we can access it. Let's call it name to number. Like this. Very well. Now we have all of the
variables in the data setup. We have a struct
where we're going to have a name and a number inside. Then we'll have an array. If we're going to have
all the struct inside, then a mapping where we can, we can associate name and number and then we
can look up for them. Now let's create the function. This function is going to
be used to do two things. One to add the information into the strap and then to add
the struct into the array. We do all of it in the same, in the same function. So we'll start with function, we'll call it add person. This function is going
to take two parameters. First one is going
to be the name. So we'll have a string. Remember when we
put input strings, we have to declare the memory, so it will be strained memory
and we can call it name. The second one is
going to be a uint8. Though we can call number. This will be public. We don't need to return anything and we're not
making a pure review because we're actually
going to write stuff on the blockchain. These things. Anyway. Remember how do we add
things in the array? We use the push method, will take the array
name, people, dot push. That's the method. What are we trying to do in the people array
will push a struct. Struct is also called people. People read the name and number associated
in it, like this. In the same function, we're also going to add the
same name and number two, the struct, I'm sorry, I took the mapping and
there will be take the name of the mapping,
name to number. The first side will be the
name associated to the number. So this is actually a
contract that we could use for developing part of an app
to keep track of contexts. Let's see if it works. We can we can compile it with Control S doesn't work
or did I miss this time? Portion of this happened
because I wrote it like this. I tried to pull the type of
variable instead of name. Here. I actually have to put
people at the name here. Sorry about that. Composite the show work. And indeed it does say the ID is very useful because it helps
a lot with mistakes. Now with applied, here
we have our contract. So right now we don't
have any name and number. And it could be me
start the contract with the constructor function
if we wanted to have some default inputting there. But right now we have to add it. So I'm going to expand it
here so we can see it. Sorry, We can see it
a little bit better. We had to add the
name and a number. We'll add. And let's make an hypothesis. These are phone number. We'll start a transaction
which is complete. Then let's add another
name entirely. Charlie has another
phone number. I don't know. Don. Donor has another phone number. Now we should have three inputs or three different variables
inside the array. If we go look for the spot 0, we see that we have Dave with
the phone number, Spot Run. We have Charlie with the phone
numbers but three sorry, spot to three, non-existent
yet we have done. Now let's say that
we had the name and we want to have
the phone number. Well then we will
just type it here. Top Charlie. And it's going to retrieve
the phone number. And we retrieve
the phone number. Just like this, we create
a simple storage contract. Very nice. These conclude this part
where we were able to actually structure and
make a smart contract. In the next video, we'll do something even a
little bit more interesting. Agreed to create a contract. Where are we going to keep
track and allow to rent a car? In the video, we're going to see few extra uses for functions where we're
going to also talk about events AND
function modifiers. So I'll see you in that video.
9. Rent a Car: Hi, Welcome to the
second project video that we'll have in
this hearing today. We're going to call
it another contract that has a little bit more of a practical purpose to show everything that
we learned so far. We'll make a contradiction, for example, be used
and linked to a nap. They will verify
the availability of something. In this case. Today we're going to
pretend that we have a car. Let's pretend we have Rambo
and we want to rent it out. This contract is
going to allow us to check if the car is available and if it is
available to receive a payment for rent in it. And at that point, if the parent is received, the status of the
Gameboy is gonna be switched to a non available. This is going to be very
good contract because we can introduce a
couple of new things. First of all, we introduce the payable status or variable. That means that we can, we can specify if a variable is a variable of a function
or a function is payable. Let's go through that right now. Let's start with
the usual contract and we would call
a rental amble. Just render lumbar. Now if you remember from
the previous video where we discuss the structure
of a smart contract, we want to have
all the variables, the data, the top, solve for right now at this
moment, in this version, on the contrary, we
are going to make, we just have two variables. We will need to have an address that
receives the payment. Then we will need to have an enumerated list
so we can keep track what the status
of the car is. Let's start creating the
address for the owner. Will create an address variable. In this case, before making
it public or putting a name, we'll have to define that this variable is payable
with the payable keyword. This means that this variable
can receive payments, will make it public so
we can call it from outside and we can call
it contract owner. Contract. Now we have a
variable that defines specifically the address
that we received, the payment, the
enumerator list. And we can call the
lumbar conditions. The idea of this contributes
to rent a car, right? So we need to know if he's already rented or
if he's available. The two conditions
will be available. Rented. That's it. We're going to call these enumerator list
just lambda real have to recall the number of conditions and then
we'll give it a name. Now, how do we know who
the contract coronaries? Well, we can initialize it with a constructor just like we
did in the previous one. So we'll start with the
constructor function, that contract constructor. Constructor function
that if you remember, it just runs the first place. The first time that the
contract is random. We want to do two things
in this constructor. We want to associate
the constructor, sorry, we want to associate
the address of the address of the wallet creates the contract
to the owner variable. We want to also initialized a standard situation for
the enumerator list. We will take the contract
on our variable. We will associated to
the payable address. So now I just want to talk for a second about one thing
here before we proceed. We're using version of solidity. In this case issue can remember
in the previous lesson, we will take the address
of the contract. Construction from
the message sender will be something like this. The sender. Now these in, in Solidity, 78 will not work because the message sender
instruction is not payable anymore
as it was before, we will have to cast
the payable functioning here for the message sender. If we cast it like this
now is going to work. If you're using a solidity
version before seven, you don't need to put
the payable in here. We can also initialize. In order to list. Whereas lambda will equal to lambda condition dot available because when we
create the contract, the car will be available
to be rendered. Here is pretty standard so far. Now as usual, we're
going to need a few making something wrong here. We will need a few functions to keep track of everything
that is going on. First, let's create a function
that returns a status of the car so we can understand what it started as
n if he's available or not. We'll create the function. We'll call it Get condition. Condition. We are now going to pass
any parameters through it. And this is going to be a public function view
because it's gonna read something and we
want to return something. So returns. What is a variable
that is returning is the enumerator list that will be called from lumbar condition. In turn, the lumbar
variable that we created turn. Just like that. Now we have a function
that can tells us, that can tell us if the
car is available or not. Now, how do we book the car? We first need to
receive a payment. We're going to have to
create a function that can receive the payment function. And we can call
the rent lambda2, because the function that
will actually gonna issue the rent just as the
address it will do. We create a here. This
function has to be payable. It means that it
can receive the, in this case, it's
gonna be public so we can call it
from outside as well. Just as simple as that. Now, ideally, we want to do a couple of things
before we continue here. Because you don't
want to just create a function that
receives a payment without checking a
couple of things. First of all, we are
going to need to check that the car
is available, right? Because if the carriers
already oriented, we can now call this
function again. Otherwise someone else
will have to book the car. Then obviously you could
create a schedule system, but this is not the
point of this video. How can we check if
a condition is met? We have a keyword
that we could use. The keyword is require. Basically what this
does is that it requires a certain
condition to be met. So in this case, we want to make sure that
the car is not oriented yet, that the carriers available. So how can we do that? We can check the status of the variable lambda2
is equal to available. We can do that like this. We didn't put the name of the enumerator list
dot available. Now, before this
function triggers, we're going to check first
that this condition is met. The cool thing about the
requires that we can even give them a error message. For example, here we could put the lambda is already rendered. If someone tries to call this function while the
car is unavailable, is gonna receive, the function
is not going to complete. And he's also going to receive these error message
that says, hey, you cannot do that because
it's already rent. That's very nice. And then the second
check that we want to make is that we want to make sure that we receive the right amount there we
want to run the car for. We're going to use
another require statement to check if the value that is the person is sending is at least equal
to what we want. So we'll create another require. Now we are introducing a new thing that you
remember how we can capture the address or host calling the function
with this message sender, we can do the same with the value that they're saying
they were message value. So you will just type it
like this message value. And we want to make sure that the message value
is at least equal, is bigger than or equal to, let's say two weeks. We can specify there like that
to ether, just like this. And then if it's not the case, it looks like I
spelled it wrong. Many things wrong. Ether. And if that's the case, we're going to give a message that says not enough either. Not enough. So right now like
this is pretty good. Because before
launching the function, we are making sure that the conditions that
we want are met. Now how does the function actually send money
to the owner? We're going to use the
transfer method will basically take the contract
owner variable. Why does it do that
contract variable? We're going to use
a transfer method. We'll do dot transfer, and then we'll transfer the message value that is associated now
with this function, like this, what this instruction does is that takes the value, that is the address descending and
ascending n is transfer name to these contract
owner variable here. Then after that's done, we can change the status of
the car to none available. We'll do landlord equals
to the lumbar conditions. Conditions dot granted. Now this function is going to handle all
the payments stuff. N is going to switch the car
the car status to rent it. So if this happens and then we tried to call
this function again, try to run the code again, is not going to go through. The last piece of logic that
we will need is a way to return the status
back to 12 able. And four there we can just do checkout or check-in
rather function where, where we are calling it
when we return the car, we will do function. We can call it return lambda2. Also, this function is
not really going to get any parameter through it. We have it public because we
want to be able to call it. The function does is
that takes lambda, turns it back to available. Just say that this point, we basically have a
completed smart contract. We can, we can use as a
prototype for our app. Let's try to compile it. Test it out. We're
using in eight, so let's make sure that
we use for your name, compile it Control S
is compiled correctly. While we're here, I can
maybe show you what I was telling you about the difference the
different versions. I mentioned that this payable
here is necessary now that we use version eight for it, there is another
similar situation that you might encounter a few years older or newer compared to a newer
version of solidity. And he's on the constructor. Right now is you can
see we are stating every visibility state
in the functions, but not in the constructor. That's because version eight doesn't require that anymore. So for example, we
could put public here. We could say that the
constructor function is public, and if we try to compile it, it's still going to work, but it's going to
give us a warning. Here says the visibility
constructor in the visibility for cost
structure is ignored. And it gives us some other
information that we could use, still going to work, but
it gives us a warning. And this was different. For example, in version six, Let's say that we use
solidity version six. So we'll move the compiler
vector version 66 by six. If we remove public is
actually going to give an error because version six requires the visibilities
to be specified. And hearing, it tells me, Hey, no visibility is specified. Did you mean to add one extra thing that I wanted to mention just
to give an example of the difference
between the versions, let's turn it back to version control as to
recompile it is correct. Let's deploy the contract
and see what happens. We have our address virtual
machine with deployed here, the contract is deployed. Here we have all our
variables and functions. So let's first check
who the owner of the contract is and check
if the constructor worked. If we call the contract owner, going to give us an address, which here you can
see your hands for DC for that is the
address that we used. This tells us that
we are the owner of the contract and that also means that we can
receive the payment. Now in the constructor, we also specified that the car has to be available
when it's launched. If we do get condition
is going to give us 0 that equals to
the available side. Work so far. Now,
let's check if the function to rent the car
and make the payment works. And if you notice
this one here that is payable is red compared
to the Ottomans. Now let's, let's try
to make a transfer. These is a section of the
page that you used to actually specify how
much you want to send. And you can see here that
we have different measures, make sure that IT or ether. And let's try to send one ether. Our function specifies
that we want to have to. In theory, if
everything works fine, we tried to send one ether. It shouldn't work,
it should give us an error. Let's
see what happens. We'll go back down here. We have one Ethan,
let's run lumber. Guess what? We have an error here. It provides us with a
message, not enough. It looks like our
system works so far. Now let's try to send
to see if that works. We put two Rambo. Now I worked. If I did something dumb here because I didn't
switch their counsel, we basically sent the
Ethernet to ourselves. Let's let's change the account. We can use another account
and let's do it again. Well, actually we can't. This is gonna be, there's gonna be another arrow is
great to test the next, the next part that
I wanted to test. If we do run lumbar now
that we already rented it, it's gonna give us
another error is why? Well, the lumbar
is already rented. How do we do that? Well, we can call the function
to return the Lambda. Now the is back. So let's try to use these second address to
render Lambda. Again. We'll send the to read lambda2. Worked. So now I frequent
check-up here we can see how now the second adder has 1970 and the owner
of the contract has 101. So that's exactly
how this works. Again, if we now take
another address and we say, Hey, I'm a third person, I want to run the Rambo. Oh wait, I can someone
already has it. In this case, we
don't really check if the person who rented
the land was the same. That is, doing the
return function. That's something that
we could implement to make it a little
bit more functional. With any free
return, the Lanval, then someone else
can rent the car. This is a pretty
good overview of how payable functions work. Payable function,
payable variables. But let's step this up a notch. Let's introduce a couple of
more mechanics that will make this contract a little bit better and a little
bit more real. So first of all, The require statement here. Okay, way to make sure that
we meet some requirements, but is not the preferred
way because let's say that we have an app that
does this many times. Let's say that we have
up there has ten lambda, we have a current of
the has ten number. Then you'll want to have a specific function for
each of them or something that we want to render
Greenland where we want to run the red
lumber and so on. This means that you will
have to write these code. For each function,
which is doable. It will work, but it
will be very repetitive. And it's gonna actually, the gas p is quite a bit
because we are writing more and more code to use. To overcome this situation, we use something that
is called the modifier. Modifier or let's place
it here just before the constructor
function modifier or is the called function modifier starts with the
keyword modifier. And basically what it does, it allows us to
place these require inside this modifier
and then we can just The modifier to each function that we want to have
that checkmate for. Then now, I'll
show you here now, let's say that the first one is make sure that the
status is available, will create a modifier, though we can call we
call it subtle Sarah. Status error. What we will do here, we just take, let me make
this a little bit smaller. Just take the require
that we wrote before. We cut it and paste it in here in the modifier
code. And that's it. That's how we transfer it. When we use a modifier, we have to also just make
sure that this is correct. When we use a modifier, we also had two other
special character in it. There will be an underscore
after the checks. We want. These underscore. Basically it says after
this has been checked, then run the function. And if it's not met, then you will get the error. Then we create a second
modifier for the payment. Will do modifier. We'll call it payment error. It's basically to not
be the same thing. We'll take the payment required. We've cut it out and
paste it in here. And then we'll add the
underscore to make sure that the function runs out to the checklist complete. We can clean up this on here. Alright, so the function to
rent the only thing left is the actual transfer
n change in condition. How do we tell this function that we want to access
these modifiers before? Well, we simply add them in. We simply add them
inside the head. Here. We will just add started
to say payment error. Actually, I just
realized that we have to make a slide
modification here in the permanent or because now the function is passing
something through, right? Because it's the message value. Instead of specifying here the payment that one
will specify here. In there we'll put
two ether here in the require will
have to something. The modifier here will
need to add a parameter because the payment error passes the value
that we want to add, we can add a parameter
called value. And then here, the
require will check that the message value is at least equal or
bigger than that. Now that's going to work. This was the next step
that we wanted to show. Let's check if it works. We'll kill this contract. Essentially these
contents should work just the same way
as it did before. Control S to compile. We made a mistake or
they didn't mistake, we make identifier not found
or no unique or the dy du. Let me check this. Here, I get it. Here. We didn't specify the
type of variable. Now let's try to compile it
again. Sorry about that. We can deploy the contract. This time we deployed
it for these are from these
other address here, so that's gonna be the owner. We can check that
we are the owner. The lumbar is 0 is
available to be rented. Let's see if we can use these other first
daughters to rent it. This time. We switched the address, will try to transfer to rent
the car and you worked. The payment is being done and we have the situation
like it was before. Let's try to return the Landow and let's test if this works. I started to pass on
your 1 eighth this time. When we tried to rent it. We can't. And the modifier is
going to also give you the there is not
enough, eat enough. Same as before. If we try to rent it again, this gives another mistake, color another error
because we're passing, we're not passing enough so
it triggers the value first. But if we pulled it to
eat and we try again, well, not supposed to happen. Okay. I did something wrong there to the alarm is already ranked
and yep, that works. I didn't check to make
sure that he went through these exactly the
same thing as before. Just has a little bit
better structures, a little bit more flexible
because then if we have our 10th function
that do the same thing, then we will have a little
bit cleaner and code. Now, let's add one last thing to make it a little
bit more usable. And we are going to
explain the event. An event that does
is that allows an external application
to listen to the blockchain for
specific changes. In this case, we could have a safe software connected
to a piece of hardware that listens to the app on the blockchain and whenever
the car is rented. And so whenever the payment went through and this function here, the rank lambda function,
is completed correctly. Then maybe you can activate some automatic mechanism to
give you the key of the car. So how can we do that? We use an event. So up here in the variables, we'll put on an event variable. We can call it a rented. And rented is going to have
a couple of things in it. The event is going
to have information. We're going to have to
need an address and an amount will have an address variable uint8, that I didn't name. The address can be associated to a variable
called customer, the uint8 to a variable
called amount. Because we want to make
sure that the amount that when the software that list and the
amount is correct. So we had the advent here. And how can we trigger this? We can do it in this red lambda function
with Emmett event. The meat is the keyword
to trigger the event. Once the thread, once these instructions went
through, we can emit. We basically meet the
event which we rented. The two parameters that we pass through, the message sender. Because we pass the address
and the message value. This way. The app that is listening
from outside the contract can see who, who said what. So then you can authorize the release of the
key or something like that. Now, we also going to require
this function here, Rambo. Be external. If we want, if we
make it external, then we don't have to actually called the
function by itself. So let's step back
for a second here. I'm going, I'm getting
ahead of myself. In this way we are simply
a meeting the event. Now. This function right now
has to be called manually. So someone will have
to make a payment and manually call this function. What if we want to have a function that is
triggered automatically? If a parent is made, we can do it using
another special function. It's the same principle constructor because
it's a special function and is called the receive. When we use the
receive function, visitor will say the
retail, the country, hey, whenever our payment
is received, you don't need to have
someone clicking this button, just do the thing automatically. Now this receive function
here has to be external. External is another condition, another visibility state that is only a variable
for functions. And so it basically says
in an app from outside, the contract can
call the function. We have to make this
payable as well. We're going to have to add
the two modifiers because we still want to check to make sure that everything is good. So we will use the status
error here modifier. These are good example of how, uh, why it's better
to use a modifier, because otherwise we
will have to write the entire code from the
modifier again inside it. Status error and payment error. We also want to receive
two ether for this. Now, the code inside here, it's gonna be the same that
we have in this function. Copy this, paste it in here. If we tried to compile
it, Control S. What did I do? I guess I forgot something. Expected a semicolon
burger modifier because I created the event, but I didn't close
it with a semicolon, save control S. Now it's
compiled if we deploy. If you look at this, you can see that this receive function is
not, doesn't appear here. Because this receive function, it's only available from
outside the contract. We cannot call it from within the contract is from outside. And so whenever we are
sending something to it, then it's going to
automatically be triggered. Because of the emit. If there is an
app, listen to it, it can then giving instruction
to something else. This contract here was
a little bit longer, a little bit more complex, but it illustrates many, many things available
to us in solid. Next contract that
we're going to show, it's probably the most, a little bit more
exciting because we're gonna show how to
make a contract to actually means the transfer
coin between four down.
10. Coin Minter: Hi and welcome to the
last video this course. Today we're going
to put together everything we've
learned so far and we even going to add a
new element in the mix. We're going to check how we
can reverse transaction in case I'll condition is
has been failed to match. What we're gonna do
today is going to be we're going to create a smart contract where we can meant and send coins
to water addresses. Whenever you were trying
to make a contract. It's good. Or it's pretty
much required that you make a general plan. So you want to have a clear idea of what
the contract makes. So for example, here we can see how we can
make the structure. We want to make a contract
that can mean coins. The coins can be maintained
and sent to our addresses. Now we want to add a little
bit of functionality. So we're going to
make at least have the introduced in
the first place. The main function can only
be called by the owner. That's pretty essential. Otherwise, every person
that acts as the contracts can just create new coins and
we don't want to have that. Then we want to have a function
that can send the coins. And before the function gets
validated and completed, we want to make sure that the balance in the account
rent to send coins is enough. So we don't have accounts with 1000 coins trying
to send 5 thousand, otherwise I will not work. And then we want
to have an event. We want to be able to emit
events when the coins are transferred or
when a transaction to send coins is called. Because then we can
have apps that can listen to that and do some filling when that
happens, I don't know. Maybe you can have a
confirmation message. You're sending coins for someone else and
there's someone who can receive a confirmation
message based that. Then at the end, we also want to have
an external function that can check the balance of the addresses from
other external apps so that we can have, we can access the contract from another app and check
the balances of the addresses that you could
see that it almost as like ether scan type of application. Let's start by dollar for this. We'll start, I'm sorry, making the usual
contract will have the contract keywords and
we'll call it a coin Mentor. Mentor. Here's our contract. Now, in the first, the contract we establish all the variables and
we're going to have a few. The first one that we want
to have is the address for the owner will have an address
variable that is public. So that can be accessed
and we'll call it owner. This one for now is
initializers 0 or nothing. So we're going to place, we're going to associate
that variable to the address of the owner when
the contract is deployed. Then the second variable
that we need is a mapping. We can associate addresses with amount of coins
that they have and we can check their balances. So we'll call this a mapping. Inside this mapping we are
going to have two variables. We're gonna have a
variable of address. This address is going to be associated with a uint8
because we just want to have an address
associated with the amount of coins in these coins
are checked in numbers. The mapping is public. We can call it balances, because this is the
mapping we use to check the balance of the address. Then the next two are
going to be the event. Because we remember
that we wanted to have a way to emit an event. Solder apps can check if a transaction has been
centered, not the event. We can call it sent. Let's call it sent
with capital S. We're gonna, we're gonna send, or we're going to meet
three different variables. So we're going to send three different information
through this. We're going to send the
address where the scent, the coins there is a received
them and the amount. We will have two variables, address in their address. And these are going to be called from because this is going to associate the
arteries ascend the coins. Then the second address
variable is gonna be two, which is who receives the
address, received, the coins, and the second one, Sorry, I'm, the last one, will be a hint that
we can call amount. Because this is gonna be
the amount that is sent. Then the last variable that we need is going to
be an error variables. So we are introducing
this system. In this lesson, in
the previous lessons, we checked how to have function, makes sure that every condition
was met using a modifier. In this case, we use an
error because the error allows us to revert
the transaction. When you reverse
the transaction, it means that it is not
is not transferred, is not validated
by the blockchain. That means that
no gas is wasted. So this function will
fail if in this case, the balance of the
account is not enough, but it's not going
to waste the gas. So this is a good feature that
we cannot do our contract. I'm gonna be an error
variable like this. And we can call it
insufficient balance. Sufficient. We're gonna check
for two things. The amount requested,
an amount of variables. So we'll have to
uint8 inside this. We can call it requested. The second uint8 would
be called the available. We're basically check the
balance of the address c, how much is requested. And if there is enough, we can send transaction. Very well. Now, we have all the
variables that we need. So the second part of the
contracts are the functions. The first function
that we want to add if we need one,
is a constructor. In this case, we want to have a constructor function
because we want to have the address that creates the contract associated to be the owner so they can
create the coins. Will start with the
constructor function. This should be pretty
simple by now. We'll just set the owner variable to be equal
to the message sender. So now whenever the
contract is deployed, that arteries are deployed, it is going to be the
owner of the contract. And so these addresses is going
to be able to Mint coins. Otherwise, if there are
no coincide domain, then you can't really have them. The next function that
we're going to make as a main function because we
want to have the coins. We will create a function
that we can call Mint. One local minimum. This function is gonna
get two parameters, one address and one uint8. One address, because
we want to send these coins that were
meant to and address. It can be, let's
say the owner wants to maintain a bunch of
coins for themselves. They can start doing something, then they will place
their own areas. Let's say that the owner
wants to mean coins to send to other users
of the platform. Then this function
allows to make the coins and automatically
send them right away. The first variable that we will have is gonna be an
address variable, and we can call it receiver. The second one is gonna be a UN, where we have the amount
that we call the women. Then this function is
going to be public, so it can be called from
outside the contract. But remember that only the, only the owner can, can mean this herb
non-mental can call this function to employment that will use a require will require will require that
the message senders. So we required the address
that causes function. Is the owner. Said sander equal, equal owner. That part is done. Now, only the owner of the contract can
call this function. And then what we want to do here is that we are
maintaining coins. What we're gonna do
is we're going to take the address that is passed through the function and add the amount to
their balance here. So we're basically going
to add into the mapping. So we'll do that. Calling the mapping
balance, balances. In the first, on the first
side of the mapping, we're going to
associate the receiver. So that's the address
and receives the coins. And we're going to do, is we're going to add the amount of coins
to their balance. We'll do plus equal amount. Remember that the plus equal means that we take whatever is in already there and
add the new amount. Technically, if we want, we could also write
it like this. Amount plus amount. But we want to do it just like this because it's a little
bit more efficient, is a little bit more elegant. Now, we have the main function. This means that we can
actually meant and send coins to an address.
These are indices. We'll have a balance of
something in this case, right now, just with this, we cannot transfer the coins, we can only meet them, so create them and send them. I realized that I could
say meant without explaining what it is in case you don't know
what it means. Means. It means to create
like you meant an NFT, you create an NFT, you mean coins,
you create coins. You're basically create coins
from thin air in this case. So that's why we want to have a restriction Hutu
who can do that? Because now if you
have a contract where these coins are associated to an actual real monetary value, then you will change the value by maintaining
these extra coins. Now, we have the function to create and send
the coins on others, but we want to have the
ability to call this continues this contract to send
coins between addresses. So let's create a
function for that. We'll create the function
that we can call send. And again, we're going to
take two parameters in here. Basically the same as the mean function
because we want to take a certain amount of coins
and send it to an address. The parameter that are
gonna be the same actually. There's gonna be another is
that we can call receiver. And this is okay to have the
same names because there are different functions
and they're done in these parameters on
interact with each other. The first one is going to be
again the receiver and the second is going to be
again, the amount. I forgot a few things here. We want to have it
public as well. Then the brackets. Now, this is a pretty
fairly simple function, but we have to add the
functionality of making sure that the balance of the address is enough to be able to send it. So let's say that we have and
others that have only has only a 1000 coins but tries
to send 2 thousand of them, then that's not allowed, that's
not going to be possible. So we're going to
make, we're gonna use a conditional
statement here. We're going to use
it if we check if the amount that we tried to send is bigger than the balance that we
have in the address, then is going to revert
the transaction. And it's going to use
this as a way to do that. It's going to reverse
the transaction using the sufficient balance. Will do if the amount that
we're trying to send is bigger than balance of
the message sender. What are we doing here
with this instruction? This instruction, we are taken the amount they were
trying to pass through the function and match it with the message sender
inside this mapping. And obviously if there is no account in the mapping,
then it will show 0. So it still, it will still work because it's still going
to show that it has no, it has not coined to same. But let's say that
the addresses in the mapping and
has a 1000 coins, then it's gonna check, it's going to take the outers, places here measured against it and see how many
coins is in there. Here's how we can check that. Then we'll do that. If that's the case. Then we reverse the transaction, will use a keyword revert. We'll use the insufficient
balance error. To do that like this. Then we want to do inside the Sufi
sufficient balance error. Then we can also add
some information here. These error has these
parameters in there. What we can do is that we can match the requests that amount, the amount that we're
trying to send like this. Here, we just need.com. You can just write
it on one line, but this makes it a
little bit nicer. Then. There are variable
amount that we have will match it to the
balance of the center, just like we check here. M as G center. Just like that. Then don't forget here to put the semicolon on
otherwise now going to work, what this does is that it checks that we
have enough coins. If we don't have,
it's going to reverse the transaction and
call this error and so on the constellation shoes
show that we are trying to pick what we're trying
to send these many coins. But we only have these many and so that's
why it can't work. And then when that condition
is not met instead, then we can make the transfer. How do we do that? Is that we take, we basically take the
amount that is in the mapping associated
to the others, remove it, will associate it to, we'll take that
number m basic gauges credited in associated to
another address in the mapping. How we do that, we'll call
the balances mapping. First, we're going to take the amount of weight
from the sender, will do MSG sender. In this case, we're gonna
use the minus equal. Oops, sorry about this. I press on to run the
minus equal operator. And this means that we
are taking whatever is in there and removing
the amount from it. So we'll do minus c equal amount because
that's the amount that we are trying to send and we're going to credit
it to the receiver. Will all again, we're
gonna call the balances. But instead of having the sender will have the receiver instead. We'll do the opposite here. We'll do plus equal amount
because we credit it to them. So now at this point, the address that is
sending the coins, remove the amount and the
address that is receiving the coin is going
to get the amount. Struggled in there because
I realized that this is the wrong one here is not
required, is received. Now it's going to work better. I mean, it's got to
work at all. Received. We also said that
we wanted to emit an event whenever the
transaction is made. So we can have an app maybe say, Hey, you'll receive
these many coins. So let me do event like
this and will emit Sent. Then we're going to take
the message sender, the address of the
receiver, receiver. And the amount. These are gonna be the
information that are transferred through the advent. The address sends it. Who is receiving them, and how many n is
pretty much what we have here from to an amount. Very good. So now we have the function
made to transfer the coins. And it might seem a
little bit complicated, but once you go through it, once you think about
it a couple of times and once we
actually tested is going to be very
understandable. This is very simple
code overall. Now the last function
that we wanted to have is a function that can call the balances of the different addresses
from the outside. So if we have the address of an account that we
want to check them we can use we can use this function to see how
many coins are in there, similar to chain
Explorer ether scan type of thing will call
this function. I'll create this function and we can call it good balance. Good balance, and we'll
just have one variable, one parameter here we
only need the others. Will have the address and
we can call it account. The account that we call. These function is
going to be external. This means that we
can call it from an external application
or at it only from an external application is going to be view because
this doesn't really change anything on the
blockchain and just reads it from the blockchain and returns, it will return a UI
in because we want to return an amount of violence. How many coins are in a very simple is just going
to return without the ears, the balances because we want
to call them mapping, right? So we'll call the mapping, will just look for
the account address, for the address
called dot count on. Keep doing that.
For the headdress. Pass through these parameter. That's it. So now our
contract is complete. We didn't test it yet, so there might be a
few syntax error. The logic should all be right. If we have some mistakes, is most likely just
some syntax errors. So I want to just want
you to take a look at the structure for a second. Let's remove all these
comments just so we can have a little bit better formatting. Look how we made this country. We have the contract name, the solidity directed
identifier name, and then we have all
the variables on top. Then we had the
constructor function, and then all the other
different functions. So this is the general
layout that you will see when you're looking up different smart contracts. Now if we put, let's say that we want to put to make it
more clear for ourselves. Because sometimes I find out that it is a
little bit more clear. Let's say that I want to pull the variables associated with this function just above the function and so on you
could do it is still working. But then if someone else goes and looks through the
content contract, let's say that you need
to have another developer helping you doing something
or working with you, then it's gonna be more
confusing for them because they are most likely used to have a format like this. Okay, so let's try to test it. Let's see if we
can compile it as make sure that we had
the right compiler. We have version 8.103 Control S. See if it works and
we have a few mistakes. Of course, I would say. Now let's see what those are. Okay, so first of all, I made the first
syntax error here. We are trying to call a mapping or use a
mountain called balance, but we don't have a mapping. Cold violence, we have a
bumping called balances. Will just add the S there
and that's going to work. Let's see what these arrows are. These ones here. Again, only mistakes
for syntaxes. This one here should be
receiver now received, I don't know how I
missed that because the parameter that we
pass code receiver, we call this receiver. The last one. Did you mean sand, mint or sand? So now the advent, it's sent with a capital S. So be careful with
the 0 mistakes. We are still going to make them. It's, for me is rare that our write up a whole
bunch of code all at once. And it works without
this more mistakes. But the remix ID and this saluted compilers are
very good if you notice, it took a second to the bug, the code because it tells
you it tells you what did, what did you try to
do all is wrong. Do you probably
meant to do this? And it does it for yourself. Now if you do Control S, not a word, we compiled it and let's try
to deploy it and test it. Let's take that as his first. We're going to deploy
from this first others, EDD C4 in 108th. So this is gonna be the
owner of the contract. And I'm going to extend this a little bit so
we have a bit more. We can see a little better. Let us apply. The control was deployed
and we have it down here. I'm going to extend
it up a little bit. And here we have
all dysfunctions. Now these two functions are
orange and they do something, and these are just
other functions that you just read stuff. For example, the balances, we can read the balance, the mapping and so on. And the gate balances
the external one that is going to read
from an external source. So let's first check that
the owner one works. Let's call the owner. And here we have
the outer side is the owner and we have EDD C4, which is our address. We are the owner
of the contract. That means that we
can also meant coins. So let's try to create, I mean, I don't know, 10 thousand coins, then we can use how we want. We go here, we copy
our address here, and this is going to extend it. So it's a little bit more,
a little bit more clear. So the main function, it needs a receiver and an amount the receiver
is going to be over self will paste the
address in here. And we don't mean to
10 thousand coins. If we called the transaction is going to work because
we are the owner. And if now we are going to
take our address again, we'll check our balance. So we paste the
arteries in here. We should have 10
thousand coins, and indeed we do. Now let's try to saying
2 thousand coins to water addresses
because they are user of our platforms
and we can, we want to send them so they can do stuff on the platform, will take this second address. We copy it. We want to send it. The sender is going to, this transaction is going
to need two variables, is going to need whoever
receives the coins. How many services that
we want to center. Now we're going to have to
call it from the first one. Because otherwise we're not going to have
enough coins right? Now if we make the
transaction was successful. And if we take this address
and check the balance of it, then we have 2 thousand coins. Very nice. Now let's try to see if the In section, if
the error works. So we now have a 1000 coins
left in this account. Let us say that we tried
to send a 10 thousand of them to this same,
to the same areas. When we call the function,
it's going to give an error. If we scroll up a little bit, we can see what's
going on. Here. We are trying to call it
and then it reverted. The transaction has been
reverted to the initial state. So this is now going to use gas. The error is gonna give these parameters requested
10 thousand, but available is
only 10 thousand. That's why we coded it that way. And so we have an
information that oh, wait a second, I'm
trying to send too many. That's not gonna work. Now. We can try. We can use these arteries. They just received
2 thousand coins to send it to another one. We could switch their address and it said we want to
send it to this guy. Let's copy this. Put it in here. Then it was the second address. So now when we tried
to send 500 coins, which we should have make
the transaction worked, and now others should
have 500 coins. Let's use the external function
to check this one here. These get buttons. It's an external
function I should do basically the same of this, of looking into the mapping. Will the only
difference that we can call it from an
external application. Now replay, we pasted
the address in here. We'll call the balance. And we have 500 coins. Our contract to mint and send coins work
just as intended. So these are fairly
simple contract, but I think it's very good to put all these different
information together. Obviously, contracts for
if T's and coins that work may NADH and they have an unnatural value associated and do things are much
more complicated. These are just what,
40 ions or code compared to a hundreds that you will find in a regular contract. Now, you should have
enough knowledge to be able to at least understand what's going on
inside his contract. So what I will recommend
to do is go find contract for tokens and
coins you're familiar with. You can find them on ether scan, on that scan or whatever chain Explorer you'll want to explore. And try to read through it and see if you
understand what's going on. Obviously, you're not gonna
understand everything, but you should be able
to have a good idea or at least what these functions do and what they're
trying to do. Good. This is concluding our
fundamentals course. I really hope you
enjoyed it and it was fun for me to create it. It's been, I've been
thinking about this for a while because when I've
started learning solidity, I could only find fairly
complicated things or any way courses
and tutorials, they don't really explain
the basics, how I needed. And so I really hope this course is going to help someone did as, as they're trying to learn
to become a developer. Now this was the
first one that I created here on this theory. I'm working on another one
about Web three interactions. So stay tuned for that one. That one is going to be working with Python and
we're going to use the Web three library
in Python to be able to access the blockchain and
do stuff with Python, which is a greater risk
for gray language. Well, thank you very much for following and I'll
see you next time.