A Rust-based Smart Contract Language

ETHCC 4 · July 2021 · 41:29

Alex Hansen introduces Sway, Fuel Labs’ Rust-inspired smart-contract language and ecosystem. He compares it with Solidity and walks through developing a contract for Fuel running on Ethereum.

Speakers

Topics

From ETHCC 4, hosted by Ethereum France.

Transcript

all right i'm getting a thumbs up so i think that means i'm good to go for those of you it seems unlikely at this point but if this is your first talk you've been to today welcome um also if you make your slide deck with uh you know a github pages link and javascript it's a little bit harder for the organizers to deal with so thank you guys for for dealing with that um there may be times where it appears that i'm quizzing you like a high school teacher who's trying to see if you're paying attention i'm not it's actually because my focus is uh heavily impacted by jet lag so i might just actually lose it and need you guys to help me out so if that's that's what's going on just letting you guys know um so if you're here for this talk you're

in the right room um the uh more or less on time so welcome i will be talking about a programming language that we are building at fuel labs i am the main compiler engineer we we are hiring uh by the way rust and typescript and solidity developers so keep that in your mind while you're listening to this talk and maybe talk to me afterwards if you have any interest in such a thing this talk will assume some decent familiarity with solidity the programming language for the ethereum vm and familiarity with rust is optional this is a language the compiler is completely implemented in rust but we took a lot of design decisions

from rust so with that in mind i think we can go ahead and get started i might be doing a little bit of dancing over here because i got speaker notes on one and um but yeah all right so let's get started so sway is the name of the language um we we bike shouted on that quite a bit ended up just picking an arbitrary four-letter word because that seems to be all the uh all the jam these days so that's what we're at it's sway um it was motivated by solidity and rust as i mentioned previously so obviously solidity has done great things for the blockchain world for the ethereum world and um rust has done great things for the programming world

so i've i've heard it said multiple times that people keep reinventing technologies that other areas of computer science had achieved 20 30 years ago but just in the blockchain space uh this this is uh there's a little bit of that going on in this in this space we're just basically taking decisions that have already been made and re-implementing them but we think we're doing it the right way so um the main things that we took from let's see rust are i advance my speaker notes but not the other ones yeah so from rust if you're not familiar this is ferris he's the logo the mascot for rust um he's pretty cute so from rust we took

i know solidity is statically typed as well but our type system is basically modeled after the rust type system so it is uh if you're familiar with the rust type system statically typed very um very expressive you have some types you have union types we'll go into detail on that a little bit later if you're more mathematically versed that would be pi types and sigma types or structs and unions if you're a c person so we have all that good stuff we have a verbose and friendly compiler so our compiler is very similar to the rust one in fact we use the same crate to print out those little error messages has anybody here use the rust compiler okay that's a lot of hands has anybody used the solidity

compiler another show a lot of the same people um i want to go out on a whim which which error messages would you rather deal with uh late night you got something due show of hands for the rust one maybe okay cool yeah rusty is really great about its error messages and we wanted to just start with that from the beginning so we always try to add additional help additional context additional line numbers as much help as we can and uh the syntax is clearly rust inspired as you'll see we'll be going into that very shortly and let's see here yeah so we use trait based inheritance i'll also go into

examples of that but for the uh inheritance of both contracts and just general types um it's actually not technically inheritance it's traits so if you're a haskell person it's a type class if you're a java person it's like an interface but we use in rus they're called traits they're all kind of the same thing they're an opt-in interface for a type so we use that to represent contract apis as well and yeah another thing is we packaged everything with the tooling all together so it comes out of the box with a deployment to the chain testing framework just like rust it's extensible so it's a sensible default with extensibility and configuration so we have let's see testing code formatter builder runner profiler deployment

test network deployment don't think i'm forgetting anything we have a lot of cool things packaged into it it's essentially our version of cargo and the last thing i want to mention is team organization so we are just one team building all this stuff and we are sharing a lot of code so we're working together very closely uh the formatter is using you know the same parser as the actual compiler and we're able to get a lot of consensus amongst us for tooling so we're able to produce a very coherent product um so this is different from like the the c approach the slowly approach where you know this compiler was given to the world and that's very good we very much appreciate that

but then all the tooling came from the community and that's certainly a good model but it's not the model we wanted to go with because we wanted sort of that clean customer experience you know the apple wallet garden except for it's not walled it's open source anyway so what do we take from solidity sorry tripping over my slides here so it's designed around smart contract development clearly the biggest thing solidity well okay maybe maybe i'm making a big claim here it's given a lot of things to the world but it's a language designed around smart contract deployment and or development and developing for the blockchain which uh that you could consider that a programming paradigm if you want certainly uh a novel thing so that that's obviously huge

