 I think it's important to start with the why question. So besides selling JPEG monkeys, what are we all doing here? I think we've reached a critical mass, or we've gathered a critical mass of people here, that actually believe we stand a chance at re-architecting, rethinking, and even adopting some core-level systems that we rely on, things that touch on our governance systems, our financial systems, and some of our social coordination system, so how we work together. I think our window of opportunity is unknown, so ultimately, we should seize on that while we've got it. The success of Ethereum and decentralized technologies is or perhaps should be measured in terms of adoption. And by adoption, I think that at least a couple of the things that move the needle most are, number one, that we're solving real problems and number two, that we are providing powerful and accessible tools for people to solve real problems. And my thesis here is that the latter comes first. And in that, it is unlikely that one DAP will solve all the world's problems or one sphere of the world's problems, right? By putting powerful and accessible tools in people's hands enables them to solve their problems locally. And so that's where I think I can move the needle anyway. So this is the framing for this talk. My goal is to increase awareness of a set of Python tools, some best practices, and some other projects that I think you might benefit from being aware of. Sort of the template for this talk is that I'll give you just enough information to know whether you want to learn more about it and point to somewhere where you can learn some more. So this is a blog post I wrote about a year ago now that I think is still relevant that digs a bit further into this call to action. So this is meant to be beginner-friendly, sort of a series of lightning talks smushed together. Sound good? My perspective is informed by five years at the Ethereum Foundation, thinking a lot about what it takes to get people to adapt this technology. Starting on the missed browser team where we produced one of the first UIs for Ethereum. When we sunset that, the team moved over to do some UI experiments on configuring and running Ethereum clients, called that Ethereum grid. And a couple of years ago, I pivoted to the Snake Charmers team, the Ethereum Python team, where I write some code, but also prioritize creating education content. In the last year and a half, my life has done some zigging and zagging. My wife and I welcomed triplets into our family and then while I was on paternity leave, I helped establish DeveloperDAO, which is a very reasonable thing to do. I'm excited about DeveloperDAO because it's sort of this hive mind of bright and passionate people, all sort of focused in digging into this solving challenges of adoption. I'm proud to be part of this Ethereum Foundation Python team. We are a small team and most of us will be hanging out at an Impact booth hub for a lot of the day tomorrow. So if you wanna come say, hey, meet some of the team and get some very exclusive, snakey mixed snake face swag, come find us there, come hang out. We just welcomed our fifth teammate this month, Linda. So hi, Linda. Welcome to the ruckus. I'm gonna take a moment to burn a couple seconds of time here that I don't really have to say that this is like a full circle moment for me. When I joined the EF in 2017, my first DevCon was in Cancun, DevCon 3, and Ev Fraga is in the audience who was on stage giving a shout out or like giving the talk for the misbrowser team and he gave me a welcome shout out. So it brings me joy to make this a newfound tradition. Quickly, the EF Python team manages or maintains about a dozen Python libraries, most notably Web3Py and PyVM. The rest sort of roll up into those two libraries or help make those two libraries work. A shout out to our open source community of contributors. They also help things move along here and shout out to our, the snake charmers who've come before us that kicked off essentially all of these libraries. Let's get to Web3Py then. Starting with the why question again. Why does Web3Py need to exist? And the same question is applicable to EthersJS, Web3JS and language libraries in other languages. The short answer is because JSONRPC exists or more specifically that the execution clients in Ethereum speak JSONRPC to, if you want to communicate with them, you have to speak their JSONRPC standard effectively. So in a command line, if you want to make an ETH call request to an Ethereum node might look like this where you've got a stringified JSON object that you're passing along, the Ethereum client comes back to you with this bit of this blob of data which is then up to you to decode and make sense of. Web3Py and similar libraries give you like a human readable interface for this. So you make the request for whatever it is you're looking for and ideally you get back exactly the data you're looking for. For the deep dive into what happens under the hood there, got another blog post for you. So what might you know Web3Py for already? In order to communicate with an Ethereum client, you'll have to configure a provider. This is your friendly reminder that the most secure way to do this is to run your own node on your own machine and connect to it via an IPC socket. All know well that this is an unreasonable ask for most of the Ethereum community. So I'd like to plug here another project to keep an eye out on the portal network. There was a great talk given yesterday by Piper Merriam about the portal network, what it is, how it works, what the progress is. The idea here is that there is a fundamental redesign of the peer-to-peer protocols to actually allow light clients that are light enough to run in your consumer grade hardware. So your laptops, your Raspberry Pis even. That's in flight. There are three clients that are being implemented and the spec is effectively done already. So hopefully coming soon. In the meantime, use your HTTP or web sockets providers as needed and once connected to your node, you can do various things like lookup account balances, convert between way and ether, send ether from one account to another, deploy contracts, interact with deployed contracts, get block data or transaction data, and then watch for events as they occur on chain. That was intentionally quick. If any of these concepts are new to you or you're new to Ethereum in general, then welcome to this weird and wonderful world and our docs are fairly good, but I've also written a couple of introductory blog posts that will hopefully make these concepts a bit easier. So what's new? A lot of work has gone into making a sync functionality just plain work in Web3Pi this year. We've started with the HTTP provider because that's where the biggest bang for the buck is. This is available today in beta versions of Web3Pi. Instantiating or configuring these new providers is a little bit more verbose and that will improve over time, but you're welcome to use it already. So very quickly, an example of what some Python or asynchronous Python code might look like. In this example, we're just grabbing the first 50 blocks from the Ethereum blockchain using async.io's as completed method. So as each one of those requests goes to your remote node and comes back, we just print out the block number that was received. So you'll get it in, in this case, a fairly random order. But the takeaway here is that if you spend a lot of your application doing read operations, you, in particular, to and from a remote node, you can see some massive performance improvements like in the neighborhood of 10x moving right along. ENS support is not new to Web3Pi, but it's gotten some love in the last year. So you might know it best for looking up the, like it's read operations. So looking up the and address for a name, resolving a name from an address, or getting some arbitrary text that ENS allows you to store as part of your record. New this year is async support for ENS. So if for whatever reason you want to fetch the address of Shack, Vitalik and Paris Hilton and 30 times in rapid succession, you can see some massive gains in performance here. Same async.io as completed code sample there. That's the takeaway. Your gains are, might be even more significant than the standard Web3 methods. Let's get a little weirder. Web3Pi introduced support for CCIP read functionality. So this EIP was introduced by Nick Johnson of ENS. CCIP stands for cross chain improvement proposal and read alludes to your reading some data on off chain or otherwise not on Ethereum mainnet. So this EIP introduced a standard for contracts to let the user know it's going to fetch some data from somewhere else other than mainnet Ethereum. The simple version of how this works or what this introduces is just a pattern for using a custom solidity error to return some metadata and of note, you can include one or more URLs where that off chain data can be fetched from. And then a callback function for where that off chain data should be returned to to be verified as authentic, essentially. This diagram is included in the EIP and we're gonna use it as a quick example of what this looks like in practice. So the use case will chat through is ENS placing some or there let's say ENS is some sub domain is registered on a layer two, like optimism. In our case, the client is your web three script or app. We will be making some funk in this case is looking to resolve the domain or the sub domain of an address. The contract is an ENS resolver contract that says this value does not live on mainnet Ethereum but you can find it on off chain somewhere at this optimism gateway, for example, and that information is packaged up in this off chain lookup river message. So under the hood without the user having to know this is even happening, web three pie will go and make a get or post request to that optimism gateway, get that address back and then pass the relevant data to the specified callback function. The callback function within the same ENS resolver contract then reads the signature, verifies that this address came from a source that it trusts and sends back along the answer to web three pie. So from a user standpoint, this looks dead simple, right? You are just looking up the address for a name and you get a value back and this address might actually live on optimism on another L2 on somewhere else entirely. So just for context here, ENS had to implement a protocol change of their own to support this functionality called wildcard resolution. If you're interested here, they've got a full open source example of their resolver contract that supports this functionality. Also of note, Nick is giving a talk directly after this one and I believe he's digging in a bit further into CCIP read functionality. Cool little update from last week, the lens protocol folks announced that they're gonna be using the same feature set to supply social graph data from their protocol via their own ENS resolvers, I guess they're running. If for whatever reason, this functionality introduces some security concern that is not compatible with your use case, you can fundamentally disable that at the provider level or at the call level. And then again, for more information, go hang out with Nick or check out his blog post. If you are looking to do something outside of the normal scope of what Web3Py does, you have a few options. The first is middleware and this is the most common tool you'll reach for. Effectively what it does is it lets you inject some behavior either just before a call goes out or just when it returns. So you might be using this for some special logging behavior or some data visualization, some additional munging of data points or whatever your use case might be. It's pretty flexible. And then you inject that into what we call our middleware onion. Your next option is a custom method. So if you're using a client like Aragon or Otterscan, one of these that have some non-standard RPC functions, you can choose just to lump those directly into the ETH module or whatever feels appropriate for you and you can use some of our data formatters and call that just like you would any other ETH method. Also of note here is that you can use this to override any existing method in the module. So if you wanna change the way that any call or getting of gas works, et cetera, sorry, you can essentially replace it with your own version. Your third option is external modules. This is intended to be plug-in support. So if you want to include an entire API within Web3Pi, a whole set of functions, you can do that via external modules. This is very flexible as well. You can, our only stipulation is that you create these as classes and if you need to make use of the parent Web3 module, then you have access to that via the init method. You can nest these how you choose. I think that's all there is to that one. And fourth, custom providers, you're unlikely to reach for this unless you're creating something like a custom test harness or you just need to fundamentally alter the way that every request is made. I'll leave that one there. Finally, I don't recommend it, but if you got a monkey patch things, do what you gotta do. For more context on when you might reach for each of these, got another blog post just for you. We good? We taking breaths out there? All right, let's talk about the merge. As an app developer, what do you need to care about? The good news is that not much else, like not that much has changed here. So a couple of things. We said goodbye to some test nets. Gorly is still a good choice. Sepolia is still good as far as I know as well too. Block times changed. There's maybe a subset of applications this might be relevant for. Pre-merge, a new block was added to the chain on average 13 seconds with high variability. In our new world, we have a new block every 12 seconds even with much less variability. And I think it might be useful to understand where that variability comes from by differentiating slots and blocks, if you're not familiar. So every 12 seconds, a new slot is made available and a randomly chosen validator can then propose a block to fill that slot. And if a validator is offline for whatever reason, then we might miss that slot and you're waiting for the next 12 seconds for the next slot to fill. So that's where your variability comes from. This happens very infrequently, but it does happen. Next we've got block identifiers or sometimes called block tags. So you might be familiar with latest or pending or adding a specific block number if you want to specify when a particular ETH call is made. We've got a couple new ones now, safe and finalized. And the short version of this is that safe is going to give you a result that is based on a period where it is very unlikely for a block reorg to occur and finalized is one in which it is extremely unlikely for a block reorg to occur. So based on your use case, explore those block tags. And finally, we've got the Beacon API, which has existed for a little while within Web3Py, but maybe it's more interesting to you now. We've got, there's nothing fancy here. It's a very simple wrapper around the Beacon node, restful HTTP endpoint, HTTP endpoint. I don't know where the I came from. That's about all there is to that. Couple debugging tips. These both revolve around ETH call. I've prepared this little example scenario, but in the interest of time, I'm going to skip straight to the good stuff. What is ETH call? You might be familiar with it. You're probably more likely to use it as attached to the contract object. So for example, if you're going to execute a function on a contract, you effectively have two options to do so. One is to call call on that method or transact. Transact will submit that application to the transaction pool to get picked up. But if you call call, that simulates the effect locally. So that didn't feel like the perfect explanation, but let's see if we can get there. ETH call simulates a transaction in your local environment. We're going to use it in isolation here to highlight a couple of debugging tips that might help you out. The second parameter it takes, the first is the transaction. The second is that block identifier. And the default is latest, so you would play out a transaction in whatever the current state of the blockchain is. Let's say, for example, you wanted to find out why a transaction failed at some point in the history of the chain. So the revert reason is not something that's stored on chain, but you can get it by essentially replaying a transaction at the time it originally occurred. So in this example, we've got a transaction we're interested in. We build up a new transaction object to replay, and then we call it at that block number minus one to replicate the state that it was in at the time it occurred. And then you get that human readable revert message that you can then do whatever it is you need to do with. For some more detail here, another blog post, but that's not all. There is a third optional argument on ETH call, at least within GeF and Aragon and possibly some others called state overrides. This can save you some serious development cycles if you need to get a contract in a specific state to perform whatever testing it is you need. For example, you need specific state values in that contract, or you want to even alter the bytecode a little bit to, or like the operations within some of the contract itself or like undo a condition for which the contract would normally revert just to see what would happen. Otherwise, you can override that in real time within the ETH call method. In this quick example, I am telling, I'm using, so in this example, we are telling ETH call that the contract that lives at this particular address, I would like you to replace its runtime bytecode with this altered version that I've made, this version that I'm interested in testing. And then we can run that and in this example, we've got a successfully executing call in the last example that would have reverted. For more detail here, check out the blog. Finally, last chapter, we, the Python team, know that as time goes on, more and more of our users are going to be using our tools through one or more layers of abstraction and that's a good thing. Specifically in mind are development frameworks that sort of package together a bunch of functionality that let users be super productive in a much shorter time. So I'd like to encourage you, if you haven't yet, to check out our friends over at Ape. They are, they can be thought of as like the, a Python version of hard hat. And they are, I think, more and more in the future, they will be our biggest or they will be the biggest consumers of Web3Py as a vehicle for their users. So again, this, this gets us, this enables our users to be more powerful, to do more and to solve their local problems. So that's a good thing. So that's, that's what I've got for you. We covered everything today. Show of hands, make it a little interactive. Do we touch on anything you weren't already aware of? Is there anything that you're ready to dig into a little deeper? That's like, for the camera out there, that's like 4,000 people that all raise their hands. That's cool. Cool, then mission accomplished. Again, thesnakecharmers.etherium.org blog is where a lot of this lives. If you'd like to catch up, review on any of what we've chatted about today. And eso es todo, muchas gracias. We have room for some questions from the audience. Just a quick comment in terms of slots and block times, there can be mixed slots where the slot occurs, but there is no block. So the block time doesn't necessarily increase every 12 seconds. Yeah, thanks for clarifying though. I'm not certain, I got the clarification. So a block, I think we're on the same page. A block can fill a slot every 12 seconds. But it doesn't always. Correct. Everyone? We'll have to.