Testing Smart Contracts & Multi-Chains | Chainlink Hackathon Workshop

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello hello welcome welcome welcome back guys today we're going to be working on testing our chain-link smart contracts testing especially locally uh right it's because we're going to make them very powerful so we're just going to wait a couple minutes people roll in i'll let people rolling so we can have this be a little bit interactive again feel free to jump into the comments before to ask some comments uh these are these sessions are for us to chat uh to talk and um to learn about slowly and smart contracts and building uh really powerful applications obviously testing is a really important piece of the um of the development world because we want to use our tests we want to iterate very quickly over trialing and erroring stuff right and and being able to write effective tests is going to really enable us and really empower us to write our smart contracts much faster much more much better and more fun so we're going to give it a couple minutes let some people roll in unless uh you all are testing wizards in which case we will not do much testing just kidding no you the other thing is if you want to go mainnet if you want to take your project from you know fun hackathon project to live to mainnet you definitely definitely a thousand percent need tests there's no way uh any respectable project is going or or whatever your user is going to work with your protocol if it doesn't have tests i mean these are really make or break facts for sure absolutely facts uh welcome to the string uh welcome to the stream and we are also going to go over multi-chain use so we're going to quickly go over that because um understanding that that network uses is going to be helpful and we haven't quite covered it yet and we have a fun little thing to to demo that's new for you engineers for matic in particular um excuse me matic binance and xdi in particular so we're going to go over that uh really briefly we'll probably will release another video sometime in the future showing people how to do that because it's working with the chainlink vrf so it's 4 33 uh we are going to just go ahead and jump right into it let's get into uh let's get into everything here so let me switch to the stream oh i don't know if i have this up oh yeah everything's black ah sorry one second let me swap to this much better boom all right cool so first thing i want to show you guys is working with multiple chains so i know a lot of you guys have um metamask right so we're going to expand this view so this metamask right here and what we're going to do is we're going to jump in and we're going to look at the different networks so obviously different test networks are pretty simple right we have ethereum robson really you just kind of switch right and your metamask kind of updates obviously these are all tested and it's fine when we're working in our vs code it's going to actually be pretty similar let me let me expand this so that it's actually covering the whole screen here it's going to be kind of similar right so when we looked at you know we can look at our truffle config for example we have this module.exports and we have our we have all these networks defined in here right so again they're defined with this rpc url that we're setting as an environment variable here so really uh usually on any type of framework whether it's truffle whether it's hard hab you can do you know command dash network and then whatever you set in here right so if we set coven up it'll be kelvin we could add a new network and and you even saw me do this a little bit earlier um switch to like ring p whatever and it's the same for everything it's the same for for like xdi it's the same for you know fine and smart chain it's the same for a polygon where the url is just going to be the url from that like rpc so for example we can even go to like metamask setup metamask setup polygon setup metamaster polygon and they'll even show us the rpc url and the uh and the chain id which are the important pieces so we have the rpc url boom this guy chain id manic so we can just copy paste this so instead of like url we would do something like this for polygon for chain id we grab this right here and that's pretty much it and then boom all of a sudden we can start to point to these other chains so the only other thing you'd have to do obviously is especially when working with link tokens is get the link token on that network now here's where i'm going to show you guys something really cool so to convert to something like polygon right it's actually really easy to convert from a mainnet ethereum to a mainnet polygon because they have a proof of stake bridge which is uh which is really sick and you can actually convert your assets over to polygon really quickly so this is in our documentation like i said uh i think i do need to switch to ethereum mainnet or something connect sign so i'm signing in to the bridge here and this is their bridge so it's really easy we just kind of pick the token that we want for example you know maybe we want link so we can interact with stuff we want link and then we transfer we just hit this transfer button a big thing will pop up it'll say sure you want to do this you say yes it does it in like seven minutes it's really nice right i mean we're doing we're doing interoperability we're doing cross chain stuff here obviously if you okay so if you switch it uh it kicks you out it doesn't let you do that so once you transfer your token over uh what you can do then oh it looks like i do have four cents on medic maintenance nice cool once you do swap your tokens over what you're gonna need to do when you swap your link tokens over is you're actually gonna have to swap them from the uh the bridge link to true link so we actually don't even have um we actually don't even have uh polygon on here so let's even do it polygon add it right here polygon matic rpc url fan id attic block explorer boom save polygon matic done awesome then we can come to this peg swap thing right so once we get some uh once we get some link token over here oh it looks like i do have 0.1 matic nice once we get some link token over here we actually let's see if i have any link in this wallet i didn't know i had money in this okay cool i got zero link guys i just found like half a half of a half of a penny you guys excited for me boom boom so i don't have any in this wallet but what we can do is the bridge link that we actually bridge over actually isn't erc 677 compatible so what we need to do is we need to swap the bridge link over from matic bridge link to true like wrapped link this is the link that actually works with oracle so that's just the next step for working with matic uh and it's the same thing for binance smartchain xdy actually does give you the correct token but if you bridge from binance smart chain to x die it'll give you the wrong token so we just got to do this extra step when bridging over but it's super quick super easy so uh that with that being said i'm going to go switch over to testing now uh and we'll take some questions let me look at the comments here hey patrick i understand that chain link uh main use is to bring it um bring off chain data to chain um as that is a major problem for blockchains yup bring off chain data on chain yep however messing with brownie i think i can process data that is option either from a file or an api then use that in a smart contract thus bringing it on chain without using chain link uh what am i missing okay great question so for ref for your reference you should go over to the everything chain link intro workshop that we did that goes over and answers this exact question so you can also write your smart contract in python you don't even need to deploy to ethereum so why are you even bothering just spin up a server you don't have to spend any gas just write your smart contract on your centralized server what's the issue there oh it's a centralized server that's the issue the whole purpose of this blockchain world in writing these smart contracts in the first place is to be decentralized and have these autonomous automatically executing smart contracts that don't need a centralized intermediary so the same reason why you don't say oh my python program that's running on my computer yeah that's a smart contract that's the same uh that's the same logic behind oh the data that i'm going to um to give to my smart contract yeah it's decentralized it doesn't work like that you need your logic layer and your data layer decentralized so sure you can put data onto your smart contracts you can say the weather outside is 12 degrees or you know it's raining fire or it's raining basketballs you can absolutely do that 100 but your data is coming from a centralized source it's coming from you so this is not something that we want we want our data to come from a decentralized network so if you think you can put data on chain yourself and it's just as good then i would say then your python program that's running on your you know your raspberry pi in your basement is also a smart contract which is clearly not true so so that is the answer there great question all right any other questions on multi-chains any other questions cool all right well i just took a second to answer that question let's move on to testing stuff right because that's why we're here so a couple things we want to do um we got a couple did i are these the right tests let me just check real quick sorry it pull the i got to pull the branch sorry guys i i had the wrong branch up two seconds here two seconds here so we're gonna be testing with both hard hat and we're gonna be testing oh this is on patrick alpha c master okay paul okay here we go now we're in the right one sorry about that guys so let's jump into some code so testing our smart contracts this is super important obviously this is super important why because we want to you know do things correct we want to actually deploy smart contracts in a smart way so when we deploy our smart contracts what we're going to do and i'm going to show you guys how to do this with with truffle and brownie uh we're not going to show you guys hard hat i don't have those ones those examples done yet but the concepts are going to be the same and actually i highly recommend you guys check out hardhat for running these tests because hard hat tests are even faster they are super super fast um they run on the hardhat runtime environment and they're awesome so definitely recommend you check that out so if we look at our package here right this is a sample truffle package it's going to be very similar to a hard hat package when we use this what we want to do is we want to run our tests locally right right now so far we've been talking about running tests and working with tests on a test net which is great and a great way to actually test stuff however the issue is that you'll see you'll run into a lot of you know oh you always need to have these tested tokens and you got to wait a lot longer for stuff to come back and and you can't unit test as well so how do we fix this how do we address this well what we do is we um and then one other thing is that we can actually work with local on our you know our local ganache is because we need to work with these oracles right these oracles are watching these chains so how do we get them to like watch our local chains we can test faster well we can't really do that right that's that's going to be really hard so what we want to do is we want to deploy mocks we want to deploy basically fake contracts that dummy what is happening on chain right so for you know if we run a local test net we're clearly not going to have um maybe i should even draw if if people are getting confused with this let me know um if we're running a local test net we're not going to have access to stuff that's being aggregated on chain right all those all the oracles that are returning data we don't have that so we want to deploy a dummy contract that pretends to have it so let me know in the chat if that doesn't make sense or if that does make sense let me know either way i'm looking at the chat right now if you guys are like this makes perfect sense move on let's do it um mocks are pretty fundamental to most testing infrastructures um they're really good um and they're it's no different here we mocks are very very important for our testing i'm not getting any feedback here so i'm assuming you guys are all wizards and you guys all got it well then i will move on i will continue with the testing here so here is a simple uh it's gonna be a sample of uh testing a um [Music] testing a price feed oh okay now they're coming in streaming r was just slow makes sense a dummy article simply we should make chain link exactly okay so yes so we're gonna deploy a dummy contract oracle that's pretty much it yeah we're gonna deploy a dummy contract that is going to pretend to work uh to get data right so let's let's deploy those dummies so here's an example of of the contract now in truffle we can run truffle test and we're even going to run a specific well to do all of our tests we can just run trouble test you'll see that this is a little bit slow again highly recommend you guys checking out hard hat because hard hat tests stuff fast hard hat tests are really fast uh this isn't in the main um truffle box repo yet we are working on uh pulling it in there but you can check out my repo which has all these tests in there cool 13 passing but if we want to do certain specific tests we can do test um excuse me truffle test pass price consumer v3 test.json so we can just test this one and i'm gonna i'm gonna walk through this real quick um actually you know what let's just live code it because that's more fun right let's go live code goodbye see ya now it's gone um and now i'm like wait hold on i gotta i gotta get my my tests in order here i gotta figure out what i'm doing what is this price consumer if you think three sorry one second just getting all my my bearings in order here test all right cool sorry about that so we're gonna we're gonna write some tests here so the first thing is we're going to uh we're going to grab a cert so we can actually do our tests so we're going to const assert equals require so chai is a package um pretty much most solidity both hard hat and truffle use this so it's gonna be pretty familiar uh hard hat does have some nice additions for markers definitely again recommend you guys check that out so now we're gonna test our contract so this is what all we really need for testing so let's do let's start testing our contract so we're going to test the price consumer v3 so we're going to do contract price consumer v3 counts and now we're going to do a function here accounts it's going to get us set up to actually test this contract the price consumer v3 we're going to const price consumer b3 equals artifacts r to fax dot require remember this is truffle syntax price consumer v3 again artifacts grabs from the build directory right so it's going to contracts price consumer v3 which is in there again this is that really simple a really really simple like demo contract right here right and it's all it's doing it's grabbing the latest price that's it right but we we don't have um an address we can give it you'll notice here too that actually that i should have mentioned this before the constructor is now taking a variable instead of just having everything hard coded and we'll show you'll see why in just a second here and again feel free to ask questions so we are going to be testing this which has been slightly changed for that one piece and again we'll show you why we also need const [Music] what else do we need we need a mock price feed equals artifacts dot require mach v3 aggregator okay so cool so this is what we need so you're saying okay price consumer v3 that makes sense that's this guy that we've been working on this whole time what is this mock v3 aggregator so if you notice here on the contract side we have a new folder called mux oftentimes this is also called test or whatever you want to call it it holds stuff in here for testing our contract so you can see in here we have this mach v3 aggregated outsole which actually imports directly from the chain link repo so we can even click on it we can go into it we can see what's in here this is just a it's a smaller repo it's literally exactly the same interface as a regular you know aggregator but it's just easier for us to actually test stuff so it's if we're saying hey we're going to get a mock price feed consumer or excuse me a mock price feed and this is what we're going to reference instead so remember how when we deployed our price feed smart contracts we just kind of copied this and you know had this be had this be blank and we had it like this and we just hard coded it like that now we're going to have it be a variable and we're going to pass our mock uh price feed address in here so that we set our our smart contract to look for this this fake this dummy price feed that we're actually deploying okay in oracle there is only actual prices or can we call prices from yesterday yes you cannot call historical prices go check out the docs look up and get historical prices so anyways we're going to swap this out for price feed right we're going to swap this out for a variable here whoops so great so that's what we do here now let's come back uh now you'll see in a second we're going to take this mock price feed and we're going to deploy a new one to this price view consumer so also let's get our default account again um we need to be able to um [Music] we need an account to deploy from and let's do this let price consumer e3 mock price feed okay so we're just gonna we're gonna define these um so that we can use them later so we have our contract basically uh our contract section basically set up let's start testing our actual contract so let's do describe get latest price right because all we want to do now is test getting the latest price okay so we're going to do it as a function here and we're going to do this fun little arrow syntax and we're going to let price equals i don't know 200 or 200 way one two three four five six seven eight nine ten one two three four five six seven eight that is 200 uh 200 way so uh this is what we're going to set to be our price feed so we're going to say when we call our price feed when we call get latest price we're going to call this is going to be respond this is going to be the response why well it's because we're going to set this to be the price of the mock that we're going to do so now we're going to do it before each and again before each um when we run this test before each uh happens before each one of these little these tests that we do and you'll see um you'll see us do that in a second so we're going to make this an async function because we need to do some awaits in here and now we're going to deploy the mock price feed so we're going to mark price feed equals weight mark price feed dot new and what are the parameters of mock price feed well again we can find out by going into um the contract right here so we again we're looking for the constructor what's the constructor okay it takes decimals an initial answer so the decimals are how many decimals on it and this is the question we get a lot how many decimals um how many decimals in the uh in the answer and then initial answer so this is going to be the answer that we're going to return here so back in here we're going to say we're going to go for 8 decimals and again most of these are 8 or 8 or 18 and we're going to say price is the initial answer okay now we're going to say price so this is going to be deploying basically a new mock price fee it's going to be dummy deploying a new product mock price feed great so now we're gonna do mock consumer v3 there's gonna be price consumer v3 equals the weight this is really p3 this is us deploying and we're going to add mockpricefeed.address as the initial parameter right so if we look on price consumer e3 we look at ad we look at its parameters we see it takes an address as a parameter right and this is how we we get it we we set this up so we can test it efficiently so we add it so that it actually takes the price feed as a parameter um and we can um and we can then test this a lot easier right so now we do price consumer v3 equals weight this dot new and boom now we have this in here so before each one of our tests we're going to we're going to deploy a fake mock price feed and we're going to deploy a fake price consumer v3 great now it now we can write the test that we actually wanted to do so we're going to say it returns the price um async function and we're going to do some weights so this is so uh this before each um we're saying before each one of these it's that are coming forward we need to do this and um hope did i do that wrong oh yeah and this describe we're saying this kind of whole section is getting the latest price and we're saying this whole section is this price considered v3 contract so that's kind of how it's split up here so you make a fake oracle and a fake contract so we make a fake uh um we make a fake price feed right so we're kind of we're basically making a fake oracle to do our tests here so we're dummying uh getting a response from the uh mock price feed and you'll see why so it's the same thing as if um we had added a real one in here but instead of a real one we we pointed our contract to a a fake price feed a fake price feed so that we can test the rest of our smart contract a lot easier right and you'll see why in just a second so now we're going to say it returns the price we're going to make an async function because we're going to do some awaits i'm going to do assert not equal or actually just to make it easier we're going to say let uh it is price equals await that's consumer v3 dot get latest price and this is the um this is this function right here the latest price so we're saying latest price is going to be this and then we're going to insert that equal latest price is going to equal what it's an equal price right because that was the initial price that we set it as so we set up a fake price feed that had an initial answer of 200 or um actually excuse me i guess it should be 18 right because it's uh this is definitely 18 18 decibels so an initial um an initial answer of 200 and then we're going to call it later from our smart contract and assert the latest price is equal to price now obviously this is a really simple example here but what if we you know what if we did a bunch of crazy stuff here what if we were like all right um would get latest price when we were like okay you know price equals price times the square root of infinity and beyond or something crazy like that right uh we want to be able to check to see that our math is good and we're not doing something crazy um and if we you know the more intricate these gets the harder they become to test so with this simple example it's obviously really simple um but or with this example you know it it's not necessarily simple um but this example so now let's test just this right so we're going to test just this so we can do truffle test test price consumer v3 test and we are going to see what happens here so we're going to just test this testing just this bit that we just did let's see if we did it right so what's happening is ganache is running a local chain in the background we're going to deploy this fake uh get latest prize price um get latest pre it's not a function let's uh let's get latest pre let's get latest price what do you guys say let's actually get the latest price so we're going to test this now and great passing it returns a price so and you can see like it kind of gives this nice little output here this is you can ignore that that's a console log i put in there so the contract is price consumer v3 we're testing the function get latest price yes it does return a price great any questions here so you make a fake oracle and a fake contract basically yep is there a way to test the deployment of the smart contracts as well on test net aka integration tests great question actually yeah um there are integration tests are really important right so this is how you do it locally um and this is important for doing um for for doing really quick quicker iteration on testing for doing integration tests um you can actually do network oven right or whatever you want it to be and uh sometimes what people do is they'll have like if network dot id you know does not equal 42 or whatever you know tests like this otherwise test a different way so there are there are some setups uh there are a little bit of additional setup sometimes when doing these integration tests and some people actually have a harder time understanding the mocks so they just go right for the integration test and they skip over the mocks and they just do everything integration tests obviously the disadvantage there is integration tests are going to be let me even switch obviously the um the disadvantage there is integration tests are a lot slower right you got to wait for every transaction to come through you got to wait for you know the link to happen and everything so you absolutely 100 can write tests without doing mocks and just on a network and again you can just do that dash dash network bit there um but you you definitely want if you're trying to iterate really quickly uh it's gonna very the larger your project scales the harder it's going to be to maintain doing integration tests every time you make a small change so it's really important to kind of understand the difference between the integration tests that you're going to do on a test net and the unit tests that you're going to do kind of locally and with mocks so that's a really good question actually that's a really good question type 1 get latest price yep sorry about that is there a tool to establish test coverage i think there is but i forget the name of it right now um come back to me why is an integration test valuable um good question integration tests are basically uh hey does everything work does everything work together the way i we expect it to right and this is really important unit tests are great because they test a singular piece of your of your code and this kind of gets into just smart contract excuse me this just gets into software engineering you know uh general concepts here unit test is like testing a function and it's important to see okay does this thing do what i want it to does does this little thing do what i wanted to do integration tests are like does this thing do what i want it to do when everything else is happening right and oftentimes there's a lot of everything else happening that can screw something up that you wouldn't expect so integration tests are super valuable what is the process for running nightly regression tests um that kind of depends a little bit more on your setup i don't know if there's a specific like this is how you got to do it um yeah i don't and i don't know if every project even runs nightly regression tests maybe they do um i'm not sure i don't know that much about nightly regression tests actually so good question i'm not sure is all of chain link contract also available with mock and repo uh pretty much yeah so there's a mock aggregator mock vrf coordinator um actually i'm in the process of adding or requesting a mock oracle to test uh api calls locally as well uh right now uh what i kind of do is until we get that in until we get that improperly is i just do like a mock oracle contract like you see here where it's basically the exact same thing as an oracle contract excuse me but i have like a couple variables modified and i'll show that in a second so this is kind of the simple one here let's also do a vrf test because we want to take a look at that and then if we have time we'll look at some of the brownie stuff because i love brownie um and brownie's the best you guys can see i'm very very biased to python i think i think python's awesome let me just look what how are we doing on time here we're doing good we're doing quite well okay so with let's do let's do a random number consumer test here because this also this is going to be a little bit different right this is going to be we actually are working with a link token here and the contracts are going to be a little bit more uh they're going to be a little bit more intricate so let me just uh let me just delete everything in here and we're going to do the random consumer boom really everything in here uh looking at a couple more questions it's all chain like repeatable also yeah so like i said there's a lot of mocks in there if you head over to um like the tests folder there's a lot of these mocks in there that you can just grab and drag and drop like you see here great question to what extent do chain-link devs at least in development contracts adhere to tdd as in writing the test first before one writes the actual phone um i don't know that's a good question i mean chain links open source so uh you're asking like what do people do to you know i don't know maybe maybe they all do maybe they all don't um i mean tdd test driven development is more like a and just for you guys um awareness here's the question tdd test driven development is more like a methodology um so i don't know um that's a good question i'm sure some do some don't beats me will you do more polygon stuff yeah what do you want to see let's finish this let's finish this first and then we'll we can talk about more polygon stuff um but yeah i i definitely i highly recommend if you guys are looking to get you know real link check out this this bridge um this double bridge so all you got to do is bridge your link token using this bridge and then just swap it using this peg swap so really excited to see people using that i'm really excited what i really want to see is i want to see a bunch of projects deploy nfts on matic using chain link vrf um i'm we're hoping to to give out some more details on the main net for that very soon but we'll see we will see cool all right let's do some tests here because these are going to be interesting as well so let's get uh we're going to start the exact same way we're going to start with a cert equals required shine then we're going to do our contract and this is going to be the random number consumer uh comma accounts boom boom boom so we're going to test this random number consumer now so what is this random consumer that we're testing well let's take a look let's take a look so it's this one it's this simple example of um i should i should stop saying simple because sometimes these are difficult for people to understand so it's this it's this uh this boilerplate example of uh of getting a random number right so we have request random number and fulfill randomness so we get a random number and we then we fulfill it right so if you if you're unfamiliar with the chainlink vrf we just deployed a whole bunch of video content on it uh definitely like click back or whatever um and then just chain link vrf and there's a ton of videos on it that go over this really in depth especially with remix so you'll see here we've changed the contracts a little bit so that they're they're better to test and this is actually good um software development practice we want everything that we code to be able to be testable specifically we also want every function to be uh be testable we're not testing every function here but um just for the demo but you want it you typically want to test all your functions and test everything so here we have all of the inputs to our constructor here they're variables this is again so we can kind of do some that mock stuff right if we're testing locally there's no link token so we need to deploy a mock link token there's no vrf coordinator so we need to deploy a mock vrf coordinator is there a fee sure there's a fee right we could just set the fee to whatever we want it to be we can set the key hash to be whatever we want it to be so we're going to have to deploy mocks of these two so this is why we need them to be um we need that at least those two to be parameters uh i also have last request id as a uh as a as a um thing in here this isn't the best um uh practice here the best practice actually is to uh omit an event uh and you'll see how i do that in a minute um but just for the purpose of this demo and for simplicities we're just having it be last request id okay let's get into it const random number consumer equals artifacts dot require b choir random number consumer boom again hey give me the random consumer it's in the build we did truffle compile or hardhat compile or browning compile or whatever it's in the build it's in the build [Music] in the build give me the build now const brf coordinator or the nato or mock equals artifacts don't require erf you guessed it coordinator again we can see that in here right when we compiled we have this test um vrf coordinator mock why is this one mock aggregator and this one vrf coordinator mock good question i don't know um great question uh this is vs code that i'm using yeah this is this is vs code so we have this vrf coordinator mock and we can and this is going to be the exact same as the mock like price feed right uh very very similar to that except for instead of having this on on-chain contract that's going to verify randomness we're going to have a fake dummy one that's going to verify randomness uh we're going to have a fake we're going to be calling a thick chain-link oracle here okay now we also need a fake link token right and this one where we don't have um [Music] wire we don't have in our tests but we we could we could put like a mock link token but we're actually just going to pull it right from the um right from our package right so when we installed this we installed we did npm install this in in the back scene when we did npm install right so we're actually just going to pull the link token and let me just do this from from our package here and do we need do we need to mock anything else no not really this we need a mock this we need a mock this is fine as it is right this is the contract where that we're testing so again you know per usual counts we need a default account equals um accounts zero and great now we're just going to do a couple of let's because all of our contracts are going to have it's going to be all of our tests are going to have some stuff in common we are going to have random number consumer with the lowercase r because this is us pulling us in the class this is going to be the actual instance of it the rf core mach we're also going to need a seed phrase we need the mock link token we're going to mock key hash key host hash and we're going to need a fee okay great so that's all the stuff that we need right there so let us proceed time for us to build uh the test so let's describe what are we testing uh describe to request um random number this is just gonna be a regular function that's this arrow stuff function and our first test is oh um excuse me sorry we're not going to do tests so we need to do it before each again right before each of our tests we need to do some stuff what do we need to do well we probably want to deploy this stuff so that we can test it right before each one of these tests we want to deploy uh deploy the random consumer uh so we can test it let's do this so let's set up the key hash equals and i'm just going to copy paste the key hash value in here boom super long doesn't really matter the key hash fee equals doesn't really matter the fee we're gonna do one one two three four five six seven eight nine ten one two three four five six seven eight uh link equals wait link token.new from default accounts right because we need to dummy a link token so we're going to deploy a dummy link token then we need to deploy our vrf coordinator mach equals await vrf core the nato mach dot and what are the parameters for the vrf coordinator mark so we know there's nothing for the link token we can check we go vr coordinator mark control click into it it's a constructor all it takes is the link address so that's all we need to do for our test here so we can do link dot address [Music] from default accounts oops default account so we're deploying a mock link token mock rf coordinator guess what we deploy now you got it a mock excuse me not a mock a a random number consumer an actual random consumer because this is the contract we don't want to mock we want to test this uh oh excuse me we also want our seed seed this is going to be the the seed it's going to be whatever let's just do one two three it's gonna be the seed for the random number we'll need it a little bit lower so now we're going to do random number consumer equals await and number consumer dot new and we needed to deploy these two first obviously because we need those addresses so we come back to the random consumer the number consumer look at its constructor and we see it needs a link token for the first one so for the first parameter so we can do link address great second one is going to be the key hash key hash which we have defined up here and we're going to do the vrf coordinator pref coordinator mock.address and last but not least the fee fee just kidding last but not least the default account remember you need this remember you need this from anytime you make any type of transaction with web3 or or ethereum you need it like a from it's like who is this transaction happening from and we're saying default account which is our account zero which gets pulled in from uh truffles fancy keywords cool gonna quickly look at some comments isabel is it better to build on remix or truffle uh i think i like to say like remix is is really good it's kind of like a little bit like training wheels it's great for really visualizing and understanding smart contracts if you want a really sophisticated application you need to use truffle brownie or um hard hat you there's there's really there's really no other better way to say it you've got to use one of those if you make it on remix you should import so many contracts from github um yup you have to yeah if you make this on github or on remix you do have to import from right from github will this video be saved yes absolutely 100 definitely come back to it later cool so we have the describe up now let's we have the before did i not do the before each [Music] oops i didn't say that this was a before each oh sorry guys my bad this is actually before each this and this is an async function because what you're doing awaits so sorry about this guys so this is actually gonna go into there why are we doing this before each so this is saying for everything that's happening in this describe before each of these um tests that we're going to do we need to set it up so we're going to set it up like this so let's keep going we're going to hit excuse me now we're gonna do our first test and i gotta be a little bit quicker because i'm running out of time although i don't think anyone's after me right so we can go a few minutes over yeah no one's after me so we can go a couple minutes over worst case uh we have almost 70 people watching great awesome hello welcome welcome everybody we're learning really important stuff here um hey remember everyone who's watching feel free to like leave a comment you know say hello ask question you know these are meant to be interactive so questions have been great so far definitely good questions no question is too dumb no question that there are no dumb questions here no dumb questions here okay um so what do we want to test so oftentimes i'll do this it reverts without link i mean you don't really have to do this um but let's just do it kind of real quickly so if our contract doesn't have link it's gonna revert right because the vrf coordinator needs link to to function right it needs the link token link token is that erc um erc677 is this big enough by the way oh that's kind of that's like obnoxiously big if you guys want this bigger let me know um hello hello welcome and so we're going to have it revert without links so if we try to call a function right we would expect it to revert so we're going to call weight expect revert uh and then actually we gotta add some add some open zep1 test helpers so this is something else we want to grab if we want to use expect revert which you'll see how i use it right here opens that one again opens up and has amazing tools so await expect revert dot unspecified we should actually put what the what the revert message in here this is basically saying hey we expect a revert to happen we don't know what kind uh we should probably put the real one in here but um just for simplicity we're going to keep it like this now we're going to call the function a number that gets random number seed and again always from fault accounts we should expect this to revert right because and again in our random number uh dot sol if we call get random number this needs link we know it needs link this should fail so if we run this it will pass oddly enough because we're telling it hey this is going to fail so let's run the test just on this shuffle test random consumer test.js so this will pass because we're saying we want it to fail great so it does revert so we're saying this did fail if this didn't fail um this we would be confused so so we did this right hello hello oh everyone's saying hello now yay welcome what do you think about using fsm final state machine for building smart contracts i don't know uh or sorry finate finance i don't know i don't know that much about that sorry how does this how does each test hey love your questions by the way great questions over here how does each test differ from the previous one since you are setting it up the same um setting it up the same each time won't each test result be the same how does each test differ for the from the previous one since you're setting up won't each test ah okay good question so i'm setting it up the same right because i want to do this in every and every thing and every test but for else this is actually a perfect question but for example in this test here i'm calling get random number but i didn't supply it with link right so this test is going to be very different than the next test that i write which will supply it with link so these how you kind of capture these different uh these different um these different scenarios right so now i'm going to say it [Music] returns a random number with link right so this this is one that's going to be different so it's going to be set up the same but we're going to do different stuff in the test that way we can see the different stuff and we can see the difference is there a way to capture events great question we're actually going to come right to that great question really good question this is um alejandro we will we're actually gonna demo that very soon hey what's up how we doing hello hello hello hello all right cool so now the first thing we want to do is we want to send our random number consumer link so we're gonna do link dot transfer and this is going to dummy sending our our uh random number consumer contract link uh we're gonna send link.transfer address and then we're gonna do some web3 stuff actually web3 dot utils dot 2 way one ether from full account so no we're not sending one either we're sending um we're sending one uh one link which is uh we're saying hey grab this one this number one turn it to whey in ether so we're really this could also be kind of replaced with like one one two three four five six seven eight nine ten one two three four five six seven eight but actually javascript might kick out because javascript doesn't like big numbers um so we're saying okay transfer and you can look up um you know the parameters transfer takes it takes an address it takes a you know amount and then obviously everything takes it from default so we're just sending our random consumer contract um some link so that we can test let's keep moving on so then what we want to do now we can actually call that contract so we're going to say let transaction again because we what we get back when we call function is a transaction equals await of number consumer consumer dot get random number and what are the parameters of get round number i believe it's just a seed yep it's just a user provided seed so we can call it so again we have the seed defined up top so we're going to do dot seed or from seed and again everything is going to be from default account okay so we have a transaction and we're going to equal it to that so here's the answer to your question actually and then we can even console.log uh transaction dot receipt dot raw logs so i'm just going to run this to show our friend here um how to actually see events data so if we admitted events um you can see everything in this transaction receipt in these logs basically and that's actually a really good question and you can see kind of everything here here the different topics there's all this stuff in here each there's the log index log one um log0 these are the different events that are being emitted so that's actually a really good question and events are actually the way we want to test um test things so i'm doing kind of this cheaty way where i'm setting like uh last request id to um to a public variable what we really want to do is like define an event you know event whatever uh and i'm not going to go into this here um and then we do like a mit event and then what we'll do in our test is actually um is actually check we'll do like an assert um dot equal equal you know transaction.receipt.logs you know whatever log you want to do at whatever point equals what the res uh the event that you're expecting that's a really good question i know i kind of skimmed over that material um but events are really good for for writing tests and um they're really just good to have in general so uh yeah yeah so there you go so this is kind of that whole that whole bit so you can write your tests and actually check the events and that's actually really good practice so i'm giving you kind of a cheater practice here i'm sorry um in your tests it's it's much better to actually check the uh check the uh events so great question uh really good question so and then even you know uh then we can do smarter things that and like dot assert.exists tx dot receipt receipt logs so this is like the super lazy way to like check hey did we do this right are there even logs yes okay cool we'll move on um so the better way like i said is actually to emit some events to see that this worked so we're gonna get a round number here we're doing kind of this really lazy lazy test here um now now what happens okay so we need to get uh we need to figure out okay are we gonna get a random number back how do we get that random number back well this is a great question so first off we need to get uh we need to get the request id because what we need to do is we actually need the vrf coordinator mock to call back um call back the function so in our mock in this contract our oracle actually calls the vrf coordinator which calls fulfill randomness so that's something that we need to understand and it calls it with this callback with randomness function see it's even um [Music] excuse me this is the function that uses that it uses to actually call back that um fulfill randomness function and you can even see it here it's doing some a little bit fancy slitty stuff uh it's calling the uh the fulfill randomness.selector oops which i forget where it is it's somewhere in this this code base here um but this raw fulfill randomness function calls the fulfill randomness function but this is the this is the method that actually does it so this is another reason we needed to deploy the mox we have control over the vf coordinator so we can actually call back so we've made this transaction to make a request to an oracle we need to pretend that it is going to respond so i'm going to do let request id equals await random number consumer dot last request id and now i'm feeling kind of silly and i'm like oh i should have done i should have done it with the event actually default accounts so again i kind of cheated here and actually i'm probably going to update this letter to do it the right way um i have this last request id so that i can get the request id uh and what i do is i just set that last request id variable to the return of request randomness so that we can have the requested before the vrf coordinator mock but again the right way to do that is actually with events so i will probably update that so that we can test appropriately but for now we're going to test it in this kind of cheaty way because and the reason i'm saying because is you actually can't get the return value of a smart contract just kind of like by calling it like this so we're calling get random number and if we look hey get round a number it returns a byte's 32 right um tough in web 3 the return value is going to be that transaction actually so uh like i said the correct way is to use events as alejandro pointed out so thank you alejandro we're going to do this cheaty way for now uh request id equals away random number.consumer.last request id um and then we're going to do now we're going to call the vrf coordinator lock the rf put in with random mess and we're going to give it the request id because it needs the request id we're going to give it the random number which we're going to set to 777 and we needed to give it to random consumer.address so we're saying okay this request id returned this random number and this was the address that called it and we're going gonna say this is from again default account because we don't really care which account we're calling from now we're just gonna do a quick insert dot equals cert dot equal excuse me actually should be um not asserted equal now we actually need to get that random number equals a weight random number consumer that random result from default accounts the vrf coordinator map called it back called back the function all back the function gave us a random number and now we're going to get that random number from the random result right so all these public variables are secretly uh functions secretly view functions right so we're going to call this view function for getting random results and we're going to say okay get out get out of the way all these things keep popping up um random number that'll be equal to what we set it to 777 right so 777 or 777 so let's test it and see if we did smart things let's see if this works we did then we've successfully tested our random number consumer locally right this is all locally this is this is testing our chain-link smart contracts locally okay we did something bad here uh tx is not defined okay well it's because it's transaction now let's see if we did we did this right we did something else random yeah that's that's not a thing so that that makes sense as well random number a little tongue twist a little tongue tie for you there that spell wrong anywhere else spelling programmer's greatest strengths spelling things right now let's see if we spell the right great and now everything's passing and now we can say great we've successfully tested our smart contracts uh we are now wizards of testing and and this is obviously incredibly powerful because we don't need to do all of our tests on a um on a true um on a test net right we can you know we can still do this dash network coven or whatever and we can also just hard code everything in here to be you know for specific addresses and oftentimes like i will i'll do that too um but more often than not you know i'll do that for like the scripts in the script section is okay this is where i'm gonna kind of do an integration test as a script or something like that it's good to have maybe like a separate folder for integration tests it's really kind of however you wanna do it um but uh it's uh you know now now we can do this without even having to get any test net link any get any test on ethan it's really really powerful in that regard so uh i didn't get to show you guys um how we do it in brownie um and mo pretty much everything that we just went through the same methodology is going to work for hard hat some of the syntax might be a little bit different but you can check out the hard hat docs they are fantastic at explaining their testing their testing is really good um one other note to mention with truffle if your migrations aren't perfect it'll freak out and not let you do anything um kind of annoying but it is by by design that it does that for some reason um so just make sure your migrations are good as well that way you can actually do stuff so i'm trying to pull up brownie um so my brownie tests are in here as well i have test contracts i have mocks you can check out the tests here they're pretty similar and by pretty similar i mean like they're literally the exact same steps just um [Music] just in python right so here's a python test for testing a price feed it's doing the exact same thing so it's taking an address this is creating uh this is actually creating a mock address um okay latest price it's in the comp test i'll just kind of look through really quickly test or what is it called fused price here we are um and you can see it's doing the same thing if network dot show active it's saying if we're testing on the development network we're going to deploy a fake aggregator here and actually to your other question well okay what about my other test well okay great if network.showactive is in the defined networks then we're going to use a real network right so this is a way to test you know with networks that we actually have and then if it's not then we skip it so it's literally the exact same methodology then we deploy our our price feed contract or price feed consumer then we test it we say okay get the latest price assert that it's a value um that's an integer and that is greater than zero so uh it's really it's going to be the same thing here there's a mock oracle contract um a whole bunch of fun stuff and uh we are a little bit over time but um there's no we don't have a hard stop here so we have time for some questions i hope you guys learned something here i know we kind of went through a lot of stuff like i said testing these smart contracts is incredibly valuable and it'll help you iterate much quicker on building these dapps if you do some of this this testing right locally um yes you can absolutely 100 test and deploy everything on a test net and in fact when i was first starting out that's mostly what i did but doing a lot of this stuff locally will make you a lot quicker i promise it'll make you much faster and it'll make you much safer right because you're gonna have tests on everything and if you accidentally break something you'll know about it because your tests will fail so tests are absolutely massive especially in the smart contract world so hope you guys learned something um patrick you're kind of hilarious well thank you i'm gonna take that as a compliment appreciate that um looks more succinct python is king okay cool well we have some other python enthusiasts here love it um looking at questions now this might be off topic but just wanted to confirm for smart contracts can we make a call to one of our hosted apis on google cloud using chain link absolutely 100 percent go check out the make a get request pop your get request in here right swap this out um for an api call that makes sense make sure you kind of watch our our video on making api calls right because you're going to need to know how to choose an oracle in java d just follow this tutorial if you're like wait i'm still a little confused go through this advanced api calls it will teach you everything if you're like i'm super confused this will teach you everything if your api call is really advanced and you're using like some stuff in headers and bodies or you have api keys you're going to want to look into external adapters which we're going to go over tomorrow is today thursday how's today already thursday today's already thursday oh my goodness i hope you guys are building crazy stuff so we're going to go over that tomorrow we're going over a local chain link node external adapters on your chain link node so you can kind of do more customizable crazy stuff so looking forward to seeing all the crazy stuff people uh build good questions looks more succinct yeah python is python is um i like i said i start all my projects now with brownie big um hard hat is also great hard hat's really good uh great workshop thank you thank you so much so uh i know we're over it but we don't have a hard stop here so i'm happy to take some other questions um if you guys have questions or comments or um thank you for the thank you for the kind the kind words here really appreciate it um really hope that you guys are getting value out of these because uh you know i think we're going over some really important stuff and some stuff that's really going to help you uh take your smart contracts to the next level so looking at questions we'll take a couple more questions oh is that the one and the only oh one on the only hey hey welcome how's it going the one and only ladies and gents ladies and gents well we'll wait maybe 30 more seconds because it sounds like you guys are you guys are all testing wizards you guys were like yup no patrick got it makes sense your question skipped oh well what was your question it looks like my my my my thing is updating a little bit slow feel free to drop your question again uh general question about the project should we aim to implement our project on the ether maintenance or keep it on the coven test net uh it's whatever you want to do actually and it doesn't even have to be the ether maintenance it can be uh polygon who's a sponsor avalanche who's a sponsor solana who's a sponsor um moonbeam who's sponsored plasma sponsor polka like the list goes on you if you want to deploy now you absolutely can um i will say though if your project is handling money or something you probably want to go uh get it audited right you want to get it audited um if it's like an nft or something you know maybe it's a little bit that's a little bit easier but if you're if you're trying to deploy some real powerful applications that people are going to want to use you absolutely need to get it audited um uh and uh for me i i like looking at open zeppelin and what opens up and does uh that's that's a personal thing here um but yeah if you're going to go to maintenance you definitely want to get audited you absolutely can deploy on mainnet and i would actually love to see some people deploy for example like on matic with some vrf stuff or on matic with some price feed stuff uh because it's the it's it's so the cast fees are so cheap there i would love to see some people deploy some applications there but no you do not have to deploy to a mainnet you can deploy everything to a testnet and that's good enough for like a submission here so you do not have to deploy to a maintenance good question what exactly is open zeppelin okay good question so open zeppelin let me even flip back to the stream here um so open zeppelin is like a collection of smart contracts um and they also do a bunch of other stuff they do audits um they do defender platform to automate ethereum operations uh reusable libraries security audits um they have a lot of really cool stuff probably their their coolest thing is this this uh contracts application build secure smart contracts in solidity so you can see here we even use some of their stuff or do we oh maybe we don't not in these but in the um mmos nft in our eminence nft demo we did earlier we did use some of their stuff so if we go into dungeons and dragons we did we imported some of their contracts so they have a whole bunch of contracts that are basically already preconfiled for pre-configured for standards um have a lot of safety measures already built in they're they're already audited so it's really kind of easy to just grab what they've done plug it into our projects and just and be ready to go so open zeppelin absolutely love them i pretty much use them in all my projects so um definitely opens up them really cool i don't couple these questions i don't really understand sorry what about this platform uh truffles trough is good too yeah all these platforms are good if you want to build all these platforms we'll get the job done all right cool well if there are no more questions thank you everybody so much for watching i hope you all learned something you know i'll see you guys in the discord feel free to again ask questions really looking forward to the products that you guys build and we'll talk to you guys soon thanks all you
Info
Channel: Chainlink
Views: 4,284
Rating: undefined out of 5
Keywords:
Id: d8SqLaH8pu0
Channel Id: undefined
Length: 72min 54sec (4374 seconds)
Published: Thu Mar 18 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.