there are other ways to develop uh for the evm there are other ways to develop smart contracts yes solidity is very popular um integrates contract storage as a language construct that sort of builds off my previous point um as a first class language construct you're able to do things like contract storage as well as declare smart contracts things like that uh shareable contract interfaces is really important by that uh we'll get into that a little bit when i show exactly what we implemented in sway but we're talking about abis and being able to like to share types across interfaces so when you do a contract call you're able to share a lot more information

and it feels like it was made for the task when you're writing solidity for the evm you're like you're drilling in you know you're using the right tool for the right job sometimes there's a little bit of a impedance mismatch if you're using say some sort of sdk there's a few rust sdks there's a few i think there's a python sdk maybe not that like generate code for the evm and you know these these are great and all but they do have this impedance impedance mismatch problem where you're using a general purpose programming language tool to attack a very specific domain of a problem and it doesn't always feel exactly like the right tool for the right job so this is our logo by the way fuel labs um

so we also wanted to bring our own priorities to the table so we want both the compiler and the generated code to be fast and efficient we want to be easily auditable so has anybody here dealt with auditing for security in their solidity code or just any chain code at all okay a few hands that's certainly a really painful thing and we wanted to make sure that our language implemented that as a priority so we have a lot of we have some bells and whistles we have fancy things like uh visual graphviz control flow diagrams and things like that but we also just have a philosophy behind the optimizations that we apply and the manner in which we structure the language that it will always be easily

auditable and traceable and reproducible that's not something that rust or slowly lack that's just a priority that we are taking very seriously um we will maintain some verb back port security fixes um just like russ does so maybe i should put that in the rest category and we will be learning from the memes on twitter so we basically just search you know rust and angry emojis or slightly angry emojis we see what the people are feeling and we try to fix that pain so let's take a mean break thank you um yeah so this this first one is actually uh june june 17th semi-recent

talk of a less recent vulnerability i think if anybody's familiar with this one but essentially it was a typo where um there is a local variable wallet and there is a global contract storage variable wallet and there is no real demarcation between these two types in the syntax and so this typo well you can read the you can read the tweet it essentially um ended up referring to the wrong wallet so that's one thing we've gone around we've gotten around by uh introducing a specific syntax for addressing contract storage variables as an entirely separate thing from uh regular variables and i will go into codex there will be code examples you right now you're like where's the code you will be sick of

code another thing is you can have more than 16 variables so has anybody hit this error anybody okay yeah so we uh we actually are targeting a register based system so it's it's a little bit of a different paradigm than the stack based system so you not only is it impossible to get the stack too deep error because we don't have a stack inherently in the compiler but um we also have not not uh reproduced this path so you have as many variables as you want just go to town and then rust is often criticized for a having a learning cliff instead of a learning curve so if anybody has ever tried to learn rust and you know you you learn language

and there's that curve where there's the confidence versus how much you know and when you know a little bit you feel really confident except for in rust that curve is uh it's not really a curve you just kind of hit a wall and fall back down on the ground um so i want to say that we have a solution to this but what we did was we mixed the blockchain into rust um this is still going to be a problem but we'll document it really well and we're really nice people and we have a twitter and you can tweet at us and we'll try to help you out and uh i'll just i'll let that one sink in for a moment before i go along this is in reference to the previous tweet

okay moving on okay so how exactly are we accomplishing this okay so we have a swappable compiler back-end we i have mentioned ethereum many times i've mentioned solidity many times mainly because that's the impetus for us to really start this project that being said our compiler does have a swappable backend and we do plan to expand this project out using the same syntax obviously there may be some minor tweaks for the implementation details of various environments however it will be modular on the back end and we would welcome contributions um we are essentially for the design of the product right we're we're terry rust has gone through so much turn so much you know design over and over again

did anybody use rust in 2015 oh i'm the only one that means i get to tell you oh two okay great rust used to have a garbage collector um and it used to have two separate types of pointers one of them was denoted with the at sign like from an email so just picture this right you have a garbage collected version of rust where pointers are denoted by at signs then you have a separate pointer type that's not garbage it's been through a lot of changes okay and uh we're taking all of that work that they did in language design which most people seem to be pretty happy with now it's really quite a revolutionary language as far as popularity and adoption goes and we're just picking those decisions and we're using them because we feel like

