Python Web3 Development #4 - Connecting The Frontend and Backend

Tech With Tim · Beginner ·🌐 Frontend Engineering ·2y ago

Key Takeaways

The video demonstrates how to create web3 applications using Python and the Cartesi library, connecting the frontend and backend, and utilizes tools such as Metamask and Linux distributions.

Full Transcript

hello everybody and welcome to video 4 in this tutorial Series where we'll be continuing from where we left off and coding the rest of the back end now I'm inside of the main.py file so make sure you navigated there in the previous video we handled all of the routing so now all we need to do is actually write the individual functions now I think it makes sense just to start by writing the create challenge function and then we can go through accept reveal and then finally get challenges now first things first I just want to declare a few Global variables here that we're going to need to use throughout the rest of the code so the first variable we'll need is called challenges and this going to allow us to store all of the different challenges that are going on so we'll have challenges is equal to an empty dictionary and then we will have player uncore challenges is equal to a dictionary as well now this will store a key value pair which will have the player's address associated with the challenge they're currently in this way we know if a player is in a challenge and we can only allow them to be in one challeng challenge at a time at least that's what I'm going to do now I'm also going to have next ID equal to zero now this is just going to keep track of what the next ID of a newly created challenge should be so that all of these challenges have a unique identifier now notice here that these Global variables are actually like the state of our application if you've ever worked at solidity before you know that you have state variables or storage variables and that's exactly what these are in Python any Global variables or really any variable at all that we have stored in some glob context will just be here forever so this acts kind of just like storage or state and there's not as many restrictions on this as there would be in something like solidity okay so let's go over to create Challenge and the first thing we need to do when we're creating a challenge is we need to actually get the commitment from the user who created this challenge so to do that we're going to say commitment is equal to payload doget and then we're going to try to get the key commitment now I spelled that incorrectly so let's spell that correctly remember that payload is the data that's been sent in now inside of the payload we have a method and we could have some other data as well now what I'm going to say is when we're creating a challenge we want the user to send us their commitment which is that secret string so we're going to check the payload and see if that commitment is inside of there and if it's not inside of there we're going to tell the user so we're going to sa not Commitment Report no commitment okay so like that and then return reject now we're going to do this add report so that's spelled correctly okay so that's good next thing is we need to make sure that the player that's trying to create this challenge is not already inside of a challenge so we're going to say if player challenges. getet the sender which will be the key of the player and we're going to say if that is not equal to none then we will add a report and we will say player is already in a challenge and then again we will return reject because an error occurred okay so at this point we've checked the two preconditions we've made sure that they sent us a commitment and they're not already in a challenge now what we need to do is make a new challenge and Associate it with that player so we're going to say challenge is equal to challenge remember we imported this at the top of our program and if we go back to challenge we can see that we need the Creator address the ID and the commitment for this challenge so we're going to say sender we're going to say next ID and we are going to say commitment like that now that we've created The Challenge we actually need to store it so we're going to say challenges at the next ID is equal to this challenge that we store it inside of that dictionary and we're going to say player challenges at sender is equal to the next ID so this is indicating this player is currently associated with this challenge then we're going to add a notice this notice again will be verifiable on the blockchain and something that we kind of want to spit out in log and say okay someone created a new challenge so we're going to make an FST string and we're going to say challenge with id nextore id was created by and then this will be the sender okay then lastly what we will do is we will say next ID plus equal 1 and we're just going to Global next ID here and what that will do is allow us to actually increment this value so the next time we make a challenge the ID is plus one right so it's a new ID we have a unique ID for that challenge make sure you add this otherwise you'll only ever be able to have one challenge at a time okay so that's all we need for creating a challenge if someone calls this successfully it will make a new challenge again assuming they're not already in one and they sent us a valid commitment okay so now we'll go over to accept challenge now if a player wants to accept a challenge we need to know first of all what challenge it is that they're accepting and they also need to send us a commitment so what we can do is a similar thing to what we had before we're just going to copy this line here so commitment and we also going to look in the payload and get the ID of the challenge so we're going to say challenge uncore ID is equal to payload doget and then challenge ID okay so again we want them to send us commitment and the challenge ID so now what we'll also do is we'll say that the challenge they're referring to is equal to challenges doget and we will try to get the challenge with the challenge ID that they sent and then we will check if that challenge exists so we'll say if not challenge add a report and this will say challenge does not exist and then we will return reject otherwise we will we will say if not commitment okay then we will say add report no commitment okay and return reject and then lastly we'll do the exact same thing here so we're just going to copy this line and paste this here and make sure that this player is not already inside of a challenge okay recapping we get their commitment we get the challenge ID we see if there is actually a challenge with that ID so that's what we're checking here we make sure that they have a commitment and we make sure they're not already inside of a challenge now at this point we pass all the preconditions so we can actually add them to our challenge so we're going to say challenge. add opponent because now we know this is a valid challenge because it does exist now to add an opponent we need the sender and we need the commitment remember if we go back to challenge here we have a method add opponent right this just adds them in and kind of accepts the challenge so we need to pass the address in the commitment which is what we do now after we do that we need to add this challenge to them so we'll say player challenges at sender is equal to the challenge ID that they submitted okay and then we will add a notice this again will be an FST string and we will say challenge with ID and this is the challenge ID was accepted by the sender of this uh what do you call transaction okay so that is all we need for accepting the challenge get the commitment get the challenge ID check our preconditions add the player to the challenge and at this point in time if someone has accepted the challenge both the commitments are there and the next thing we need to do is actually reveal what the answers are now there's a bit more to this because this reveal function will also need to determine the winner once uh both players have revealed their answer so let's go inside of reveal and start coding this out first thing we need to do with reveal is we need to get the move and we need to get the nons that the player is submitting so we can verify if that actually matches with what their commitment was so we're going to say move is equal to payload doget move and we're going to say the not is equal to payload doget and then not like that okay then we're going to say the challenge ID is equal to player challenges doget and then sender so we're going to say if challenge ID is none then add a report did not mean to do that there and this will say challenge does not exist and then we will return reject remember that when we need to reveal we need to get the move and the kns we then hash that and check that against the commitment and ensure that the player uh did not lie and that they are actually telling us the correct move that they committed to previously now what I do is I just make sure or I check sorry the challenge that the player is currently a part of by getting it from the player challenges if they're not a part of a challenge and they have no move to reveal so we simply reject okay so now we're going to say challenge is equal to challenges do get and then challenge ID that's so we have access to the challenge object now I'm going to put a try and accept block and I'm going to accept an exception as e because there's many exceptions that could occur in what I'm about to do and just down here inside of my accept I'm going to add a report and I'm going to say error colon plus the string of e like that and I'm going to return reject so this way we're just capturing any errors and just putting those inside of a log uh what is the error here e is not defined okay that's fine once we write the try this should be good okay so we're going to try to reveal the move so we're going to say challenge. reveal and then we're going to pass the sender the move and the knots if we go to challenge and we look at reveal wherever I have that so it's right here we take the address the move and the Nots so that's exactly what I'm doing now notice inside of here an exception is raised if the move does not match so that's why I'm handling the exception here if they submit us the wrong move now what I'm going to do if this works successfully is I'm going to add a notice this will be an F string again I'm going to say challenge challenge ID and this will be the sender revealed their move of and then what we want to do is convert their numeric move to string move so we can read it in the logs so we're going to say move. move to string the int of the move okay if we go back here to move just to show you we have this method right move to string takes in an integer representing the move and then gives us the string representation so what we're doing is just using that so that we can print out the player had a move of rock or paper or scissors not 1 two or three okay now that we've done that what we need to check is if both players have revealed their answer because if they have we need to actually determine the winner so we're going to say if challenge Dot and this is both underscore revealed then what we're going to do is evaluate the winner so we're going to say winner is equal to challenge Dot valuate winner like that and we will kind of add some notices to tell the users who won so we'll say if not winner so if there was no winner that means it was a draw right so we'll just add notice and we'll say F and this will be Challenge and then we're going to put the ID so what is this the challenge ID ended in a draw okay otherwise if there was a winner then we're going to say add notice we're going to say f challenge challenge ID was one by and then this will be the winner okay so we'll just print out with the Winner's address is sweet then we can go here and we can return accept but we're going to do that make sure it's outside of the if statement otherwise you're going to get an error if you don't have any return so we need this kind of outside of the if statement here okay so let's quickly go through this get the move get the kns make sure the player is inside of a challenge get the challenge attempt to reveal the move if an error occurs we'll handle that here let me just get rid of that accept statement down there we don't need that inside of here reveal the move add a notice with what the move was check if both the players have revealed if they have then we can evaluate the winner if there is no winner it means it's a draw so we say that and if there was a winner we just indicate the winner now last thing we need to do here is simply delete the challenge or remove it from the players that um are playing inside of the challenge so I'm just going to going to make a little helper function here and I'm going to say Define delete challenge this will just take in the challenge ID so what we can write here is if the player challenges doget and this is challenge Dot and the opponent uncore address so we're going to say if that is not equal to none then we will simply delete this so let's go D and take this now let me just quickly explain why we're doing this so our player challenges we have an address associated with an ID right so what we're doing first of all is we're just making sure that the address we're about to delete here exists because if we run this code and it doesn't exist inside of the dictionary we'll get an error so we say if player challenges doget the challenge. opponent address I'm just checking the opponent first next I'll check the check the Creator stor if it does exist we'll simply delete that from the dictionary now we can can copy this and paste this down here and we'll do the same thing except now it'll just be the Creator address and then Creator address like that okay so all this is doing is simply removing the challenge associated with a player from this player challenges dictionary which we have up here as a global variable so now what we'll do is we'll go into the reveal and when we do have a winner right so when both players are revealed then we will go and we'll say delete Challenge and we'll pass in our challenge now notice the indentation levels here they're quite important we want to make sure we only have delete challenge inside of if they are both revealed okay if we don't have that we're going to get an error because if we put it here once one player reveals then we'll delete the challenge and then that will cause errors for us so we got to make sure it's inside the right indentation level okay now that we have reveal and we've deleted and we've cleaned everything up we want to write get challenges then that will actually be all of the code we need for the back end and then what we'll do is we'll start writing the front end so that we can actually test this code it's a lot easier to test it once we have our own custom front end so we'll spend a bit of time setting that up I know it's kind of annoying to write a lot of code and not test any of it but in this instance we actually need to kind of write the front end to be able to interact with this in a way where we can actually test it anyways for get challenges what we want to do is we want to list all of the different Challen and we want to give some meaningful information about them so we're going to start by say challenge Keys is equal to challenge. Keys okay this just gives us all of the IDS of the challenging keys or the challenges Keys okay so challenges. keys we're then going to say the challenge list is equal to and this will be an empty list now what I need to do is I essentially need to parse through all of my challenges and convert them to some kind of Json serializable object so something like a python dictionary so that's what I'm going to do here I'm going to say for challenge ID in challenge keys I'm going to get the challenge I'm going to say challenge is equal to challenges doget and then challenge ID and then I'm going to get the opponent move the Creator move and I'm going to kind of make a list of all of the information we'd want to know about a specific challenge so I'm going to say opponent move is equal to challenge do commitments doget okay and then I'm going to say challenge. opponent uncore address I'm then going to say the Creator move is equal to challenge. commitments. get and then the challenge. Creator address so just a show you why I'm doing this if we go to challenge you can see that we have this dictionary here right inside of this dictionary we have an address associated with a move so what I'm doing is I'm just getting this move object here when I access these right here okay so now that I have that I'm going to go down here and I'm going to say challenge unor list. append and I'm going to put inside of here a dictionary that contains all of the information that I want so I'm going to say the challenge ID is equal to the challenge ID I'm going to say the Creator is equal to the challenge. Creator address I'm going to say the opponent is equal to the challenge. opponent address Okay so we've got the Creator we've got the opponents I'm going to say the winner is equal to the challenge. winner because we'll have that information stored then I'm going to say opponent committed and this is going to be equal to challenge. has underscore ponent underscore committed now I know I spelled that incorrectly uh I'll have to fix that let's go over here though and have a look at this method so has opponent committed okay so I'm just going to copy that and paste that here so this going to tell us okay do do we currently have another player or is this challenge still open to be accepted by someone then we're going to have opponent move and this is going to be equal to the opponent move do move if the opponent move otherwise none so what I'm really saying here is I only want to try to access this move if the opponent has made a commitment and they actually have a move otherwise if the opponent move doesn't exist so if they haven't um kind of accepted this challenge yet if I try to access do move that's going to give me an error so I need this little inline if statement here where otherwise I just display none okay now we'll do the same thing for the Creator move so we'll say this is simply going to be equal to the Creator move do move the reason why I don't need the if statement is because I know that this will always exist because to create a challenge you must submit a move perfect so now outside of the for Loop what I'm going to do is I'm going to convert this list that contains all of these dictionaries into a Json object that I can actually return from my code so I'm going to say output is equal to json. dumps which stands for dump string and I'm going to put challenges like this and it's going to be associated with the challenge list then I'm going to add a report and I'm simply going to add the report which is this output and then return accept Okay so let me just break this down a little bit remember that we're going to be returning and receiving Json okay JavaScript object notation I need to make sure that anything I return from my code is Json serializable so it's not possible for me just to return the kind of challenges dictionary because that contains python objects like challenge move Etc that don't have a known way to be serialized serialize just means converted into Json essentially so what I'm doing is I'm kind of just manually converting them into Json and Json is any valid types right so in our case valid types are like strings integers booleans numers Etc right so that's what I'm doing here and that's why I had to kind of parse through these different dictionaries to make sure I got all of the values that we can actually put inside of a Json object anyways we add all of our challenge objects here into the challenge list we convert them to Json and we simply make a report that the user will be able to access when they call this function okay so that's pretty much it that actually wraps up the entire backend now that we have the back end done I want to start writing the front end so we can actually interact with our backend end now one thing to note is that if we make any changes here in our backend we do need to rerun this now there is a command from the caresi documentation that will automatically reload it but I'm just going to rerun the back end and you can see that we actually got an issue here it says Dell player challenges dog get okay well that makes sense so let's go fix these issues really quickly so I have this the reason why I'm getting this is because I'm using doget what I need to do instead is I just need to put these in square brackets so that I'm actually deleting the key inside of the dictionary okay so hopefully that's going to work probably we'll have some other errors as well but let's run this now uh and see if we get any issues okay looks to be fine and we'll see when we interact with it if any problems occur okay so I just reran this now the back end is finished and we want to write the front end now what we'll do just to make our life a little bit easier is if we go here inside of the cartei rollups uh what do you call this repo we'll see that there is a frontend echo now this frontend EO is just written by cesia it already contains a few dependencies and this allows you to interact uh with your application but only the echo applications not the one that we wrote so what I'm going to do is I'm just going to copy this so just hit contrl C there and paste that inside of my folder so that we already have kind of a front end directory set up with our react code and we can just modify this slightly so let me close this let's make this a bit bigger and I'm just going to rename this to be front it now let's have a look at some of the code here so I know there's a lot of files popping up but we have a get ignore we have our source we have public we got a bunch of stuff we don't need so it's actually going to be faster to do this I'm just going to delete a bunch of these files that we don't need so like monster and all this stuff we don't need those index. HTML uh we can change the description if we want so we can just say rock paper scissors and same with the title rock paper and scissors okay then we can go to source and we can start deleting a few things I'm just going to delete everything inside app.css I don't need that for app.js we can delete everything inside of here except for the div and we can just remove some of the things that we don't need so I'm going to remove Echo and Roar here because we don't need those I'm going to get rid of Echoes and Roar okay let's delete those index. CSS that's fine we can keep that index.js we'll keep all of this stuff cuz we're going to use this later and that I think is okay for Source anything else package.json we can change the name here to say rock paper scissors and this has all of the dependencies that we will need okay so now that we've kind of set up this front end directory what we'll do is just go in and build it so I'm going to go to my console now keep in mind you don't need to do this from WSL you can do this from any terminal you want because the front end is kind of separate from the back end and it can run in isolation so what I'm going to do is type CD do Dot and I'm going to CD into the Rock Paper Scissors directory and I'm going to CD into my front end okay so now we have this front end directory now what we'll do is we'll just type yarn and when we do that it should install all of the dependencies that we need or all of our node modules so give this a second and you can see it's generating the node modules directory all right so all of that is installed and what we'll do now is we'll just start working on the front end now for our front end we're going to use metamask to interact with our application now the reason we'll do this is we can very easily change between accounts because we need to have some different users to be able to test creating and accepting challenges right we need to have user one user two user three whatever and they need to be able to well accept the challenge create the challenge Etc so what we're going to do is just remove this account index I don't need that for now and I'm going to start setting up something known as the signer now the signer is the account that's kind of currently authenticated with our web page using metamask now to set all of this up we're going to use something known as ethers it's going to look like a little bit of gibberish if you've never seen this before but just bear with me this is a library that we actually just installed by copying that kind of front end um directory here and this will allow us to connect with metamask and get some account information send transactions Etc so what we're going to do is set up some State we're going to say const signer and then set signer like this is equal to use State and this will be undefined for now because when we start the app we don't have Aigner then we're going to have a use effect and essentially as soon as the application loads we're going to try to connect to metamask so let's make our use effect hook inside of use effect we're going to say if the type of this needs to be inside parenthesis so if the type of window do ethereum is equal to undefined then what we will do is we will return an alert and this alert will say you need metamask to use this application okay so this is just checking to make sure that we have metamask installed window. ethereum kind of exposes the metamask extension or some other types of extensions as well but in this case metamask if we don't have it will tell them hey you need metamask for this to work okay otherwise we're going to try this so we're going to say try catch we're going to catch an error so we'll just handle this first okay we'll say console.log and we will log out what the error is and then we will alert and say connecting to metamask failed okay so if an error occurs during the connection process that's what we'll do otherwise just giving myself some space here we're going to say window. ethereum and then this is do request and we are going to request the following so we're going to say method inside of an object and this is going to be fcor request and then account make sure you type this exactly like I have now what this is going to do is request to connect to the different ethereum accounts we have in metamask we're then going to have a then so we're going to say do then and inside of here we're going to create a provider so we're going to say const provider is equal to new ethers do providers. web3 provider and we are going to connect to window. ethereum which will be metamask okay I know this seems weird but the way this works is in ethers we first create a provider the provider gives us access to a bunch of different accounts in this case we are creating the provider from the metamask extension in our browser that's really what's happening that's all we're doing then what we need to do is get the signer and the signer is essentially getting the current account that is active in metamask that we'll use to sign transactions so we're saying consigner is equal to provider. getet signer and then we're going to say set signer like that and we're going to set this signer okay that's it for the use effect this means when we first open up the window it should attempt to connect us to mask sometimes this will just happen automatically sometimes it will prompt you you got to type in your password Etc and then it should give us the signer okay so we can actually test this out by running our react application so to do that I believe we just type yarn start and that should actually run react so let's give this a second to run and see if this works all right so I ran react and I just got an error here saying ethers is not defin so we just need to import ethers just forgot about that so we're going to say import ethers like this from and then ethers okay so that should fix it now let's go here and we can see nothing's really happening but if we go to metamask notice that we have um kind of this little popup here and that's essentially saying hey you know we want to connect to metamask so let me type in my password I'll be right back all right so we are now connected and you can see that I have a few accounts and I'm actually connected to the hard hat Network now what I'm going to do is just remove a few of these accounts because I want to show you the process of adding them and I don't want to have this already set up beforehand so let me just remove any of them that it will allow me to remove okay that's fine now notice here that I am on the hard hat Network now this is a network I've manually added to metamask obviously I think goes without saying you need to have metamask installed for this to be working but if you don't yet have the hard hat Network which is the local node that we're connected to for our development environment you're going to need to add that so you can go to add Network and it will bring you here and it should show you a few options now you're going to have to add a custom Network so if we go full screen here we can add a network manually now for the network name you just call this hard hat let me just zoom in a bit so you guys can read this for the new RPC URL we have to enter in the URL for hard hat which should be this okay so HTTP col1 127.0.0.1 otherwise known as Local Host and then Port 8545 now it's saying it's already being used because I already have this network but I'm just trying to show you what we need to type in so make sure you type in this exactly and then you type in 1 337 or sorry 31337 that should be the chain ID now for the currency symbol I don't think this matters but I'm pretty sure you just type in E and then assuming that this is uh not incorrect you should be able to just go right so again I already have this added which is why it's not letting me add it but you guys should be able to add it using this if for some reason e is not working it's prompting me to use go doesn't really matter what the currency symbol is so just use whatever it tells you okay so I'm going to cancel that because I don't need that if I go to hard hat you you can see that this is my setting so hard hat 31337 and then hard hat eth okay so I guess you can just go with that and you do not need a block Explorer URL okay now once you change the network here what you're going to want to do is reset your accounts or if they don't have it here clear your activity tab so if you're ever getting any errors where transactions aren't going through or things are kind of being messed up and you're not sure what's wrong what you can do is open up metamask go to Advanced and just click clear activity tab when you do that what it's going to do is reset some of the nonces and some of the state metamask is caching for this network so whenever you kind of restart the node so let's open this up here right if you restart this node which we can do right now so let's just close this all right sorry for the cut there but anyways this is stopped right so I'm going to run the commands now that will actually shut this down and then once we restart it so let's go back and compose it up once this gets running again you go here and you clear the activity tab just to make sure any of the accounts that you have don't have all of the nonces in the cach data okay so I'm going to go back here and we're almost done but what we want to do now is actually add some accounts to uh our hard hat Network so I'm not going to connect to one of these I'm going to go to accounts and I'm going to go to add account and I'm going to import an account now what we'll do is when we see our node here we can actually see if we make this a little bit larger that at the very beginning it will spit out some PR keys and they're Associated accounts so you can just grab any random ones you want but I'm going to go with account five for example I'm going to copy this private key again this is in the logs right when your node starts running okay so grab one of the private keys go here and paste it in and hit import now what that will do is actually import a new account for you again I'm going to clear this transaction kind of cash in a second now I'm going to go add account again import account and I'm going to go back here I'm going to find find a private key so let's just go to account number 13 doesn't matter which ones you use they all are just pre-loaded with 10,000 eth that you can test with so we're going to go back here smiss okay add account import account paste this in and now we've got a new account now for some reason the accounts are glitching for you you can just get a different account again go back here and just copy another one uh oops this one shut down sorry this is what I meant so let's go get you know a count 18 just to be safe go here and we'll add another one okay so dismiss account add account import account and import okay so we're going to use account number six and account number seven for our testing just because they don't have any transaction history so we're not going to get any weird cashing issues again I'm just trying to make this super clear because metamask can be a little bit glitchy when you're switching between networks and using local nodes and stuff that keep going up and down so if you do have issues just make sure you refresh those accounts and you can add the new private keys if you keep restarting or rerunning your environment all right so this is working now we're connected with metamask let's rerun our back end though because as soon as you shut down the node the back end's going to disconnect from that so now we've got the node and we've got the back end running now we want to start actually writing some code on the front end that allows us to send inputs or transactions to our back end so let's go ahead and do that all right so we're going to make a new component here in our source directory of front end and we're going to call this create challenge. JS now for this component obviously it'll do what it says create a new challenge so we're going to say import react and use state from react like that we're then going to import some pre-built components so we're going to import button use toast and select from and this is going to be at chra I forget how you pronounce this chakra I don't know ui/ react anyways this is a component library that has some components for us okay so now we're going to say function create challenge we're going to take in a signer as a prop and we're going to start setting up some state so let's start by setting up some State we'll say const Choice set choice is equal to use State and by default we'll just set it to one which will be Rock we'll then say const toast is equal to use toast this just allows us to kind of pop up some notifications on the screen and we're going to say const loading set loading is equal to use State and for now it'll be false just so we have a loading indicator when they are actually creating this Challenge and they can't spam the button now we're just going to set up a function so I'm going to say aset async sorry function create challenge okay inside of here this is what we'll do to actually create the challenge and we're going to have another Asing function which will be handle submit this will take in some events and what this will do is handle the submission of a form which we then call create challenge so we can actually write this right now we're going to say event. prevent default we're going to say set loading is equal to true we're going to say await create challenge we're going to say set loading is equal to false okay so all we're doing is we're just going to set loading we're going to wait for this to finish and then we're going to say set loading is equal to false okay pretty straightforward we're just setting some State okay now what we're going to do is create the UI so we're going to return a div the class name for this div can be the challenge form if we want to style this eventually and we can make a form now we can say on submit is equal to and we can call the handle submit function when we submit the form so now we'll actually import heading here and we'll use a heading so we'll say heading like that for the size we can specify that this is going to be large and then we can do create challenge like so okay so that's just going to be the heading for our form then we can have a div we can have a label in here the label can say Choice okay so this is the choice that you're going to select when you are uh kind of creating the challenge and we're going to have a select field okay so for the select I'm going to say the focus border color is equal to Yellow going to say the size is equal to medium the value is equal to choice and the onchange event which is the most important is going to be the following so so we're going to take in event and we're going to say set choice and let me just save this or format it so that we get some better uh kind of spacing here we're going to say event. target. value okay what I'm doing uh just to clarify here is I'm setting up a select field which will have a few different options that we can just choose that we can click on so kind of a drop- down menu and we're setting the value of this field equal to our state variable Choice and then whenever we change the value we're going to get the event and we're going to get what we clicked on so whatever the value of the target was and set that to be our choice now inside of Select we need to specify the options so we're just going to say option first one is going to be Rock okay and then we are going to have paper and scissors however what we want to do is associate these with a numeric value so we're going to say value equals 1 value equals 2 and and value equals 3 so that when you actually click on these here they get converted or sorry not get converted but when you click on these we get the value not the inner HTML so we end up setting the choice to be one two or three we don't set it to be uh what do you call Rock Paper Scissors okay now what I'm going to do is just make this value a string as well just so it matches and now we should have the main UI the last thing we need is a button that will submit the form so we're just going to say button here and and we're going to say type is equal to submit we can set the color scheme so I'm going to say the color scheme is equal to yellow and for the button we will just say create challenge like that and I'm going to do one more thing I want to add some state to the button that indicates if we are loading or not so I'm going to say let button props equal to this I'm going to say if loading then button props do is loading is equal to true so I'm just going to set this property and then I'm going to go here and I'm going to say dot dot dot button props so this way if we are loading the button will appear as if it is loading otherwise we just won't do any changes okay so let me save this and format and now we should have the main component of our UI obviously there's some more stuff that we need so let's go down here and Export this we're going to say export default and then what is this create challenge we're then going to go to app.js and we're going to import this so we're going to say import create Challenge from create Challenge and we'll just throw this in here so we'll say create Challenge and we will pass our signer so signer is equal to signer okay so that should be the first part of the UI I know I went a little bit fast there obviously you can pause the video type it out all of this code will be available from the link in the description as well we're just setting up the form to create the challenge this function is the logic we'll need to write to actually send the transaction to create that challenge but obviously we can't do that yet because we don't have all of that logic so let's go here though and just look at our what is this UI and there you go we have create challenge we have our choice and we can choose doesn't look super pretty we can style that in a minute but for now let's get this actually functioning okay so we want to write create challenge now in order to create the challenge the first thing we need to do is we actually need to generate our commitment so what I'm going to do is write a helper function I'm going to go to Source I'm going to type .js and I'm going to put a utility in here that can do some of the hashing and cryptography for us all right so we're going to start with our hashing function which is probably the most annoying we're going to say export async function generate hash and we're going to put inside of here input now what we're going to do is create an encoder we're going to say const encoder is equal to new text encoder and a lot of this is going to seem like gibberish just bear with me um this is just a function that will create the hash you don't have to worry too much about exactly how it works so don't stress about it we're going to say con data is equal to encoder do encode and we're going to encode the input we're then going to create a hash buffer so we're going to say con hash buffer is equal to a weit crypto do subtle dot digest and then we're going to say that we want to use the shaw 256 algorithm which is the same one we used on the back end which is very important we're going to take our data which is this encoded heximal input we are then going to say the const hash array is equal to array. from we're going to say new uint 8 array from the hash buffer we're then going to say the const hash hex the heximal version of the hash is the hash array map we're going to take in B we're going to say b do2 string base 16 that's what we're doing here pad start to zeros okay then we are going to return the hash hex don't ask me why all of that works a lot of this code I did just get from chat GPT but I can promise you it does create the correct hash that we need I know pretty confusing just type it out don't worry about it you can ask chat gbt to explain it to you if you're really stressed about what each line is doing now that we have the hash function though we can write another function and say export con generate commitment not hash okay now we should probably Spell commitment correctly I think that's spelled correctly actually and we'll say this is equal to an async function and this can take in the choice and the signer and this will generate a commitment for us that is the hash of our what is it um what do you call it the move and our knots that's what we want okay so what we need to do to generate the commitment is we need to actually create a random number and we need to store that random number somewhere so we have access to it when we reveal our move now this is where we're going to create another file and we're going to call this constants .js now inside of here I'm going to define a few constants that we're going to need two of which are going to be the keys that we're going to use to store a value in something known as local storage now local storage is associated with your browser so what we can do is we can store the random numbers that are associated with a specific account and the challenge that they are in in our browser and that way we're storing them locally on the client side we're not exposing it to the blockchain until we reveal our answer so the reason I'll store it in local storage is so that if we refresh the page we leave the page we come back to this page we still have it stored there so we'll be able to actually reveal the answer and complete the challenge you'll see what I mean in a second but let's define these constants so we're going to say export const and this is going to be the nons key and this is just going to be equal to nons okay we're going to say export const move key and this will be equal to move now doing them in all capitals just because they are JavaScript constants I'm going to go to util now and I'm just going to import those because we're going to use them in a second so in util I'm going to say import and this is going to be the nons key and the move key from my constant now inside of the generate commitment what we're going to do first is get the address of the person who is making this commitment so to do that we take the signer and we say. get address but this is a promise so we need to await it to get the address from the signer which is from metamask okay we're then going to say constn is equal to math. random multiplied by a large number I'm just going to multiply it by what do you call this here 10,000 this is going to give us a random number between 0o and 10,000 so that's what we're going to use for our random number you can make it more secure by adding more zeros if you want although either way we're still going to get a large decimal value so it doesn't really matter in fact you don't even have to multiply it but I will okay we'll just multiply by th anyways we're now going to say local storage do set item and we are going to set the nons key plus the address and actually yeah address. two lowercase to be the knots now what I'm doing here in local storage is I'm making a combined key now the combined key is simply Nots so whatever we put in UIL which is is just the string nods plus the address of the account that created this nods the reason why I need to add this part here is because we're going to have multiple different accounts that could be interacting from the same browser so I don't want to override previous nonces that other accounts have created so when I store the knots I store it with the address of the account that created that knots that way we can also access it only when we're signed in with that address hopefully that makes sense but that's kind of this works now we're going to do the same thing here for the choice because just like we're caching this random number we also need to cach the choice so that we know what that is when we go to reveal the answer so we're going to say move key plus address. to lowercase and then this is going to be choice now it's important that we convert the address to lowercase because sometimes they have like mixed capitalization and it can cause some issues when you're checking the local storage if the capitalization is off so I just always convert to lowercase just to be safe okay so now we've stored the nons and the choice which we'll use during the reveal phase now that it's stored we'll create a hash of it so we'll say cons commitment is equal to await generate hash so let's fix that and for the hash we're going to take the not. two string plus the choice which should already be a string we're then going to return the commitment okay so what we did is we got the address we generate a random number we store the random number and the choice that the user made and then we create a hash that takes the nons first and then the choice the order here is important it needs to be in this order then we return the commitment which will just be a random string notice on line 15 we're generating a random number using math.random now this will generate a random floating point value between 0 to 1 and then we multiply it by a th000 what that means is we're going to have actually quite a few decimal places in our number and we have a floating point value here now we really shouldn't use a floating point value for our nons because the amount of digits that can be represented floating Point digits that is in JavaScript is different than in other languages say like python or go or whatever our back end is written in so what we should really do here is actually round off the nons now in this video I don't do that and I end up using a decimal value and you'll see that everything works completely fine but I wanted to mention that really we shouldn't use a decimal value Nots we should use a whole number so ideally what you would do here is just round it off you just simply round it to the nearest whole number and that way you'd avoid any significant digit issues with kind of values in different programming languages and how things are handled okay so we now have the two utility functions we need to generate the commitment which also involves generating the hash now we also need a way to send an input to our smart contract or to to our back end now to do that we're going to go over to constants and we're going to write another few variables so we're going to say export const and to be able to send something right to be able to send a transaction we need to know where we're sending it so we're going to get the DAP address of our backend okay so we're going to say export con dap address I'll show you how we get that I'm going to say export const default URL okay and this is going to be equal to the URL that I'll type in here which is HTTP Co Local Host Colin 55/ inspect just copy that in don't worry about that a ton that's just the port essentially that we are running the kind of inspect server on WE we'll talk about that later but just put that in we're then going to say export const and we're going to say input box address is equal to the following so let me just pause here and explain something when we send a transaction to our backend so something verifiable on the blockchain it needs to First be logged on the blockchain so we need to send the transaction to the blockchain it then needs to get forwarded to our cartez node where it can then be handled by the cartei framework and our backend so what we're going to do is use something known as the input box now caresi will deploy a series of contracts that are used within the caresi rollups framework to interact with our backend which is running offchain if we go into our folder here and we go to deployments and we go to Local Host you can see that we have a bunch of different um what do you call it contracts right one of them is the input box now the input box lets us take a transaction and forward that to our backend okay it's like sending an input remember we can send inputs or we going send Advanced requests and inspect requests so this is how you send an advanced request using the input box so we're going to copy the input box address again you go into the kind of root folder go to deployments Local Host and find input box and we're going to copy that in here for the input box address okay now there's a bunch of other ones as well so if we go here we have authority bit mask cartez dap Factory dap address relay portal right ether portal erc20 portal these are contracts that you would send assets to that would then tell uh our backend that the asset was received okay so what would happen is assets would be stored inside of these contracts which can be controlled from our backend and our back end can be indicated when something is sent to that contract now what we need as well is the DAP address so if we go to dap. Json we can just copy the address here okay that's for the current deployment and paste that in here okay I know it was a bit confusing but whenever you need any of the addresses you go to deployments and Local Host and if you restart your card aresi node these addresses might change so you may need to change these when the node resets okay when I'm talking about the node I'm mentioning the kind of hard hat node that's running that test Network for you okay so we have these inside of constants now we're going to go back into util and we're going to write the function that allows us to send an input so to send an input we're going to do the following we're going to say export const send input and remember this is advancing the state so we're going to say async we're going to take in a value we want to send we're going to take in signer and we're going to take in toast toast is something that again will allow us to kind of pop up a message on the screen and we'll use that in a second so we're going to say const input box is equal to and we're going to import an input box Factory from the cartei um what do you kind of call this I don't know node module I don't know the name of it the uh the package that caresi has that works in react and works in node.js just stuttering on my words here we're going to say import input boxcore uncore Factory from at caresi rollups now caresi rollups is already installed inside of this package okay it's already in the uh the yarn lock we already installed it when we copied the frontend directory into here and we typed yarn now inside of this rollups package we have a bunch of different factories which essentially instantiate the contract that we're going to use to interact with our backend so just like we have the input Factory we have other ones for things like the portals right for sending Assets Now really what these are doing is wrapping a lower level operation that is getting something known as the contract ABI now the ABI is a specification of the different functions that exist on the contract and it kind of maps it into JavaScript code for us so we can call those functions without having to know all of their heximal representations and some of the weird stuff that goes on in solidity anyways we get the input box Factory we're going to go here and we're going to create a new instance of this so we're going to say input box factory and we're going to connect the input box Factory to the input box address with our signer okay so this again is going to create kind of like a JavaScript instance or connection to the input box which is a contract running on the blockchain Network which will allow us to forward information to our decentralized application okay so we have input box next what we're going to do is we are going to get the bytes that we're going to be sending so we're going to say const input bytes is equal to ethers do utils do is bytes like and then we're going to say value question mark value otherwise ethers do utils do let's spell ethers correctly do2 utf8 bytes then we're going to take in the value now we're also going to import ethers oh ethers is already there okay and we're just going to save this all right let me quickly explain this so what we're doing is we're getting the input box which I already did and then we're saying okay we're going to have some input that needs to be in a bite format or kind of like a heximal format that we're able to submit to our D so what we do is we look at our value and we first check is it already the format that we need it to be if it is then we can simply just take the value otherwise we need to convert it to utfa bytes which is what we do right here okay so that's what we're doing with input bytes now that we have that what we can do is send a transaction to our input box so we can say const TX is equal to a weit input box do add input now notice I'm getting autocomplete here the reason I'm getting autocomplete is because I use this input box Factory that returns an instance of the input box class okay so we're going to say input box or add input sorry we're going to send an input to our dap address and the input we're going to send is the input bytes so we connected to this contract which allows us to send inputs to our decentralized application we turn the input into a format that we can actually send and then we use this contract to send to our dap address the following invites all right so now that we are sending the transaction what we're going to do is just write some code that will wait for the transaction and give us some kind of output on the screen so we're going to say export const weit for transaction and this is going to be an async function again which is going to take in our transaction and our toast object now what we're going to do is say toast and we're just going to put kind of a notification on the screen that's what toast does we're going to say title and transaction sent we're then going to say description waiting for confirmation like that we're going to say the status of this is success for the duration this can be 9,000 so that's 9 seconds we'll say is closable true and for the position we can say that this will be the top left obviously you can change that top right bottom left bottom right Etc okay format that so we're going to do the toast we're then going to say const receipt is equal to wait transaction. we one now what this does is wait for one confirmation for the transaction just to make sure that it went through we're then going to say const event is equal to receip do events question mark. find and we're going we're going to say e and then e. event is equal to input added like that so what this is doing is just giving us the event associated with the transaction which will contain the logs with anything like reports or whatever else is generated from that uh transaction you'll see what I mean in a second but what we're doing is we're looking at the receipt we're checking if there is any events if there are we're finding the ones associated with input added which is what we just did with this transaction so now we can do another toast so let's copy this okay and we will say confirmed like that and we can say input added and then the index of this will be the following so let's just add our back ticks here so we're able to actually embed this value and this will be event. args do inbox input and then index okay I know this a bit confusing but what this is really doing is telling us the index of the transaction that we sent to the back end or the input we sent to the back end to advance the state so it could be the first one second one third one Etc okay then we're just going to return the receipt of the transaction so now we're going to go up here to where we have send input and we're going to wait for the transaction so we're going to say return await wait for transaction and what does this take well this is going to take the following the transaction and the toast okay so that is send input and wait for transaction now we are almost done we're going to go to create Challenge and we're going to write this function here which is going to use the code that we just wrote which was the more complex stuff so to create the challenge we first need the commitment so we're going to say con commitment is equal to a wait generate commitment and we're going to take our choice and our signer we're then going to say wait send input and we're going to send our input now the input we're going to send is json. stringify and we're going to create the Json object we want to send so we're going to say method is create undor Challenge and the commitment is the commitment right and then we're going to pass our signer so let's go down here and we're going to pass our toast and let me just save that okay quickly go through this generate the commitment using that hash function we're then sending the input using the send input function we just wrote here which uses all this other stuff now remember what we're passing here is our payload okay so this is the Json we have our method which is creating a challenge what we also need to pass with that is the commitment to make the challenge so that's what we pass to do that we need the signer and we need the toast so we get our notifications now let's just quickly have a look at our code looks like everything is running so we should be able to go here and try this out I'm going to refresh the page let's just open up the inspect window see if we have any errors appearing uh don't worry about this unchecked runtime thing these are not really associated with us I'm going to go ahead and click on create Challenge and when we do that metamask should appear uh it says you do not have enough hard hat e in your account to pay for transaction fees okay that's weird so I'm going to change the account that I'm using I'm probably just connected with the wrong account ah so that's why I'm going to connect with account 7 okay so let's refresh the page there let's check our account looks like account 7 is connected now I'm going to create the challenge and there you go so let's go ahead and click confirm we get the toast transaction sent waiting for confirmation and we should be able to see it popping up in our back end like here okay so it says receive advance request data method create challenge commitment and then we have this array adding notice challenge with ID Z was created okay so that worked successfully however this is a little bit messed up um I don't know if that's exactly what we wanted I think we wanted it in a string format so let's just go and have a look at our functions and see if we made a mistake which is quite possible okay so we're going to go to generate commitment and we generate the hash okay so generate hash we have our hash hex but I'm pretty sure we need to convert that to a string so yes the thing we're missing here is join and we're just going to join an empty string and that's going to take this array and convert it to a string so we're no longer getting an array submitted there okay so that's what we wanted so let's go and fix this now what we're going to need to do is just restart our back end here because this player has already created a challenge but I don't want them to be in a challenge so I'm just going to stop that and restart it to kind of clear that application data okay so now we should be able to go back to react go to the left side of our screen okay and let's just refresh to make sure we've kind of cleared this over we'll do rock that's fine we're going to create our challenge this time says we have one pending transaction that's fine we're going to go ahead and click confirm and we're going to wait a second here and we should see that we get the result appearing on the blockchain and we do so we get the method create Challenge and we get the commitment okay it says adding notice challenge with ID Z was created by this address fantastic so I think guys with that said I'm going to leave it here that's all I want to do for this video is get the backend finished and start interacting with it from the front end in the next video we'll write all of the rest of the front end codes that we can list out all of the different challenges that we have we can accept those challenges we can reveal our answer Etc anyways I hope you guys are excited and looking forward to it I will see you in the next [Music] video

