 Yeah, hello everybody. Thanks for coming. Yeah, welcome to this Ethereum.js workshop I am Gabriel from the Ethereum.js team My name is Scotty also from the Ethereum.js team. Yeah, so today we're just gonna be walking you through our monorepo called, you know, the Ethereum.js monorepo so we're basically the JavaScript team of the Ethereum Foundation and what we do with the Ethereum.js monorepo, let me actually bring up the slides and be helpful So yeah, what we do with Ethereum.js is we basically build a set of tools that people can build upon so we're used by lots of you know JavaScript tooling that you I'm sure you're familiar with and Yeah, and it's really a great set of tools for people to learn About blockchain in general because JavaScript is a you know, really easy to use language that a lot of people a lot of web developers are familiar with and Yeah, we're focused on You know helping out a lot with research as well I mean we have for example the client going but it's not a production ready client like like get and others and That's kind of an advantage for us because we can jump in early for you know newer EIPs and Implement stuff because we're not constrained by the maintenance of like a production ready client for example So yeah, we've been helping out with lots of you know newer EIPs So yeah, that's just you know an example of that So yeah, three of the latest like PRs that are in progress in the monorepo or You know a stateless Virgil state manager to help out with Virgil trees that young and a bunch of other people are working with EIP 4844 which I'm sure you've heard about like proto dainting sharding EIP and Yeah beacon chain withdrawals which are going to be a part of the Shanghai Hartfork Hartfork Hopefully I think community would be pretty mad if that doesn't get in so Yeah, you want to And sure, I'd also like to just say hello and if you get a sense of who's with us today If people used our mono repo yet, are you daft developers? Just get like a sample from the crowd of like who What brings you guys to this workshop? And so raise your hand if you've already interacted with the ethereum.js mono repo Okay, this is relatively new to most of you. Awesome. Awesome. And that's good. It's a part of our focus is having these tools available in a language that devs know and are building in and You know as you're as you're learning more about ethereum and about how all this works Hopefully our library can help you get there So yeah, I've been with the team since the beginning of the year Gabriel's been here a little bit longer And Yeah, yeah, so we So I'm gonna go through that slide quickly just to give you a sense of the kinds of like packages that we have So we have an implementation in typescript. I mean, we're college from JavaScript But technically right at the moment everything is typescript. We've migrated to typescript about two years ago So we have a typescript implementation of the ethereum virtual machine We also provide, you know building blocks like transaction block blockchain We also had to have a bunch of like smaller scope like utils like for example, if you want a RLP Like recursive land prefix thing like encode things decode things We have a typescript implementation of a Merkel pituitary as well, which is you know, the data structure that ethereum uses We have a devp2b package and an experimental client. It has sync magnet There's been a guy who is was able to sync magnet up to the tip of the chain It's not really Performant so I mean you wouldn't want to use it in production and we don't have like the mitigation that are in place for more like production ready Clients, but it is able to run all all blocks from mainnet So yeah, I was just mentioning it's used by a bunch of tooling So all these are some of them, you know packages that I'm sure you're familiar with like hard hat truffle metamask remix Web 3ds and a bunch of other, you know projects Use us as a dependency for to to build upon so yeah, let us give you an overview of how the Ethereum JS packages kind of work together, right? So at the very bottom we have the client now the arrows pointing to the client mean that the client is importing You know the packages all these other, you know packages So at the very bottom we have client which imports basically everything that we've built in the monorepo or as common is just going to be more like General things that you probably wouldn't use by themselves, but are going to be helpful for Like for example in common you would have like specifications for hard forks and stuff like that which if you want to you know build a block You know you need to know like which hard fork you're building, you know a block for same thing with a transaction Same thing if you want to run a block in the EVM and stuff like that So that all lives in common. We've tried to modularize it in a way. That's more that makes more sense and that makes it easy to To import and export things without them being all intertwined So yeah, you might have heard like term VM EVM II We also have you know a state manager so basically VM is like a higher level like virtual machines virtual machine which Sends You would provide that like a block you would tell the VM. Hey, I want you to run a block or I want you to run a transaction Then it would forward An individual like message calls to the EVM which would deal with like the op codes and all that sort of stuff Then the EVM would report back and communicate with a state manager that's going to update like whatever state you have In your miracle patrici tree So it's much easier to interact with the state manager because then you can just for example update an account's balance rather than like Finding the proper key in the Merkel patrici tree updating that and recomputing the route Which would be you know super tedious obviously, so we've abstracted most of that away with the state manager Yeah, I'll Leave you to Scotty to talk about the portal network, which is another thing that we are working on right portal network it's actually a series of Networks that are peer-to-peer networks special storage networks, and this is All in under construction and under design at the moment, but we are implementing Portal network clients in typescript using three mjs libraries There are two other teams working in Rust and NIM at the same time to implement this So essentially if you if you want to interact with the blockchain right now You either need to run your own full node, which is a very heavy process requiring a lot of your resources and most Most people aren't going to do that and most devices aren't going to want to do that some most reach out to in Fira, which is a centralized Access to the blockchain which works fine, but it is Is a centralized access to blockchain which is kind of the thing we're trying to avoid so People have been working for many years trying to figure out what goes up in that top-left box where we can have something lightweight accessible but also decentralized and The work on LES late clients has eventually led us this concept called the portal portal network portal network is It's an in it's an independent peer-to-peer network. It's almost like a bit torrents. It's working on that principle where If you need access to some amount of information from the blockchain you don't need to actually sync to the entire blockchain to Retrieve your you know your block history or your account history or many of the things that human-driven wallet interactions Need so that's the idea we we're building Networks to support the users of this protocol not necessarily Building up the protocol itself the way a real full node does and therefore this can exist on Very light resource constrained devices you could build it into The back end of a wallet app and it can just be running in the background of your phone or your watch or your anything and Essentially the more more devices hooked into these networks the better they will work and Part of that is that you don't have to sync to the entire blockchain Because that takes a long time and doesn't really make sense for a small app or a small device to want to do that It takes a long time. It's very heavy And doesn't really get you where you wanted to go So with the portal network you could just reach out get the tip of the chain get your account balanced and all these things and be immediately Immediately serve your purpose I'm Just kind of explaining the same thing with in cura everyone's reaching out to the same thing with the LES you get this kind of pile up where the more nodes involved in the system the more clunky it works and the harder it is to Actually return anything, but it's distributed system Every everybody's got a piece a little piece of responsibility of the network and they Hold as much data as they're willing to and they serve as much as they can or want to so for a practical example in a You know just a Jason RPC call for eith got balance Right now if you're running a node you have to maintain all of these databases where you can look up the Knuckle index you can look up storage you can look up state and return these things Calculate them and then return the balance Portal networks gonna work exactly the same But instead of looking into your own databases your own huge piles of state and history You can reach out to these light networks. You can Receive your balance receive history receive state and send it and return it in the exact same way so for For the user using a Jason RPC call it feels exactly the same, but it is possible with very very limited resources and Are just called ultra light there's two other teams ones called trend they're working in What are they their rust and the client called fluffy that is working in them So cool thing about ours is that we can we have a CLI client, but we also have it working in a browser So we can open up a browser page to And we built like a stupid Just a small block Explorer, but you open up your browser page to this thing and the browser itself becomes a portal client Using the same kind of Same kind of memory and and storage is anything else and You know can both can both look up Look up and serve Yeah, what else am I saying? Yeah, essentially your your app can be a portal client if you if you were to bake this into They could bake it into your app it can basically just be running in the backgrounds You don't even really have to think about it, but it's distributing the data among a large large network of pockets and phones and laptops Essentially taking a lot of the load off of full clients and making a lot of this data available in a much more light way We have been building the history network for last year or so and that is eminently operational And then the idea is that the other networks can just build upon that, but they will be Independent networks so as a portal client you can Participate in one or all of them you can You can be there as a freeloader and not contribute anything and it really doesn't take much away from it if you think about You know bit torrent most people are Most people don't really go into their torrent apps and change a lot of configurations to be selfish about it most people just download the thing and use it as it comes and Essentially you don't even really have to know that it's happening, but you are serving the entire network yourself So that's yeah, that's a side project But it's very exciting and is definitely part of the future of how these things will work. Yes So it's a distributed distributed hash table both of content and user addresses So for the most part you're gonna be randomly assigned an address in that in that sphere and you can Sort of configure the radius of data. You're willing to be responsible for Yeah, so you you would be up here on the network, you know If you constrain yourself to only holding like a tiny bit of data, then you're not going to be asked for it very often There are certainly malicious ways to You know put a bunch of nodes up that aren't doing anything but I Don't know the It just kind of means that we've built something worth attacking first of all and that there are solutions to those problems that can be worked out and Just I think we're counting on the Just general laziness of users that are going to download a wallet app that somebody made and not Necessarily configure it to be like weirdly malicious. There's no incentives here. It's all just It's all just there because it benefits users and by benefiting one user you benefit all users So, yes, there are ways to attack it. There are ways to Be mean about it, but I think for the most part as long as As long as enough users are just kind of passively participating then that's not as This is in this isn't crucial to the protocol itself like Portland. We're going down does not affect a theorem in any way So we can build this thing that's lightweight ends. Hopefully just working on Just working on like natural natural law essentially Nobody really has anything to gain by trying to shut it down and it doesn't really affect anything Yeah, you know problems that we're working out where we're trying to steam ahead with like building the thing and then like Solve all of these problems along the way But yeah, please Our it's ultra late team is just two people. It's me and me and Andrew from our team. So We're always looking for help or for Whatever kind of contributions are out there Cool other questions on that before we move back to more like the actual it's MGS motor repo Yeah so we We have a concept of a bridge node, which is something that is Is synced to the net and is it's into the chain and is just feeding feeding into the portal network? If we have enough of those it just kind of saturates over time. We also have just kind of ideas of how to Maybe like a babysitter node that kind of like circles the network and looks for gaps and kind of helps helps fill in the gaps But yeah, it's these kind of bridge nodes that Originally saturate the network and maybe maintain that the boot nodes are We have dev ops just put up a bunch of nodes for us that that are acting like boot nodes There's no real difference between a bridge client and then just regular client. It's more Are you? Are you doing this extra work to like add to the end to the network or are you just helping to gossip around the network? All right, so we'll move ahead with a demo of it your MGS so as you know the next hard fork hard fork is going to be named Shanghai and There's a testnet running at the moment. It was down for a couple of days, but it got back up I think this morning or last night It's a it's a testnet that basically implements a subset of the Of the EIP's That are going to be part of Shanghai So there might be additional ones the one on this list at the moment But that like tentative like list of the IPs that are going to be included at the moment is is the one you see on the screen So the beacon chain withdrawals and the deactivate self-destruct aren't implemented implemented the yet in our in our client But yeah, the Shandong testnet is up and running. We have it running with load star as a consensus client which is like the TypeScript, you know consensus client and Then we have it there with the ethereum.js as the execution client. So that testnet is so it's live You can look it up. There's a block explorer that I think would just put up this morning And as far as I know like the only execution client that it's actually running that at the moment is ethereum.js or the javascript Client So what I'll do is just I will not like run. I will not access like the Actual in a live testnet, but I'll run like the testnet locally to give you a sense of how you would go about doing that And you might be interested in running that yourself when we go into the more like interactive part of the workshop So I just need to check out the proper full request from our more repo So it's just that here So yeah, as we said our mono repo is broken into you know packages, can you see the VS code? Yeah, cool awesome So We'll just go to the package client. I have you know a couple of instructions. I've I've done here So basically what we first want to do is we want to create, you know data folders for both You know the execution layer data and that consists there. Yeah zoom in I'm not sure if I can zoom in notion actually, but I can definitely zoom in VS code. So at least it's gonna be that Is that better? Yeah, cool, no worries. Oh Yeah, yeah, they're actually available on that pull request and in a couple slides There's a link tree with all of these outlines. So you definitely can access all of these nodes and Yeah, it's it's a good exercise as well to you know run that yourself You will have time for that and we'll be happy to help everyone get that running So yeah, the first thing we want to do is just create some data folders where the the state of the you know Where the consensus client data and the execution client is gonna live. So we're gonna put that in the data Yeah, so We're gonna create an Ethereum Folder and we're gonna create the load star folders. Well So now we're good to go for that part so the next step is we're already gonna start our Execution like a client and it's gonna use a Genesis that's been done by by one of the guys on our on their team You see like Shandong and Genesis that Jason you'll see that more clearly Here Oh, yeah, yeah, you're right Thanks Yeah, and there we go Hopefully that works live coding is always bit Sketchy and the the Wi-Fi is pretty good Actually, if you haven't noticed there's a workshop specific Wi-Fi network that you can access because they're the global Wi-Fi isn't working that well Yeah, we see that we have a Jason RPC server started because we started, you know, our client with the RPC RPC engine Engine flag we have a Genesis that we've specified and the data directory is Ethereum.js, which we've just created and created so that's pretty Fairly simple. So by default when you run the Ethereum.js client It's gonna consider that the merge hard fork has been activated because we've specified, you know a Genesis After that so at the moment, it's just waiting for a consensus layer client connection without that It's gonna be not gonna be able to you know, obviously execute blocks because it's not getting getting any So this is exactly what we're gonna do. We're gonna start the load star consensus client So the first thing we need to do is we're gonna need to specify the Genesis hash to the To the consensus layer client. So to that to do that I'm actually gonna bring up, you know in Fira and we're just gonna query the hash of the I'm not gonna bring up in Fira. Actually, I'm just gonna query the local RPC That we we've seen specified here, you see Somewhere up here Start JSON RPC server local host 8 5 4 5 So I'm just gonna do this is just a tooling to like visualize You know requests a bit better, so let's see if I can recall how to do that my heart We'll see so we're just gonna send a standard like JSON RPC requests to get the data of the, you know, the very first block in that, you know Execute execution client state. So method Then it's gonna be what is it? It's eat get blocked by number And if you see me make a typo be sure to point it out so that we don't break our execution layer client by sending him like bad stuff and So we're just gonna specify, you know the very first block we could specify earliest as well This second option is just if we want the transactions will say yes, but it doesn't really matter all that much Then we need to specify an ID. I think we'll just go with one Can you see properly? Yeah, so let's see if that works cool. Yeah, so we've got you know the first genesis block We should expect like the parent hash is gonna be zero This is post merge. So the mixed hash is zero. It's It's unused the the nonces 1 2 3 4 not sure what that is But that is probably like a default value or something. So we're just gonna take the hash and Yeah, we're just gonna copy and paste So then the only other thing that we need is we need to specify like an initial like timestamp. So I'm just gonna quickly Get the timestamp like in seconds and we're gonna add like a few like seconds to that when we do that, you know right after so I'm gonna Start the consensus line client here and This is a fairly, you know long command it's running with Docker like I've already installed a little star in my machine I didn't want to do that, you know here, but we're gonna help you, you know set that up later If that's what you want to do. So all that we're gonna need to specify is we're gonna need to specify the genesis Eat one hash and we actually have that from here Pacing and Then we are gonna specify Genesis time Which is gonna be that and I'm gonna add a number of seconds to it So let's see if this works. So we should eventually start, you know Producing blocks. Oh, we see published block that looks pretty good And then if we go back to the execution layer client It should have picked up on, you know, the consensus Client starting to run producing blocks sending them back to it So let's see if we yeah, it's a assembling blocks build block That looks perfect. So we we are seeing that We have a local a shangdong watching and running with a bunch of newer EIPs Now one thing we can do we have a test suite. I think for So we have a bunch of tests here That we can run to see if the, you know, EIPs have been properly Implemented so I won't go through all of them. Feel free to go through them yourself. So EIP like 3670 is Like the EOF Valid the code execution the code validation So if you try to publish like a contract code that's doesn't conform to the EOF standard it will get You know rejected we have a bunch of related tests. So we have Can't exactly recall what this one is actually a bad that label here just fix that and Yeah, so we can try and see if we can Run that test. I think it's in the sim Yeah All right, so it should Oh, I have to specify External run through. Yeah, right. So this is gonna interact with the chain that we have running locally and Check if everything seems Good, so we've been able to make a transfer. That's already You know, not so bad and then it's gonna test EOF and a couple of other, you know, EIPs This is a bit slow maybe because I'm sharing the screen. I'm not sure But yeah, we see that test running And yeah, I'll keep that running while I Keep it up and go back to the presentation slide show All right, so this is a Where we're gonna start like the more interactive and I feel like interesting part of this workshop Where I mean we encourage you like to bring actually your laptop style And if you have if you don't have a laptop or you don't feel like, you know coding yourself I would really encourage you like to to meet up with someone or to pair with someone who actually has a Laptop going because I feel like that's probably gonna be the best way that you can We can show you about the mono repo and if people have like different degrees of Skill levels or familiarity with like a blockchain in general. We have a couple of like suggestions and do what we suggest you to do so If you're and that your code is a delink tree I was mentioning earlier, so it has links to all all of these things along with like Shandong test that instructions That's not what I mentioned The structure of our mono repo you can clone the whole mono repo and it'll come with Was it 12 packages? So all all of the relevant packages will come in the mono repo if you clone that from get hub But each individual package is also installable on its own So you can you can install just the transaction package or just the block package You don't need to have the whole mono repo as a dependency. You can have each individual ETHJS package Yeah, yeah, but I would encourage you today to maybe clone the whole mono repo So you can see everything and and get a sense of how they all connect to each other Yeah, yeah cloning the mono repo is probably the way to go if you want to experiment a bit Especially since some of these packages are enter and they're dependent on you know each other But if you were for example building a set of tooling and you only need to build blocks from data or build Transactions from some piece of data that you have you could only import like app ethereum Block and that ethereum transaction and that would be you know all as you need you don't need to you Don't import the whole mono repo. It's just package based So yeah, what we have like sort of prepared for you in terms of like paths If you're more like I wouldn't say beginner But like if you're more novice or if you've never really learned about you know, Merkel Patricia trees A good way like to explore that is with a tutorial that had been written like two years ago And has been like updated recently And it basically goes through it uses our Tree package to teach you about the very fundamentals of that data structure. So it just starts with you know Putting a value inside the Merkel Patricia try database getting the value Computing a hash looking how you can you know make proofs from these hashes eventually all the way up to you know querying data on the blockchain and Interacting with it more dynamically in a way that's more similar to what you'd expect in the real world context, so I'm super happy to help you as well answer any questions on trees. It's the package. I've worked the most on In the more I guess intermediate track, although I mean Merkel patrutis are certainly like not Super easy, so we could have put that in the intermediate track as well You can experiment with like RLP and coding or decoding So this is the serializing Algorithm currently used by Ethereum And we cover a bit of that in the Merkel Patricia trees tutorial But if you want to experiment with like, oh, what does a an area containing a dog and cat strings Look like when you are open code them. That's the package you would go for it contains two methods RLP dot encode I'll be that decode super simple and you have a bunch of helpers like to convert two strings and stuff like that Another I feel like exciting thing that you could use our packages for is The block and the transaction packages one of the things you could do for example is query, you know, just like we've done Here we've queried a block. So a good exercise would be to recompute the hash of that block From that data. We have helpers that can do it for you Like super easily where you basically just paste that Jason object And it's going to recompute like the hash or a block object for which you can get the hash But it's also it can also be interesting to just take those fields like manually and try to recompute the hash yourself And we have all the helper methods you wouldn't you would need to do that And if that feels a bit bit hard, you can look at how we actually implement our helper methods and you know Try that out All right in the more Advanced I guess track one of the things you could do is invent and implement your own EIP No, no, that might look like super hard but We have an example here of a super like minimalistic EIP and I'm actually going to show that to you just so that you see how Small like potential EIP can be so I think it's 18 14. Yeah, right So it's adding like 92 lights of code removing to Pretty simple. It's an EIP that goes into Shanghai. It just warms the Coinbase address so if you take this as a As an example You're I think you're easily going to be able to you know, reproduce at least a scaffolding for any IP and You can like invent this Perhaps not so useful, but like easy one where it just modifies the way maybe a block is run it maybe modifies the name of field or something like that and Yeah, that I think that PR can serve as a guideline for how to do that and yeah Most of the implementation is actually like it's basically just That line here in addition to like the scaffolding and a bunch of tests that are just confirmed that the EIP has been implemented properly In terms of other things that you could do You can run the local client as we you've seen us do and you can run the Shandong a test net with low star as that consensus client So, yeah, now it's off to the races as the return always says So any does everyone raise your hand if you don't have a laptop all I have one so I won't raise my hand So everyone has one awesome so Was everyone able to scan that the linkry thing? All right, cool. If not the link is just linked link tr dot ee Slash if you're MGS you just bring them so do I'm wondering how to best like structures is so either I can Go through one of those myself for those who want a more follow-along But I think what would be helpful is maybe if we just help everyone, you know set up a local environment and if At some point you want to follow with what I'm doing you can do it or if you want to work on your own thing You can do it as well. Is that sound good to everybody? Yeah, all right cool Walk around Might not be best for the live stream not that interesting to watch in empty stage But I will be walking around and just raise your hand if you have an issue is setting up your Local environment just clone the mono repo its link that So if you click on intermediate, it's gonna bring you to the mono repo itself All right, and once you've cloned on the repo the way to install it. We use npm. So just npm install Is anyone running on the windows? Very happy to hear that There's the door here for Windows users. So he's I assume people are on Mac OS or Linux. Yeah. Yeah, okay. The the workshop Wi-Fi space where there's a build it 22 Lower caps build it and 22 the number So just npm install from the mono repo itself make sure to run npm install in the you know A mono repo instead of in packages themselves. So that's gonna build the whole thing, which is what we want Is everyone good? Raise your hand if you need additional help So I think you just entered. So yeah, just you can clone the ethereum.js mono repo The second link intermediate link in the in the link tree that you see here and then yeah Just make sure you're on the master branch. That should be default and then Yeah, just pull the latest and npm I have to install the mono repo. That should be all that you need so just just so that I do something that's relevant for most people who's thinking of doing the Merkle patriciatry's tutorial Okay, cool. Yeah, I would quite recommend it. It does cover some of the stuff that were We would be doing in block transactions in the RLP, but it just guides you through them rather than just showing you out there Who's thinking of just going straight intermediate and building blocks transactions? All right, and Who's thinking of trying to implement their own EIP is anyone motivated? All right, awesome and What about running the client or running the Shandong testnet? Okay, yeah, so I'll just be going through the tutorial as well in front since everyone is going to be doing that And it's gonna be more interesting for People who watch the recording rather than just looking at the link tree for one hour. Yeah, so this is the folder that you Should go in if you want to do that tutorial and the read me is is you know the tutorial itself What we also have is a set of example like I had Written this tutorial in in JavaScript Just so that people who don't want to learn about theorem didn't know about types here didn't really have to You know, they'll learn about it. So those are like GS files that you can just run with a node So Yeah packages named try so once you've Let me actually just reinstall since the Shandong thing is a bit a bit different. Yeah, was everyone able to install successfully? Cool, no issues You're waiting for the installation Yeah, it takes a while because it's building every package. So, yeah Are you trying to run from the monorepo itself and PM run test? Yeah, it might be just because of the sub modules in the like a lot of the a lot of the general test We have depend on that those sub modules Yeah, they're pretty big they're pretty big I can't say for sure like depending on the bandwidth. How long it's gonna take My own machine at home. It doesn't take that long but You can just leave it running and see if oh that's singular test, okay Let me give you an example of running an individual That's all just go Okay, the the the principle is going to be the same for all of the packages themselves So if you go within the individual package that you're trying to run the test in just do npm run Tape and tape is like the testing, you know framework that we use then you do Double I think those are called dash in English. I'm not even sure Then Test to look at the test folder and then you just select the file basically that you Want to run right? So if I wanted to run for example that I Don't know that the proof that spec test. I would just Do that and it's gonna run that test individually if you do npm run tests, it's just gonna run like a massive suite of of tests including like integration test that depend on browser integration stuff like that and that's Typically like super long. We only do that like in the CI once in a while But locally it's a bit tedious. So and yeah, then you see the result of the test It passes So let me close that up All right, so let me open up the tutorial again All right, so there's you know a bit of preliminary info that you might want to read You know data structure of Ethereum is called the mergel Patricia tree It's basically a combination of a mergel tree and a Patricia try a try is a data structure in which keys represent the path leading to a Specific node and the mergel tree is a structure in which a parent node The key of that is the hash of the all the child nodes mergel tree is Interesting because if you want to prove that the certain value is part of the data at the large mergel tree structure that you have you can do so by providing a Bunch of like the sister nodes We'll see that super clearly in the tutorial itself. So yeah, the instructions are here. They're the same that you've just run So clone them on the repo Install it and then go inside of that try package So I'll been going through these like fairly, you know slowly So feel free if you're you know want to go a bit faster to just go forward and don't let me like slow you down With the sort of first example, we're gonna use the try, you know library for is a creating and updating a base try So what does that look like? So first of all, we're importing the try class from the the try package and we can look at what you know, that looks like it's probably like try file yeah, so try is simply a class and you know has a bunch of properties that you would expect on the, you know database like structure it does use like checkpoint DB as a As like a database and then you can provide options for the tree. So some of the option or Do you want to use this specific type of keys? You want to use like plain keys or hashed keys like our What is used in? Ethereum then we instantiate database you could provide like your own database here. We're instantiating a new like map DB and Yeah instantiating a new tree when we you know construct a tree with the tree class and You can see you have a set of methods here. You can for example, you know, I get the root of the tree You can verify if a certain root exists you can get those are like these two methods or the ones We're going to be using the most we have a get method to retrieve a value by providing a key and then we have a put A put method which stores a given value at a specific key. So fairly standard, you know database stuff But this is going to give us insight into how you know That actual data structure works because it's not like a simple database So let me go back to the tutorial. So the first thing we're gonna do is like instantiate the tree. So I'll go to Yeah, I'm just gonna comment that So, yeah To run a specific example, you're just gonna go Know examples and for example example one My doing typo It's within Merkel pressure trees and then example one There we go So this all I'm gonna be doing here as you can see is instantiating in your tree With you know the the the try package from the Monoripo and then logging the root of that tree and This is gonna give us the the the root of the tree Which is you can look up in the docs, but it's basically that The the encoding of I think an empty array RLP encoding of an empty array So, yeah, we see like pretty fast we see we output a buffer which is Which is that Now that doesn't tell us a whole lot but we could look up in the docs and see that this is actually exactly what we'd expect and as the root of Genesis like root of a Try like data data structure So then we're gonna move on to a more, you know a more interesting test. I'd say We're gonna we're gonna try to just put a value in it and see if we can actually retrieve it Another thing we're also gonna be able to see is how the the root, you know has been Updated given that so yeah, what do we do here? We're creating a key I mean a try natively uses buffers. So we're doing like buffer from for for all of these So we're having test key that's gonna be your key and we have test value This is gonna be our value and then we're doing an asynchronous operation like putting that Key value pair inside of the try and then we're gonna try to retrieve that value fairly simple What we should expect here is So what should be the value? Well, it should be the you know the encoded version The buffer from version of a test value and the value string We should expect to see value and if we don't there's there's been an issue either, you know The library or in the way we've used it. It should also update the tree root So one thing I'm gonna do is I'm gonna also log the try route before and what we should expect is like each Miracle purchase tree like each state tree should always have a different Hash if it differs and if it's the same it should always Have that the same so let's try running this again So what do we have here? We start with the empty Try route. Yeah, we had logged that before actually so the try route before, you know, it's the same We just log the same thing twice The value that we've retrieved is it's this if you're familiar with the, you know, that's just the hex correspondence for all of the all of the characters and then if we Convert that to a string we get back this value. This is exactly what we expect Then we see that the try route has, you know, massively changed as you'd expect from any kind of hashing If it differs slightly totally different random result Right that clear to everybody that feel intuitive Yeah, any questions? Yeah, and then we're always a so an a normal tree So this is the actual Miracle purchase tree like data structure that would be That would be used like in production with Ethereum that the only slight difference is that Miracle purchase trees use like hash keys. So instead of using the key We'd use like that the the hashed version of that key and this is only to balance out the tree so that there's no vector of that Where you always update like values in the similar region and make it more costly for those to run operations The so what I think your question is is, you know, there are There's a if you had a normal data structure like this You would always like traverse every single load would only give you one hex, right? Because it's a 16 like with Tree So if you have a key of like, you know, 32 bytes Then you would traverse like all these nodes on the way down there Now Miracle purchase trees are more efficient than that because if if they know that given a certain path There's only one possible path down. They're gonna create what's called an extension node Which extends all the way down to the to the leaf So this allows you to shortcut unnecessary paths What you'd see if you didn't have that is there would be a bunch of layers in their Miracle purchase tree Where there's only like one specific branch that has a value and then you go down and there's only one specific branch So for like sparse trees meaning like trees that aren't filled like with data all over This is incredibly more, you know efficient because you don't have to store like all these unnecessary nodes I'm just collapse collapse those back up into into one leaf instead of a Tree with only one Absolutely, so yeah, I'll go ahead and check what example two Is about Yeah, there's a couple of additional like Notes here that you might be interested in some of them. I mentioned while while doing it It's also talking a bit about the RLP You know encoding Function, this is actually not up to date It's probably here. Yeah. Yeah, so there are some very nice docs in Ethereum org for developers like if you're looking to sort of a bit more about RLP, you would just go there They have a bunch of examples and you couldn't even like use our library to test it out and play around with it So before values or so there's a bunch of values You could want to store in a Miracle purchase tree, right? And those need to be serialized before they are, you know put inside of the tree This serialization is done with the recursive lamp prefix encoding function And And yeah, as I mentioned Keys also go in additional additional transformation They're not used like raw. They're used We first take the kekak 256 of the key before we we update the tree So Here we're basically going to do the same thing But we are going to use the hashed version of the key So how we're gonna do that is we're just gonna you know import the kekak 256 that we have in you know, Ethereum.js slash util package and The only difference is we are going to As you see here Put the value at the kekak of the key instead of the key itself. So everything else is going to be You know exactly the same So let's see Yes, similarly, we're gonna get you know, an updated tree root so that You know nothing surprising here It's basically just you know, we we had an alternative key, which is the kekak of the key We got the same value back no difference there any question that Okay, so the the values themselves aren't hashed because otherwise we wouldn't be able to retrieve them since you know hashing is one way The only thing that we hash is I mean, this is like a key value, you know data structure The value we keep, you know native we just RLP encoded for you know serialization so that it's compatible But the the key itself that we're hashing we could very well well have a mergel but should really like data structure without hash keys and However at the you know early days of Ethereum it was chosen that the keys are gonna we're gonna be hashed The main reason without why that was done is So that it evens out The tree Naturally, so it mitigated like vectors of attack where you could have people like constantly update like A part of the tree like very easily and now if you wanted to do that you'd have to like pre-compute a Hash and since it's like non deterministic well It's deterministic where you can like predict an event what the hash is gonna be obviously you basically have to do like proof of work to like This target like a specific part of the tree it imposes some randomness on the actual address And so if you have keys that are related they won't cluster in a part of the tree They'll they'll be dispersed evenly And your key can be a short string and it ends up 32 bytes Yeah Yeah Yeah, so in our case like keys are always like Hatterses like in the case of the the state tree keys would be like that the account addresses But yeah, the kekak like hashing something obviously also has the benefit of making everything equal length Which you want in like data structures like this All right, so as we said like fairly Fairly straightforward now, we're gonna do something, you know a little bit more interesting Now what we've seen is that the Like we've used the kekak to 56 of the key But there's a you know There's a property of the tree that we can just use in order to do that natively that properties called Use key hashing it's a Boolean that defaults to false But as you can set to true if you want when playing around with a tree is just more convenient to set it to false or have it You know default to false just because you you don't have like to do all do all that additional computation It's also easier if you want to debug What a value You know, if you if you only have the the hash of the key You can never know like what was the actual key that I use to update this you cannot retrieve it back Which is actually an issue that has also come up when Making the transition from mergle trees to vergle trees, but that's a different. That's a different topic All right, so let's see what example 1c is about so I think it's basically the same thing, but just using the use key hashing so what we should expect Unless our use key hashing Boolean is implemented improperly is we should expect exactly that the same Values as we have here including the updated tree root given that we are using the same yet asking this value to That should work So let's see and yeah as expected we've created a new tree But we've updated it with the same key value pair and we are getting the same updated tree Try root now we're gonna do a different operation So Among the operations that are possible you can retrieve a value you can update the tree by adding new values You can also delete values from the tree So let's see what this looks like the as I as I kind of mentioned before every Tree that is similar that has all the same data should you know compute the same route That's how we get you know the security properties of these Of these trees So what we're gonna do is we're gonna update the tree It's gonna update the root and then we're gonna delete that same key and it should give us back the exact same route that we started with Let's look at the code Create it update it then delete using the wait deal helper method get it again we We shouldn't be getting a Value when we try to you know retrieve At that key. I'm not exactly sure what we're gonna get. I'm not sure if it throws or it looks like yeah it's gonna be null fair enough and Let's see about that all right So we are starting out with the m3 empty tri-route here starts with 56 e eight Then we are updating the tree We're getting an updated tree root, which is a Similar to the like unhashed key one we had before and then we are Deleting that value again and what do we get back when we query that that tree for that key? We we get back null which means like empty it's not there and The tree root that we get back after the deletion is the same that we start with So yeah, it kind of demonstrates that every you know the same tree is gonna have the same route Yeah, so now we're gonna take a bit of a Deeper look at the actual you know data structure of The Merkel budgetary so it has you want I feel like I've been talking about now you're you're a good communication. Yeah, all right. All right, so there are four kinds of nodes in Mergel British trees So there's the null node, which is the one we just queried accidentally by you know deleting the tree That's a non-existent node. You get back now when you query for something that doesn't exist There is a branch node What a branch node does is it's basically an intermediary node that points to a bunch of child nodes There is then the leaf node, which is you know, this is called the tree and the leaves are the very end These are the nodes that contain like, you know, the final values and then there are extension nodes extension nodes are the shortcut. I was kind of hinting to so if If you have a key for example, I mean, we're gonna see examples actually so it might be easier Any question before we dive into looking we're gonna look at all these Four different kinds of nodes individually. Yeah. Yeah, how how is that initial route created? Yeah. Good question. I am I Think it's the RLP encoding like it has basically still, you know, it's it's the hash of the value at that route Because it's initialized with a value if it wasn't initialized with a value would just be null, you know initially The way they're defined. I'm sorry. Are you asking about the extension node? Like how how that route comes to be? The very first. Yeah. Yeah Yeah, so how how would we able to calculate ourselves like manually the hash of the the root node and the empty root of an empty tree? Yeah, so Yeah, we can actually look at that directly in the code We have We set empty tri root. That's like a specific like constant property when so when we construct When we initialize a new tree what runs is like this construct our function If we don't provide options that we we have like default options that we provide We instantiate the database and then the very next thing we do is initialize the empty tri root Which is exactly the thing, you know, you're asking about This is actually quite simple so what it is is the RLP encoding of an empty string which It's in Constance Yeah, Constance. Okay, so it's buffer 0x80 and that's that's like it. I guess sort of a universal for empty tree Yeah Or empty RLP Well, that's actually Desirable property. Yeah, that all you can know if and you could identify all empty trees from exactly that, right? I get the same tree should always have the same root same with an empty tree every entity tree will have the same root Yeah, and if we let me take that example file actually and just compute That you know Something from let me do it in the RLP package actually. I think a bit of trouble navigating with my screen. So zoomed in Feel free to throw out questions or call me over if you want to Chat individually So this is importing the encode method from the RLP library So what do we should expect to get back from, you know an empty string RLP encoding would be 0x80 which is you know the buffer we just saw before So I'm gonna have to move out of that repo go into the examples folder and then run this Why is it not logging? Always interesting when you do live coding Figure out how to console log something. Yeah, I switched package before I did that Can just actually import I'll just import it directly from This oh, it's actually been for that folder. All right, let's see if we can get something going All right, it is not working at all We're finally Getting back something now. We're getting back 128 is that 0x80 in the hex Let me actually I didn't believe it. Oh, yeah, it's gonna be hard to import packages in a JS file like that Just okay. Yeah, so 128 we we got back the decimal value with 128 is like 0x80 in decimals Which is the the the value that we are using inside of the tree to compute the root hash So we are basically just to to compute that, you know root hash. We are just hashing 0x80 so if we take the kick-back hash of the Let me look back at a place where we were using kick-back So I don't have to re-import manually So if we're doing the kick-back 256 of a buffer from like 0x80 We should expect to get back to the exact same like empty Hash that serves as the root of an empty merkle participatory. So let's see if we can reproduce that You know ourself We'll just comment out the rest to remove some noise navigate back to the Tree package as this. All right, so we're getting back a uint array. I just need to convert that to hex then we should be getting back to the same route that we Initially started with so we have a buffer to hex Util in the package now the way my testing thing is set up might not allow me to import that Yeah, so I would need to do buffer to hex here Well since I'm now running on a Like JS thing I would need to build it before I'm able to run this So I will not do this here But those are we can trust that you know the values that are output here if you were to convert every one of them And you know in hex would be the exact values of the the root of D of the merkle participatory that we had in The example D Sexy yeah, nothing here. Is that a satisfactory answer to your question? Are you? Yeah Yeah, yeah Yeah, cool any other questions before we move on to going to all specific kinds of nodes. We're good Everybody's following along All right, nice So, yeah, we're just gonna start with that creating and looking up null node So how do we we're not actually really gonna create a null node We're just gonna query for a key that is not present and the merkle participatory So it's basically the simplest like test case you could imagine So what we're gonna run is to to a right? Let's look just at that here. Yes, we're instantiating a new tree We are trying to find a path, you know to the To the key test key and we'll see what kind of node we'll get back now what you Will see now is that we're using find path Which is gonna provide us with the actual node and then all the object instead of just providing us with the value So if you want to query the tree for actual values You just do get but if you want to get more information as to you know what the path is and what the node looks like You would just do a fine path So we're running example a this provides us with yeah a no node as we would Expect we could change that to a pretty much, you know anything and We would get back now as well no difference Now one thing I'm gonna try actually is if I query Buffer from that. I'm not sure if that's gonna be a null node as well. Yeah, okay. That's not Oh, yeah, the thing we were using before Yeah, I think it's still not it's since it it's like defined as You know the the initial hash is defined as that but there's no actual no that's present And that key from what I can recall the specs So there yeah Yeah, it's basically a way to bootstrap the tree so that it starts, you know with something You could define like a new mergel Richard Petitry data structure that uses like something different obviously from RLP encoding And also has a different like root hash. You don't necessarily have to use it It's useful in the context of Ethereum because we obviously want to be consistent throughout like implementations But it's not it's not a necessary part of a base data structure like that. You could define it any way Anyway, you want so yeah, the null node is a bit, you know, boring. It's not as interesting on the ones that are to come It's also like slightly more complicated to create because if you think about how you know These kind of keys work, right? You have a key and to retrieve the value for it You just go down each note is a hex value, right? So let's say the next part of the key is like seven you go branch number seven And then if it's you know for like in this example, you take branch number four and you go all the way down Now since like mergel Petitry's are like optimized with extension nodes You wouldn't get a branch every part of the way down what you would see is you would start at seven Let's say you only have like one of the keys you would start at seven It would give you straight it would go you straight to the end because there's only one value that starts with seven So it would like kind of compress the tree for you So if we want to create a branch node that's like acts as an intermediary node You would want to you know, we want to store key that are all basically in the same spot and Then branch out at some point and that's actually interesting because it's super easy to do that You know with what we're going to do in this example But if we were using a hash tree, then it's basically, you know impossible to do that do that voluntarily And that gives you a sense of why that was chosen in the first place, right? Why we're choosing to hash keys in the context like a production You know database in the theory I'm to prevent like DOS style attacks with you know Just putting keys always in the same spot All right, so let's look at that actual example simple to be What it is that like native format that this tree accepts like you could do it Like we could have an implementation that just basically allows you to input anything But it would still be converted into something that natively ingestible by the tree So the tree is defined as a like hexary hexary tree meaning that every key must be like hexadecimal For it to be like conformed to the data structure if we didn't have exit this small values We'd have to convert it anyways so that I mean So that it maps to like a 16 16 with Key So, yeah Yeah, absolutely So and also like RLP encoding encodes things in hexadecimal So we're all like working with native like hexadecimal here. It was in that tree So yeah, if we Like unlike like hashes Buffer is gonna be it's just like the the hexary like encoding of the these keys. So we should expect these All these values to still be quite similar and that is what we see here. So right we have The prefix test keys coming for all of them and test key is basically that part, you know of the Yeah that part of the of the buffer Now we have 30 which is a zero and 41 which is capital A which are you know the last parts of it so what we should basically expect right is a Would you agree that we should expect like a branch node at 79 at which point, you know, it branches out What we would see is like there's gonna be a value at 79 a branch node You know can have a value, but then there's gonna be two paths There's gonna be path number three and path number four like in indexes of the array Then it's gonna go down all the way to you know a leaf node because it's basically the end of the path for that part of the Path and then 41 which is gonna be the end of the part for that, you know other path. Does that make sense to? buddy Yeah, yeah, that's um, it's for the idea of the the Patricia tree is that you're following the Sort of following the keys along that path and everything that shares The shares by it Yeah, yeah, and something like to mention here. This is only keys, right? This is not the values themselves and Like later a bit in the tutorial we see how you know the hashes of every like parent is computed Which is like different, you know from this but yeah, so if we had like also a key at just T We would see like that that would be only 74 because that's like lower case T is 74 in hex and We would see a branch node at 74 There would be value already there and then there would be like nodes Like paths to all the way down to you know 79 It would be like we'll see that after but it will be like an extension node for optimization purposes And then you have well branches as we've said to 30 and 41 so Yeah, what we're gonna do is update the tree with all those keys We're gonna find a path to test key and we're gonna see what that node, you know Actually looks like So that's actually pretty nice like visualization. I think of what's of what's going on So we have, you know first the tree buffers then we're updating with all those three keys So we're updating the tree with test key test key zero test key eight which all have the same prefix We query that the node that lives at key Test key, which is that the common prefix for all of those So what we see so this is index, you know, zero one two three four Which correspond to numerical values like just plus one since indexes started zero and Actually, no, that's not true. Just correspond exactly to the actual values and And we're seeing that there are two Different, you know values here So that is what we'd expect we have like this is basically like empty So like null nodes because there's no path at that point like At key zero, there's no we don't have any Anything that lives at zero, right? We don't have anything that lives at one We have nothing that lives at two but starting from three. We have an actual path And we see that complete path here We also have the same for 41 which is you know index four and Then we have nothing all the way down An interesting thing is we also have a value already here at address, you know That's basically test key and hex. So a branch node is not only an intermediary node It can also contain values, you know itself in the case of keys Which would always have the same length you you might not see like values at an intermediary node because they all leave on Leaf nodes, but you can still use that data structure for other purposes where you know the length of keys wouldn't always be the same, right? Yeah, that's exactly exactly what we see and we can We can take the value of that node and see if we can Like the value here we can Yeah, we can parse it to string. Let me find you the code. So it's more revelatory of what's actually Going on so yeah, we We found a path we found a node we take that node We look at the value at that specific point and it should be the value that we've put at test key now if we were to take The value of one of the nodes that is a child of that parent node We would get also like test test value zero and test value a so it is what we're doing Further down here. So let's look at while how we're you know retrieving that We are taking, you know, the third branch and the The second element that's just that that's the value of that of that leaf and node Converting it to a string and then we get we retrieve the value back That's somewhat clear Russian nodes are a bit trickier, but is Everyone sort of following along Yeah, yeah Yeah, yeah, yeah. So let me I think we're There's a bit more clarity about that After so I think the next example is gonna clarify that for you And if it doesn't we can come back to it and play a little bit more with it. It is Like getting like nodes and how they're structured and how they they operate within one another is that trickier part But yeah branch nodes and extension nodes, which are you know somewhat similar in structure are the more complicated part of that So once you get that and it kind of clicks the way they work together You're pretty much, you know done understanding that that data structure. So it's definitely something that's worth, you know Coming back to and making sure that We understand so many. Yeah, if you see that array of 16 buffers and two of them have have keys in them Every every parents as soon as that branches out has automatically 16 children regardless of how many values are actually there and like where they go If there's only one then we can compress it down and call it an extension node But here where there's like two in that array you just automatically have the rest Rest of its siblings are empty buffers And like I said, if there's only one child to that parent, we can collapse it back up But if there's at least two then you're going to have an array of 16 Regardless of how many actually have actually have a leaf Yeah, yeah, absolutely so this Clarifies this is a bit like in the other example, but I think this clarifies You know what's going on. So it might look a bit confusing because we're using very similar keys and values So this is actually the values and they're also, you know similar But we're not really concerned with the similarity, you know of the values. We're concerned with we went all the way down to a branch node We had two paths that were defined and we had also a value that lived there So your question is basically well, why is it an array that lives there, right? So there already contains the two pieces of information that we need to Finally, like get the value at the leaf node. So this is pointing, you know to a node and it's telling you Well, actually the the the remaining part of the path is going to be three zero and Then the remaining part of the path is going to be, you know, three one And then the value you're going to retrieve at that, you know and point is going to be, you know That whole thing and this is the thing that if you pass it to a string you would get like test value zero and test value a And it's the reason why when we're Trying to retrieve, you know, the values here we are You know taking the corresponding indexes, but then taking the first Not the first like the second but index number one This this is exactly that's the value Now we're working with like fairly small values So the values are directly inside of the tree if you had very large values It would point like back to another node that would have an encoding of the of the value Well at that point it would be like the end node So it would only be a leaf. So all the leaf contains is the the the last remaining part of the path that was that led there And then the full the value And then yeah, that'll be the root of yeah, yeah, let's do that actually So we can We're gonna create So what would you suggest test keel one? Yeah, let's do that. It's gonna be test value, you know, I want as well and actually let me put like some Fairly like different values so that we're not confused by the similarity of the values themselves I think that values themselves don't Determine where it is in the tree. Yeah So we're gonna run that again And we're gonna all that we're interested in at the moment for you know This example you've suggested is that the branch node like what does it look like at that point? And then it's gonna have a child. That's also gonna be a branch node, right? That's what we would you know expect So that's why I need to save it first. Let's try running that All right So what we see is it's actually quite similar to what it was before but instead of getting an array We're getting a larger larger buffer So what is that larger buffer that larger buffer is Now there's two kinds of keys in mergel but trees. That's just a hash that points to a different node, right? So it's not about, you know path path is still like path, you know number three But to know like what's the hash of that other node that we're trying to retrieve This is going to be that so that's just a hash of the Of the child node that is going to be the one that contains, you know, zero What was it like zero and zero zero one, right? So now Yeah, yeah, yeah So let's see how we can go about Well, I'll do next is look at the path at teski Zero right and we're going to look at what you know that actual node Looks like I can also remove that So what do we have here? What am I logging? Okay So if we look at those keys You have a common path that is teski zero And then you have a slightly like longer path that is teski one So what we should expect again is a branch node at that point It's going to contain the value itself because teski zero is actually defined, you know, as a valid key that contains a value But it's also going to continue at one And now obviously we're dealing with like hex conversions of this So it's not going to be at the actual index one. It's going to be at the different index What we're we do see that there's Exactly one valid, you know branch that points to another node And then there's an actual value here and if we were to You know convert that actual value to a string We would expect to get back Whatever like gar badge I typed in there and this is actually Exactly what we retrieve here And if we look at This this branch We're going to try to retrieve that Number three thing here. I can just do it So what's the index of this? It looks like okay index three I have to do actually branches True and then this would be the remaining part of the path And this is going to be the value. So if we do the string, we should expect to retrieve that Number three, you know thing that we had above Let's see if that works And yeah, we're getting back, you know Number three, uh, well, I kind of messed this up. I should have commented this out Can you can you repeat that? Referring to the branches in the terminal right like we have buffer placeholders and The value of the key is being shown as zero one two three on the third element Is that right? Yeah, so in that scenario The total number of Buffer placeholders are 1515. Is that right? All right. Yeah, it's actually 16 We have 16 elements in the array. I believe it ends up the end index is 15, but it starts at zero So we have 16 Got it. Thank you. Oh, okay. I know what that is So zero Is actually like it's encoded as like two hexary, you know Number is only like not at like a single one So we're seeing three because that's the like second number of the zero at which point You know, we have a value like directly there, but we have we're branching out. So I think if I created Like another one It might be a bit tricky to actually create all the cases that we'd want We might end up with the same sort of issue Yeah, so here we're getting again, uh Like you remember how we were getting like a path in the value That was because that was the only value left now We're again and getting a hash pointing to the common path of like the next one. It's going to be a branch note again We could you know again query Find the path To that Or in this case, there's no value at that note. That's just pointing to child nodes Yeah, well, there's a value like if I query test key o2 there's going to be again a value here But yeah, I'm not actually sure why we're always at this index. I'd have to look at the The way this isn't code. I suspect it's like the always that the The latter part of the number two is what's used here instead of tree itself I can't recall exactly what that is But uh, yeah, we in a normal like setting with like keys and stuff We would expect like every Basically level to to to branch out and and the fact that it's tree at the moment There's just a peculiarity of the test case. I've come up with Yep Yeah, lowercase uppercase. Yeah Yeah, it's not lining up perfectly to Yeah Exactly. So if we wanted to do like if we could natively like compute, you know buffers and hexes Then it would be much easier to see what's going on now. We're using like human readable keys So, I mean, they're broken down to that. They're, you know, they're converted to hex So at each uh, each part of the way down that we go, it doesn't line up exactly with the end of the key There's often like one Next like character necessary to to finalize that the number zero, for example um All right, so I'll go over We've we've three minutes. Oh, we have three minutes. So I I think maybe open up to just like general questions or um Comments or anything, um You know, we're we're Building this for you guys. So if there are things that are not working or confusing or that you'd like to see we're Very open to feedback and suggestions and help Yeah, so like most of what we've done so far has been like working on, you know, just merkle participatories themselves A bit further down in that tutorial like I encourage you to just keep going at home and ping me like on Discord or telegram or twitter if anything like doesn't work as you'd expect Uh, but there are like we're working also like with blocks and with transactions and rlp encoding Uh, which is quite I feel like it's how I learned about ethereum initially like through learning about these data structures And the first draft of that tutorial was actually like me learning, you know about this stuff and figuring out what's going on and and yeah And yeah, we're we're an open source project you can find us on github. You can find us on discord and chime in or ask questions Yeah, we have a massive number of uh external contributors who've helped, you know over the years the repo is Fairly old. I think it's like six years old or perhaps like even more than that Sometimes I'll work on a part of the code and I'm seeing like the git blame like five five years ago or something like that So it's really like a pretty old repo We we are extremely open to external contributors Like sometimes we'll have people come up and just help out and then we we you know We include them in the team like not in the formal like team itself But we do like chat with them and are always happy to help people, you know help the project we're working on Uh, our future projects are we're trying to improve the client syncing at the moment. We only have full sync It's super slow and you know, you know that would never use that, you know in production, obviously Uh We're trying to do, you know, general like optimizations as well So if anyone like is competent at that, we're really happy to like Get you started on that We're improving like the json rpc endpoints. We don't yet serve all the rpc calls That's uh, it's an excellent place to start if you want to help out implement a new RPC endpoint for us. Exactly. You can just go through the list of what we've implemented and just, you know Come up, you know with Easy ones that you want to implement and it's a good way to get started learning about our repo My side i'm working more on rnd for vergo vergo trees and statelessness, which is you know, sort of related to the merkle tree stuff We've been exploring Scotty works on ultralight, uh, amongst other things And uh, yeah, we're just improving the cold base as well making it a nicer with nicer types and better performance Any last questions Oh, that's a good point. Yeah, I didn't think of adding that to the Link tree. I will uh that link tree linked above all update it with a link to our Discord so that then you can come in it's the ethereum.js discord probably fairly easy to find as well But I'll link it nevertheless Yeah, I feel like one last question. I had a friend who actually worked with theory and he asked and he was like telling me Uh about like he also used that um, is this actually Interconnect is just for ethereum. Yes, or it can be like interoperable in other like, I don't know proof of proof of history like solana or something like that I don't know if i'm just telling nonsense, but he was telling me like he used that for Our rcp support Kind of the thing how does it work because I was kind of confused and like He was actually using ethereum.js for connecting with solana Yeah, so it's uh interesting question So there's there are we've increasingly made the our packages Configurable so one of the things we've done in the past here is we allow you to provide your own vm or evm Implementation so you could have a chain that is not like strictly evm Or maybe that has like peculiarities or that are evm like but not like strictly the same And you can just like Parse that in when you instantiate for example the client you can provide your own like Whatever like rules you have for your blockchain There's obviously like a limit to that like there's a point where it's probably better just to build something else if it's like super different But it's still quite Quite configurable. So you could also like there are chains like cello I think which has like different rules for computing transaction hashes and stuff like that I'm not like I haven't worked with that So I'm not sure how easy would be to configure it but you can definitely adjust some parts of the code and provide your own like hashing algorithm and Use that instead same thing would like the mergel busher trees thing We've been working with you could provide your own hashing algorithm it defaults to kekak But I mean you can use whatever you want Okay, thank you Other questions. Thanks for coming. Yeah, thanks for coming