they're really good decisions same thing with solidity we're picking the decisions we like and that fit the most with the decisions we're making from rust and doing that we are hopefully implementing a really well designed language from the get-go and lastly we do have a full team of developers working on both uh working on a lot of tooling in parallel with the compiler i would say we have a full team developers working on the compiler i would like for that to be the case you are looking at the team of developers working on the compiler so cool so i'm going to pause for a moment ask if anybody has any comments before i start digging into code excerpts uh oh is there a microphone sorry i should have warned you guys there's

probably there's a process yeah so we um there's a lot of things in this is okay a multi-tier answer here um so yeah you will be able to support uh unsafe code yeah we're not gonna like enforce any extra safety it's obviously in such a um tightly constrained execution environment you want to be able to squeeze every little bit of performance out right and a lot of like even more so than general purpose lvm you know rust stuff uh so yeah you'll

always be able to just like drop down into assembly and write assembly and stuff like that we do support that um but the even bigger truth is that this project i haven't actually even implemented like safety checks yet like we're we're still building out basically the core language it's mostly there we have contracts that you can build and deploy and run and stuff but um stuff like safety checks and borrow checker the designs actually need to be changed for the new problem domain they don't actually work the rest way because many reasons single threaded execution environment for one um so that will definitely be different but we will support on safe code i will try to answer the others quicker so i can get through um i saw a couple other hands maybe just one other hand and a itchy

head yeah so i'm wondering you said you had swappable back and what just like what specifically is swapping like generating different languages or oh yeah so um also i just want to say like uh i'm not saying you did this but i realized that i'm using a lot of terms if anybody is just like yo what is that term just raise your hand and i'll try to define it um for anybody who may not know uh compilers typically have a front end which is the language like the actual syntax of the language uh and then there's some sort of intermediate representation there's a backend which is the code generation uh so that's like generating assembly and stuff so the language itself would look the same sway would look the same but the sections of the code that are generating the code are entirely

modularly modular and separate from the syntax tree which is generated from the language so you can just write a new code generation module to target something else and do you use this or do you just have one back in that we just have one back end right now yeah but we're implementing it like thinking forward like we're going to want to expand it yeah okay cool uh those are the two that had their hands up earlier i will circle around um for more questions in a bit let's go ahead and dig straight into some code so let's take a look at some solidity so we're gonna do a bit of a b here with solidity like i said we're picking on solidity a lot because it's the main impetus for our particular use case in wanting to implement this product so let's take a look um

solidity begins its documentation and by the way i'm going to be basically going through the first five chapters or so of like highlights of the salinity documentation with the code excerpts and re-implementing them in sway and you guys can hopefully see the differences ask questions disagree with us give us better ideas which we will then take and probably credit you um okay so this is uh like the very first one of the very first code examples in the solidity documentation so you have this contract called simple storage and it has some stored data which is a state variable hopefully it oh we also i also left the pragma in there because i just wanted to point out that we will handle versioning in our tomo file just like rust i just want to point that out because we have a tomo file our project structure

is actually basically the same i actually took a i would i would call it heavily inspired code from the uh cargo repository um yeah let's let's leave it heavily inside it's mit license this is fair game um so yeah we have a fork we call our orchestrator fork instead of cargo and i believe that name is pretty much final so i can say that so if i accidentally let that name slip and you're like what the heck that's what i'm talking about so instead of a cargo cargo.tomo we have a fork.tomo fuel orchestrator instead of a cargo build we have a fork build that kind of thing okay so let's take a look at some contract storage in okay so

first bit of sway code we're 18 minutes in and i'm showing you the language sorry about that um so we support a couple different types of syntax trees you can build a script predicate library contract a couple different things we're going to focus on smart contracts here because that's the primary use case so you declare what kind of program you're building with this contract declaration so you're just saying the code i'm about to write is going to be a contract and then this is your stored data so any any globally mutable stored data is contract data so this syntax we're not 100 married to yet but it's what it is right now so this can only be accessed inside of a contract function

with the predicate contract dot so that would be an implicit variable inserted into contract functions only to access variables that are inherent to the contract or storage um the reason we do it that way is because you we want to explicitly prevent you from doing what that tweet did right the wallet uh you don't also on a if for those of you who aren't familiar data stored in a smart contract in storage is expensive it's not cheap at all and you don't want to just accidentally treat that the same way as you would a regular variable which is cheap so we want to make it really obvious that you're you're really doing something here okay so a pretty simple code example you can see you can mutate it because

