Skip to content
by Unity Nodes
NEAR Protocol

Blockheads Ep 4: BLOCKCHAIN TUTORIAL - How to make a blockchain voting app

about 1:24:08 long

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 words

Captions as YouTube publishes them, usually machine-generated, so product and people names can be misheard.

  1. 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

  2. 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

  3. 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

  4. 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

  5. 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

  6. 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

  7. 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

  8. 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

  9. 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

  10. 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

  11. 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

  12. 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

  13. 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

  14. 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

  15. 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

  16. 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

  17. 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

  18. 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

  19. 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

  20. 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

  21. 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

  22. 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

  23. 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

  24. 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

  25. 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

  26. 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

  27. 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

  28. 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

  29. 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

  30. 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

  31. 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

  32. 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

  33. 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

  34. 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

  35. 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

  36. 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

  37. 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

  38. 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

  39. 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

  40. 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

  41. 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

  42. 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

  43. 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

  44. 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

  45. 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

  46. 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

  47. 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

  48. 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

  49. 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

  50. 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

  51. 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

  52. 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

  53. 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

  54. 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

  55. 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

  56. 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

  57. 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

  58. 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

  59. 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

  60. 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

  61. 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

  62. 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

  63. 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

  64. 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

  65. 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

  66. 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

  67. 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

  68. 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

  69. 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

  70. 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

  71. 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

  72. 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

  73. 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

  74. 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

  75. 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

  76. 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

  77. 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

  78. 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

  79. 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

  80. 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

  81. 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

  82. 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

  83. 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

  84. 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

  85. 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

  86. 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

  87. 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

  88. 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

  89. 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

  90. 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

  91. 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

  92. 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

  93. 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

  94. 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

  95. 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

  96. 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

  97. 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

  98. 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

  99. 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

  100. 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

  101. 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

  102. 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

  103. 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

  104. 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

  105. 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

  106. 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

  107. 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

  108. 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

  109. 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

  110. 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

  111. 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

  112. 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

  113. 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

  114. 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

  115. 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

  116. 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

  117. 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

  118. 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

  119. 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

  120. 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

  121. 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

  122. 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

  123. 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

  124. 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

  125. 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

  126. 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

  127. 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

  128. 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

  129. 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

  130. 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

  131. 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

  132. 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

  133. 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

  134. 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

  135. 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

  136. 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

  137. 1:24:08

    all right where to first your mother's butt i'm so alone