This video demonstrates how to implement staking functionality in a decentralized application smart contract, including depositing tokens, tracking staking balances using mappings, managing staking status with boolean flags, and creating reward distribution systems. The instructor shows how to write functions that transfer tokens using transferFrom, maintain user balances, and implement owner-only access control for reward issuance. The complete implementation includes comprehensive testing with Truffle to verify that staking, unstaking, and reward distribution functions work correctly before deployment.
Build a DApp Staking Smart Contract with Solidity (Full Course)
Added:[Laughter] all right so now comes the good stuff now that we have all the groundwork set up let's actually add the implementation features for our digital bank for this decentralized bank so remember the point here is that we want our investors to come in they can deposit their tokens and then they're staking those tokens once they're deposited and they can receive rewards so we need to have a function so essentially what we need in order to do that is we need to create a function in this contract and the smart contract where they can deposit these tokens and that function is going to keep track of them staking if they've staked if they haven't staked and be able to react and transfer the amounts accordingly and we're going to be transferring from right this is not just a basic transfer because it's a third-party transfer since they're going to be transferring these tokens since it's going to be transferred on behalf of them uh once they give the approval so we have a few things we have to consider we have the approval and we have the staking what we need to be thinking about so first and foremost and hopefully that makes sense if not we're going to see it in action and it's going to make a lot more sense but a real simple version of that is you know we just need to create some functionality in a smart contract so that our customers can actually stake they can put money into this application and once we build out the application it'll make it we'll see these functions in action but for now we just have to imagine them so let's use our imagination and create a function for depositing these the staking so i'm going to write function and we're going to call it deposit tokens okay and it's going to take an amount so we're going to call this uint we're going to make this public so it has visibility and then we're going to have some logic inside this function and this logic is essentially going to transfer our tether tokens to this uh contract address for staking so no so knowing that this is the logic how would we write this so what do we want to address from this well we want the tether right we want the tether tokens right and we have already imported tether here and we've set tether to tether here we've made it public as well as in our constructor so what we can do is we can say tether dot tether dot and what are we calling what we're going to call the transfer from uh the transfer fund from function right so transfer from and that gives us already automatically a from to and a value but in this case our from is actually going to be coming from the global variable here message right and solidity and specifically it's going to be a message for contracting for the sender so the person who's calling it uh some message dot sender two and in this case we can actually use our constructor and use this method so we could just say address is going to be this so that's where it's going to and then the value and the value we can also and the value in this case will be what well it's going to be the amount right that's the point of the deposit token we need to see what the amount is oops and remember we are using solidity so we have to put our so we need to place our semicolons accordingly and let's actually add underscores here and let's just okay okay so hopefully this makes a bit of sense if not let's just think about let's just think this through together one more time so what are we doing well we're going to be staking this is a function a staking function okay and essentially what we're doing here is we are depositing our tokens into this contract we are transferring our tether tokens to this contract to this contract here the central bank contract for staking and in order to do that we can't use a regular transfer because this is third party this is coming through a third party so we're trying we're going to use the transfer from function we get that function from tether inside our solidity right we already set this all up so we can access our solidity in our constructor uh sorry another solidity our tether contract and if we go to our tether contract we see that we have just like all erc20 all erc20 tokens have a transfer from function from address 2 and the value okay so it goes from an address into another address with a value okay now in okay so in order for this to work for the staking to work we need to be able to actually keep track of to keep track of a lot of things here um one of the things we need to keep track of of course is the amount that our customers are depositing the amount that they're staking okay and we can do that actually using again the mapping so using the the mapping method here so so we can bring in our mapping and we can set it up to address and that can go to uint and we can go public and staking balance okay so now we have a key store value set up for the address that each address is going to get their own unique integer and we're sending it to a visible visibility of what the staking balance is this way now we can actually start to keep track so this way we can actually keep track of our staking balances as they change right so so let's say update staking balance over here and we're going to do this i'm going to do this by putting in staking balance and what do we want the staking balance to come from well we want to come from the person who's using it the contract right and this is going to be equal to the amount but it also has to be the current balance that we have plus the amount right so we're going to do staking balance okay great so now we have an update for staking balance um what can we add also well the other things that we need to add here is whether or not they have staked to check for that and also to check if they are staking so have staked and if they are staking those are two more things that we should be adding into our deposit tokens over here for our staking um and we can create more mapping to keep track of all this so we can do mapping mapping and we're going to do address same thing to uint uh sorry and this time this time since we're actually checking whether or not they have what's better to use besides an integer well it would be just true or false so we can use a bull public has staked and then we can do the same thing with another boolean and do a mapping uh but to see whether they they are staking so is staked and to keep track of all this oops a little equal sign here to keep track of all this we're going to set up an array of our stakers essentially so we can keep track of it of the addresses that way and we do that simply by setting up an address of an array public and then we can just call it stakers don't forget the semicolons okay uh so now that we have this set up we can actually write okay uh so now that we have this set up we can actually write to check whether they have staked or not to check uh whether they are staked affect whether they have staked and whether they are staked so how can we write some logic for this well we want to check whether or not they have so a really good way to do that of course would be with a conditional statement so we could use if and what we can say is we can use a bang which stands for false because remember whatever we put in the if value will be true so we can say if they haven't staked right if they've never staked up to this point then what we can do is we can say to the stakers we can push oops push right and this and push is a method that works both in solidity so from javascript that's just going to push a into the array the message sender okay so it's going to update and then we want to update the staking balance after this so we can say update staking balance and we can do that simply by saying is staking message.sender and this should be true and also has staked should also be set to true okay this is pretty robust now for depositing um for depositing we have the really important information we have the really important logic here where we get the information we need such as the person who's using it to transfer the address of the actual the central bank and the amount very important we have our mapping set up to keep track of updating our staking balance to what the new amount is going to be based on the previous amount we also added logic so that if they haven't staked then if if they have a stakes so that you know that's just extra precautionary uh then we can push the new amount and we also then update everything to true for our booleans for our keystore booleans we update our staking balance so this is really neatly laid out is there anything else you think that would be important to add i'm gonna add it but i want you to just think about it well what else would be really important important so that so that this function doesn't break down or so that it doesn't do something wrong what other logic should we add into this function to prevent something to prevent something to prevent our customers from breaking the application let's say all right so pause the video and think about it and if you come up with it then go ahead and write it out yourself give it a shot based on everything we've done up to now okay so hopefully you had some success and you came up with a solution if you did not come up with a solution don't worry about it we're going to write it out together now these things really take especially if you're new to coding you know these things take a lot of time to develop the skills that you need to come up with to come up and have that foresight in mind and that really just comes with practice but what you want to do essentially here is we want to bring in another conditional statement because because there's two things that we don't there are two things that we never want to we never want our customers to be staking right and that is zero we don't actually want to add zero we don't want any transaction to happen for zero and anything beneath zero right anything of the limit up to zero no we that should not be there so we want to add this into our function to make sure that doesn't happen and we can do that in solidity with require so all we have to do really is write require and we can require that the amount is going to be have to be sorry greater than zero and we can add to this you know a um description and we can say the amount cannot be zero it's not going to really be less than zero all right and let's go ahead like that let's just clean this up and let's comment it in so pretty self-explanatory but always good practice require the amount to be greater than or require staking amount to be greater than zero that's good okay that should be pretty clear okay so we've completed writing out our deposit tokens for staking essentially into the application it's pretty much everything that we need for it to be functional and not to break down and do what we wanted to be doing but but of course we don't have that front end developed yet we don't have a test environment so what so how can we know if it really works or not well we can run our truffle tests we can that's what it's there for so in the next video let's go ahead and run some tests to make sure and set up some tests to check to see that this deposit function is working okay great work going through this hopefully it's making more and more sense and i'll see you in the next video okay so back in our testing over here our decentral back our deception back in our decentral bank test over here excuse me let's add some tests now to check to see that our staking is working so we want to do tests to see that the staking is there that we can reward for the staking and the best way to do that is to create our own describe to bring in our own describe hook and to bring in our own separate describe hook to do that so we're going to get a little bit of space here and write a describe and we're going to call this um yield farm yield farming we're going to the same same pattern as always where we need to make sure that we are going to be fetching some promises to do this and it essentially we can say rewards tokens for staking all right and let's create a variable called results and what do we want to check here well we want to check the investor balance so let's comment check investor balance okay so we can set our result to a weight tether dot balance of our customer right so this is the overall balance and what is the balance of our investor before we start staking like right away automatically well if we remember back in our deployment we are issuing technically a hundred mock tether tokens to our investor so in order for this test to pass the result here should equal that amount right because they they have not staked anything yet so they should have a hundred tokens available to stake so how do we write that out well i'm gonna let you give it a shot first so go ahead pause the video and try to write that equivalency out okay so hopefully you had some success if you didn't don't worry about it let's write this out together we're gonna bring in our assert same thing cert.equal okay so it's an equality test and we want to test the results right and we want the result to be tostring and it should equal 100 tokens right so we bring in our tokens function and we make it 100 and now we could add a note and we can say investor mock tether balance before staking and we can say customer mock wallet balance before staking okay so let's just go ahead and run this see if everything's working so go to terminal truffle test oh okay and we see a compile message from before is staking message sender equals true compilation failed okay so we did not successfully compile so i can actually go back to the the central bank contract and we see that i wrote is staking but it's actually is staked i see that i wrote is staking but i didn't actually call it is staking which is a mistake so maybe i should have called it is mistake okay bad pun let's just fix this is staking so now we can map through this better and let's run the compile again and the test by just writing truffle test okay and we're seeing another compilation error over here we see that it says what do we have a mapping problem when it comes to if we haven't staked so we're pushing up an array but it says it has staked and i think i'm it looks like i actually forgot to add if you haven't staked from the array of message senders so we're going to put msg.sender like this see that was the mistake this is back in the the central bank uh the central bank dot solar central back the central bank contract it's not if hasn't staked nothing isn't true right with the bank but it's if you have staked of the sender the person that's calling the contract for that message so let's save that and run it again and see uh you know fingers crossed hopefully we get a successful compile so that we can see the test is working uh-oh looks like i made another mistake stakers dot push now the push method in javascript of course you want to be calling it you don't want to be sending setting it up for an array so that was just another type of mistake that i see over here so stakers.push see i wrote it as an array see i should have done stakers.push like this you'll see that the color actually even changes js style like they do the same thing in solidity so let's save that and send it out one more time truffle test and this time i think we're good all right awesome looks like we have compiled successfully and now what we see is a syntax error in the testing so we're actually running the tests contract is working we've got some sort of issue here in our test let's take a look line 62 result equals a weight tethered up balance of customer customers so it says that the weight isn't working potentially so let's see what's going on with the awaits over here it rewards tokens and then oh wow so for some reason i did this too fast so we got to remove again this parentheses a sink needs to actually have its parentheses initiated okay and then we want to close our bracket of it after we have ran after we have ran our async so that ends over here bracket should close over here let's save it like this and let's run again and see if the testing works now okay everything is passing awesome so you should you should have everything working by now if you're running into errors of course you can always just download the final project and check over the code that way and see that it's working like that um but if you're coding along you should see everything passing up to this point so let's finish off this video by running a few more tests just for your test to see that our staking is really working here because now we know that our deposit function is fully working and that these tests to check the the initial balance is working so what's the next test that would make sense well why don't we run a test to see what happens if we actually use 100 tokens can we check the staking can we check the staking updating can we can we actually check the functionality of depositing and staking and we totally can we just have to write a simulation for this and see that it works successfully so why don't we do check staking customer okay so we're going to run a weight and we can actually take the deposit tokens wait we're gonna have to take this from the central bank dot deposit tokens all right and we want to run tokens right to convert it and let's just say 100 tokens all of it take the full amount all 100 tokens that we got we're going to stake them all we're feeling like hey we're going all in over here it's just a simulation token's 100 and we want to do it from the customer right because the customer is the one who is taking this now if i run this test it's not going to work right because if i run it like this there's no allowance if you remember like we said back in our [Music] back in our deposit token here function in order for this to work we need to have permission has to pass from the message sender the person that is doing that has to approve it so it's not actually going to run it's going to fail if i do it like this so what we're going to need is the approval and in order to in order to get the approval to pass from the message sender we can actually all we have to do is run a simulation of the approval of the approve of the approved function which we wrote if you remember oops which we wrote if you remember in our tether function here when we wrote the approve so this can allow for an omission of approval from the message center the spender and the amount and we do that here by writing in a weight we're going to get tether.approve and we want to prove the same amount tokens 100 from investor from customer so you know what from oops from customer and we need the address as well right what's the address here well which is the address that we want to approve this deposit it's the central bank address right okay so first we first we send out the approval we say hey you can approve 100 tokens to send to the central bank address wait two s's haha i caught that in advance from the customer after this has been approved then we can actually deposit these tokens to the central bank address from the customer so let's go ahead and run this test and hopefully it should work okay and we see that our promise was rejected oh man why were we rejected all right well let's take a look back in the code here okay so i see there's a syntax error where i'm closing this parentheses here and this is why the approve wasn't working if you noticed because when i had it like this let me go back i'm essentially closing the it statement and so it's not actually capturing what we need from tether doesn't understand what approve is because we never waited for it so if i move the parentheses underneath and i run this test again all right everything is passing excellent always a good thing means that we can move ahead this is what testing is for okay so what we've done is we've simulated here staking for the customer so that we issue 100 tokens here let me add of 100 tokens customer and then we approve it and we wait for that to happen right so we deposited that into the bank so what else can we check now that we've deposited that well now we should be able well now shouldn't we well now if we do that then shouldn't the customer have nothing left because they gave everything away so we should be able to check check updated balance of customer and essentially it's the same thing that we would do up here right we're just going to send the results back so let's just write let's just copy paste it in and then now instead of a hundred tokens we should have zero tokens because the customer has deposited a hundred all right so that should okay so that should check for that what else can we check well if the customer has zero then shouldn't the the central bank have a hundred okay so pause the video and write the test for the central bank to check the central bank and you know just a hint it's the same thing that we've been doing but we want the address to move towards an update of the central bank okay good luck all right so hopefully you had some success let's go over it together so let's check updated balance of the central bank and we're going to do the same thing once again only here what we're going to do here i'll just copy this instead of the customer what we want is the balance of the owner right actually actually we don't want to give the bounce away of the owner that's not right we want it we want specifically the decentral bank dot address let's just do that that's better and right let me actually fix these messages so update balance so this should be a customer this should be mock this could be mock wall balance after staking 100 tokens before staking let's do okay fine and this should be the central bank mock wall balance after staking from customer excellent all right what else can we test for well we could check to see that the is staking function is working because if you remember the other thing is we have our boolean we have our boolean over here for um where is it over here for is staking so we can check is staking because they should be staking at that point and it should be true right so you can pause the video and if you're feeling brave go ahead and try to write the test to see that the updated status should be true all right hopefully you had some success so we're just going to do this together is staking balance so we want to write results await and we want to take it from the central bank here and we're going to check for is staking and we want to see if it's staking from the customer okay and let's check our quality here would be equal result to string and he and here it's not about a number right here it's just a value so we want this value to be true lala true and we can have our notes saying that uh customer is staking balance to be true sorry customers taking status after staking okay so let's save that that's a lot of great smart tests to make sure that everything's working before we actually deploy on the blockchain and so what do we just do let's go over really quickly let's go over briefly again so we're checking we're doing a test to check the investor balance uh we get the investor balance of the customer right customer remember comes all the way up from here from our contract it is the second address in our ganache where's ganache over here it's this address right um so we get that and then that should equal to 100 tokens right before staking because we remember in our deployment we've got 100 tokens we've gone over that a bunch hopefully that makes sense now then we check the staking for customers of a hundred tokens all right so here we actually have to run an approval first right because we can't actually deposit without getting the approval because this is a transfer from not a transfer function that we're taking so we go to central bank deposit tokens we have a hundred tokens from the customer okay but in order for this to work we have to get the approval uh and so we run the approval basically a simulation here we run the approve 400 tokens first and after we do that then we can deposit a hundred tokens from our customer into the the central bank so the customer says hey you can take 100 tokens then we run this okay updated balance all right so after the customer has said you can take basically all their tokens the customer should have zero tokens left so that's what this checks right uh and and oh here i made a mistake the central bank should have a hundred tokens right because then after you know the customer has no tokens we check the balance of our the central bank and we should have received 100 tokens so we get the balance from the central bank address and that should be 100. finally we check for a deposit token boolean updates to true and we run an assertion for that and that's that final staking and this is basically all the tests it's really all that i went into hopefully you know i've gone into a lot of detail to connect this for you over and over again so hopefully it's clicking it's coming together now if not don't worry about it just keep going with it especially once we get the front end working you're gonna see all this in action but let's go to our truffle console uh sorry just a regular console and let's run a truffle test and hopefully we have and hopefully we're in the money and things are looking good so let's hit enter okay so we've got one thing that's not working out here the central bank mock wall balance after staking from customers so plus expect minus actual so it was expecting something different so let's take a look oh okay i see what's happening here um all right we are actually getting the results to be the wrong thing here we're sending the result to be the balance to be the tether balance of a decentral bank address when i switch that with owner which doesn't make a lot of sense to be honest so what i want to do actually is we don't want to take it from tether we want to see the balance from actually um from the central bank and we can actually do this if we grab from the central bank we have staking balance right and we can grab the staking balance from the customer okay so i can save that and just to clarify that if i go back to the central bank we have our staking balance here and our staking balance is the updated amount right after we're staking okay you know we're going to do so because we want to check updated balance of the central bank we're doing this wrong we want to grab the balance of right because we want to get the balance of the decentral bank and so we can use balance of from tether we can use this functionality and we can actually grab it from the central bank address we can grab it from the central bank dot address like this let's try this okay so great so all of our tests are passing amazing in the next video let's build out more functionality for issuing tokens rewarding tokens because this is a digital bank and people can put their money in and then they get uh or people can put their crypto in and then they're going to get tokens in exchange for putting in their tokens so let's create the reward functionality run test for that and then also after that we're going to do the unstaking so people can take their tokens out if they want and have that functionality as well always good to give people the choice after they put it in to take it out it's not very nice to say hey you put it in sorry it's just gonna have to stay there forever right so we're really working under the hood here hopefully the dots are starting to connect keep on practicing keep it up and i'll see you in the next video all right so we basically have our tests working and for our deposit token now and we have the ability to deposit let's now create the functionality to reward and to issue tokens for people who are depositing you know like a bank we want to say we're going to do something where let's say somebody um deposits 20 tokens they're going to get x amount back if they deposit 40 tokens maybe they're going to get more we'll have an incentive so if they deposit all their tokens then they'll get the most amount back if they deposit just one token two tokens we give them just a smaller amount back okay so let's write some functionality to do that so where would we do that well if you guessed in the decentralized bank solidity contract oops not the json file then you are on the then you are getting this all right so let's go into our contract to central bank and if you didn't yeah and if you still weren't sure where that kind of logic would go don't worry it takes time and you'll takes time and these things will start to click so i'm going to scroll down and we see we have our function here for the deposit token so let's do the issue token so issue reward rewards all right so we're going to create a function here called issue rewards or issue tokens it's fine all right and it's going to be visible public and the first thing i want to do the first very first thing we do before we issue tokens i want to create a restriction i don't want anybody to be able to use this function to be issuing tokens we want to make it so that only who should be able to issue the tokens the owner right like we should be the ones to issue the tokens makes sense so let's require the owner to issue tokens only yeah so we can just do that by typing in require solidity and what should we put in here well we want the message.sender we want the person who is in that instant calling on the contract to be the owner the double equal sign is equal to not to be confused with equal which is something that equals something this has to be the exact of what this is which is the owner okay and we can say here we can write and write some kind of message the caller must be the owner right okay great so now we have that set up let's think about the actual logic how can we do this well let's just say theoretically the way that we want to do this is that the owner can actually call this function whenever they want depending on a schedule that they have where based on that schedule where based on that schedule whatever is convenient for them they can go ahead and they can issue tokens and so what we can actually write here is a for loop so a loop is something that can iterate through and make decisions based on what you imply and you can create the parameters for the iteration itself um and we'll see what i mean by that in a moment but essentially we want to iterate through our array of stakers and then we want to be rewarding our stakers that actually are staking right so we want to make we want to iterate through that and then reward based off of that so we do that with a for loop and if you're new to javascript you're new to solidity it might look a little bit weird to see it might be a little bit confusing at first to look at at these for loops but really um it re but really it's just a syntax that you kind of get used to and then you see it so many times and it's really not a big deal but at first it may seem confusing for sure for sure so just like with javascript what you do is you type in four and the only difference here is that we have to remember that it's static for solidity so we have to write uint so we're gonna say i equals zero and so this is our starting point so i starts at zero our first iteration's at zero i should be less than stakers dot length that's our array right so this is the point at which we um stop our iteration we go all the way through until the full length of i dot stakers and then what do we do after each iteration well well we can add another one to i so we can say i plus plus okay so this is really a standard setup for a for loop but you get used to it uh if you're new to this and it may seem a little bit weird and what we want to do is we want to say that for our recipients here we do stakers i and our recipient's going to be address right so address recipients so each iteration of stakers is going to go to this recipient okay which is going to be an address all right so that's how we're going to keep track of each address we're also going to create an integer called balance and here we can say it's going to be the staking balance saving balance of the recipient okay so we create balance and then we set uh we set and then so we create balance as an integer and we set it to our staking balance of each recipient and we set our balance to the staking balance of recipients so essentially we're saying that how much do we reward them in our balance well the reward is going to be the whatever it is whatever was the amount that they were staking that's what this is so the staking balance of the recipient the amount that the recipient is taking is going to be the balance that we return to them okay and finally we can transfer the tokens with by running the transfer function from rwd right because we want to we want to be sending them reward tokens so reward and we're going to send it to the recipients and what is the amount it's going to be the balance right isn't that beautiful at the end there we take the recipients for the stakers right and then we reward transfer the recipients and then for the amount all in a loop very nicely very nicely done again we're just reverse engineering what greg wrote but hopefully we're going through it step by step so you can really see the process here it's pretty standard stuff but stuff but very useful to learn and to learn it like this in my opinion finally something that we can add is to ensure to ensure that the transfer happens only if the balance is greater than zero we can write an if statement we can say balance has to be greater than zero okay and then we can make this transfer happen only if the balance is greater than zero like this and there it is that essentially is our rewards functionality to issue rewards so let's go over it again so basically what we're doing here is that we create a function called issue tokens which we can then which we then we can then access with visibility which we can then access publicly then essentially we make it so that only the owner can call this right because we only want the owner to issue tokens and how do we actually go about the logic of iterating and issuing these tokens well we make a for loop and we set the the loop to basically all the stakers in the array and then we loop through it now as we loop through it we send a uh we as we loop through it we create recipient we we create recipients that go to an address and they each take an i all right that's they all take an eye then we set essentially a balance to the balance to the staking balance of the recipient so the amount that they're staking and finally we say that if the balance is greater than zero we're going to reward them what that is and that's we we use the transfer and essentially we transfer to the recipient the about we transfer to that recipient recipient of the stakers the balance now what if i wanted to create an incentive here well let's say i don't want to give them that many tokens for starters let's say i'm like well i don't want to give them the equal amount of tokens because this means tokens because this means that if they uh if they're going to stick 50 tokens then they're going to get back 50 reward tokens if they stick 40 tether tokens they get back 40. all right and so on and so forth well what if i only want to give them one-ninth of that amount no matter what it is that they stake they only get one-ninth of that amount well what we could do is we could actually well what would that do well that would mean that if they were to stake uh 20 tokens then they would only get instead of 20 tokens uh 2.2 tokens i just calculate that on a calculator if they stake the hundred tokens they would get like 11 tokens or something like that so the more they stake the more they're going to get back so that's a nice incentive so we're going to go ahead and say divided by nine okay so we're going to save that and now we've created our incentive and we can even say divide by nine to create incentive for stakers all right to create percentage incentive all right okay so that's it then for the issue token let's go ahead and write some tests now to make sure that our issue token function is is good but actually wait a minute before we do that let's first just compile this down let's just compile this down i know i know i get excited i want to rush rush right i want to rush to the next thing but i don't want you to i don't want to leave you stuck last i don't want to leave us stuck like last time trying to solve the truffle compile when we're already testing so i'm just going to do a truffle compile now and let's see what happens okay great so it says that it's compiled successfully good news all right so let's move over into our tests and write the tests that we need so the first thing we want to do is the is just check that we can issue tokens here from the owner so in order to do this it could be a simple test we can just say await and we're going to go to central bank issue tokens we're going to grab that function and we're gonna grab say we want it from the owner okay so that's gonna run to check to see that this function we can issue the tokens from the owner and then the other thing we should check is to make sure that only the owner can issue the tokens so to do that i'm just going to copy paste this here let's bring that back and ensure only the owner i don't know why i'm putting this on cash only the owner you know these are comments you can just comment how you want i don't know i guess i've been doing this so that they're like titles but usually you just write out sentences right and sure only the owner can issue tokens and so that means that if i were to switch this from the owner to the customer customer's not allowed to issue tokens right that would be bad news so what would happen if i switched this to the customer well then we should get it should be rejected and we can actually test this by using our should so we should say should be rejected we can type it in like that so there it is there's our dot should coming in handy let's put a semicolon and let's save this and go ahead and run the test and see if it works so we're going to go and go into our truffle and type in truffle uh truffle test sorry we're gonna go into our console and type in truffle test enter yeah so the caller must be the owner okay so if we go back in our code into our decentral bank we're gonna see here that in my constructor i don't actually set the um the central bank i don't i don't actually set um owner to the message sender right that's where we want it to be to be so what we're going to do so what we're going to do is we're going to add owner equals msg.sender okay so i'm going to save that and now when we require it to be the it should be able to recognize in our test that the owner that it's okay to receive this from the owner um so let's go ahead and run the test again so back in the console truffle test okay and now everything is passing excellent so there we go that actually would conclude our test for now for issue tokens and for building out the functionality for issuing tokens um the only thing we really have left now is to do our unstaking right so we're able to stake and we're able to issue but our customers or our investors aren't able to unstake so let's go ahead and set that up in the next video run the test for that and after that it's time to build out the application on the front end and hook all the and hook all this functionality up so that it's user friendly and anyone can go on and anyone can go on and with a click of a button uh start depositing their mock tether into our account all right that's exciting okay that sounds that sounds pretty exciting great work see you in the next video okay wow can you feel it we are getting pretty close here i am definitely getting excited about this so let's let's now take a look at what we need to do so we've done the staking function and the issue function right now we're in our decentral bank solidity contract right uh and so the last function that we want to create here in our smart contract is going to be the unstaking right so right now our customer can come to our bank and deposit a certain amount of money and then withdraw that amount sorry tokens withdraw the tokens and then in exchange we can check to see what that amount is and then automatically send an amount of a percentage back on some type of schedule and that's with our issue and our staking but we also want to give another feature for our customers to be able to just to be able to unstake to be able to take it back let's write this underneath our staking function so we can put some comments and write unstake tokens okay and let's go ahead and write a function for that so function we'll call it unstake tokens and it's going to be public and we're going to create an integer here so we're going to call it balance we're going to set our staking balance to the message.sender so already we're setting it up so that the amount of the balance right now is going to be the amount coming from the person who is calling upon the contract so that's going to be that amount from the staking balance that's important we're also going to have to require that the amount is greater than zero right that makes sense we don't want people unstaking anything less than zero that just doesn't make sense require the balance to be greater than zero staking balance can't be less than zero okay uh and actually this isn't gonna read right we should put this underneath so we're gonna do that so uint balance equals staking balance array for the message sender and we require that the balance is greater than zero okay so we can even comment require the amount to be greater than zero just right all right so after this we want to transfer the tokens to the specified contract address from our bank right that's essentially what we want to happen here we want whatever that amount that they've been staking to be unstaked sent back to them from our address back to their address so how would we write this go ahead and give it a shot see if you can actually come up with the logic yourself all right so hopefully you had some success if you didn't don't worry about it we're gonna go ahead and give it a shot together so basically we want it to be the tether to be tren basically we want tether to be transferred back right so we can call the transfer function from tether and remember that transfer takes the amount and it takes the address right so what's the address where we want to send it to well it's going to be the message.sender and what's the amount going to be in this case well in this case it can just be the balance right pretty awesome and and if you got that right awesome job okay so now we're doing the transfer we're requiring that it's over zero what what other logic should we be adding towards this unstake function well if they're unstaking all their tokens then we need to update the staking balance in our app right they can't still have tokens there after they take it back and we need to tell our function to do this otherwise they will they can just they can just continue to do this over and over and our application will not be the wiser and how would you do that well you can just say staking balance of the message on standard should be equal to zero and finally we want to update our staking status remember we have our staking status here so is staking is essentially what we want to be updating so we can say is staking msg.sender is going to equal false right okay and so that's it for our unstanking function so let's go ahead and compile this and see that it's working so go to the console and just run a compile okay so we've compiled successfully awesome so we haven't made any mistakes in here from what we can tell but let's go ahead and now write some tests to make sure that the functionality makes sense and is working the way that we would expect it to okay and we can run our tests we can back into our and we can run our unstaking test and we can write these unstaking token tests back in our test right in our decentral bank uh test over here nope yes wait oh i was confused there's too many tabs let me just close this tab we don't need the json okay excellent so back in our decentralbank.test.js hopefully you're getting the hang now of writing these tests a bit the first test that we want to write here is just to check that we've unstaked the token so we can do unstake and it's very similar to uh our issue tokens but we're going to use the unstoke uh the unstake and we want to see it from the customer right so i can actually just copy this wait and this is going to be on stake tokens from customer all right and that's it that's really it to check because what is this going to do it's basically going to go back to our decentral bank contract it's going to check the unstake function on the unstake tokens function and make sure it's coming from the customer okay so that's going to make sure that it comes from the customer now what other kind of tests can we write for for unstaking well we can actually write some tests thinking ahead right like if we think in advance well what would happen after we unstake well after a mistake for example the application there should be a hundred tokens now returned back to our customer right because they're technically going to be unstaking everything right we're just going to have a button not on stakes at all so we can write a test to check that so why don't we say check on stake on staking i'm staking balances and we can actually run a very similar tests like we did with the staking only the logic just needs to you know be copacetic with unstaking right um so if we scroll back up we have some tests over here and i can just copy these over like this and we can rewrite them together so i'm staking balance so the first one here result equals a weight test for a customer so after we unstake instead of having zero tokens for the customer we should actually have how many we should have everything back right so we should have a hundred and we can rewrite this here customer walk balance after unstaking right and i can remove this hundred tokens like that okay and we can check the updated balance okay and then we could go to the unstaking and we could go to the is staking update should be is taking update better than that uh and you know i'm going to write this here it's taking balance i'm going to change it to is staking update because this is booleans for true or false values and here essentially we should no longer be staking so what should we change here well the equality should not be true anymore right so we're going to switch it to false customer is no longer staking after unstaking and then how much and then finally what should be the updated balance of our decentral bank after they take back their 100 well we no longer have 100 so this is going to be zero and and that's it all right that's that's a complete test suite that's everything we've basically covered our staking unstaking staking updates issuing tokens our three functions you know our main three functions in our the central bank smart contract here of unstaking rewarding issuing tokens and depositing tokens staking our tokens so let's just do the old the good old save and let's open up our console and run a truffle test let's see let's see what happens when we run this test enter and everything is passing ugh amazing all the tests are passing that's it we did it this is a full test suite that's been completed and not only that we've actually completed all of the important functionality for our smart contract and for everything in our smart contract we've checked out all for the staking not only that we've actually ridden out everything all the functionality for our unstaking for our staking so congratulations getting this far this is no small feat we've gone through writing the functionality to looking at line by line code by code what everything means and how they're connected with each other so in the next video we're going to write our final script so that we can actually issue reward tokens to tokens to our customers and we're going to have a script where we can just run the script on truffle and do it like that and after that comes the actual front end functionality and the fun stuff for building this out onto our ui so so great work have a coffee break or something you've come really far and i'll see you in the next video bye-bye all right so let's write out a script that we can use in our truffle terminal which essentially can just issue the tokens so that way we don't have to write out a function every single time that we want to issue tokens we can just call our script and whenever we call this script then our tokens get rewarded uh we can our tokens get rewarded we can reward our tokens to the to those customers who are staking you know and that's something that we do on our schedule remember and the script will follow all the protocols and everything that we wrote right it will only work once when they it will only issue the tokens when they are actually staking and it will uh it will follow the code that we set up in our issue tokens function accordingly so we're just going to be running it essentially and as the owner we can decide how we want to be running it when we want to be running it so so the first thing we want to do is we want to go back to our d5 staking app in the directory we want to make a new directory from there so mkds or space and we want to call it script and now let's cd into scripts and here we're going to make a new js file for our for issuing the tokens so we can just say touch issue tokens dot js we just go to our back to our text editor and we should see scripts over here and here's our issue tokens file okay awesome and i can see already that i misspelt issue so i'm going to just rename that issue to issue even better okay so the first thing we want to bring in here is going to be our decentral bank and hopefully you're familiar with this by now artifacts.artifacts now artifacts don't require central bank and what we're going to do just straight up it's we're just going to export this function right away and we can do that by just passing the function into our module export so we can just do module.exports like that and we're going to make an async function so so async function issue rewards okay and in here we're going to bring in our decentral bank so we can say let decentral bank equal decentral bank dot deployed and what am i missing here you probably guessed it by now the wait right otherwise it's going to skip right through and now we're going to actually await await the central bank dot issue token issue tokens right because that's what we want okay and then we're going to console.log tokens have been issued successfully and this is going to be a callback function and what's a callback function well it's a function that just kind of calls itself so we can just put as our argument callback like this and then we can actually call it so we can do that by just putting in callback here and calling it okay awesome and so that's essentially what we need for our script we need for our scripts so that we can actually call and reward tokens from the terminal okay because that's what we're going to do from the terminal and let's just take a look quickly so we created an async function here called issue rewards so this is what we're going to be calling and within that we just take our decentral bank we take our decentral bank contract we grab the issue and we await to call the issue tokens so we actually call issue tokens from our where is it contracts from our contract over here issue token here right function issue token so we're going to basically execute this command whenever we call this function where is it whenever we execute the function in our scripts which is in our scripts over here okay i'm kind of getting lost in my own thoughts so now that we have this why don't we run the script and see if it runs and when we get this console so we're going to go to our terminal over here and the first thing we want to do is let's just run a migrate reset so we're going to do truffle migrate dash dash reset so let's make the updates happen okay so we've ran the updates and now let me cd back to the d5 staking app and now to run the scripts all we have to do is use the truffle exect command and you can go to the truffle website to look at all the truffle commands on the terminal but this will just execute scripts right so we can say truffle exact scripts because that's the file folder and it was called issue tokens issue dash tokens dot js okay and now let's run this and see what happens and it looks like i made a mistake i did not it looks like over here i didn't spell artifacts correctly maybe you guys saw that let me take a look let me take a look i was too excited artifact cats i just like cats what can i say artifacts okay save and let's run it again okay and there's another mistake here it seems like the central bank is not defined but it should be so let me go back in again okay so first of all i see some mistakes here the decentral bank dot deployed should be coming from our decentral bank so this should actually be coming in from here and this way it should actually detect it when i switch it to the central bank yeah so these should have been capital capitalized first of all and second of all well i don't think there is a second of all i think that's it so let's go ahead and run it again so we're running truffle exec script slash issue dash tokens dot js right it's right over here and third time's third time is a charm so hopefully this time we go green go green or go home and there we go i don't know if you see it but we can see it right over there i'll make it larger because it's success so successful it's so exciting tokens have been issued successfully all right so actually the reality is that no tokens were issued right because nobody deposited anything but we just ran the console log just to see that the script works so the real test will be once we have the website working in people's stake and then we're going to run it to see that it actually issues the tokens over but just to get the console.log that's a great green flag good test it passed excellent okay and that ends this section on building out our test suites congratulations for getting to the end if you're having errors you're having some problems go back see where the errors are you can ask somebody in the community or go to my github and get the final solution copy it down and check it that way but great work getting this far and next up when you're ready and we're ready to go ahead in the next section we're actually going to build out the front end so we're going to develop the application we're going to build out a nav bar we're going to build out a loading bar to make sure things are working and and then staking and unstaking buttons and we're even going to build out build out an airdrop timer for us so we're going to we're going to work and react and we're going to see how react works with blockchain and how we can take the blockchain smart contracts and implement them leverage our web 3 meta mask and actually integrate all this together so it's the coming together of all the things you made it this far you deserve you know you deserve a celebratory high five take a break or something and when you're ready i'll see you in the next video okay bye for now you
Up Next

Build a Decentralized Application (DApp) with Web3
@DappUniversity
198.4K views•2018-03-07

Triumph of Orthodoxy Icon: Byzantine Art & History Explained
@BenCallan
2.1K views•2024-08-06

FastAPI vs Flask vs Django: Choosing the Right Python Web Framework
@TechWithTim
302.5K views•2024-05-26

Game of Thrones Opening Credits: A Cinematic Analysis
@gameofthrones
46.3M views•2011-04-18
Related Study Plans & Knowledge Roadmaps
Structured learning paths in General & Interdisciplinary Studies







