it's mutable if this was not mutable um then it would just be it wouldn't be put in the storage contract storage because it's unnecessary it's not mutable you can just bake it into the code all right any any terms how am i doing on like throwing terms out oh if it was immutable oh that's a compiler yeah so we we have a lot of compilers um that's what we want we don't ever want the compiler to panic we don't ever want the compiler to crash or anything like that it's we we will spit thousands of compiler errors in your

face using the rust philosophy it's not great for self-esteem but it's really great for solid code so cool um how how are we doing any other i've been like steeped in this is my life so i i fear i you know say things that i i'm like oh of course yeah from the context of the rest of the code that that's why you went the uh implement oh yeah okay i'll repeat the questions um so once again thank you conference organizers for dealing with my sporadic and uh you know i didn't warn you guys um so the question was uh how do we know what type this is is that fair yeah so the same way russ does

it we essentially you can annotate it if you want exact same syntax it's just a colon and then the type but if you don't we infer it and the default numeric type here is a u64 so 64-bit unsigned integer that's just what we default to because that's what solidity defaults to seems like what people are used to um we'll get to types later like what types we have specifically but cool all right i'm going to move on uh just because i think i am going a bit behind schedule here um was that it for storage yeah that was it for storage okay so let's take a look at some functions function syntax stuff like that okay solidity um a lot of things going on here uh let's

break it down we're building a smart contract it's called simple auction um in the simple auction there is a payable function uh which is public and it's called bid okay and we have a helper function and the helper function takes a single argument uh it's a uint uh named x it's a pure function it returns a uint okay cool so a pure function by the way is a function that doesn't reference or mutate contract storage so uh there's a lot of stuff going on here let me show you what it would look like in sway all right i apologize that's a few more lines of code sometimes russ does that

in my experience writing sway so far the trivial examples result in a couple extra lines of code but on the larger scale you'll actually end up writing less okay so a couple of things to break down here we're still doing a contract uh and now we're using this abi keyword so abi is how we declare the interface for a contract so you might be wondering but alex if you remember my name if not you're like but guy why don't you just let me declare the functions in line like i hate c plus plus you have to declare all the functions at the top what the heck well simple reason we want the interface of the contract to be independent from the implementation of the contract

so that both the caller and the callee can import the same type so this is essentially a trait definition that you can import and use it to call this contract or you can implement it for your contract so your contract is now callable there's also a third one third use for this which is that other contracts cannot import this we can switch this word contract up here to be library and now it's code that's not ever going to be deployed and instead if it's a library it's just code to be reused right it's in a registry just like you know creates.io which is the it's also like npm if you've used npm um or github if you've used go anyway so that's the reason for this

extra syntax which cost us a couple extra lines of code so we're implementing it for our contract here contract is a type when you implement it this smart contract gets this abi it gets encoded there are function selectors just like in solidity you know it's it's the hashed name and the arguments it's it's the same kind of technique there and yeah i also wrote the helper function from solidity which looks exactly like a rest function oh osha should point out implicit returns just like rust so a little bit of syntax fun we get implicit returns we get all the all the fun ergonomics right so let's look at another function example who here uses a lot of uh

function modifiers let the record show there was a hand um hey john can you raise your hand no okay okay so one hand okay fine uh so modifiers are something that we don't um support at all the reason is because modifiers are essentially completely replaceable with function composition and traits so they don't really have a use in our language uh so modifiers in our opinion they they um what is the word they redirect the logic it's like a two-dimensional pointer array uh there's a word for this i'm gonna let the dead space sit for a second don't remember it okay uh but it's it's a little bit of

it's hard to reason about your your code could be executing in other places uh without you realizing it so it's hard to analyze it's hard to statically analyze and it's unnecessary in our language so we just don't have them and instead we support function composition another thing is this underscore does anybody hear how familiar you guys are this underscore and function modifiers given the one hand that went up i'm gonna assume it's the one guy so that um a function modifier let me back up here for a second because i realized i dived right into this is essentially another function that wraps your function and calls your function so if you have a function that multiplies number by two

and you give it a modifier that adds one to it or something right it'll add one and then multiply by two and your modifier can control how to call the original function this underscore is the original function body so this this modifier is saying like insert this code and then put the rest of the function body here um let me double check that i'm not missing something here yeah okay additionally when this is used if you use it multiple times and paste the body multiple times that code is uh put into the final product multiple times identically and it is not optimized away in the current version of soul c so we also wanted to avoid that and so we don't have that problem at all because we don't have modifiers at all

