New Ethereum talks, every Monday. The week's conference uploads by event, in your inbox.

Loading player…

Onchain Chess in Rust With Arbitrum Stylus | Chris Cordle - Arbitrum

Ethereum DenverWed, Oct 9, 2024, 12:00 AM

Speaker

Chris Cordle

By leveraging Arbitrum Stylus, we can take advantage of the existing Rust ecosystem to build powerful onchain gaming primitives. This example showcases the usage of Rust to validate chess moves in a two player game onchain. This technique can be extended to similar competitive strategy games. APPLICATIONS FOR ETHDenver 2024: #YearOfTheSpork ARE OPEN APPLY NOW https://ethdenver.com/apply

Transcript

[Music] hello my name is uh Chris cordal I go by Chris Co I'm here to present uh how to do onchain chess and rust using arbitrum stylus for those of you that aren't familiar uh Stylus is a new parallel execution VM on arbitrum chains um basically any web assembly programming languages supported that includes uh C C++ rust other uh Niche languages like assembly script and Zig are also supported um it allows up to 70 times more computation per unit of gas and and as much as 1,000 times more memory uh per transaction compared with the evm um all the while it remains fully composable with the evm so you're able to write solidity smart contracts and you're able to write rust contracts and have them talk to each other um as needed uh so you can still um plug into the broader arbitrum ecosystem you don't have to give anything up uh you just choose which execution environment that you want for your smart contract um some of the other benefits of using stylus is that you get access to general purpose uh language tooling uh such as like crates.io which is a a package registry that Russ provides uh many other languages also have package Registries solidity does not so you really just have to import um based off of GitHub uh repos and whatnot so um you get access to that you've also got access to different coding paradigms different design paradigms uh solidity is a very opinionated language it has a lot of um you know warts um you know so if you want to explore more of a functional style or you want want to use um you know kind of rust uh rust paradigms or know different design paradigms uh it's a powerful concept there uh additionally like the the point of uh additional program languages is to allow us to on board web two devs more easily and uh gain access to all the libraries and tools like cryptography and gaming libraries that exist in the ecosystem for um that other developers are out there creating that we can tap into in smart contract development as well so just uh I'm not going to I'm just going to briefly go over what some of the prere are if you want to develop on stylus you can uh look all this up on uh docar arbitrum Doo to review and go through a little more slowly than this 20-minute presentation so a little hard to keep up but I'm going to go through it pretty quick um but just as a high level overview you just need you need rust installed on your system you're going to need to make sure you have rust up rust C and cargo the CLI tools that you can uh that you can use when you're coding in Rust um also just as a suggestion you can use whatever editor you want but vs code with the rust analyzer is a good go-to for uh beginners uh in Rust uh to deploy and test your stylist contract you're going to need Docker and if you look up under run a local Zev node on the arbitrum stylus docs uh you should find a section that will explain how to install a local arbitrum uh Nitro test node that will allow you to run a local node and deploy locally on your system uh we also have a public test net that is currently in L3 on top of arbitrum seoa stylus is currently still in audits but we're getting very very close to presenting this to the arbitrum Dow to get approval for mayet so we're very excited about that but in the meantime you can deploy on top of the test net and the RPC for the test net is right there stylist test net. arbitr from.pc so in order to write a contract in Rust uh you're going to probably take advantage you don't have to you can make your own SDK if you want but we provide a rust SDK that leverages the library called alloy which is uh part of The Foundry um Team a lot of the dev from The Foundry team also wrote alloy and that provides solidity a ABI compatibility it helps uh you know like convert between rust Primitives and solidity Primitives and kinds of does it in a very aesthetic way that enables you to like quickly switch back and forth between them and and declare your your state variables in a uh solidity ABI compatible way optionally uh you can you can use while you're coding and I'll show you in a sec you can use either solid Style doc uh declarations so you can literally write basically solidity syntax as part of your smart contract to declare your variables um so that makes it easy if you're like porting over something like an existing uh solidity contract makes it really easy to make sure everything's lined up and in the same slot that it would be especially if you're doing something like a proxy upgrade uh a nice thing that we did with the SDK is we disabled reinsures by default reinsures have caused like a lot of hacks and exploits uh so we just disable it by default you have to write unsafe code in order to uh to uh enable it this is just kind of like a high level overview of the syntax just a like real simple example so basically you just declare struct this is a counter contract with just a single count variable and the silus SDK provides a set of storage uh Primitives that you use when you're declaring your state variables on on your contract and this one is a u 256 so it's just a standard 256 bit integer uh so it's just it's it's uh just a struct with counter the count field with the u56 we declare that entry point to let the uh that's a a macro that just lets us know lets the SDK know which uh which struct is the highest level or the root level of your contract State you can declare multiple structs and you can reference those from this root state but this is just a a very simple example um and then just to like Implement methods on that contract you just declare this external macro and then you write your implementation uh methods very simple um you know here we got Getters Setters and an incrementer we're just returning a result that either has an okay or error um you know for the the G it's just returning the count it's just called self. count.

