DappCon 2023: Build, Test, CI: Zero-Setup Infrastructure For Dapp Development - Nenad Vitorovic
DappCon 2023 · September 2023 · 1:54:19
A talk from Nenad Vitorovic at DappCon 2023 on building a zero-setup continuous integration pipeline for dApp development. It addresses what it takes to get a build-test-CI workflow tailored to smart contracts and on-chain testing running with minimal configuration.
Speakers
Topics
From DappCon 2023, hosted by Dappcon Berlin.
Transcript
so the music stopped that means that uh I'm going to take over uh welcome everybody uh today we'll do a little workshop in uh um a journey through building and testing and doing CI of smart contracts but also testing of the D uis like uh uh automated testing of the UI specifically and we're going to do that using a piece of tenderly technology called Dev Nets and you'll uh see see it all uh as we go along this QR code that you're seeing on the screen if you could scan it it will give you a link to a notion page which has a walk through through the workshop itself let
me know if uh if that works or doesn't work for any reason so I'll just wait a bit for that okay works and I suggest if you could open it on your laptop because during the workshop you will you will need it so let's let's get that set up
all good there okay now I will do an an orthodox thing I will ask you all to stand up and to approach sorry yes yes yes everybody has to be like close and while we're getting here it the agenda says 2 hours I think we'll finish sooner so that leaves us time for more questions or or trying something together but for now if you could all approach here closer to me as you know the workshop is a little
bit about building and testing and what happens to that in the world of web 3 so I would just like to see the movement in in your experience and your uh uh your thoughts and views on testing uh and we're going to do it like that I will say a statement and whoever wants to say yes goes to this side whoever wants to say no goes to that side let's try this out I came here on a horse today oh where did you park it yeah all right I have written tests in the past make us work out here yeah yeah yeah get
uh get your bodies moving a bit all right I was made to write tests in the past I do think it's a good idea to write this you're the one of the ad rather revert yeah I've used or set up a CI in the past okay all right so so today I'm hoping that everybody will be standing on on this side of the room because we will write some tests we will see some test fail we'll set up some CI so now that we know uh the the feelings about testing
that's cool one last thing um I'm familiar with hard hat what hardhead all right and I'm not familiar with react okay okay hardhead hardhead people hardhead people no front end people all right so uh the best way to go through this is actually to work with somebody in a pair so uh if you want you can just randomly pair up uh and uh go through the workshop together maybe just person closest to you uh he doesn't count as a this is philli he'll be he'll be helping
out Jo all right so I had fun hope you had fun as as well uh let's see uh let's spend a little more time and uh maybe you and your partner could discuss two questions testing yes no and why and most importantly what's your experience with testing in web 3 or what would you like you to be if it's not that so we have 5 minutes for this uh chat away of course you will be sharing with the group afterwards so no pressure I mean it
depends that's not an acceptable answer usually yeah you can make a I mean don't time IDE if you just if you want to optimize and the risk was low
ofing and Market but most of the time couple of test you don't need to worry [Music] like I was starting doing tests at the same time found was coming up
you're speechless you got three more minutes so I can cut it shorter you guys prerry test why I mean you can all the [Music] operations
EAS like languages true just I much done this for a couple years so my mind it's normal different langu for the same on this set up you can just set up youres set something balance
not yet so [Music] howest I if I want to if I want to mute myself and just like hardcoded the hacker address into there and then they
waited until you click the certain button in the UI we kind of we need a mic now they hacked couple million think was Badger 10 seconds left closing the discussion and time let's uh let's share the The Impressions from the discussions you had uh who who wants to share something with the
group no I just joined I just joined okay um you guys yeah yeah we were just talking about how testing became easier in our opinion when Foundry came out cuz it's just a it was easier than hard hat for us at least yeah all right and uh is there something from your experience that missing that's missing in the web three testing what we just oh no not that no I'm on the spot now right let's put the pressure down you guys had a lively discussion maybe you want to share something about something that's missing yeah or anything that you
concluded from talking about testing why and why not well about the why we had some I think it's a spectrum of yes no I mean it's it's on there usually you should write them we I had bit more the opinion that you should write them unless there's no risk and you're not working but you really just want to learn something optimized for Speed but most of the time you want to optimize for security as the code is handling money mhm and then we're discussing how to test like I learned testing with truffle many years ago and stopped at hardhead so Foundry is kind of new for me so I learned a bit about the advantages of Foundry
but yeah at the end of the day uh testing is good yeah do it Tes is good do it I think that's a that's a solid conclusion there yeah all right so now let's get into the workshop let me tell you about what we're doing today so today you and your group you get a little project it's not Mini safe I'm sorry it's mini multisig and essentially what it is uh it's well a little UI that a team has made sorry uh this is for some reason this is not mirroring unplug it plug it in again yeah maybe that might
help all right it's not that ah there we go is the PowerPoint okay so essentially what this is It's a UI that a imaginary team has built and what it does it's a little multisig so uh I will connected through metamask okay now metam mask is giving me hard time okay not wasting time on this but you can imagine that it is a multisig similar to safe so you have options to
create multisig to set owners to add transactions to approve them execute them everything that a multisig is uh and your task is to take over the codebase and to see where it's at if there are any bugs to fix it and to go through through some testing and and now let's just uh spend some time on the architecture overview so we had one bit that is hardat and two important contracts multisig Factory and multisig wallet and uh the the piece of infrastructure that's used here for example for for testing and for staging the contracts is tenderly devet so
that's a piece of infrastructure that we'll be using today I'll explain that in a bit but you can imagine that this command Run 10 devet new uh actually takes main net adjusts it a little bit and gives you your own private testet version of it so imagine like you're having your sepolia on demand but it's just for you you can manipulate the balances the rc20 tokens and and all that stuff and you get an RPC link that you can use so you can actually test your code on the devet so that's the first bit of infrastructure the layer of smart smart smart contracts uh how Dev Nets work as I said you can take an
actual Network such as mayet and these represent transactions and you can write a little yaml file that is your declarative way of telling us hey I want to set up this taking devet uh taking the main net but I want these accounts to have this much test teeth I want these these smart contracts to have some storage slots overridden by these values so we just take the yaml and when you want to spin it up we do a couple of transactions that set it up so in a way it's a fixture of the network that you need for testing or uh you know doing some uh transaction scenarios and stuff like that and the cool thing is if you will spin up a devnet and you get an RPC
and you can use it uh but then after a while you want to start over so you can just spin up a new one and it sets it up in a in an identical way so using a little bit of uh de comparative uh stuff in there in the yaml that's all about the architecture for now there is the uh next JS app that I failed to run but we don't need it for the first segment of the workshop uh so we can see that later and for now uh in the next let's say 15 to 20 minutes uh you can go through sections one two and three of the workshop guide uh and uh first one is about the project setup and the depend you need including cloning
the repository that you as a team are taking over the second is setting up a devet for yourself and the third one is bringing Deets to the hardit so go uh if you have any uh any any issues in the meantime uh you can call uh Phillip uh or myself and we'll just hop over and help you uh get through them I so 15 minutes it's now um who came a bit later here's the QR code with the notion do with the workshop guide so scan it open it on your laptop because there will be lots of commands you should copy actually oh my
God there we [Music] go sh
I just missed the set for sure
with for for
for SC
that's trial I have have an old F can I delete [Music] for
for for St
TR for dep
you for e
let's do a little show of hands who managed to go through step one okay step two the down the template okay who's stuck on mpm install we need something better yeah I think this is the lengthiest part of this Workshop because it's it's downloading so much and uh somebody managed to finish the section three to bring it to hardhead okay take your time uh because we need to go through all of these
for for the
C this is my depes modone
so while we're comfortably waiting for mpm installed to to complete I'll just uh go through the interface uh to to to show you around what's actually happening when you do the devet so you've done the yaml configuration and and you're probably seen here that we have some wallets with some private Keys exposed and don't worry it's just uh Stupid wallets we use for ENT test so not used for anything else and they have some balances overridden so we use that one to configure the devnet so end to end tests could actually work and another peculiar thing here is that we've overridden the chain ID so we did take mainnet but we
didn't keep the chain ID one why because we want to prevent replay attack even though these transactions will come from these completely irrelevant wallets it's a good practice to just prevent this from ever happening and when you get to the to the step where you actually bring hardcut to bring devet to the hard head uh you will run a command that will uh give you well one of these which we call runs so we take the template and we uh spin up a new devet and you can see uh a bunch of things here let me just zoom in because the resolution is off so you can see all the balance over eyes that that you specified uh you can see the contract
creation over here uh you can go into classical uh more of a block Explorer kind of thing where you can see the transactions well not nothing interesting here at this point but we'll be later uh and you can see Json RPC calls so if something fails in there those calls should be visible so those are all the that uh are sent by uh wherever whoever uses the RPC so you can actually see that and uh and analyze as well so I just wanted to uh go through this a bit and uh TV says enough uh so keep going and uh let's say in couple of minutes we we switch to to
the next stages of the workshop that interace only or is a CLI that can have the same information Ry calls and stuff yeah so the question was just for for the stream if there if the interface is the UI only or there's a CLI yes there is the CLI that you just installed uh it's got a command that spins up a new devet so you would Define a template in the UI and then you would use a CI to say hey tally spin up a new devet from this template and this is exactly what that command hardhead devet new or whatever it was does mpm install
done megab sorry almost a gab for me yeah the yeah I tried
and down the rabbit hole one on the
directly okay right Okay C it there stuck if you're too stuck raise
your hand nobody's too stuck that's good okay so let's let's just wrap it up the the first part was very painful because we had a lot of configuration to do there was Predator issues and uh and stuff like that uh but by now hopefully your let me just get this out of the way yeah but by now you should probably have this multi Factory contract deployed on your devet and we can take the workshop further so one thing that I would like to sort of look into now is the way that uh that we can actually uh use the CLI to uh deploy a
new devet and also to deploy new contracts so in this step three you had this command that runs this uh mpm script tender DEET new and uh now you see it no you don't uh on this project mini multisig using this template mini multi tests using this chain ID uh for it so when I go to my hardit this is the lower window down here uh if I just run this command what happens there is that now let me go into the VSS code here's the hard head so I'm getting the configuration uh of the devet RPC I'm also getting the exact chain ID because
hardhead has to know the exact chain ID of the network it's connecting to otherwise it doesn't work so if you don't have this number here or in the devet template then you have to do the the whole thing and and reconfigure it again and the second script that you have ran uh by now is this hardhead scripts deploy Network to the network tenderly so if I go back here and run it uh again you get the contract in there now what this script does is besides uh deploying it also verifying the contract on tender so you can actually have debugging and all the all the cool stuff that you need and now for
the next step this is why we waited for so long for mpm install uh you will actually uh run a an end to end test so let me just kill this thing over over here so I'm switching over to the the front end folder and um whoops and I'm just running mpm run test and it's starting so you can do this command alongside with me because uh hopefully you're you're done with the first three and what's happening is that we're running uh an end to end test that's written relying on uh synthetics uh wrapper around Cypress sypress uh and uh
Cy Cypress and playright so what it does it takes the the Chromium browser the longest awaited install that you had adds metamask and then you can actually WR test it interact with the wallet so you can test every single step in the flow of the UI using an actual wallet and a little Network that's behind it so as this thing runs uh well the this is somebody proposing a transaction and then the transaction shows up and then that person approves it and then there's a switch in the address so now you'll see one green box and here's another one and then there's somebody who will uh do something come
on something should happen now but it's not really happening yeah anyhow you saw how this can actually go through the steps of executing an NN test and actually messing with the UI and the cool thing about it is uh when you go back to the the browser so this is the latest run all of these transactions uh that that we did end up here actually so these these are the three transactions that successfully happened so the thing that uh the U the UI froze a bit here means that there is
a bug that the team who did this and I'm the team uh left an error in there uh for you to to find and fix uh and there's also one little issue here if you notice oh the test have failed that's cool if you notice you may or may not have your contract verified here so this call multi Sig Factory create that creates a new contract and these three are the the calls to the very multisig now what happened the verification the the the very very oldest problem uh didn't succeed so what you can do is you can go in here into this transaction and you
can go view details and yes it is the creation because we can see these are the owners these these are the sign signature requ signatures required so from here we can we can see actually the parameters if you go to the events uh you will see the create event if you scroll a bit down and there will be a contract address so here it is you can copy it and after that to make this thing verified uh going back to hardhead so this is terminal in the hardhead no it's
not uh let me go back here so what we could do here is MPX hardhead verify existing multisig blah blah blah I will leave this command on on the screen so if you run this one with the address that you picked up from the dashboard it should verify our contract so you can see actually everything decoded so if you get that glitch you and you can rely on this command so you can proceed by running the test yourself play around with it see why it failed try to fix the test uh we have uh let's say 20 minutes for this tops no
account Can Am T
through I have the error at least I missed a little bit we supposed to verify for different address is not verified it's not that's so let's uh let's pick up the pace uh
and I will just uh go through the some of the issues that that are present in there so the first one was you you saw it when I run the test it sort of hanged uh it couldn't find account five and I would be lying if this was was intended it was not but it was an accident uh yeah something something changed in the meantime so one thing that we could do is actually what is happening in there so the test uh what it does it switches to account three that's one of those that we we loaded with tests eth and then we um called actually we did the interaction with the UI to create a new
multisig with these three owners and two required signatures and then what we did we proposed the transaction a the one that's pure profit uh just sending some value to to un address never mind which one and then what we do what we're doing we're we're approving transaction as this first account number three then we're switching over to account number four for it to approve the transaction as well and then we attempted switching to account five which for some reason didn't exist so this can be easily resolved if you just replace this by either three or four Tada is the multi sorry count is the multi no it's just uh three
different signers that we added and in metamask on that drop down they're they're called count 1 2 3 4 five yeah there's no five so this is how it shows up in the metamask extension when you want to switch over the accounts um and what happens then we're funding the multisig and now that we have our two confirmations out of two expected executing a transaction should uh should go through so now that I changed this I can uh run the test again and is it on it's on and it does look look a little spooky when you when you see your browser doing things with metamask
right I think if we had like a wallet specifically for this type of thing it wouldn't be so scary uh you you should have worn death first that's true yeah yeah yeah I'm like what have I done yeah but honestly it's happening in chromium so there's nothing it's not touching anything of of yourself that's exactly what the Deep would say I would [Laughter] never yeah so now we there we are we're approving the first
one and uh second approval and now we have the funding of the multisig because we need them to and now it hangs it hangs the execute never happens so now if you open up the the inspector and if you go into the the console oops I closed that one down but we don't need it we can see here that the contract function reverted insufficient number of confirmations cannot execute transaction so this over here is sort of indicative that yes we did have two it appears we had two confirmations but this thing fails over there for some
reason now uh if we go into the dashboard and if I go into this latest run well I still don't have this verified so let me go through that again I will open up this transaction multisig Factory create and um I'm going to go into details because I need to get the address of the new multisig and I can get that by opening events and scrolling down um I can see here oh get out I can see here that there's the create event and then there's the contract address I'm copying it and going back to
um uh hardhead verify existing so this little task that you can find in the hardhead config file if I do this now we have it verified and moving back and reloading so now we have submit confirm confirm and those those are the three successful ones that we saw in the UI but there is a failing one apparently and um I don't want to even go into the fail Json RPC calls here because uh too many uh what we can do is actually the
next phase and that's uh the local hard head testing so uh we've been through the local end to end and now in the section five you can very quickly run hardcut tests if you haven't already anybody did the step five of the the the flow in the notion all right so I think it'll take you like five minutes stops to complete that one and there's no metamask popping up I promise
sorry for for
for for for
for for for
for did you manage to run the and did you find a failing transaction and did you find a bug would you like more time yes or no requ check
for yeah I think that's re the solution and the bug are very close
so I'll do the same thing so right now I'm running the hardcut tests locally and as you you've seen it's actually sending everything over to to the devet and while this is running I will quickly uh go over that uh no test yes so these are practically the the hardhead tests and uh in this fixture or setup what we're doing is we're deploying the multisig so testing the multisig waiting for it to get deployed and from within the test we're actually asking tenderly to verify the contract so we could debug the transactions that
are going on there and there's also the funding transaction and now we have a bunch of tests uh the ones that we particularly care about is is this one because this one failed uh or will have failed let's see yeah so so accepts execution with required approval number so this is the one well this one fails and uh to debug it to to figure out if there's an issue in the smart contract uh we can actually hop over to the devet and oops this is the one and enter the latest run and now
this transaction doesn't show up in this overview here because it has failed but what we can do is we can find the what is it here the Json RPC call that uh should have been that transaction and if you scroll down a bit a bit and skip over some of these uh Json RPC calls you should see here a failed Ean transaction and what what the cool thing is besides seeing all the information about that Json RPC call you can hop into the debugger and from there you can actually see the message and jump exactly to the line where the the thing
failed now I guess and I assume that most most of you already had the solution that this sign over here was off but this was just to we entertained this idea just to show you the way that you can spot the transaction that failed uh the way that you can reach the debugger and you know have a little bit of of of easier time figuring out what went wrong and uh one little tool that can help that is evaluate something awesome in 2023 uh that you can use to well evaluate Expressions so if I paste this here and hit evaluate we'll get the result all right and uh also if I modify this into a little array or a tupple by
adding a comma and wrapping it into brackets if I evaluate again I can see that we have two confirmations two required signatures so this one should have been executed and um again the the fix for that is going to to the multi- wallet contract line 159 and adding greater than or equal to sign but there was also a solution in the notion doc if you looked for it you you found it uh I just wanted to to give you a little walk through uh through the tools that that you can use in this process so now with the bug fix in place uh if if we run these tests they should be successfully
executed uh there we go the wallet is funded and now it runs it one by one it is significantly slower than running it uh on a local node but it does give you the way to visually go through through the issues and uh figure out what the heck is going on and before the last part now let's just wait for this one to yay all the tests are successful
so our job is done here and now it's testing the factory but we don't need to to wait for that one so that was all cool uh but one question actually that I want to uh to address before we go on to the to the last segment and that's the CI is how did hardhead and uh and front end actually collaborate because you've seen that we have this uh we had that script uh of that deploys the contracts onto tenderly but how does the frontend learn about where the contract is how does the front end learn about the RPC and how
does it add the RPC uh in there at all so let me just quickly open this up in my browser so outside of the tests um here we are here it says wrong Network so uh what you can see here we use the rainbow connect and uh here you can actually add the rpcs such as this one as an option for Connect ction so this is testly based on mainnet with a different chain ID so if I click it this is the first metamask popup and you can see the weird
chain ID we're connecting to you can see the RPC link of tenderly so if I hit approve that network will okay I need to also allow it a bit to switch and now we are on that particular DEET so whatever you do here for example create multisig it uh oops when I hit create well this should execute this should run oh there we go there's a confirmation and a little to it pretty much done so it when when building UI we're trying out out UI when uh doing some sort of testing then this thing can speed it up
and uh gives you a nice way to understand the issues coming from Smart contracts when you're building the UI so closing the cycle in in that sense and now the question remains from the technical side how did the the nextjs app the thing that we're seeing here how does it know about the RPC and how does it know that um the multi Factory is where it actually is so the the the trick to that the the the big question to that is actually where did I put that one oh here so it's a it's a little bit annoying it's practically the
configuration management so when you deploy a new devet from from that hardit module it spins up here but you have to somehow let the front end know where that network is and the second bit is when you run the deploy script which is over here the the thing that you can't properly see uh it deploys the contracts on the devet but how do you let the front end know where the contract is and um one of the the simplest way uh and I can just show you how how it's done here and uh deploy script what we have here is after uh after the multisig factory contract is deployed we wait for that we
verify it and then we're collecting all the abis and uh and the addresses and just simply play out writing that file into the front end Repository sorry this is like the the stupidest but the most effective way that I I found to to achieve it so um and if you want to have more elaborate uh config management schemes uh schemas go for it and uh let me know what you do there uh because I like to know um so so this is the bit that ties the the hard head and everything to to the front end and uh yeah it's somewhat important to to make that happen especially if you have uh like a separation of who in your team
does contracts and who in your team does does uh front end this is just like a very super easy way to give them staged contracts whenever you develop something or whenever you involve contracts in a way so that was the bit about the configuration management and uh the the the next and the final segment that we have here wait yep setting up the CI so uh I'm also assuming this won't take more than 15 minutes and uh I'll give you like 10 minutes to do it and then I'll walk around and bug you or help out if you get
stuck so so uh the the the CI I guess you've
done it or if not it should be fairly straightforward um I would like to uh just briefly reflect on on what we did and uh maybe you guys have some uh closing considerations or or Reflections that you would like to share so what we did we use the uh the tech of tendo Deets which practically allow you to take a network spin up your own like private version of it uh and you can customize it by using uh a little bit of yaml a little bit of declarative uh style of configuration so whenever you run either your local uh tests whether
it's smart contract tests or UI tests or you're just running deploy scripts to test them out to try them out and to debug them uh you can plug in Dev Nets in any of those workflows and the cool thing is because they are created on demand via CLI you can easily plug it in into the CI and have all that Machinery coming together uh for for your tests um is there any insight or reflection or or idea that you would like to share or a question you'd like to ask doesn't look so all right in that oh
yeah we have a question can you just wait for a mic please uh does teny provide something similar like a local EA scan I could like I mean I know the tenderly way I can go through but something more let's say simple or like is there something like that like local ether skin uh yeah basically for my spin up RPC yeah so yeah well there is that bit that shows you all the transactions that are executing so if if that's what you mean there's that there's also like in the devet you have a simulator practically uh calling contracts uh either right or
read methods of the contracts so in in that sense it allows you to uh look at what's happened and interact with the contracts in a simulation yeah sort of manner yeah is anybody closer to writing more tests in the future yeah okay I see a couple people smiling so I take that as a as a yes yeah we have a question there how do I add fonts testing fonts to some specific addresses sorry can you bring the mic closer I could hear can you hear me now yes uh how do I add uh
testing funds to um my keys like before like testing suit starts all right so you would do that let me just go back here so one thing that that you have in your yaml configuration is like this section called wallets or contracts or whatever and you can provide either PR oops yeah this is what I'm showing so you have this wallet section in the yaml config so there you can either set up balances for uh the private keys or for the addresses of of the wallets and contracts that you want to to top top up
and um let me show you just another bit in here so what you can actually do is you can override the storage Slots of particular contract so set set an address uh get the hex of of the storage slots for now it's just a hex and the value you want to override it with uh also you can override the erc20 balance say uh you know this is the the erc20 contract and I want to set uh that the address zero has 100 dies for example in a devet so in this way you can do customization in in that regard through through Theo file only and there is a button in that says account so you can
there's also that awesome thanks yeah so here for example if you if you look at this you can just paste an address and it bumps it up uh we have another question here um you also have a ec20 foret like for example for usdc in theory you could manipulate the chain like that that you can give yourself usdc uh you can manipulate the devet chain the one yeah yeah yeah so so in that yl file uh there was this little bit now it now
it's out but let me open it again uh there's this little bit erc20 so you can actually set the amount of erc20 for particular addresses okay thank you yeah so this address that much and also customer for examp proposals so you support all the hardhead evm commands uh yeah I just trying I'm just trying to
open up those specific um Json rpcs that we have there is for example um The Well add balance set balance RPC so you can do it uh VI an RPC call there's increasing the time stamp there's increas increasing the block number so you can actually tell them hey pretend like 50 blocks are mined and now receive my transaction so stuff like that so it gives you really a lot of uh tools to play around with the actual the actual thing you imagine it like a copy or cop can like your own copy of that netork that you can figure in anyway so like
like a loal version of main yeah yeah so these are the funky ones all right we have one more minute so I think uh it's time to wrap it up thank you everybody for the workshop thank you for the patience and for waiting for mpm to install um hope you had fun and uh hope you you do more testing in the future in a in a pleasant way and uh would like to talk to you guys on a coffee break or something if you have ideas or want to share Impressions uh highly highly appreciative of that so thank you very much and uh enjoy the rest of the conference