Getting The Pixels and Ethereum Events

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the Million Ether Homepage course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Million Ether Homepage, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Million Ether Homepage

Our contract has a million pixels. At some point, we're going to want to draw the image that all the pixels create . Our current pixels method lets us retrieve one pixel at a time. That would take a million calls. I'm sure we can do better than that. A first try might be to create a function getPixels, which just returns them all. If you try this, it may or may not work. It will be slow either way, because it's a good amount of data. Another idea we might try is to just get each row. This will work in a pinch, but it still requires a thousand calls, one for each row. When we build the UI, we probably want to cache the image, so we don't have to keep reading it from the blockchain. If we had a script to periodically recreate the image, making a thousand local calls isn't that big of a deal. However, it would be great to have a real-time component to this page. We want any visitor to this page to automatically see any new pixels the instant that they're purchased. And thankfully, Ethereum has some mechanisms for this, so we don't have to read every pixel to find out what changed. The mechanism is Ethereum Events. The idea with Events is that our contracts can emit events at certain points in our code. These events can be indexed, which means we can find specific events very quickly. In our case, we're going to emit a pixel-changed event whenever a pixel changes . Later on, when we build the UI, we will subscribe to these events using Web3 over WebSockets, and automatically update each pixel as it changes. To specify an event in Solidity, we use the Event keyword. We'll type event pixel-changed, and it will have three arguments. The x position, the y position, and the color. We emit an event by using parentheses like we're invoking a function. Here we can add this event to Color Pixel. Now when we call Color Pixel, Remix will also show us the logged event as well. There are three important things to know about events. The event can be indexed. The data cannot be accessed by the smart contract. And the data is available for as long as the blocked data is available. Event parameters can be indexed by using the indexed keyword. When you index an argument, you can search for those values, but know that you cannot retrieve the values themselves. In our case, we don't need any indexed arguments. Our event is already indexed to the contract and the event name, and we don't need to index it beyond that. Data emitted by events is not accessible to our smart contract. This data will live in the blockchain lock. Its function is primarily for use by tooling outside of our contract, that is in our Dapps interface. Lastly, these logs are available for as long as the blocked data is available. The consequence here is that these logs are already on our machine alongside our blockchain. We can search for logs using filters such as the block number. That is we can say, "Show me all events for Pixel changed after block 3000." Events can be used as a convenient record of changes. They also can be used for optimizations for your UI. For example, in the million Ether page code, what we have is an X-Y grid of a million pixels. In the naive case, if we wanted to draw the whole image, we had to make one million calls, one for each pixel. However, with events, we can snapshot the image periodically and then query for the events that made changes after that point. But the general idea is that you can emit events in your code, and then your tooling and UI outside of the EVM can query and subscribe to those events. We'll do that when we build our UIs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . [BLANK_AUDIO]