Writing a Solidity Watcher in Elixir!
Hello again, folks!
So…Recently I’ve been studying more about the whole Web 3.0 Projects and Proposals. I started my studies using some implementations that are already “mainstream”, for instance, hardhat and web3js. But, as soon as I got a true glance of what I could do with all this stuff, I wanted to turn it into my loved language: Elixir.
Existing Solutions
But, as you might know, in IT we tend to avoid reinventing the wheel, right?
Yeap, and because of this, I started searching for some solutions, like a “web3js but for Elixir”, and I came across ExW3, which is an awesome (and still small (in codebase size), what really surprised me) library.
At the time, they had that in their documentation:
Compiling Solidity
To compile the test solidity contracts after making a change run this command:
$ solc --abi --bin --overwrite -o test/examples/build test/examples/contracts/*.sol
What really got my attention, was that any other library I know about web3 (which isn’t that many libraries), already had an out-of-the-box approach to make the developer experience better. But this one, although is awesome, hasn’t.
So, let’s build it, long live to the open-source!
I started a simple local phoenix project on my local machine and started the implementation.
The first step was to figure out how other famous watchers work on the Elixir ecosystem. I started looking into the Tailwind one, they actually look at any time to the code, and whenever there are changes on the actual files, they’re built all over again.
Also, there’s an entry point called “install_and_run”, which is a simple method, that takes profile and args as arguments, being the first, the kind of installation, and the second, extra args for the execution of the actual compiler (the tailwind compiler).
So what I did was started to create my own watcher by creating the same methods, to keep the standard (as other watchers use the same structure).
This was the first actual implementation, dead simple, but exactly what I meant. We should just look through the PATH of the user (the developer), and look for solc
, I also considered using solcjs
, but it’s not exactly what we need here.
If the binary isn't found, then we should first install it (locally, as tailwind does, because we assume the user will use it for the scope of this project).
And so…Here’s the install method:
Pretty straight forward right? This is one of the greatest things about Elixir’s syntax, in my opinion, look how readable this code is, you can actually break your functions into micro-procedures, enforcing, even more, the concepts and aspects of functional programming, something that other functional programming languages very often don’t do.
But let’s dig into the implementation of this method and its children:
Firstly, it’s worth mentioning that at the top-level in the Watcher module, I’ve defined these module variables, which are just conveniences for accessing either the user-configured values (by reading config.exs)
, or the default values.
So, heading back to our install function, we get the user-chosen (or default “latest”) version of Solidity. Then, we use Erlang’s :os.type()
method, which returns a tuple, containing the architecture, and the distribution as the elements.
After that, we pass these data, to build_download_url
and download_release
which are two helper methods that are not worth mentioning here (but if you want to, you can always check it out on the repo).
After this process, we are left with the downloaded release inside the _build
directory.
So, in our checklist, we’re left with:
- Running the compiler at startup
- Listening for changes on
.sol
files, and re-run the compiler.
The run step is as easy as:
And what about the reloading?
In order to accomplish the hot-reloading feature, I’ve used amazing library FS. Which encapsulates system events from the most used 3 OS Kernels (Linux, Windows, macOS).
Then just added these two calls, to subscribe the compiler process, to the FS events listener process, and then, BOOM, we got our results:
The next steps
And that’s it! We reached our goal! and what about now? Well, I started this project thinking about the open-source and integrating with ExW3, which I already proposed through an Issue on the official repo. So we’re still without the next chapters of this history for now, but my single implementation of the watcher is already available and published on Hex, so anyone can use it with ease!
Thank you all!
See you in the next post! 😃