Original Description

In this series I will be showing you how to create web3 applications using Python. With the Cartesi library, this method can be done using ANY coding language. So whether you develop using Python, Javascript, Go, or C++; this video is for you. About Cartesi: Cartesi is an app-specific rollup protocol with a virtual machine that runs Linux distributions, creating a richer and broader design space for DApp developers. Cartesi Rollups offer a modular scaling solution, deployable as L2, L3, or sovereign rollups, while maintaining strong base layer security guarantees. To learn more about Cartesi, visit https://cartesi.io/ Cartesi Discord: https://discord.gg/kusye4BjGk Cartesi Docs: https://docs.cartesi.io/ Windows Setup Guide: https://github.com/cartesi/DevGuide/blob/main/windows/ Linux Setup Guide: https://github.com/cartesi/DevGuide/blob/main/linux/ Mac Setup Guide: https://github.com/cartesi/DevGuide/blob/main/mac/ Cartesi Repo URL (To Clone): https://github.com/cartesi/rollups-examples.git DevAd Seed Grants ($$$$ for building with Cartesi): https://mugenbuilders.notion.site/DevAd-Seed-Grants-dc0a2420a08c49a983b919aa9246dcbc Main resource hub for builders to get started: https://github.com/Mugen-Builders Setup a call with Cartesi for FREE! https://calendly.com/d/4x2-2hx-scf/1-1-technical-with-mugen ⏳ Timestamps ⏳ 00:00 | Finishing The Backend 21:44 | Starting The Frontend 28:45 | Metamask Setup 34:23 | Creating Challenges (Frontend) 41:42 | Cryptography & Hashing 48:50 | Sending Inputs 01:00:55 | Testing The Application 🔖 Tags 🔖 #techwithtim #ethereum #web3 Hashtags - How To Code In Web3 - How To Be A Web3 Developer - Coding In Web3 Without Solidity
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Tech With Tim · Tech With Tim · 0 of 60

