A year's progress in Sway, the smart contract language for the FuelVM
ETHCC 5 · July 2022 · 27:11
Alex Hansen reviews a year of progress in Sway, the smart-contract language for FuelVM. The speaker discusses Fuel's development vision for modular blockchains and demonstrates application examples.
Speakers
Topics
From ETHCC 5, hosted by Ethereum France.
Transcript
all right cool hello everybody we're going to go ahead and get started all right so let's all quick say uh a quick prayer for the the single air conditioning unit in this room let's hope that that one stays going uh my name is alex i'm here with fuel labs we gave a predecessor talk to this last year one room over at the same conference at that talk we essentially announced we announced this way programming language we announced that that's what we were going to be working on and i'm going to pull up the speaker notes right over here
and this talk is going to be a little bit of an update a status update on what we've been doing over the past year what promises we were able to keep and and the progress that we've made sort of a state of the union of the sway language also a little bit of a victory lap because we actually were able to keep pretty much all of the promises that we we made last year so i'm going to go ahead and go over here so what has been going on since last year so last year fuel as an effort was very small had very little uh very little like public notoriety yet besides john's tweets basically and we announced this smart contract development language called sway we drew
a lot of comparisons to solidity because that's obviously the other big smart contract development language in the room and we kind of said hey this is the the state of the union uh with smart contract development but we think that with modern programming language theory you can do a whole lot better we can have a lot more safety we can have a lot more security and we can have a lot more ease of use and that was essentially our mission statement with sway um so at this time last year we had about two to five prs a week a small group of contributors um the language barely existed there was like a parser some notion of a type system but not very much the syntax was still very wishy-washy we hadn't totally nailed all of that down yet and um we had yet to run a single functional smart
contract it was all hypothetical we were all specifying everything um so one year later now uh what do we have so we have about five to 15 contributions per day with 53 total contributors to the repository um those are external internal people who are parts of the fuel organization people who aren't it's just it's an open source project you're welcome to check it out in addition we have applications being developed in sway so we've gone from hey we're going to build this compiler it's going to be it's going to be nice we have a lot of aspirations to actual contracts being deployed and used in one year which we're quite proud of in addition we have a robust tooling surrounding sway that we'll talk about in a little bit and we also have built
up quite a community there's a discord channel with a few hundred people last time i checked at maybe 500 or so we've got a lot of external contributions on github and what's really crazy is people are starting to recognize the lightning bolt when we walk around here that was not happening a year ago [Music] cool so gonna give a quick overview of this talk so this is not going to be a super technical talk we're not going to dive in and develop a contract or anything like that this is going to be sort of an update on the project um there was a workshop earlier today in sway like how to develop a smart contract we also have tutorials online discord channel documentation if you're interested in any of that please just let me know after the fact
after this talk we'll go ahead and get you hooked up with some of our community people who will help you get started so we're going to start off with some of the technical stuff uh some of the some of the technical promises that we were actually able to keep so there are three examples of some stuff that we talked about last year so this is ripped straight from a slide last year you'll see at the top we have some solidity an example of a contract declaration with some storage some state variables and at the bottom is what we thought we would have storage looking like last year this is not what we ended up with but this is uh this was kind of what we hypothesized it so that's that's where we were at that was our a b comparison like this is this
is what you right now this is what it's going to look like uh we also had an idea of a contract abi so you declare your api it's an abstract interface you implement your api for your contract and that's essentially how you define a smart contract this was what we thought we would do last year in addition solidity has a notion of view functions pure functions etc um we thought we'd have some syntax that was similarly declare view and you could use that in your api so this was this was all pseudo code last year so what's really cool about this talk is that we're not going to show pseudocode anymore this is actual functional sway part of our test suite
it's one of our basic test contracts it's an incrementer contract so you deploy this contract and then anytime you call it you can increment it by a certain amount it's a very basic contract it's one of our test contracts but what's cool and uh the excitement that i hope is coming across is that it's fully functional working contract that's deployed in our language which we've only been working on for a year uh it's kind of my baby so i'm a little proud of it but so let's go ahead and break this down so of those three things that i just talked about we had the abi declarations we had uh vue pure functions and we had um the abi syntax so uh i have to stay over here because of the camera but i'm going to point and i hope you guys can see where i'm pointing
unless there's a laser does this have a laser same way no okay is this one better okay um okay so at the top you have your contract storage declared that's the first thing that changed so now you declare your contract storage and it is essentially a global variable that's stateful in between executions of your contract uh you'll see that we've adopted rust's annotation syntax so i'm gonna hop over here and point this out um that is something we took from rust which is a language that a lot of our syntax is inspired by um this is it's a pretty simple notion and it's also extensible so you can annotate other aspects as well but this just says this function will read and write to contract storage the writing is here the
reading is here and the bottom function which just lets you get the current value of the counter is only a read function so once again this is where we ended up at with those notions we're really proud of this we think this is a very clean way of writing a contract and we think there's a lot of improvements to be had when you write a contract like this instead of in solidity um another thing that we promised and before uh yeah another thing we promised was uh structs and enums so some of you might be familiar with c style enums or um you know strucks and solidity and stuff like that um what we mean here is some in product
types so who here has familiarity with these terms quick show of hands some and product types okay it seems like the room is pretty knowledgeable so we don't need to go too deep into this but essentially an enum uh is an enumeration of potential values so it could be this it could be this it could be this whereas the structure is a grouping of data so it has it has you know this field and this field and this field solidity has strucks it's like a if you're familiar javascript javascript object is a product type um so what we were able to deliver on this and uh the fact that we have robust sum types with uh generics which we'll get into in a second leads to a lot more safety and expressiveness than you would have in the solidity program
so this is a really trivial example uh oh i can point like this so over here on the left we have a generic structure this is just a very basic example where you you have a wrapper type this just kind of shows some of our rust inspired generic syntax and struct instantiation so this is more just to get you familiar with the syntax over here we have a declaration of an enum so uh these parentheses are what's called the unit type or the empty tuple it's a type that has only one value you can only ever have one value it's usually used to signify nothingness it's zero sized it doesn't have any size in the compiler or in the bytecode so what this means is there's an enum that can have five potential colors one of them is represented with zero
size so what this essentially has it has an overhead of one u64 one number to keep track of which size it is and our enum instantiation syntax is down here so this is a really trivial example let's go ahead and take a look at what we've been able to accomplish with this notion that you wouldn't see in for example the solidity standard library so uh and we'll we'll talk about this more in a moment we have our own standard library and development and one of the biggest things that makes it safer is new so if anybody's ever used rust or haskell or anything like that this is a really common notion so it's a generic type and can have two variants it's either okay there was no errors or there was an error and you
throw an error so what does this actually mean in practice so this is our ec recover function in our standard library we're not going to dig into it we're not going to go you know into the details here so don't worry about that but i want you to pay attention to the function signature here on line 15. so does anybody know what the behavior of ec recover is in solidity if the recovery fails you get all zeroes yeah so uh does anybody see any problems with that if you get all zeros back from your ec recover function like from a programmer's ergonomic perspective well it doesn't give you any information
about the failure that's that's definitely true uh but also it's up to you the programmer to kind of know that behavior you have to read the documentation which is you know always good practice but what's important is that your tool knew that it failed and it did not force you to handle a failure right like let's say you're transferring coins uh you have to you have to double check that it wasn't zero every single time and there will be no compiler there will be nothing to tell you that you mess that up and there's no reason for that modern programming language theory is so much further beyond that um i mean extremely unlikely somebody could you know get the keys to the xero address and take all your assets or something i don't know but um what's more likely is that you would have asset loss right
like you would send it off maybe somebody can never recover it but uh just because as a programmer you failed the check and that's kind of like buying a car without a seatbelt that's not really something that should be acceptable today we know how to handle these situations so our ec recover function and our standard library will return a descriptive error of what exactly went wrong uh if it does fail or it will return okay if you were able to recover the public key when you use this function it does not return just the key it doesn't throw an exception it returns a result so if you're familiar with uh some types it's either the successful value or there so this is already
cutting down these kinds of things in our standard library functions is already cutting down the the rough edges if you're just now learning how to write smart contracts there's hundreds of these rough edges that you just kind of have to know through going through the school of hard knocks okay so we're just going to take one more quick look uh i'll go a little bit more quickly through this one as it seems like the room is pretty familiar with some types but i was just going to go over how expressive the you can be with combining sum and product types so up here is what you would have uh you would call a product type the reason for that is it has two it's a structure with two fields a and b both of these are numbers they are u64s um
sticker for anybody who can tell me how many potential values of a u64 there are anybody okay it did yes yes cool so it's two to the u62 to the 64. and so this is called a product type because um let's say you have 2 to the 64 potential values of a 2 to the 2 to the 64 potential values of b so there are the product of those two numbers is the amount of potential values for my struct bit of word salad we still here okay so that's a product type and a sum type here uh the unit will you add them
instead of instead of uh multiply them so variant one is the unit type it can only ever have one potential value variant two as we've covered could have two to the 64 potential values and then variant three which is my struct has that product type that we calculated so this is the total number of potential values of this enum so you can get really expressive [Music] in instantiating these xeniums and you can represent all kinds of cool things with static type safety to access values inside of them we have match statements so this is something that we talked about last time match statements with exhaustiveness checking so
solidity doesn't have switch case statements you just have to do nested ifs there's no exhaustivity checking let's say you're iterating over potential magic number error codes you have to remember to check every single error code this is just not a secure system this is not a secure way to write code we have better tools than this so there's this underscore down here which it means any other case so so the way to read this it says okay why based on what the variant y is we're going to perform different behavior so we know y here is variant two so if y is a variant two we're gonna take the value y out of it and return it from the main function otherwise we're just gonna return ten this is a total dummy
function contrived for the sake of this example but um that's that match syntax and that's how you would get the values out from inside of an enum uh this is just how crazy you can go with destructuring and structuring so to access interior values you can either just you know use the dot syntax and access fields but also you can completely destructure a type if you're familiar with javascript if you've ever destructured an object in javascript where you you put the object structure on the left hand side and you pull the values out we won't go too far into that but essentially what we're trying to say is we have extremely ergonomic syntax pulled from kind of the latest and greatest of the most popular programming languages
to access complicated data structures and make them safe because at the end of the day we want it to be safe but we also want things to be ergonomic so our type system is strong and static those are two adjectives that would typically be used to describe this type of type system the technical term is that we use an algorithm called hindi milner it's used in languages like rust it's used in haskell it has type inference it has it's it's a very intuitive type system you're probably very familiar with it if you use it you can annotate types but also there's you can allow them to be inferenced it also supports generics which i hinted about earlier which allows you to write code parametrically over multiple types
so that's like some of the language things that we promised last year that we actually delivered on and delivered on in a big way we're going to move on from the language itself to kind of the surrounding tooling around the language uh so yeah i saw it in time so part of our vision is not just to have an ergonomic and complete language we also are trying to build out an entire ecosystem a full stack where you can deploy safe contracts with auditability security performance and we want it to feel like you know you don't have to pull any strings you don't have to uh go through any personal hardships to deploy a contract um and so to support this vision we
we were shipping sway with a robust set of tooling around it so we have a lot of other things but i'm just going to go ahead and go through these really quick we have a rust sdk and a typescript sdk they're used for orchestrating and deploying contracts programmatically so if you say have a you know an app and you need to deploy contracts on the fly or interact with contracts we have an sdk for interacting with the node and the language and testing we have fork which is stands for fuel orchestrator if you're familiar with rust it's like cargo if you're from javascript it's kind of like npm but better it handles dependency management plugins formatting the block explorer all sorts of things building dependency management which i already said module resolution log files
all those great things we have a block explorer plug-in we have a canonical formatter with configurability um by the way some other feel people are up here and the guy with the formatter is here and emily wrote all of the match expression and pattern matching which is really awesome so uh yeah and then we have a language server for vs code or just any you know language server protocol uh we have a vs code plugin which consumes the language server and we have a lot more than just that but this is some of the tooling that we're deploying alongside sway so if you've ever written in solidity first of all the ecosystem kind of changes every couple years and you need to figure out what the latest and greatest is are using hard hat are you using foundry are you testing with this testing framework or this one or
whatever we have a canonical way uh where everything works together we're all everybody building this stuff is all friends we're all in the same group chats and we're all making sure that we're reusing code when possible to provide the most seamless experience another thing we take really seriously is compiler user experience so we talked about this last time uh solidity errors are not the best in sense that they don't always lead you to knowing exactly what's wrong there's different ways there maybe it doesn't actually point you to the part of the code that that's actually broken or maybe the error message is not fully descriptive but we we take this problem very seriously and obviously this is a pretty trivial error but what i'd like to show here is that we use the same
error renderer that russ does so we always try to have descriptive and um direct error messages that point directly to the problem um so an example of that let's go ahead and take a look at a quick code example does anybody see any logic flaws with this piece of code it is not exhaustive yes that is correct so x uh this is obviously silly uh x is five we all know that pretend you don't know that x could be anything it could be any integer uh why are we only checking if it's one or seven right like if if you don't have exhaustivity checking what you'll do is you'll progress past this match
statement and you'll never know this is something the compiler can check though and what you'll get is a pretty descriptive error message so this is one that we're kind of proud of which calculates all the ranges that you've missed in your match statement all the ranges that you've missed in your match statement and uh what you need to do to fix them so obviously we've only checked for one and seven but we still have the minimum u64 value which is zero to zero uh two to six and eight to the maximum value uh shout out to emily for writing that that whole algorithm she's right here okay um we also this also works for enums so for example if you did an ec recover and you
did not check the error case this is what would happen so this is what we mean by safety in a practical sense uh so now we're going to get to kind of the exciting stuff i've got five minutes left so we'll just swing through this the most exciting thing for me as the person who typed maker and created like the project in the beginning and to see it grow over time is the fact that i'm no longer code reviewing the compiler i'm code reviewing applications that are written in sway like the extension is sw instead of rs which is it just blows my mind so this is the part that i'm really excited about we have been building applications in sway some internal to our organization with a lot of our oversight and some completely
external this is our uniswap code clone it's on a devnet you can go there and you can get some test eth it'll just drop it into your wallet and then you can mess around with it you can pay attention to the transaction speed which is something that the fuel node is very good at parallel transactions not the topic of this talk but that's a test full stack application totally open source if you ever would like to check out what's going on there [Music] another application obviously that we're building is our standard library uh which is uh we're quite proud of it it's a lot of has a lot of the tools from solidity but in our opinion in a safer and more extensive way
um that one is also growing by the day we have all sorts of uh contract primitives and cryptographic primitives that we're still building out in addition to that we have an escrow application we have auctions we have dow voting we have a fundraiser we have a multi-sig wallet and we have a lot more applications that are still in development and these are complete projects written in sway some of them have front ends they're really robust applications and yeah we'd be really excited if you were able to check them out so what's next some of the things that are on the sway road map are we're going to be working on optimization our by code size is kind of big right now obviously build the mvp and then optimize we're going to be building out more applications we're going to be working on a macro
system which is something we promised last year that we have not developed yet uh but most excitingly and maybe like the most exciting piece of alpha from this talk is that we're beginning the talk beginning to uh work on an evm back end so instead of just having to develop for fuel you'll be able to write sway for the evm we're really excited about that that's going to be a long project hopefully we can we can continue the trend of announcing something at one ecc and having it done by the next one but we'll see so that's really exciting um before we get to questions since i only have two minutes i just want to announce that we're also starting a grant program so if you would like to build an application and sway on fuel or just in sway
on the evm in like a year or something and you would like to be a part of a receive fund for it this qr code takes you to a google form we're giving out grants anywhere from 10 000 to 150 000 us dollars to develop applications i'll go ahead and leave that qr code up uh i'll i use i guess my last like 30 seconds for if there are any questions so yes does anyone has have any questions generics uh yeah it has full support for generics yeah okay and i was wondering um you said you have like a support for ad
integration right i think we have a language server yeah i mean how much of this uh framework is uh is it the same as the compiler i mean it's like we reuse a lot of the code so the language server imports a whole lot of code from the compiler and we do that on purpose right to make sure it's consistent yeah okay up here thank you uh thanks alex for the presentation i have a question about the ira error handling mechanism here you mentioned about the renault and we can use this way we can have the exceptions
routes so can we define this the uh um you know the the um different type of the uh the exceptions and we can catch them yeah so there's no exceptions in the sense that you just throw things in abort control flow but there are error types that you can define yourself using enums you you declare the errors i can show you a couple examples of that both in in rust and sway but if you want to just crash the whole program and revert because like sometimes in a smart contract you just want to revert there's also a standard library function which just aborts control flow um this is an old code example but we essentially have a function called revert which just immediately stops the transaction in reverse and at that point you can pass out
an error code which could be an enum and our sdk will decode that and tell you the specific error message okay another quick question is about your union okay in your previous code in our example and we have the three different variables and then uh should be the the size of this immune it should be the largest the size so instead add it up together or it's just a two uh two you add add these three together and that's the total domain the total cardinality of this union okay since yeah okay last one yes
like your language is obviously inspired by rust yeah yeah but you do have some specific keywords that are related to blockchain yes you ever think about not having them as explicit keywords like explicit syntax but maybe something looks more like i don't know derives for example yeah so kind of like writing for solana or something where it's like rust primarily with attributes and things like that uh we specif because our whole thing is to have the most integrated and uh kind of bespoke experience possible we want it to feel really um like the tools should be built for the job right and we could jump through some hoops to make it such that you could use vanilla rust with some annotations and stuff like that but the reality is it wouldn't be as clean
of a user experience things like things like declaring contract storage in the top of a contract which is somewhere in here yeah things like this it's yes it's a concession for for blockchain development um but that's because we want to be building the best possible language for smart contract development there are plenty of other general purpose languages and that's not really a fight that we're here to fight we want to build the best possible thing for smart contracts and because of that yeah we're going to have uh that's i think one of the big the best things about solidity is that it was built for making smart contracts and that's why it's so popular because you're going to use the tool that was designed for the job so if we were to try to like completely
step away from that and make like a complete rust clone it wouldn't be a tool for the job does that make sense yeah okay that was the last question thank you all for coming and listening