DevTools Summit | Topics in Solidity - Harikrishnan Mulackal
ETHGlobal·Sun, Oct 9, 2022, 12:00 AM
Speaker
Welcome Harikrishnan Mulackal from Ethereum Foundation for a talk titled "Topics in Solidity". Part of ETHOnline's DevTools Summit. ETHOnline is our biggest event of the year! Collaborate with thousands of developers and creatives from around the world and win over $300k+ in prizes! We're bringing in 30+ of the biggest teams in web3 to give you access like never before. Learn from ecosystem leaders and build your biggest ideas as the merge nears reality. The future of Ethereum is being written right now, and it's time to make your mark. --------------------------------------------------- Follow us: https://twitter.com/ETHGlobal Check us out: https://ethglobal.com Email us at: hello@ethglobal.com #ethereum #eth #blockchain #crypto
Transcript
[Applause] [Music] and without further ado like to welcome ari to talk about everything that's happening in the solidity ecosystem so welcome back after our last year's devtool summit and excited to have everybody also learn about all the things that are going on in solidity yeah i would like to start the talk with a question to the audience um it usually works better when there's a live audience and when people can shout the answers but i'm still trying it here so the question is simply like what is the most requested solidity feature since the last two years uh you can just like type your answer in the chat or wherever you want i'm going to have a look at it later and we're also going to talk about it in the second part of the talk until then let's forget about it and talk about the next thing which is a very simple way to do something in solidity so typically so you have an interface here it is a erc20 interface that only has a single function transfer because that's all you want in this case uh you want to like encode a call so how do you do this usually so since the beginning of solidity we had this feature called avi dot encode with signature and this like this is very useful for like doing this thing um the syntax is a very simple api out encode with signature and then the signature of the contract and this has been around for since the beginning of solidarity perhaps uh but this is bad in many phase many ways and why is it bad it's actually not typo safe what does that mean so here is the same thing but with like two typos one is a space after the comma and the other one is you wind instead of you win 256 you can see u in 256 here and this actually leads to a different encoding of the call data and this is really bad and moreover imagine if you actually change something here maybe the function maybe the types it doesn't really get reflected over here so this is like a feature with a lot of foot guns and we have to really rethink if you should really do this um it turns out there is a better way to do it so let's look at abi dot encode with selector so it's pretty much similar to the last one except that you use abi or encode with selector and you have to make a reference to a function so in this case it's minimal erc20.transfer.selector which would like automatically put the four bytes of the selector here and then you can encode with the the two end value which is the parameters so even this is not very good um and why is that it's actually not type safe um the problem here is that okay uh imagine if we actually use um a uin parameter instead of an address um in in the api or encode with selector it actually compiles and it will give you probably a different answer depending on what the value of 2 is so this is also bad we shouldn't do this is there a better solution that actually fixes both these issues yes there is and that is the api or encode call so this is both typo safe as well as type safe so how does it work it pretty much works exactly like the last two ones except the name um abi or encode call and then uh a reference to the function here it would be like minimal erc20 or transfer and then the parameters in as a tuple um so if you make a typo here the compiler would complain complain and if there is a different type um instead of two let's say you win the compiler would complain so you don't have to worry about like shooting yourself in the foot so as i said before it's type safe and typo safe you can avoid a lot of foot guns it's available since zero eight one one um and in retrospect you know we have to even you know these two features we have to even think if we should even put this in the language anymore we have to probably deprecate it um at this point and it's already in use uh currently here you can see alex's contract which is um doing like a deploy of um you can also save uh knowledge saves on chain and he's already using aviator encode call and you can use it too okay let me go back perfect um so what can we do next after we have abia or encode error um so as you might already know like in the last year or so um writing tests and solidity has become incredibly popular um because of like dab herb and now foundry um and this pattern comes up quite often which is um foundry has this idea of expert reward which is you want to make a external call and you expect the call to revert with some bytes um as you might already be using i mean as you might already know by now so already has this idea called customers which allows you to have properly encoded error errors instead of just strings it's more gas efficient in most cases and also just more elegant so what you can do um to test this would be something like vm.exe reward and then just put put what whatever data you are expecting to report and this is an example from opencs new contract c port um so if you look at how they're doing it right now it's abr encode with selector with the signature of the error and then the parameters um so recall that errors and functions are encoded identically so you can actually reuse a lot of things that are done for um functions also for errors but we can actually do better here you can actually introduce something like abi or encode error with similar semantics to abi or encode call we don't have this implemented right now but there is an issue and there is somebody working on implementing it so you can very likely expect it to land on the compiler soon so this is how the same code would look like which is again type safe and typo safe and just more elegant [Music] yeah so now let's go back to the question from the beginning of my talk which was what is the most requested solidity feature perhaps for the last two years and even more um and you can look at the results and a lot of developers have uh made in the survey and there is one thing that really stands out which is fixed point arithmetic and that is indeed the most requested feature for solidity since ages so before we talk about like um what's happening i want to like i want to make an introduction to like fixed point automatic what is e1 fixed point arithmetic um effectively you can't think about it as working with fractions or floating point numbers although the use of floating point number is a bit of a misnomer but you get the idea so typically you start with a base uh we call it b and this is going to be for example 10 raised to 18. um 18 is typic 18 is a good typical number because um e has 18 decimals um one either is 10 raised to it in b so you represent a number p by i mean in real terms p by b by storing it as p so as an example if you have one way which is actually the fraction 1 by 10 to the power of 18 either you store it as one instead of like points as one so the number of points for a swirl like 18 times or 17 times then one would be represented as one in the evm and the way to interpret this would be by thinking about it as like 18 decimals so you are already implicitly using this if you are interacting with a erc20 token for example they have this innate idea of decimals for example in usdc it is 6 in diets 18 and you don't really you just like add them like any other numbers and that's my next point which is addition and subtraction requires no change um you just add you just subtract it's exactly the same but the next things the next thing is more interesting multiplication and division they are entirely different now so if you want to multiply two numbers p and q that are you know installed values uh i want to make this distinction of like stored value and like the actual value like the actual value would be p by b and the store value would be p remember so p times q in this case would be equivalent to p times q by b um i mean you can like try to work your way to like this calculation but this is how it works and similarly for division if p and q are stored values uh the actual stored value for p by cube would be p times b by q so this is fixed point 101 um now let's talk about some like history of expanded arithmetic and why why doesn't solarity already support it so solidity has the type you fixed and fixed for a very long time and also in the api so ufx stands for unsigned fixed one arithmetic fixed point type and fixed stand for uh designed just like you went and end and um what do i mean by it's in the api i will talk about it later later but just remember that it's in the api already but these types are actually unimplemented and therefore useless if you actually try to do anything with it you would try to get you would get a compiler error if you actually end up using this somehow but many of the programs you can compile but without being able to do anything with it um yeah so going back to the question why why don't we have it um we were pretty close to like merging a lot of things into the the language but in the last minute we decided no um and one reason is because it's such a contentious issue there are multiple different implementations and there is no consensus in the community on like how this should look like to give an example there are multiple ways to implement fixed point types one is you can ask the question should it be decimals or should it be binary and how many decimal points 18 20 24 or 6.
um and there is this uh third point which is very interesting um it's i i would like to call it the the shadow overflow or some people call it the phantom overflow so remember that this is the most basic calculation p times q by b so p and q are p q and b are 256 bit numbers but the multiplication p times q may not fit inside 256 bits but there can be cases where p times q by b is a 256 bit number but p times q is not and how do we handle this situation like should we reward should we actually do the computation there are people who say that we should reward there are people who say we shouldn't reward and actually do the computation in a painful manner and this also like brings the question of like chaos efficiency like if you are doing um reverting early would be easy uh but whereas actually handling the shadow overflow is much harder um so let's now look at how many protocols um implement um fixed point arithmetic um um one of the most famous example would be perhaps the word math introduced by maker as far as i know it is actually decimal it uses 18 decimals in fact and it reverts in the case of shadow overflow which is you know if p times q is um it doesn't fit in 256 bits then it's it's going to overflow and it's very it's relatively gas efficient because the computations are um very simple um a modern implementation of this can be found unlike solvemate so you can see the reward happening here for example so let's go back okay perfect um yeah so to summarize it's 18 decimals it's decimal not binary it's relatively gas efficient and it doesn't care about shadow overflow it will reward early and the next example is in unisa v2 which actually uses a binary um fixed point type with it's actually 112 bits not 122. it's a typo and it actually uses shifts instead of division where shifts are actually cheaper in the evm than uh division ships are three gas and division is 5 gas so there's a very minor efficiency improvement here and it actually doesn't care about shadow overflow at all like it turns out that this overflow case would never happen and they ignore it and it's very gas efficient because first of all you use shifts and second of all they don't care about this intermediate overflow now going back to unicef v3 this is where things actually get very interesting as far as i know they use binary fixed point but they use something called um the full mat uh and the full mat is a very very interesting function um originally implemented by remco um so you can see this like very interesting piece of code with a really complicated math um what they're doing here is um what they're doing here is trying to get rid of this shadow overflow so in the case where p times key p times q overflows but the value p times q by b is well defined unit cell b3 or the implementation by remco still manages to compute the actual number and this is very impressive but unfortunately there are a lot more checks and there are more complicated arithmetic operations uh involved in this computation and that means there is more gas um so we saw like three different implementation the vat math the units of v2 binary uh units have v3 fixed point i mean minus units are v3 with binary and the full math so the question you ask is which one do you implement the units unisa v3 is perhaps the most canonical implementation but unfortunately it is more expensive than the other simpler ones so can we find a better solution um than this probably we can um so remember that the key computation here is uh sorry the key computation here is p times q by b and if we can compute this value in full precision we can actually do the unisa v3 full math implementation um cheaply and we have this proposal for a new op code in the evm which is called maldive which actually does this computation so it's going to perform p times q by b in 512 bit arithmetic but in the end it truncates it to 256 bits so where do we go from here so first of all um it's not clear to us if fixed points as a type should be belong to the language but we want to have like very good support for fixed point arithmetic in the language um and one way to do that is by allowing users to build their own types and operations on the type and the first step towards this is already there which is user defined value types so you can try to implement your own type in this case it's fixed 18 it's exactly like you win 256 and more importantly um there is no change in the abi so the abi is going to be exactly the same as as if you use uin 256 but it's more type safe um i mentioned before you know i will talk about abr issues about you fixed so the type you fixed actually exists in the api but um this wouldn't have the same selector as the real um transfer functions so this means that the ufix which is already present that you abi it it doesn't have any backwards compatibility so if you want to try to interface with let's say die or usc die would have 18 decimals usdc would have six hmls this function wouldn't even be calling the right one whereas if you use fixed 18 it actually has exact abi compatibility so this is the very first step towards you know fixed point types in the language uh and the second type is to implement maldives and the ebm which is probably gonna take another like hard fork uh in the in the evm um and the third step is going to be implementing operators for fixed point types um this can be done in whichever order we want so just to give an idea of like how operators would look like so here is how the checked multiplication and fixed point numbers would look like if you have moldov and evm so i didn't mention this but there is a very ex there is an exceptional case in the maldive which is around zero so the eip currently proposes a um a special case for maldives a b 0 where the 0 would be treated like 2 or 8 256 and the goal would be that this is going to help with checked fixed point of multiplication um and this is an example of how it would look like here you're using like 6.8 user-defined 6.18 and perhaps a syntax like this using check mall as star for fixed 18 um and then you are user-defined fixed multiplication can be used anywhere in the language so what can you do now so the maldives eip is still um it's a relatively new proposal we want to get as much feedback as possible for the eip feel free to like talk to us we want especially to get feedback about the exceptional behavior around the value zero so that is a b 0 is treated in a special case there are ways to get around it you don't really you can treat a b 0 as 0 but then there is like more gas to actually deal with this truncation detecting the truncation case the third thing is of course we want to see if there are other uses for maldives especially for implementing cryptographic operations perhaps you want to implement evm inside evm then you might need to calculate for example mod mulmod modex things like that would that do you see a use case for maldives in any of these other applications let us know and of course we would like to get your feedback on the syntax for user-defined operators um so i mentioned how the using statement is currently being i mean this is not currently implemented but this is the current proposal so we would like to get feedback on how this looks and how this implementation feels to you and lastly you can find more notes about fixed point arithmetic and this hackmd i will be linking oh here is the link to my talk and that's it amazing um hey i'm not kartik i'm jacob just kind of jumping in um i just got to work on some stuff behind the scenes um awesome talk if anybody has any questions feel free to drop them in the channel um and i will surface them over to to harry i guess i had a i had a quick question it's it's sort of i guess related a little bit to the topic like um i know just from my experience programming with uh floating point and in different implementations in different languages um precision comes up a lot as a potential issue um and given that like with blockchains we're you know writing contracts that are largely dealing with with money and that kind of thing i kind of curious like what your thoughts are about like being able to both come up with you know great specifications for floating point but then also like teach people on the risks of of uh of precision when it comes to to dealing with these primitives yeah that's a very good question i mean um so when dealing with decimals there are two approaches one is uh fixed point numbers the other one is floating point numbers um floating point numbers are incredibly popular um in like usual computations because they are very fast implement most processors have some instructions to deal with them uh but the issue is that it can be a little bit counterintuitive to understand it and also this floating point errors um so if you look at historically maybe like 20-30 years in the past the equivalent of like the the equivalent of like maybe this 500 million smart contracts hack smart contract hacks would be um rocket failures so a lot of these rocket failures can be traced to bad floating point implementations or how people did not or how the accuracy of some numerical computations uh um event i mean some numerical computation did not end up being accurate enough because of this repeated floating point um errors and uh hopefully like the fixed point arithmetic makes this a little more apparent so the issue with um the issue with floating point errors is that almost every floating point operation it has a error associated with it so if i go back if i go back addition and subtraction it has a small error in floating point implementation but in fixed point implementation there is none similar to similarly in multiplication and division there is an error term um in division and evm there is another term but uh other other things like addition and subtraction multiplication there are there wouldn't be any errors um in in fixed point implementation so first of all the answer is we think fixed points are the way to do it but of course if you are introducing division there is going to be there are there is going to be errors and you would need to have some understanding of um rounding issues unfortunately yeah and then hopefully those don't trickle into to too many really bad outcomes at some point online awesome okay great well actually i think kartik is actually back from behind the scenes so i'm going to invite him back on stage and i will disappear and i'll let him wrap us up but uh thanks for the talk i really appreciate that and i've learned a lot about how the team is thinking about uh implementing these permits break but i did watch the rest of the talk so uh thank you so much arios was a greater review and i i feel like uh we gotta get you more here because uh oftentimes there's a big feedback with that we you know we get to close when we work without devs uh trying to figure out how to do more interest into the solidity so uh this has been really helpful and uh and thanks for also uh linking to the slides because that's the most common question we get and how do they catch up on slides and we'll share that with everybody else perfect thank you really appreciate it
Automatic transcript — names and jargon may be misspelled.