we tried to make uh Getters and Setter pretty explicit because accessing state reading State writing to state is uh the most expensive type of operation you can do on chain so we wanted to make it a little more intentional than maybe solidity is where you kind of can accidentally refer to uh State variables just as easily as local variables so we kind of try to make certain things like that getting and setting explicit um but moving on to chess um so if you want to make chess on chain what are the some of the key challenges that uh you're going to find well the board is uh 8 by8 64 spaces there's 32 game pieces it's a complex move space and you have to like validate the moves to make sure that each move is legal based on the rules that each piece has there's six different types of pieces they all have different rules about where on the board they can go um doing this in solidity is very difficult in fact I I couldn't find an example of a full 8 by8 chess board I found a 6x6 but I couldn't find a full 8x8 solidity implementation that might exist but it's very expensive to do on solidity um due to the gas limitations and one of the benefits of stylus is you get that additional computation that allows us to validate whether a move is legal or not every time a player makes a move and we're able to do it with a reasonable amount of gas so one approach that a lot of um developers figured out a long time ago about chess if you want to make a efficient um computation even even with this it's something called bitboards but even with this it's difficult to do in solidity um but essentially like it keeps a you know this is kind of a simple 3x3 example to just kind of get just give you a high level overview of what's going on under the hood to like make this computation more efficient rather than like iterating through a list of pieces and checking whether or not it can move through each individual um you know possible move iterating through all that would be computation expensive so this makes makes it easy where you can just do like simple XO operations to like bit wise operations to um to see which piece moved and to see whether that move was legal or not um I'm not going to go too much into bitboard implementations on this example because I want to get to the rust code but it's something that you can look up another time it's used in a lot of um gaming for even in in in gaming environments where the computation is a bit restrained and that includes um on chains so um but you can kind of see here as a simple example we've got a board a 3X3 with a pawn and a knight um on the pawn there's basically kn bits that represent the pawns um where pawns exist on the board uh and you would have I guess you would have two bitboard two Pawn bit boards one for black one for white uh and then you can validate for example on the lower right you can see where there's an old board there's a new board and how do you track which one moved you just exor the old board with the new board and you get the diff which tells you that the Knight moved from B1 to C3 again if you want to review this uh there's lots of resources online lots of great YouTube videos um it's a very cool technique to understand um the other alternative is you can just use a library because somebody's probably already Rewritten this in Rust by now so rust has a a nice uh package registry called crates. and um if you want to use the library you just uh look for certain things you got to you got to when you're looking through on for a stylus implementation you have to look for something that doesn't use the standard Library usually because it can be a little bulky for onchain it could be lots of megabytes or whatever so you might want to just look for something that's usually made for a no standard uh Library environment usually those are focused on like systems or embedded systems types of deployment but they work for on chain two you want to make sure there's no async uh operations in that code no randomization randomization doesn't really work on chain we need to be uh uh very deterministic about how execution goes and currently there's no float but we're planning on implementing a version of float soon so something to look out for um but the library that uh I use for this demo is called just chess engine you can find that on crates.io and I'm going to kind of walk through the code real quick so just to kind of give an example what this looks like and maybe I need to uh increase the font size maybe that's too big no let's do that okay that's reasonably good might want to closed that all together okay so just to I'm going to kind of skip over some details because uh I got to move quickly um this is uh this is just dependencies and I've set a few constants to declare like track game State whether you can continue after a move it will return a gate status and it will be one of these four integers that tells you whether that move was legal if it was legal it's going to return continuing otherwise it's going to return an illegal move otherwise it's also going to detect whether stalemate or victory was reached if somebody's got Checkmate the the engine will uh will catch that and will return Victory and set the game State um on chain correctly um zero is white one is black uh I've got a couple of cons for the different uh piece types couple of bit mkks that I use because I'm I'm basically storing the uh the game state in a single 256-bit integer um that is to say like basically each piece has one color and um a row and column uh that I need three bits for and one bit for the color so if you got four bits per piece and there's uh 64 p uh pieces um or 64 um there 64 positions on the board to track a board you need 64 positions um times four bits to so that's kind of like how I'm storing this in the games object here so I just got a simple counter tracks the total games whether or not there's a pinning game and just a simple mapping that takes an ID and returns a uh a game info struct and notice I'm using solidity style syntax here I'm using mapping with the arrow fat Arrow so it's it's using this like saw storage macro so I'm kind of writing a little bit of solidity syntax again that's optional you don't have to you can just write P rust if you want but it's nice to know and if you're familiar with solidity it makes a little easier for the ABI compatibility uh but yeah game info object is just made up of player one's address player two's address the status the turn color whose turn it is whether there was a Victor or not which color one and then the board State object that I just mentioned um the methods are quite simple just tracking total games here um and again I'm importing this chess engine so it's doing the bulk of the computation I didn't have to figure all this out by myself I'm just leveraging the rust ecosystem to use use this uh chess engine to to build this game uh so that's just a simple counter that gets the color of the current term uh that gets the current player whether it's uh player one or player two and gets returns their address this is uh this is a meteor function here this is a play Move it just to play a move we need to pass in a game number a FR row a from column a two row and a two column and it's a zero through seven based uh you know zerob based index to track the row and the column so in a typical chess game you might say A7 to B3 or whatever um this is just a0 through eight index um so just kind of walking through we've only got a few minutes I'm kind of going to really go through quickly so I can kind of uh show youall live demo real quick but uh yeah it's just it's checking to make sure that the current cender for the game is that uh is the the current player making sure that the game isn't over already and then it make sure that the move it goes through and make sure that the move was legal uh and Returns the state and updates the state if it was a legal move uh if Victory it's going to go ahead and set the the Victor it's going to set the game status and it's going to return that Victory status code it's also going to do the same for stalemate and otherwise the legal moves are just going to return a legal move and not change State um I got a simple printer function that's uh that you'll see in a sec that just shows you how the how to print the um the game board to the console so nice thing about Stylus is while you're developing locally you got access to um a local console output that you can just output locally while you're developing and it's really helpful for debugging uh these are a couple of other methods um let me just kind of do a quick demo just to so I get a chance to uh to show the uh game state um let me go ahead and pull up um my console real quick so I've already got this deployed but I think it should just go through um I should go through quick so what it's doing right now it's trying to get the code size under 24 kilobytes that's the max size it goes through a couple cargo stylus goes through a couple of uh optimizations it just deployed locally to this address so I can copy that and then I've kind of got this in my history so I'm just going to use some of these uh um functions that I've already written um but I've got a brand new contract I just deployed so I'm going to uh I'm going to create or join that so I'm going to go here and paste that contract address in an amusing foundry's cast CLI so I'm just calling cast send um that private key is public so don't worry about seeing that on there that's a a public uh test net uh private key and then uh I'm calling Creator join I'm letting I'm letting uh Cass know what the uh the function is that I'm calling on the contract and that's just going to create a contract it's going to create a game locally and if I call um if I call Total games it should say one now now that I've created the one um and let's move quickly got only got a couple minutes um well this should be one sec um yeah you went 256 that's going to let me call it hard to do this uh hang on hard to do this with the mic in my hand I'm used to doing this two hands um call call okay uh so we got the one game we're going to go ahead and call Creator join again I can play against myself if I want and then I'm going to um call I'm going to call uh I want print game print game I'll come on now um one sec uh PL move um print game one okay that's okay call and what that's going to do is print yeah that's going to print the game state so we've got a fresh board and then uh to to make a move I'm just going to demo the move real quick just uh basic basically like I've got a board here 1 through 8 Row 1 through 8 column A through H which corresponds to 0 through 7 both on the column and the row so if I go back here to uh to um to play [Music] move here okay and I'm just going to make a move on the on one of the pawns I'm going to move the pawn from Row one column 3 to um Row three column 3 and that should send and then if I call Print game State again and go back it's moved the chest piece so and it every time it's making that move it's also like on the um yeah on the the green and the red kind of shows and the the monitor is a little messed up on the colors but it'll show which piece is in a threat mode right now it's able to calculate all the pieces that are currently threatened and um yeah it's a very cool little demo um just to going to go back to the presentation real quick if you guys want to look at this example you just go to github.com offchain laab stylus chess it's on our if you can't find it just look up offchain Labs GitHub and look through our repos you should be able to find it on there um docar arbit bio for more SDK resources we also have a uh telegram arbitrum stylist dev's uh Channel and uh if you need me I'm on uh Twitter and telegram at chrisc 512 thank you very much what

Automatic transcript — names and jargon may be misspelled.