so that's fair um cool i think that's it for modifiers uh you'll notice that we use yeah okay i was in the next slide all right yeah oh one more thing is functions are pure by default in our language and you have to specify otherwise um we haven't thought of the particular word i'm going to warn you guys before it comes up on the screen you're going to giggle i'm warning you now um we haven't thought of the particular word and honestly i kind of wanted to get it out of there before i was standing up here like i am right now remembering that we didn't take it out

of the presentation uh but the word for a non-pure function so we have pure we have view we couldn't think we're like stateful io like haskell and we just went back and forth for days and uh we went with the opposite of pure which is naughty so if you see a naughty function i'm sorry we meant to take that out it's not gonna be in the final but that is the actual keyword right now if you if you were to get access to our private repo and build it you know that's it's naughty but uh it will not be that way when you see it warning you ahead of time okay so another example uh we are going to showcase a few new things so one is we have primitive

i i uh truncated this just because it's like you know it's really long um so we have primitive types uh and we support primitive literal syntax just like rust um for like hexadecimal binary octal with underscores as well for demarcation so you can do like zero zero zero underscores your count your zeros we do support that and then we support wrapper types for strongly typed uh 32 uh byte hashes and stuff so you don't mess up your address with your arbitrary other 32 byte hash that you're doing whatever with um hopefully not terribly naughty things but and it can reference the contract storage but it does not modify it and then we are implementing dead beef

by the way we will implement this api for this contract um so a couple things to note here one is this exclamation point in rust this means it's a macro a macro is code generation we do support procedural macros declarative macros and derive macros from rust and we'll get into more detail about that later but it's essentially code generation very useful especially if you're automatically implementing certain you know blockchain related boilerplate getter setters that kind of thing okay i'm gonna go to the next part here all right i have been talking for 30 minutes which

means i have 10 minutes so i'm going to keep going all right events i'm going to speed this up a little bit and then i'll do a bit more questions at the end so this is solidity um you can declare an event so so an event in solidity it's basically just like a struct except for it's called an event so it holds some data and you can emit that event for analytics and things like that and and for monitoring visibility uh it is an event based if you've ever worked with events it's exactly what you would expect an event to be we noticed that this is just a struct and that this doesn't need to be a keyword it can be a function and that's basically the extent of how we implemented events so i got a

little fancy here i'm using some imports and stuff but it's a struct it's the exact same thing and you can emit it which is a it's going to be in like the standard prelude import so it's just a function the standard library if your contract abi touches a type at all ever like this it emits this type that type is then included in the uh abi documentation for typescript integration as well so it'll be documented and that way when you receive those bytes you know exactly how to decode them all right airverse who does anybody like the rust error system i'm a big fan a couple hands all right it's a it's a

can be a tumultuous topic um tara's family is a part of thanksgiving everybody else has software engineer parents right no just kidding um okay so event handling and solidity there's a lot of different ways to do things you can revert for one and we do support reverting obviously that's necessary for a contract however we do not have try catch on revert and we instead encourage you to use rusty error handling so let's go ahead and look at some rusty error handling so i'm going to do a bit of scrolling here in russ once again we don't want to special case a whole lot of things in in

the rust style right so so instead of a specific error type or anything like that we have our struct revert is going to be another prelude function and this would essentially be the equivalent of a panic and rest it would abort the control flow it doesn't have to be reflected in the return type because you know this is a non-recoverable path therefore it never returns therefore it's not part of the return type this is impure if you're a haskeller but to everybody else who writes nevermind i'm not going to be mean uh production code um this is what you want this is coming from an x haskeller i'm not even that x i think the last house i wrote was yesterday um okay oh god the naughty it's right there oh no okay

so we would encourage you to use this pattern um you can use results uh we because of the type system that we support uh you don't even really have to we didn't really have to do any work for that um the result is just a it's just a sum type so we'll go into that in just a second do note the lack of parentheses are on there rust syntax if is an expression although it's not being used as such here and we have a storage mapping right here so if you've ever used a mapping in solidity you'll see that you can just have a hash map inside of your contract storage which is above scrolled away right now and that will be how you handle mappings all right macros yes

procedural macros drive macros and declarative macros these are all forms of code generation i'm going to give you a couple rapid fire examples you can just add functionality to some random chunk of code so like this is a contract storage variable let's just throw a getter on there so that'll add it to the abi get you a getter function in your api since you're in a contract procedural there are no rules in procedural macros in rust and in our compiler when you decide to walk down the path of writing a procedural macro a there's no documentation but you know that's whatever uh but b uh the function signature that you must implement in order to do this