← Previous Next →
1 A* Path Finding Algorithm(Visualization)
A* Path Finding Algorithm(Visualization)
Tech With Tim
2 Python Programming Tutorial #1 - Variables and Data Types
Python Programming Tutorial #1 - Variables and Data Types
Tech With Tim
3 Python Programming Tutorial #2 - Basic Operators and Input
Python Programming Tutorial #2 - Basic Operators and Input
Tech With Tim
4 Python Programming Tutorial #3 - Conditions
Python Programming Tutorial #3 - Conditions
Tech With Tim
5 Python Programming Tutorial #4 - IF/ELIF/ELSE
Python Programming Tutorial #4 - IF/ELIF/ELSE
Tech With Tim
6 Python Programming Tutorial #5 - Chained Conditionals and Nested Statements
Python Programming Tutorial #5 - Chained Conditionals and Nested Statements
Tech With Tim
7 Python Programming Tutorial #6 - For Loops
Python Programming Tutorial #6 - For Loops
Tech With Tim
8 Python Programming Tutorial #7 - While Loops
Python Programming Tutorial #7 - While Loops
Tech With Tim
9 Python Programming Tutorial #8 - Lists and Tuples
Python Programming Tutorial #8 - Lists and Tuples
Tech With Tim
10 Python Programming Tutorial #9 - Iteration by Item (For Loops Continued...)
Python Programming Tutorial #9 - Iteration by Item (For Loops Continued...)
Tech With Tim
11 Python Programming Tutorial #10 - String Methods
Python Programming Tutorial #10 - String Methods
Tech With Tim
12 How to Overclock a NVIDIA GPU
How to Overclock a NVIDIA GPU
Tech With Tim
13 Python Programming Tutorial #11 - Slice Operator
Python Programming Tutorial #11 - Slice Operator
Tech With Tim
14 Python Programming Tutorial #12 - Functions
Python Programming Tutorial #12 - Functions
Tech With Tim
15 Python Programming Tutorial #13 - How to Read a Text File
Python Programming Tutorial #13 - How to Read a Text File
Tech With Tim
16 Python Programming Tutorial #14 - Writing to a Text File
Python Programming Tutorial #14 - Writing to a Text File
Tech With Tim
17 Python Programming Tutorial #15 - Using .count() and .find()
Python Programming Tutorial #15 - Using .count() and .find()
Tech With Tim
18 Python Programming Tutorial #16 - Introduction to Modular Programming
Python Programming Tutorial #16 - Introduction to Modular Programming
Tech With Tim
19 Python Programming Tutorial #17 - Optional Parameters
Python Programming Tutorial #17 - Optional Parameters
Tech With Tim
20 Python Programming Tutorial #18 - Try and Except (Python Error Handling)
Python Programming Tutorial #18 - Try and Except (Python Error Handling)
Tech With Tim
21 Python Programming Tutorial #19 - Global vs Local Variables
Python Programming Tutorial #19 - Global vs Local Variables
Tech With Tim
22 Python Programming Tutorial #20 - Classes and Objects
Python Programming Tutorial #20 - Classes and Objects
Tech With Tim
23 Cool VBS Script to Prank Your Friends!
Cool VBS Script to Prank Your Friends!
Tech With Tim
24 How to Overclock an AMD GPU
How to Overclock an AMD GPU
Tech With Tim
25 Best GPU'S For Mining Ethereum (2018)
Best GPU'S For Mining Ethereum (2018)
Tech With Tim
26 Recursion and Memoization Tutorial Python
Recursion and Memoization Tutorial Python
Tech With Tim
27 Ethereum Mining Rig - Hardware Guide
Ethereum Mining Rig - Hardware Guide
Tech With Tim
28 Pygame Tutorial #1 - Basic Movement and Key Presses
Pygame Tutorial #1 - Basic Movement and Key Presses
Tech With Tim
29 How to Install Pygame (Windows 8/10)
How to Install Pygame (Windows 8/10)
Tech With Tim
30 How to Trade Your Cryptocurrency (Bitcoin, Ethereum etc.) For Cash!
How to Trade Your Cryptocurrency (Bitcoin, Ethereum etc.) For Cash!
Tech With Tim
31 How to Mine Ethereum 2018 - WORKING (Super-Easy)
How to Mine Ethereum 2018 - WORKING (Super-Easy)
Tech With Tim
32 Microphone Comparison - $10 Mic vs $150 Mic (Blue Yeti USB)
Microphone Comparison - $10 Mic vs $150 Mic (Blue Yeti USB)
Tech With Tim
33 Pygame Tutorial #2 - Jumping and Boundaries
Pygame Tutorial #2 - Jumping and Boundaries
Tech With Tim
34 Pygame Tutorial #3 - Character Animation & Sprites
Pygame Tutorial #3 - Character Animation & Sprites
Tech With Tim
35 Pygame Tutorial #4 - Optimization & OOP
Pygame Tutorial #4 - Optimization & OOP
Tech With Tim
36 OBS Studio Tutorial - Best OBS Settings
OBS Studio Tutorial - Best OBS Settings
Tech With Tim
37 Linear Search Algorithm - Python Example and Code
Linear Search Algorithm - Python Example and Code
Tech With Tim
38 Make Any Mic Sound AMAZING! (WITH OBS)
Make Any Mic Sound AMAZING! (WITH OBS)
Tech With Tim
39 Binary Search Algorithm - Python Example & Code
Binary Search Algorithm - Python Example & Code
Tech With Tim
40 Pygame Tutorial #5 - Projectiles
Pygame Tutorial #5 - Projectiles
Tech With Tim
41 Pygame Game - Mini Golf
Pygame Game - Mini Golf
Tech With Tim
42 Pygame Tutorial - Projectile Motion (Part 1)
Pygame Tutorial - Projectile Motion (Part 1)
Tech With Tim
43 Pygame Tutorial - Projectile Motion (Part 2)
Pygame Tutorial - Projectile Motion (Part 2)
Tech With Tim
44 Pygame Tutorial #6 - Enemies
Pygame Tutorial #6 - Enemies
Tech With Tim
45 Pygame Tutorial #7 - Collision and Hit Boxes
Pygame Tutorial #7 - Collision and Hit Boxes
Tech With Tim
46 Pygame Tutorial #8 - Scoring and Health Bars
Pygame Tutorial #8 - Scoring and Health Bars
Tech With Tim
47 Cloud Mining vs. Hardware Mining - 2018
Cloud Mining vs. Hardware Mining - 2018
Tech With Tim
48 How to Install Pygame on Mac OSX (Fast-Simple)
How to Install Pygame on Mac OSX (Fast-Simple)
Tech With Tim
49 Pygame Tutorial #9 - Sound Effects, Music & More Collision
Pygame Tutorial #9 - Sound Effects, Music & More Collision
Tech With Tim
50 Pygame Tutorial #10 - Finishing Touches & Next Steps
Pygame Tutorial #10 - Finishing Touches & Next Steps
Tech With Tim
51 How to Fade Your Screen in Pygame [CODE IN DESCRIPTION]
How to Fade Your Screen in Pygame [CODE IN DESCRIPTION]
Tech With Tim
52 How to Create a Button in Pygame [CODE IN DESCRIPTION]
How to Create a Button in Pygame [CODE IN DESCRIPTION]
Tech With Tim
53 Pygame Side-Scroller Tutorial #1 - Scrolling Background/Character Movement
Pygame Side-Scroller Tutorial #1 - Scrolling Background/Character Movement
Tech With Tim
54 Pygame Side-Scroller Tutorial #2 - Random Object Generation
Pygame Side-Scroller Tutorial #2 - Random Object Generation
Tech With Tim
55 Pygame Side-Scroller Tutorial #3 - Collision
Pygame Side-Scroller Tutorial #3 - Collision
Tech With Tim
56 Pygame Side-Scroller Tutorial #4 - Scoring and End Screen
Pygame Side-Scroller Tutorial #4 - Scoring and End Screen
Tech With Tim
57 How to Create A Message Box in Python - Tkinter
How to Create A Message Box in Python - Tkinter
Tech With Tim
58 Is Ethereum Mining Still Profitable - Is It Worth It (April 2018)
Is Ethereum Mining Still Profitable - Is It Worth It (April 2018)
Tech With Tim
59 How to Run MAC OSX on a WINDOWS PC (Clover Boot-loader)
How to Run MAC OSX on a WINDOWS PC (Clover Boot-loader)
Tech With Tim
60 Programming Problem #1 - Alphabet Soup (Beginner/Novice)
Programming Problem #1 - Alphabet Soup (Beginner/Novice)
Tech With Tim

This video teaches how to create web3 applications using Python and the Cartesi library, and how to connect the frontend and backend. It covers setting up Metamask, creating challenges, and testing the application.

Key Takeaways
  1. Finish the backend
  2. Start the frontend
  3. Set up Metamask
  4. Create challenges
  5. Implement cryptography and hashing
  6. Send inputs
  7. Test the application
💡 The Cartesi library allows for web3 development using any coding language, making it a versatile tool for developers.

Related Reads

Chapters (7)

| Finishing The Backend
21:44 | Starting The Frontend
28:45 | Metamask Setup
34:23 | Creating Challenges (Frontend)
41:42 | Cryptography & Hashing
48:50 | Sending Inputs
1:00:55 | Testing The Application
Up next
How to Speed Up Your WordPress Website with WP Rocket ⚡Tutorial 2026
Matt Tutorials
Watch →