Clean Smart Contract Practices
ETHBarcelona 2022 · July 2022 · 20:04
Shao-ku Tien presents clean smart contract practices. The talk covers readable, maintainable code and habits that reduce bugs and make audits easier. The emphasis is on writing code that is easier to review and less prone to errors. Presented at ETHBarcelona.
Speakers
Topics
From ETHBarcelona 2022, hosted by ETH Barcelona.
Transcript
[Music] [Music] hello and welcome to the forest stage here at east barcelona i wanted to introduce you to shaku tian from uh from perpetual protocol um and he's a uh he's a um smart contract engineer so come on up thank you so much give him a
hand [Applause] hello um so yeah okay so this talk will be about clean smart contract practices and it will be about solidity so this is more of a death talk but it's not going to go into so many details so clean smart contract practices basically mean that we practice smart clean code on smart conscious yeah so my name is xiao and i'm from perpetual protocol so let me start by introducing my sponsor of the trip no happens to be where i work at okay so we're perpetual protocol so we
offer perpetual contracts which is a type of derivative on optimism which is a layer 2 of eth i believe most of you know and our latest version v2 is built on top of unison v3 so you can actually enjoy all kinds of unison v3 features on us because we built on top of their code okay and we're also recently doing some liquidity mining using optimism token because they recently airdropped so we're going to give our ov tokens if you want to market make on us so if the above description interests you then make sure to check out our website and i will also be pasting a
url code in the end of this presentation and i'll also be given now the slide of this presentation so you can wait later to get the slide okay and a bit of self introduction and my name is xiao or i use the handle as tsk in our discord channel and i've been a smart country engineer for about two years at perp that means i'm responsible for writing smart contracts testing them and thinking about what can be the potential attack factors to our code and i also do some front-end project management and also did some interviews
like in the past months basically not right now because the entire history is on high increases so if you'd like to talk to me about how to get a job right now then i might not be helpful on that one you might have to i don't know maybe poison someone to create some vacancies yeah but that's just joking so uh but if you want to know like what will happen in a smart country interview then i think i might be able to help you and i speak mandarin english and umboco espanol in donses yeah so maybe not speak to me in spanish maybe not okay and i also write some articles on median it's mostly about d5
so i wrote mainly about uniswap and perp because perv is built on the unisov so i understand unit swap and then i do perv and let's those two things are quite connected and yep so we don't got a lot of times today so the only two topics today the first one is what's clean code why do we care about it and what should we do if we really want to make our code base cleaner and the second one is some our own practices at perp that we try to make our code cleaner and the third one is of course some q a session if you have any questions so clean code um may i ask how many of you are deaths can you perhaps raise
your hand oh that's quite a lot how how okay and uh how many of you have heard ever heard of clingo or you do practice clean code while you're writing code can you also raise your hand oh that's quite a lot then wow um definitely more than my teammates my teammates don't care about a lot so this is my comfort zone right now okay so um then most of you might know that i think this term comes from the book clinco a handbook of age of software craftsmanship and i actually just read this in the beginning of this year and i'm the kind of person that cares about
cleanness whether it's in live or while coding so after reading it i thought okay i definitely have to persuade my teammates into practice clean code with me but then after i share with them there were a lot of oppositions and positive arguments saying like oh no that thing is only what you care about but not us so that's why i say i'm on the comfort zone right now okay so later i realized that it is a highly subjective and controversial topic that my only matters for those who care so yeah i think this is just a really common mean
we all have different definitions on what is clean and whatnot and my personal opinion that our call base at perv is somewhere in between you know because we are definitely not like clean gear but neither are we messy and dirty because i have been the one that's maintaining the code base okay so before getting into some of the suggestions from the book uh i'd like to share like one of my favorite quotes from a book which is a scouting rule so scouts go to camp right they do things at camps but an important role for midland is to make sure like the camp is cleaner before
their arrival so i think it's a really good guideline for practicing clean coat is that every time after you add some features you modify something you fix something you always try to somehow make the code better and cleaner whether it's adding some comments to help other reviewers understand something or whether it is removing some outdated information in the code or in a comment yeah so that is a guideline of my recent coding history yeah okay so let's start with some less controversial suggestions from the book although i say less controversial i
still can expect some opposition so i mean that's all right i mean we agree to disagree just like many things in life okay so let's first start with the names of variable names function names just generally naming so they also suggest lab we prefer long names to short and vague names and the idea is basically if you can't really tell what a variable or function is doing then um then it's not really explaining a lot of things and why don't you choose why don't you just try to make the variable function longer so that people will know instantly like what this thing is trying
to do and the neither is adding comments to that show but vague functional name a variable name helps because it's impossible that you paste that comment every time to every word like function or variable is used so it's more preferable to have longer but more descriptive naming than short but vague and of course the ideal situation is to have short and descriptive name we we all know that it's not reality it's ideality yeah and the next one is to actively maintain your comments so comments can be good and bad and the key point is to maintain them so you
definitely want to just as i mentioned remove outdated information maybe it's an equation that was substituted a long time ago and you definitely want to delete them upon seeing them and you can also add some helpful comments for example warnings so if there is a function that there's some side effects that function then you definitely want to add a line saying that you have to watch out for using this function because there can be side effect and that can help the reviewer or the user to know that okay i have to pay extra attention to this function so there are good and bad comments and the key is to maintain them
okay so the third one is to write tests and then i know like writing says it's highly controversial but i'm not trying to tell you how many tests you write you know to a hundred percent of coverage that we should achieve no i'm just saying that we should write tests for third code because in the crypto space and then or more generally in blockchain space we often use a code like our v2 is built on top of unison v3 so it's important for us to know like what behaviors the unisop code is going to act so that we know how to handle some extreme conditions like overflow on the flow so i'm saying
that writing code for third-party code is really ideal that assures you and aligns your knowledge with layer code base but like neither am i suggesting like you should write test for every line of code it's quite time wasting but at least you have to know what you can expect from other schools okay so these are the less controversial one i assume maybe you you still find really controversial but let's look at the more controversial ones so the first one is about yellow is the name make it out but i mean for those who have picked into the code base i believe you're going to agree with me they have tons of weird namings like
gem earn and like you know i learned so many english vocabularies from looking into the code base apparently i'm not a native speaker so um but i actually think it's not really a bad practice because we're in this open source environment at least in eth ecosystem i don't know how if that's true in solana i don't know but since we're in an open source environment it's really hard to stop others from copy pasting our code so if you have weird names all over your code base then copy paster are going to find really hard to copy your code and then modify them and then ship
laughing as their product so i think having weird names is actually a good mode to stop copy pasters yeah so the next one is also a really controversial one tdd test driven development it's basically saying that for each line of your business logic you must first have one or several tests covering that line of logic so it is really for me exhausting way of writing code i'm definitely not going to do that but i do enjoy writing a lot of tests to cover logic that are related to money right because most uh defile or blockchain
projects are dealing with money so for me i don't do that but for some of them they find a really good way of shipping their code their high quality code okay and the last one is about setter and getter so i'll say in traditional programming uh if you set a value you might want to use another getter to get the value as a double verification so to make sure nothing goes wrong inside the setter however in the blockchain venue like more function calls mean higher gas costs and we also have requirement in solidity and other
smart contract languages so i'll say for me i prefer just to use return values from setters directly instead of you know calling getters again to get the value because if we are unsure whether that setting that behavior will succeed then we just add a requirement to make sure it succeed and then we can make sure the return values from the setters are correct and will satisfy our expectation so these are the controversies one so i will expect you to disagree with me or you might want to take whether it's weird name approach or a meaningful name path it's turned off to you
and the now i'll be sharing some of our own practices that we think will kind of make our code base better so the first one is about error message so i believe most of you know that one of the most common thing a smart contract engineer will get into is a buy code size limit we see last year like once per month so a good practice is to make your error message shorter and so there's an example here is a ch pscf so this is our own way of having error messages so the first part ch is say the abbreviation of the contract file name and in this case it's all
clearinghouse and the second part is the error message itself it's a price slippage check fails and for those who are familiar with the code base like me i'm familiar with those keywords so like i know p usually stands for price s stands for maybe short or slippage and f is the last word so it usually describes the failure so by knowing price slippage fail i know it might has something to do with ply sip check so i can see i can understand this error message just from our front end without having to open my ide so i personally find this a
really helpful trick to write short and meaningful messages but for those who are not familiar with the code base then of course is not really helpful and the second one is not really originated from us it's i think it's from compound that we separate variables into separate files like you can see that if we put storages into the main contract file we're going to have libraries and storages and functions all inside one file but what compound did is to separate into a storage file so that all things are clear there and the
i think it's also compatible with the pattern of not having nest back inside the main logic file because if you have all the storages inside the main logic file you inevitably have to put your nas back into that file while we always put nest back into another interface file so by separating storages into an incentive and independent file we can actually have net spec in the practice on the right side and it's also compatible with our because at perpetual we do upgradeable contract pattern it's a bit more centralization but it's easier for development and we also do
so this pattern is actually compatible with the upgradeable pattern because we can see there's a volt storage v2 and v1 and it's clear that we know how many new storages we're adding to after a certain new upgrade okay so the last one is input check so input check is input checks are quite important because they want to make sure things are within expectation for example we might have traders the address of a trader and i want to make sure that this trader does exist in my system so a common approach across many projects is to do input check in the lowest layer so
that all upper layers like call this lowest layer will have the same input check however a thing that is a bit annoying is that while we are reviewing these uh functions these high layer uh functions uh it's actually quite hard to know like where exactly least check exists so we do a bit of modification or improvement is by adding several lines of comments under the function and saying that for example the first maker wears a check it's inside a can so access or the function so that by eyes adding these comments reviewers can actually know
where these things are checked and so by avoiding repetitive input checks we can save guests of course that is the reason why everyone is doing that but by adding comments we can also save time for reviewers and the cons is just as i mentioned you have to maintain it you have to make sure it's right otherwise if we thought something has been checked but it's actually not checked then it might has a i'm not sure if it can be really gravious but maybe and yeah so my reasoning is that since other projects also do input checks in the lowest layer then by adding some comments to it we actually
make reviewers lives easier okay so that's actually all of my presentation and do you have any questions and you can also follow us here okay thank you and uh if you like the slide you can scan it and uh you can have a slide if you i don't know what you want to do with it whatever okay that's all for me [Applause] wow