is from a token stream to a syntax tree it just hands you the reins it's just it's like if you get in the car there's no steering wheel and it's like just reach in and turn the steering like that was a bad analogy but uh you have full control same thing literally anything goes you can just parse h2 you can just implement html parts or why not you never know you never know what you're going to need and you also have declarative macros which rust uses a lot of stuff in the prelude this is essentially you know revert if these things are not equal or panic in the llvm world of rust but in the contract world it would be revert i am broke as you can see because i flew to paris all right we're coming up uh on some time constraints

here so i'm going to speed up my my voice a little bit these are called product types pi types structs all those things we support them exactly as you would expect exactly the same as rust they can be generic this code example is not generic this one is this would be called a sum type union type i'm missing any sigma type um depending on your particular academic background an enumeration is one or the other my syntax is a little bit different than the rust one however it's the same exact functionality and you can see that we do support generic types they're monomorphized at code generation time like rust hit me up later if you want

monomorphization nerding out and knowing what that word means it's a cool word to drop at parties and all right where are we going next up all right let's run through our types they're different than rust our types are basically the solidity types so our primitive types are unsigned integers only booleans statically static length strings dynamic links strings involve heap allocation therefore will be a library implementation uh 32 byte values so like hashes addresses single byte values and the unit type that is it for primitive types for us keep it simple don't do floating point math on the chain um we do support generics and we also

support traits and we support trait constraints and like i said they are monomorphized at code generation time i'm gonna keep using that word because it's fun to say all right see this is what happens when i don't truncate the the by 32 for you see the scroll bar see how ugly that is okay we support all these cool syntaxes for declaring byte values so just copy paste it from your uh coinbase app and paste it right in and that syntax is just fine with us we do support discriminated unions which means that the different types of an enum do not have to be the same type so i'm just kind of going on a speed round here but in the previous examples they were all the same type but you can have different types wrapped in

an enumeration they'll be tagged accordingly and uh that's it okay i this was gonna be my speed feature around but i'm already doing that ifs are expressions just like rust so if you look at that you don't have to have ternary expressions when your ifs are expressions um i think that's a good idea unchecked arithmetic because of the specific way that we deal with math it doesn't make sense to have separate um functions for them so we do have a wrapping block for arithmetic you can also do the default would be checked and panicking if it overflows or underflows

uh bonus you can see the underscore syntax right there look at how cool that is and the u32 suffix so that's telling you that you have declared something in hex with underscore separators to help you keep track of it and it's a u32 matches are also expressions with enforced universal conditions so if this was not here this is an error you need to cover all the cases so obviously i've forgotten all the freedom units so you know we'll uh those would become a problem and also all the other metric units but matches our expressions and i forgot a semicolon in this code example okay visibility external public internal private

gonna make this one really simple for you guys it doesn't really apply in our language model external is a function in an abi block public is a library function that you can import and the other two don't really apply because of the way we've organized our abi blocks can go into more detail about that later should you be particularly interested let's take a sneak peek at some solidity inline assembly which is used for a lot of performance related things it's like 50 of the way to assembly ours is much more uh keep it simple stupid you just list op codes you can initialize your registers we have a register-based vm which also makes it a lot simpler initialize your registers to expressions perform your ops return a register

here's another example of an or and a type annotation on the return register um you can assign registers to expressions ifs are expressions and you can put asm expressions in them because assembly blocks are also expressions okay we don't have time for this example contract we can i'll leave that up later if you guys want to look at it like i mentioned before we have all the tooling and thank you okay uh 15 seconds left thank you all i apologize about the speed crunch at the end uh this is me this is us and if you are interested in keeping updated and uh participating in our beta testing

program if you happen to be interested in writing smart contracts with our language we would really appreciate you shooting an email to us here we will keep you in the loop and as soon as it's ready for beta testing you'll be the first to know be an early supporter and we will you will also your voice will be the loudest because nobody else will use it yet so you can you can give us your feedback and we'll be uh really appreciative of that we like i said at the beginning we're hiring typescript solidity rust remote we are a remote company this is the first time i've met john but um and feel free to dm us on fuel labs or find us after this conversation and that is that also these slides are on my github there's a github pages for it

let me know if you want the link thank you do we wait this was the last talk wasn't it that means that we can maybe ask questions oh okay okay then we're done all right here's i think i owe you guys a lot of gear you