Blockheads Ep 4: BLOCKCHAIN TUTORIAL - How to make a blockchain voting app
Nothing is loaded from YouTube until you press play, and then without tracking cookies.
About this video
Voting App Tutorial In the spirit of the upcoming election season, join me (Dorian :D) as I show you how to build your very own blockchain voting app. This is a comprehensive tutorial on how to build a blockchain app on NEAR from start to finish! If you'd like to learn along with me, try it out! If you want to see other kinds of content, let me know in the comments.
I also want to see you guys add your own spin onto this application! Send in your version of this voting app to the email below and maybe you’ll see your version of this application showcased in an upcoming episode of Blockheads!
Send your project’s Github link to this email: [email protected]
Happy hacking! :)
-- Contents of this video ---------------------------------
Intro: 00:00 - 00:26 Overview: 00:27 - 02:14 Step 1, Download Setup & Clean Up: 02:15 - 08:17 Step 2, Install Bootstrap: 08:18 - 12:28 Step 3, Setup Nav Bar: 12:29 - 13:44 Step 4, Candidates Nav Bar Functions: 13:47 - 18:14 Step 5, Candidates Part 2: 18:17 - 20:48 Step 6, Candidates Part 3: 20:52 - 27:41 Step 7, Voting Booth: 27:42 - 31:40 Step 8, Voting Booth Part 2: 31:41 - 36:15 Step 9, Contract Stuff: 36:19 - 37:17 Step 10, New Contract Part 1: 37:21 - 52:35 Step 11, New Contract Part 2: 52:36 - 55:34 Step 12, Post Contract UI Part 1: 55:35 - 01:01:04 Step 13, Post Contract UI Part 2: 01:01:05 - 01:03:51 Step 14, Post Contract UI Part 3: 01:03:53 - 01:13:04 Step 15, Final Feature Part 1: 01:13:05 - 01:17:14 Step 16, Final Feature Part 2: 01:17:15 - 01:23:23 Step 17, Success! / Outro: 01:23:24 - 01:24:16
Resources:
To get connected, join the NEAR Discord: - near.chat
Videos: Understanding What Blockchain Is: High Level understanding of Blockchain and smart contracts -https://www.youtube.com/watch?v=SSo_E... Blockchain JS Example - https://www.youtube.com/watch?v=zVqcz...
To learn the language used to create your own contracts like the one in this video: TypeScript Crash Course by Traversey Media - https://www.youtube.com/watch?v=rAy_3...
NEAR Documentation used for this application NEAR Orientation - https://docs.near.org/docs/roles/deve... Smart Contract Introduction - https://docs.near.org/docs/roles/deve... AssemblyScript Overview - https://docs.near.org/docs/roles/deve... Create-Near-App GitHub Documentation - github.com/near/create-near-app Contract Structure -https://docs.near.org/docs/tutorials/... Using Contract JS - https://docs.near.org/docs/developmen... Understanding NEAR JS implementation https://docs.near.org/docs/roles/deve...
Let me know what I can improve on, what you would like to see next, or any questions you might have in the comments below!
Thank you for watching!
Coding done by Dorian Crutcher, Editing done by Chad Lamon
#Blockchain #FutureIsNEAR #NEARProtocol
Transcript
11,461 wordsCaptions as YouTube publishes them, usually machine-generated, so product and people names can be misheard.
- 0:07
hello lovely people it's your favorite pretend guitar player dorian crutcher welcome to another episode of blog heads in this week's episode i'm going to teach you guys how to make the voting app we made in episode one of blogheads sit tight guys and gary to have some fun so here we have the application that made the end of blogheads episode one where i figured out how to make a voting app that runs on blockchain
- 0:34
um we can see that we can log in we can log out so i'm going to log in as i'm going to use the blockshop.testnet account if you haven't seen the video i encourage you guys to check it out a lot of fun and here in the application we have like two windows here each with their own candidate as well as a window for the voting topic or the topic we're putting on we have one window for leslie one window for ron
- 0:58
they're voting buttons and then their respective descriptions as to what they stand for so leslie stands for waffles ron stands to undermine the government and probably me i've been quite open about this around the office i don't want this parks department to build any parks because i don't believe in government so open up the inspection tool uh see the console here i'm logged in under under the blockshop.testnet
- 1:22
wallet account i'm going to send my vote for it's uh let's do leslie we can see leslie's vote count we can see we have a little cube message saying thank you for voting and if we refresh the page we can see the total number of votes that each candidate has as well as the voting buttons themselves getting grayed out if i were to retry the voted buttons earlier we would see a message saying that you've already voted so it was able to actually know that this account has already cast a
- 1:56
vote and can no longer recast another vote but um i think this application is cool i think it's awesome that functions on blockchain but i think we can make some improvements to it through the functionality of the visuals so i'm going to show you guys how to make a very much cleaner looking version of this application to add to your portfolio so stick around hello lovely people so here we have open
- 2:21
vs code but before we get started with the coding i want you to go over to node.js and install the 12.8.4 lts it might be update it might be a different version of node.js by the time you watch this video but for now just install this version don't install this current version because this version is more stable we're also going to be dealing with react bootstrap but we can install that in a minute we're also going to be
- 2:45
working with the create new app we're going to install this right now so after you after you install node.js um read through this document here i'm going to put a link in the description one eternity later but for now i want you to run npm oops uh pseudo if you're on mac npm install create near app dash g to make it global it's loading it's loading see here we have this installed but
- 3:15
it's still just gonna take a minute two hours later then what i want you to do is run create near app dash dash front end is equal to react if you don't put this it will default to vanilla.js and then the name of our project i'm after this so blockheads vote just call it that it's fine everything's fine cool i'm assuming you all know react jumping into this video i'm also going to assume um that you're familiar with sas
- 3:53
because i'm using sas for this video um to interact with react's bootstrap and you also need to know typescript and assemblyscript well which is a dialect to typescript to make this app application work but as usual what i'm going to say here is if you're new to this and you're just jumping in i encourage you guys to read through all the comments kind of get used to the setup of create
- 4:19
new app and what the template provides you be sure to navigate into your um into your application folder so cd block heads vote or block head vote and then type in yarn dev it took a minute six and a half hours later the app is starting after you run yarn dev you're gonna see this window appear showing the demo application door for the sign in function just yet we're gonna get to that in a minute um after the cleanup but
- 4:56
you know actually let's just jump right into here let's see what cyan has to do so sign in will take you to your near wallet if you don't have a wallet already just create a new one and simply follow the answer instructions so just put in whatever name you want so we can just put in bob one two three four one two three four go through the on-screen instructions so your phone recovery um oops uh make sure you put the area right
- 5:50
there okay after you create your wallet you're gonna see your username here and the application rerun the demo application that we opened is requesting access to your account so you're gonna hit allow and then you see yourself signed in so you know it works you're gonna use your near wallet later so it's important that we went through this process so we can have our account ready for our voting application so let's go to the cleanup it's gonna be a bunch of stuff we just
- 6:22
don't need so you don't need all of this like i said be sure to read through all this it's actually really good and really helpful but you don't need it for now here hit delete add a closing tag add the return statement inside this turn statement let's just put p tag and say hello world for now hit save go back you see hello world so that's good go into the global.css copy everything delete it put in body
- 7:01
margin zero padding zero that's good for now cool everything's good going to global. i'm sorry go into um utils.js so we're going to keep these two functions so log in and log out that will actually be they're very self-explanatory they're going to help us log into our wallet and log out of our wallet account get rid of these functions within the change and view method arrays and also i want you to get rid of where
- 7:41
is it where is it oh it's not here need a contract okay whatever yeah that's all you really need okay so login log out go to main.ts get rid of these functions here just everything except for that import statement hit save go here hit save and here hit save in a pretty good spot pretty ready to go so now we have the create new wrap boilerplate cleaned up let's go over to react bootstrap's main website and when you click on get started
- 8:32
so get started copy this line here go over to vs code hit command j ctrl j or whatever opens up your terminal so open up a new terminal hit control c to stop the uh the local host from running oh it can keep it in yeah you can't okay i can't do that there you go cool so paste uh paste in this line into your terminal and run npm install react bootstrap bootstrap just wait a minute while it installs i've actually installed on this so it's actually pretty realistic one eternity
- 9:14
later the terminal is always like it's like always like mystifying it's like watching actual code running but i mean no it's just like a very like like like standard process in the world of coding i guess they're like a blockheads like npm installation chat just like a pow however installations like huh how are you okay so there we go the installation is done um so you have react bootstrap bootstrap inside your node node modules folder um if the copy
- 9:44
pasting is work just type it in to verify that it worked or actually next step will be sorry jumping ahead next step would be to create a folder called scss inside that folder create a new file called app dots app styles.scss i'm using sas to style our components and something that i want you guys to install um we probably should have gone over this a little bit early but i want you to install live sas compiler that's what i'm going to do let's see this i'm going to actually run and compile our stats as we go through making design
- 10:22
modifications um once you do that type in sas into your settings search bar in vs code and let's see select live sas compiler go down to where it says set your exported css styles formats and save location inside and on this line i want you to copy that save path so i'll create a new file called css where the sas will be compiled to css and automatically save and as we update the sas files so we don't have to worry about the css file itself
- 11:02
so just copy this line here and you should be good to go um now we have our app styles.scss we're going to go back and we will see copy this line under sas so copy the import line here the import statement here paste it on your first line inside your appstiles.scss folder hit save don't worry this one's not going to actually create a css file just yet so that's fine if you don't have one because i'm not going to have one just yet we're going to actually import
- 11:42
the app styles file we've created so app styles.scss hit save and to make sure that everything's like running it's okay we have to rewrite to restart the server first i'm going to type in yarn dev build error if you get that build error um notification try running npm installed once more inside of your um inside of your application inside the terminal because sometimes i get that and i think
- 12:13
it's usually i found that this is a good way to kind of like refresh it and fix it i should just like crop life a bit so i can fast forward to the part where the download is done let's run yarn dev cool okay so no complaints so that's good let's take one of the examples of the thing we're actually gonna make next the navbar anyway so let's go to nav bar scroll all the way down blah blah blah blah blah blah blah blah okay here we go scroll down to it says responsive
- 12:48
behaviors then just copy copy this example here so copy and just place that right here over hello world paste um we're going to import a few things so let's import navbar and also import nav and nav drop down i'm not gonna use all of these in our file applications but i just want to see the example work from react bootstrap click save okay go back to the application and delete this old one but look at that
- 13:40
we have a functioning react nav bar from react bootstrap so now it's time to get into the nitty-gritty of things the uh thing i'm pretty sure you guys are here for the actual part where we get to communicate with a near blockchain by making contract calls and writing contract code so i mean let's just jump right in um so right at the bat i think what i want to do is i want to make a place for the voters to keep track of the of the uh i guess like the subjects
- 14:15
they voted for so once they cast their ballot they can't vote again on that same subject so let's do this let's let's call it voters reg so voters registration is equal to a new persistent map and let's see in this new persistent map we're gonna have up let's do this string as the key and a i 32 as the i32 array that's the variable recall we're going to call this coders so i'm pretty sure this is like
- 14:58
all super confusing right bad um but don't look at you know don't be too freaked out this is just a map it's like a dictionary in python in other words all we're doing is this is a data structure that will have a key value pair so we call the key we get the value in this case the value is an array and it's array we'll hold both vote subject ids this this little tag here is just to
- 15:23
it's just a unique identifier for this data collection so that there are no data collisions within this contract so let's keep going um we're going to create our function to export function uh let's call it add vote so we're going to have to make another thing to um actually keep track of the candidates numbers too why not do that right now actually so let's call this um let candidate bridge equal to new persistent map
- 15:53
string i 32 candidate bridge this is essentially same thing key value pair except that instead of um holding an array it's just holding a single value that we can add to and change in other words it's just going to be a place where we can actually count the votes for the candidates so add vote we're gonna a vote id and let's also call candidate candidate date so vote id will be a see vote video will be a string i'm
- 16:36
sorry a number it's an i-32 and candidate will be a string so again this is all an assembly script and typescript so if you're not familiar with this i definitely recommend watching some uh videos i'll put in the description for you guys essentially near contracts are all written in either assembly strip or rust assembly script is essentially type script i'm choosing assembly script because it's rather close to javascript so it's not too much of a leap just because we have done it before but
- 17:08
continuing forward um i think what i want to do for now is we can let's return let's just return the i32 ray so this is shorthand just for array this can also be like you know um like array i 32 it's the same thing but um i'm just doing it this way so now we're gonna say if this is where kind of gets a little bit easier more more javascripty um if voters voters reg dot contains
- 17:47
context dot sender so that simply means so uh let's see context.sender is equal to i don't know uh just for username dot testnet so that would just like give this that just gives back this string that has the username of the person logged into continuing forward so this is where things become a little bit more fun we're gonna call in a component actually wait let's do this we are going to make a new file called a folder called components
- 18:37
inside we're going to make a file called candidate dot js if you don't have it already i would recommend installing uh react.js code snippets by charlampose some last name that i can't pronounce but right there it's really good it allows you to create little templates just like this so you're going to like manually type out all this some all this stuff here save go back to the back to app.js
- 19:12
i'm going to import there we go import candidate from components candidate tend to write the js uh save that type in candidate here okay i'm sorry in candid date they get a self-closing tag we can actually copy this and let's put this here as well so as of right now there's nothing in candidates it's not going to show anything it's gonna be rather blank that's okay i want to go you go to react bootstrap and go to the cards section right here
- 19:58
so type in just type in cards here and then just click on this very first thing that pops up we're gonna copy over this example because honestly that step is perfect for what we want to do paste it in here let's bring it back here we go um and now we're going to import the import card and we're also going to import a button from react bootstrap and save go back to our application you can see two cards here appearing
- 20:43
that will be where we have our two candidates and our submit button okay we are making good progress so i decided to go ahead and google pictures of leslie knope and ron swanson and just kind of choose to i downloaded two um like two that look good they look pretty good to me um and i move them into my assets folder so just take your download and drag it into track the image into your assets folder once you have your images in the assets
- 21:17
folder go to app.js under candidate just to import i don't know if it actually necessarily has to be under the candidate but it's fine import uh let's do nope yeah nope from assets canopy dot jpeg the image i found i mean obviously like it would be better if you just like if you found a place that hosted online like imagery or something but i'm just for this tutorial i think it's totally fine when we were doing so
- 21:52
ron from jpg save go down to the candidates component that we make and type in picture as a prop we're pass in by typing nope we're passing nope as our first value here in the second candidate component and type in let's do ron ron swanson there we go inside the candidate component i will go if i can do my little face uh oh there you go there move my little face where it says card image here i want you
- 22:49
to get rid of the source or get rid of like what they already have in in the source file um source prop here and just type in this dot props a picture save let's see what happens here and there you go i mean there are your pictures of your candidates let's do something else while we're here let's let's center the text here and let's like just change it up to make it fit our candidates better so
- 23:20
for the card title we're going to pass in a prop it's going to say this dot propped oops okay so it's going to pass in in jsx this dot props dot title for the card text to just put this same thing so curly braces this dot props dot description here we're gonna for the button let's just do it's called just vote uh we can leave it as primary for now i also want to do i also want to do i also want to go to see the card tag and type in class name so just add a space in between card and style
- 24:11
type in class name sequel to quotation marks text align or is it text center i'm sorry text center there we go cool so buttons in the center we have no text and we have no title which is fine because we didn't make that yet so we have to add our description prop and our title prop so let's go back to app.js and type in description and actually just make a variable up here to hold these down for us so let's just say let ron just do ron
- 24:55
description and let nope description and it's like the k lowercase equal to it's gonna be a string so you just say iran's description is what i have before i had undermined the government remind the government uh can i expel government government and be a man which is like ron's whole masculine thing so nope's description will be parks for parks and waffles for all and you know what let's just put man in all caps be a man there we go um
- 25:54
so let's just do let's go back to the description just call ron description oh no not speech recognition there we go okay cool wrong description and for actually i think i might have this mixed up that's the note that's been no prescription so no no description copy this place this here and change this to ron and let's also add a title here that will say nope a title that we will call
- 26:46
ron save cool and there you go there you have i guess i could put leslie you know leslie instead of nope so let's do actually full name maybe so leslie nope and ron swanson if you haven't seen parks and rec i will fully recommend it this is not endorsed by parks and rec but i do fully recommend it i love the show i came here for the same reason people go to the zoo look at that thing nature is amazing
- 27:31
um but yeah we have our car we have our candidate cards we have our um we start to make a voting subject and we should also work on the spacing here to kind of bring this away from the nav bar but we're making pretty good progress let's keep going i know as i made one little mistake um i when i changed the background color of the nav bar to that kind of like off gray thing i changed it in the css file so like i had this as a what was it hashtag 5c
- 28:02
5c 5c so that was like that but i left green as a color in there we go the app.sci file which means my saved it just goes back to green so you never want to change anything inside the um css file except you won't always want to change all your styles in the scss folder if you are using this method you can also just make individual css files for all your components but i kind of like doing it this way better
- 28:35
so in the um app.scss file i'm just going to type in shag fc fc oops i'm sorry 5c5c 5c that was this thing fc before that's weird and now it's back general but while we're on the styling kick i like that transition let's uh let's shape up some of these um let's show the positions of these two cards let's add some margin some space between the cards and the title block let's give this like a background color so we can
- 29:05
designate our polling booth that's we're gonna call that style actually so let's go into app.js let's see so i have this class name that i am so it's class and i just like paste it here which i'm going to just move i want you to type that in for every column component that we called earlier as a class name so class name is equal to oops i guess i could just hit paste okay cool
- 29:40
and space apparently cool so type in d flex justify content center for all of your columns what this will do is that um it will center all the cards and the voting subject in their respective columns because right before um it becomes more clear where the background color but before they were just a little bit offset off to the left it's most visible with the voting subject let's go to the container
- 30:11
called class name let's call this voting booth coding booth let's go to app dot scss add a new class called voting booth it's just like normal css give it a background color uh let's do would you um tag zero zero zero for now and change it later i might even like that but whatever some margin top it's going to margin top about let's say 10 see how it looks and a padding of let's do about five percent
- 31:06
and let's add a border radius of 5px that looks pretty cool i mean i probably wanted something like other than black maybe something a little bit lighter but i think for now like it it's it's pretty alright so we can actually just you know let's just do let's do do whatever this is and switch it over to hexadecimal i think a little more okay i've got something so yeah we have a pretty good start to the like overall
- 31:39
design of our application okay it's good we're on a roll so let's keep going let's keep this flow going so we have a voting subject here it's dark you can't see it it's kind of lame looking so let's uh let's fix that so let's go to let's go up here type in subject we're going to make a subject's component in the components folder it doesn't exist yet but we're going to call it subject
- 32:09
subject go to components experiment i would make a scss folder a file to go along with the subject.js file i don't think i need it just yet so i'm going to keep going in this fashion so i'm going to type in rcc i'm going to switch this over to a function based component so subject extends component equals to um let's start making making subject and arrow function we're going to use some props later so let's type in props there
- 32:50
here is render get rid of this um get rid of one of the curly braces say hello world to see if it works go back oops did something happen we're still running so subject subject oh uh we didn't say i didn't save app.js i'm voting subject what is happening oh oh okay and also remember to call a subject here slow down a bit we get a self-closing tag there we go okay hello world yay okay so
- 33:38
we had for hello world so we know it's working let's go back make it look pretty so go to subject.js and i want you to type in uh import they import a card from react bootstrap oh no bootstrap there we go and i don't think anything else right now let's just just type in let's get rid of all this type in card dot body oh actually i think it's a new card first right so card card
- 34:23
dot body inside this card that body we can say hello world there we go so we have our little hello world button here or not button but text showing us it's exactly working so to class name is equal to text center cool i mean it was already centered but i like to make sure it's right there um let's call it a prop you say props dot subject in curly braces so props dot subject insert app.js file
- 35:08
we are going to go to subject and call in just type subject here so subject subject but lowercase uppercase um and the name of the thing you wanna gonna like vote for right so let's just say um let's do who's your favorite here's your favorite and there we go we have our little uh subjects container this isn't bad i like it but i think i like it better if the text was in the center
- 35:48
of the card so let's go to excuse me a little snazzy let's go to card body type in class name in quotation marks type in d flex that stands for flexbox or like display flexbox and then do align items center save it and the text moves to the center of the card and there we go we are in a good place i think we're in a pretty good good place so we can log in we can log out we have our cards we have these nifty buns that
- 36:35
don't do anything yet we um just because we're using react bootstrap everything make is pretty responsive so these cards will just stack on top of each other squish down a lot of buttons pushes into this little button here and we just switch it all the way back out so that's kind of fun now i think would be a good time to go into the blockchain side of things which i'm pretty sure that's what you're all here for to be able to actually add voting functionality to
- 37:06
ensure that the user can submit their vote they can't recast a vote and that all these votes be counted and displayed after the user submits their vote so let's jump in and do that so we made it we're finding the meat of the material the part i'm sure you guys are waiting for like how do we interact with the near blockchain how do we actually accept a blockchain and modify data on it um we're gonna do that through contract calls so um just a precursor for get started near
- 37:38
contract calls are written in typescript or i'm sorry well assembly script which is dialect type script and rust so if you guys don't know typescript um that's okay that's typescript we're gonna be using um i'm gonna put a link in the description to your pretty good crash course for typescript um again this is a semi script but if you know typescript it's essentially the same thing and i chose assembly script because it's close to
- 38:01
javascript so if you're coming from only a javascript background but want to know how to utilize near contracts um this won't be too much of a jump for you just some small syntactical changes so hang on tight let's just jump right in um so first what i want to do is i want to create a place that the regis that the candidates can keep track of the number of votes they have and that we can keep track of who's
- 38:26
voted and who hasn't so we can create uh some some logic for that later so let's say let uh candidate can candid registration equal to new persistent map so a persistent uh i'm gonna keep going in for a minute okay so present map string i32 and give it a unique identifier called candidate registration so i'm pretty sure this looks totally confusing to everybody which is you know like
- 39:08
it's totally understandable um but so let me explain it's actually happening here so a persistent map is simply just like a python dictionary or any other hash you'd see it's something that stores a key value pair so um just picture like you know i have some data structure that says that has this key let's call it key one i call key one in that data pair there's some value that's tied to key one
- 39:32
so um i mean like say if i call like i don't know like like you know candidate reg uh my keys name will be in this case the can it's a ron and then the value that's tied to the key ron is his number of votes so let's just say three um hopefully that makes sense i'll make more sense as i go on and make another persistent map called let voters reg equal to new persistent map uh i don't know why it's not popping up there we go string
- 40:12
bool bool is for boolean oh yeah and i 32 is just it's just a number it's just so don't um don't worry about that too much voters registration as i put these unique identifiers just to avoid data collisions within blockchain so just be sure to make something fairly unique um so i'm gonna call export function add vote i have to write exports make it public and i'll explain where this comes into play a little bit later uh we're gonna we're gonna request the candidate's name
- 40:54
i think that's all we really need so candy date this string so you always have to in typescript you have to kind of like tie your parameters to some data type and i'm going to return to colon return so this function will return uh let's just say hey number and i stu let's just get the number back i32 so it gives you this a little error here don't freak about that yet it just means like it's not returning and then never get never yet so if we do like return
- 41:27
want to then that error goes away um so what are we actually going to check for we're going to check first we're going to check if the um voter's registration or if the candidate we're going to check for a few things let's check out the candidate's name is in the uh case registration um if it's not we're going to add it uh and then we're also have to check if the voter's name is also in this registration meaning that they have voted before there's a much more dynamic and cool way
- 41:52
of doing this um where i where i wanted to like make like some with vote id so we can tie each unique subject to their own um their their own id or its own id uh but i think for the static application i want to try to keep it very simple um we can grow and expand upon that later so let's say uh say if let's check first for the candidate let's say if the candidate uh yeah let's just check for the voters registration so voters
- 42:26
registration if the nutrition contains context con context dot sender so this this value this what i'm calling here is just automatically populated when the user is logged in so context.sender meaning that like if i'm logged in as a as as blockheads.testnet i'm going to receive a string from this that says blockheads.testnet so i'm going to put that in comments for you guys so context i can't hit shift my shift number b there we go context dot sender
- 43:04
is equal to block heads dot test net so if it does contain context.sender i mean if we if the voter registration isn't here then we're not going to do anything but actually let's just do this so we're saying like if if the voter registration does not contain the voter then we are going to first add the voters so votersreg.set for setting the key the new key as the account name
- 43:55
and giving them a value of true we're just going to add true to um create the create the actual like dictionary so if it does not contain it we're first going to add their name to it after we add their name we're also going to for another conditional statement saying if the candidate registration doesn't does not so at the exclamation point contain the candidate so if it does not contain the candidate
- 44:34
first we're going to add it i'm going to say if it doesn't contain the candidate we're going to say same thing so candidate reg dot set candidate since we're since this is i'm being so since we're adding this new registration this new um candidate in this one voting function we can assume that once they call the advert function they're going to receive their very first vote if we're just adding for the first time
- 45:10
else meaning like if they are in the voters registration we are simply just going to say we're going to create a temporary variable called currentcount so currentcount is equal to candidatebredge.getsum we're going to retrieve the value from this key so candidate and then we're going to add one to that to that value so current count is equal to current count plus one then we're gonna say candidate reg dot set
- 45:53
candidate so we can call candidate ron or something we're setting ron with the value of the current count so we're saying current count is equal to current count plus one meaning that like we're just adding one to this old value so um and replacing that old value or this new values new current count into the uh the value for this key for this key so which is one bringing it to what we're going gonna return so i think
- 46:28
it's everything honestly uh so and we can add some like cool uh messages to go along with this um so we can actually see what's happening so we're gonna say uh we're gonna say if it does contain it doesn't if desktop is going to happen i also need to add another um another like condition just in case sorry so before i even add messages let's say else so we're adding an else for this if statement so else voter uh it's meaning like
- 46:59
if the voter tradition registration does contain the the uh current sender we're simply just going to well we can essentially just like run with it here again except we don't have to like set the uh we have to set a new um a new user a new account or a new voter so just copy this paste this because we're all assuming that like once this function say we're adding the vote right we have
- 47:24
to make sure that all this gets you know gets sent you know i should probably even like just houses another function but for now i think it's okay so i'm just copying and pasting what's in here and placing it in here um oh no that's actually wrong okay the clip clip this stuff okay so i can put that out the video so okay so we have to add our else statement so um meaning like the other condition if the
- 47:55
voter has voted before so they do exist within this register so else we just um give them a message saying logging log you have already voted let's run through all this again make sure we're all good so export function add vote we're accepting a string returning a number we have to return a number actually kind of forgot about that so return uh turn the uh candidate reg get some candidate
- 48:36
cool okay so let's make sure we run through all of this again so we have export function add vote we're accepting a candidate's name we're turning some number meaning the number of votes they currently have we are checking if the voter exists within the voter registration if they do not exist within that voter registration we're going to add their name to the list and then we're going to say if the candidate registration does not contain the candidate
- 49:07
we're going to set the candidate and give them one vote otherwise if they do exist within the candidate registration pull out their current number of votes add one to that adding this new voter to it and then setting that new value to the candidate's key otherwise um should the candidate should the voter exist within the voter registration we're just going to give them a message saying you've already voted then after all this is done no matter what it's going to return
- 49:40
the number of votes that the candidate has so this is our first um contract call so what we do from here you're going to take this name and we're going to move my little face i'm going to go utils.js and place it in the change methods um array as a string so what this does it makes it public for us to use and be able to call throughout our code um and also with the difference between
- 50:12
change method and view method is that view method will just retrieve some information in blockchain and display it for you or despite for you to use i'll change method actually adds or removes something from the blockchain i guess not necessarily move but it will add and modify the information on the blockchain so hit save here hit save go back up to utels or main.ts i'm gonna hit save every time you save the main.ts
- 50:42
um file it's just gonna rerun and create a new browser so you don't have to like go back to your browser just wait a minute so it opens up a new instance of your application inspect to call your function to see if it actually works we're going to do is going to say await awaits window dot contract dot add vote so this is an asynchronous function every contract call you make is gonna be asynchronous meaning that you have to
- 51:18
um write a weight or right inside of an async function for it to work um the parameter you're going to pass in here is actually an object with the name that you gave your property so candidate so candidate you can add multiple properties if you want just separate them by a comma um let's just put in a dummy name let's just say um i'm just going to actually let's just put a note just do is just give notepad so
- 51:48
nope um let's see if there's anything i'm missing we should get a number back meaning the number of website note we'll have at the end of this um let's see what happens so we have one vote for note so let's just try again let's see what happens if we try again there we go so there's a receipt nature is amazing and there's our message saying you have already voted and we could still can see that the vote for nope is still only one meaning that like no new vote has been added so there we go that's our add function
- 52:35
our add vote function so now i actually think will be useful is to create a function that allows to retrieve the votes that the candidate has also yes my hair did change i'm wondering if you guys even noticed that um moving on nature is amazing let's see i'm gonna say export function get votes candidate and string say when we go return i'm going to return i 32 which is just a number let's add the little braces and
- 53:14
we're going to first check if they even exist within a register so i'm going to say if the candidate reg dot contains candidate and we're going to do this we're going to say return say return candidate rich oh no candidate rich dot get some candidate else return zero well that's not a zero there we go cool so before i save this what's the thing what's the next thing that you do that's correct to go to the utils.js
- 54:09
also i could not hear you if you actually said the answer so i don't actually know if you're correct but i'm going to pretend like you said the right answer let's see so get votes save control tap i think it is now i'm gonna so now i have it saved in the details um so i have that you saved in utils.js so you say get votes here i'm gonna hit save in the main.ts and let's just see if it actually works so right notice i place that in the view
- 54:43
method or what's it yeah view methods array because i'm doing is just retrieving some sort of information from the blockchain i'm not really adding or changing anything to it so inspect move my little face so wait window.contract dot get votes remember to put an object as a parameter i'm going to keep saying that keep hammering that in uh and i'm going to say was it nope so we voted for so
- 55:16
okay and let's see what happens so cool nope has won now we never actually voted for ron yet so ron should not have any so ron and ron has zero so there we go we have our get votes method we are making progress our buttons work our buttons are functional but they are not complete because what happens when we click it you know we have to wait there's no notification that anything's actually occurring until we get this you know notification in our inspection tool so
- 55:56
other than that like i have no idea what's happening right here click the button nothing really shows up so i think will be useful is to disable the buttons after we click it to let the user know that something is actually occurring in the back end um so let's just you know jump in and do that let's find a way to disable these buttons so it's going to uh let's go to app.js go all the way up to this top line here
- 56:20
which says react and type in a comma and type in use state from react we're gonna go into our function type in const and we're gonna make an array we're gonna deconstruct the state we're gonna say button state as our first variable we're gonna say um for our change function uh change button uh camel case button state so if you aren't familiar with react hooks um this is definitely something i think you should
- 56:56
really familiar familiarize with yourself with because it's actually really useful uh it's just a way to set a state inside of a function based component so you state this use state function will allow us to set the initial value of button state we're going to set as false now the reason why we'll set this as false is here's the reason so let's go to um let's go to candidate and say let's just make something called button state
- 57:29
sequel to button state copy this there we go paste this in the other one hit save go back to candidate where are you candidate there you are now we're going to go over to here and say disabled disabled is equal to some jsx this dot props dot button state so this should be false meaning that we should see no change here but now let's go back into app.js hit save let's change this to true see what
- 58:20
happens there you go buttons do not work i cannot engage with them i cannot interact with them so that's exactly one so in order to make a function that allows us to do that once we hit the add vote button or submit button so let's create a function called const mod button or yeah let's just do mod button for now it's a find name pick an error function and then all we're going to do is call set state
- 58:54
oops i'm sorry uh that's that state what i'm saying uh called the change function so called change button state so this so this first parameter is just like our variable um this second parameter is the function that we'll call to modify the value of that variable this true is just the initial value of that variable so that that's all that's going on that's all you really need to know right now so let's keep let's keep pushing forward this parentheses is the new value that i
- 59:25
want to set as this value so um i'm going to type in just exposure point button state meaning that i'm going to set button state with the opposite value of true which is going to be false but also inversely if this were false that's my initial value in order to run this function the new value for buns tape would then be true hopefully that makes sense let me know in the comments if that doesn't make sense
- 59:59
nature is amazing so now i'm going to save this it's going to call mod button here equal to mod button copy paste also i hope you guys are familiar with like react lifecycle methods because that plays a big role in the cameras happening just in terms of when you modify state and how things re-render we render cycles but for now it's okay so let's just keep going so candidate.js and go to the add vote function we created
- 1:00:40
and just simply type in this props dot at uh what was the mod button my button and activate the function so save so no errors that's good it's very fresh oops i did something wrong let's go to app sorry go back to app.js and change this to false there we go pretty sweet we can vote we see the buttons disabled and then we get some message back saying that we either have voted or we didn't vote i've already voted so or ben is already
- 1:01:20
voted and we can't do anything other than that so now i won't be able to actually see like how many votes the candidates actually have right i mean it's good that they aren't displayed here because i don't want my vote to be biased yeah i won't be able to go in blind and see what everybody says right after that um so we're gonna need a new contract call it for that so i'm not quite done with the contract functions
- 1:01:44
i'm sorry guys uh so we're gonna go to main.ts and do export function call a function called did vote it'll just be it won't accepting parameters you really need any return what we're going to turn a boolean if i want to be true or false so i return voters reg dot contains and context dot sender meaning the account that i'm logged in with and honestly that's it that's all we need to do so yeah it wasn't too bad it's going to go back i hit save so it's
- 1:02:27
going to go to the browser right now so just have to give it a minute and cool but we're not gonna really use it yet just yet so the thing we have to do now after we make a new function in main.ts we have to go to utils.js and this i'm going to change methods and call did vote save that control tab we'll go back here now we can actually be able to use it so i'm going to see if this actually works
- 1:02:58
so i'm going to do a couple tests we're going to see um oops recall await window.contract and you know i guess sometimes i'm here to actually have to type a window so i could say contract since i'm in the browser contract or dot did vote and that should be true so it's true because ben did vote let's log out let's log back in let's go to dorian one two one two one two i don't think i'd use that one yet sort of game's dory anyway no wait
- 1:03:44
so window or it's a contract didn't vote and now we get false so there we go you can see here we can see we actually get deleted from that so next our goal should be is make to make this as pretty obvious for the user as possible so the user you know doesn't have to do that much when they're actually interacting with the app um meaning that or i'm referring to that um if the user is already voted i wanted to make it very obvious that they can't vote again meaning that these buttons are just
- 1:04:13
going to remain disabled so let's go back to our application or i guess our code and i'm going to go to candidate.js we're going to add a few things that's gonna make it um very clear that the user cannot it could no longer vote so i'm gonna do constructor constructor props it's called super props this dot state is equal to um let's go to an object so i'm going to get vote state so we're going to switch things up a little bit so bear with me so we're gonna say
- 1:04:57
this that's this dot props dot button state will set our initial value for our state variable inside the candidates component um you create a function called already voted so all ready voted inside this asynchronous function recall we're going to create a variable called did vote so that contract call we made earlier we're gonna actually utilize right now um remember it's an asynchronous function whenever we interrupt their contracts we're gonna
- 1:05:42
add a weight here so that the code doesn't doesn't continue to run without the needed value window window.contract dot did vote so if so this might be a little bit confusing but bear with me for a little longer so let me explain what's happening here so say this subset state vote gosh there you go so this dot set state vote state it's not false and we're also going to change one more thing before i keep going forward so i'm going to go to app.js and change this to true meaning that the
- 1:06:28
default state of the button will be disabled until we can check whether or not that the user has already voted i'm going to go back to canada.js and what we're saying here with this already voted is that if we say if we got that the user if if we i've got the boolean value that user did vote me if they do exist in our register um this will receive a value as false meaning that the button will stay disabled but if they did not vote this will receive a
- 1:06:58
value as true remember that we have this exclamation point inverting that um activating the set state feature changing the state and like changing the um button state to no longer disabled um so moving forward we need we're going to utilize the um life cycle hooks to manage to check whether or not these um people like these users have voted so or sorry we use lifecycle hooks to actually call
- 1:07:28
our already voted function so component did mount would be the very first one we create so in the component this map didn't matter we're going to call this dot already voted just activate the function so if i go back to my application i should see yeah so these are no longer changing you should say yeah that's fine so that's nothing here is changing because ben array voted let's switch ben to another user let's see what happens uh who do i not let's do tom snake juice if
- 1:08:08
you know what snake juice is i'm going to be very happy about that make sure you park's a red fan this snake juice is basically rat poison there we go okay so the mistake i made earlier was just to um change this from previously we had as many command z previously we had it as this that props that button state which is automatically simply true which means that the disabled property of the button is set to true me f8 button is disabled so here i'm gonna convert that back i'm setting
- 1:08:41
this to the state variable which receives this initial value from the property button state but then that initial value can be changed within the component itself to be false or true now what about this so this that props that mod button when i hit the button to actually vote um what that what's going to happen is so i actually hit the one to actually vote i want to actually um create
- 1:09:06
something that's going to monitor that property change or else these buttons aren't going to change um their state right away so i'm going to create something called component did update we're gonna keep an eye on the previous props so again uh this this does require kind of like an understanding of lifecycle hooks i won't go too deep into that but um if you need to kind of do some research on it this is life cycle hooks for um
- 1:09:38
class-based components um just to give you an idea of what to what to research so if previous props is not equal to this dot props now what's this mean this means that like if the old props are different than the new props then we're gonna execute some code so i'm gonna say this dot set state vote state is true so why am i doing this right so we have one function that checks whether or not the user is previously voted um at all and now we have this um
- 1:10:21
and that's going to determine whether or not the button remains disabled or becomes active after a few seconds of loading this latest feature we just added assumes that the user did not vote meaning that the button will load become active and then once we call this.props.mod button um it's going to change the state variable and the level app.js file and then bring it down and change the props in the candidate.js file and then this which monitors the change in that props
- 1:10:54
will change the state here causing a re-render cycle re-rendering the buttons to be disabled so i know that was a lot but again it's just that's just the idea of life cycle hooks so save it tom's snakejuice has not voted yet i'm gonna click on leslie note so now the buttons are disabled something you didn't forget to add is like a message getting that like we have actually voted it's actually you know let's do it right now we re-test
- 1:11:19
this so let's go up to main.ts let's go to just here let's say logging log candidate added and thank you for voting here we're going to say logging this logging log is just like a is essentially just like console.log and typescript so vlogginglog thank you for voting right we have an instance whether the candidate actually exists or not i mean two different messages based off that so it's going to re-render actually change our account again
- 1:12:04
see um switch over to another account and then see if we can if that little button trick we added works so good news is is now these buttons are disabled we can't interact with them anymore that's actually kind of what we want um let's go here join donna there we go so i don't think donna has voted yet if you can't tell i'm a little bit obsessed with parks and rec you don't even know one thing i didn't even say what they gonna do she asked me the whole thing and i didn't even do a what
- 1:12:33
let's send a vote to ron i think so ron and thank you for voting ron exists in our system which means that like we have this message saying thank you for voting and a button is not disabled if we refresh the page our button remains disabled so that's great that's everything it's almost everything we want we need one more feature and that feature is to show off the totals for our two candidates
- 1:13:11
you guys are awesome you guys have stuck with me this far and you guys have stuck through my craziness so let's keep going let's keep pushing through they have one more feature to add and that feature is to display the total result after the user has done voted or to show it our display result if the user has previously voted we don't want to display right now because you know we don't want to bias the vote if they never would have never
- 1:13:35
never voted before um so anyway so let's start off with adding a new state property so we're going to say display vote we're going to leave that as none and before you before i even go further in that let me show you i'm going to actually while i'm planning so i'm going to add list group and list group item i'm gonna pull these from react bootstrap and we go down here and just type in list group
- 1:14:14
inside that list group item inside that i'm just typing three it's a placeholder hit save so this is where our total vote's going to be this is the this is what's going to end up looking like um and what i want to do is i want to say style display this dot state dot display vote save that right now this is set to none so we should see is nothing is that kind of cool so all we're going
- 1:14:52
to do is just change this value to um to block when we if we want to see it or leave that's not if we don't want to see it uh we're going to set this uh we're going to first uh run up the changes in two places so we have our if statement here so if the user did vote then what's going to happen so if the user did vote it's going to be true the section exclamation point makes it false yeah this won't execute and the bun stays
- 1:15:17
inactive right but what happens um so what happens what else can happen if they did vote right you can write an else statement so this this line will like not activate being the button is going to stay um unusable and also we're going to just simply change so this stop set uh set state display vote to block so save that so we just voted with donna so donna should reveal the the vote output and it does that's good um so if we go over to a different user
- 1:16:04
again another parks and red character love tinnifer she's my spear general so in this instance the evoke when the vote buttons become active but we don't see anything we don't see the totals which is what we want so now let's go back and let's add this set state in one other area right and that is right here so we're going to say this dot set state um display vote to block so after they vote i want them
- 1:16:41
to be able to see the total output of their um of the vote so you know what i'm gonna do before i even do this i'm gonna put this here i'm gonna put this down here okay so now i'm gonna remind myself what yeah there we go so i want to see like so we're going to pull the values from get votes and actually place them into our total um our total vote number so we can actually see
- 1:17:12
the total votes i can candid.js we're going to add a new state variable called vote total and place a just place two dashes in here for now i'm gonna create a function called get total it's gonna be an async function and we're going to pass into this async function is we're going to have inside here's going to say we're going to set a value that will say um let's just say total is equal to let's just call this let so
- 1:18:02
let let total equal to window dot contract dot get uh what was it called get votes that's right okay get votes control tab and inside if you're going to pass an object called the candidate and this dot props dot title will give us the name of our candidate so now we have let total equal this value and we're going to call also going to add async to this so that the rest of this function doesn't run without getting the right
- 1:18:53
instance back so i'm starting to async recall await there we go so wait so once we actually have our value pulled um and safely stored in total our next thing is going to be to set this state variable with that new total so this dot set state object what was it called vote total the vote total is total so we're just placing this value in for that value i'm going to save that we're going to call um we're actually gonna call this
- 1:19:36
function in the component did mount lifecycle a method so get total we just call here because it doesn't necessarily like displaying anything we're just getting the value let's get total and then inside of list group item i'm going to call some jsx inside that jsx i'm going to call a conditional statement saying that if this dot state dot i'm always my brain is like i have the memory of a squirrel i promised you
- 1:20:08
okay so vote total is equal to this meaning like you know two dashes we're just going to display those two dashes however um oops uh add a question mark not the cool one okay there we go however if it's um not equal to those two dashes we are going to display this dot state dot vote total i guess we could just put this outside the foot to it i know i'm going through all this mess so let's let's just do that sorry guys oh all that
- 1:20:54
crazy work um i think i added another okay that's fine so yeah we can just say this dot state that vote total so let's see i should see that okay so let's see what happens so tenford's never voted yet so that's fine let's log in let's go to donna cool so it looks like they're evenly matched with two and two votes let's go back to tinifer and add a vote to ron to see if um let's see if everything is working
- 1:21:43
properly vote thank you for voting so we can refresh the page and we have three votes ron and two votes for leslie so that did make me realize we should probably um get rid of like one of these features so um let's go back to here and let's actually just remove i think we're okay with just refreshing your page so here it says add vote we're not actually updating anything so um i think i don't think we actually we're not getting the most recent update value we'd have to
- 1:22:22
call um we have to call another function that we create to actually update the value properly so let's just get rid of this line here and save that so next time we hit add and add we're not gonna immediately see the um the vote count for just that component that we hit the button on cool but overall i mean like this is our application this is exactly what we wanted this is pretty cool um let's go to
- 1:23:01
blockheads.testnet i remember buck has voted here out great so yeah it seems to be working it seems that we can actually add our votes we can display our final values and we have a fully functioning blockheads voting application we made it and i hope you guys had fun along the way i want to put out a challenge you guys make up your own version of the bog heads voting app that we created today
- 1:23:34
and send me the link to your github in the email in description below the top three submissions we get will appear in one of our upcoming blockheads videos as well you guys might be able to win a prize if you're featured in this video so that'd be a lot of fun i'm really excited for that like subscribe and comment below on what i can do to improve this content to make it better for you guys and as usual stay innovative keep learning and have a great day
- 1:24:08
all right where to first your mother's butt i'm so alone