Our lead developer Michal Převrátil answers the most important questions about Woke, our development and testing framework for Solidity.
This year we introduced Tools for Solidity, a Visual Studio Code Solidity extension, that runs with Woke, our development and testing framework for Solidity, in the background. We’re constantly updating both tools to make them even better and to make developers’ and security auditors’ jobs a little easier. Find out why these tools could be useful for you, and what other improvements are coming next year, in an interview with our lead developer Michal Převrátil.
Could you briefly describe the architecture of the “Tools for Solidity” extension?
This has its advantages and disadvantages. The disadvantage is that somehow we have to install Woke on the user’s machine, maintain the required version of it and also run it when the extension is started. The advantage, however, is that all the analysis and work with Solidity code is done with just one tool, which works independently of the extension. It also makes it easier for us to potentially extend LSP functionality to other development environments, such as Jetbrains Fleet.
How is it different from other extensions (Hardhat in particular), why would anyone use it?
From the very beginning, we knew that there were other extensions with Solidity support. However, we were not satisfied with them: the analysis did not work reliably, often it was necessary to use multiple extensions at the same time, which did not always work well. We wanted to offer functionality that both developers and auditors would appreciate. These include Go to definition, Find all references, but also showing compiler warnings and errors. A big goal was to add bug/vulnerability detectors in the code that would automatically trigger efficiently whenever there was a change in the code. I dare say we have successfully completed the first stage of development.
I think that an extension called Solidity by Nomic Foundation (Hardhat) is a strong competitor. We have a big overlap in functionalities like Go to definition, Find all references or Rename. We’ve noticed that we’ve got some little things refined better. For example, we have slightly more precise labels for the Hover functionality (when the user hovers the cursor over a variable), and it also happened to me a few times that their language server didn’t work for local variables. In terms of the extra functionality we offer, I would definitely like to highlight Document symbols (pictured below), which clearly displays a sort of table of contents, a list of declared objects, for a given file.
Furthermore, we can list the number of references (the use of this declaration) over each declaration and generate a control flow graph for functions, inheritance graphs (linearized and in tree structure) of contracts and over declarations, where it makes sense, we list selectors that are copied to the clipboard by clicking. Generating graphs requires installing one of the supported extensions for rendering Graphviz DOT graphs. We don’t want to impose one particular extension on users 🙂
In general, for me, a great feature of Woke (or Tools for Solidity) is that it works out-of-the-box in common cases. This means that when the project is opened, our extension and Woke are started and the compilation and detectors are already running. Usually no configuration is needed. On the other hand, the Hardhat extension requires a configuration file, without which the extension does not display the compiler outputs (warnings and errors).
Autocompletion is one of the functionalities that we haven’t implemented (yet Hardhat extension did), however it has lots of limitations. I think I know the reasons for those and it’s something we share. Namely, as soon as a user modifies the code, so that it is not compilable (e.g. the user has not yet written the line of code), we lose all the information to analyze. However, we can rely on information from a previous successful compilation that may have taken place some time ago. From the user’s point of view, this would mean that they delete a semicolon or an import directive and lose all LSP functionality. I am aware this would have a big impact on the effectiveness of Solidity developers, so we have included an experimental support for some of the LSP features for files that cannot be currently compiled (but were compiled sometimes before). It is only heuristics and therefore cannot work correctly in 100% cases. Still, it works quite well in our experience and I am proud of it. In my opinion, this is one of the strongest reasons to give our extension a try. I am not aware of any Solidity extension that supports uncompilable source files.
Finally, we realize that our extension can’t do everything and if users are missing some functionality, it’s always possible to try to use multiple extensions at once. Or open a feature request on our Github: here or here.
The Solidity team is also preparing an LSP server. How is the implementation different?
I know about the implementation of the LSP server in the solc compiler. I have to admit that it doesn’t seem like the best idea in the current situation. Their LSP server functionality is tied to the solc compiler version, they can add new functionality with each compiler version, but they can no longer add new functionality to earlier compiler versions. In other words, for a Solidity code that is not designed for the latest compiler version, the compiler will not be able to offer LSP analysis at all or only to a very limited extent. Also, I can’t imagine how the situation will be handled when the source files have to be compiled using multiple versions of the compiler in one project. In addition, their progress in implementing an LSP server seems rather slow to me. I would honestly like to see a stabler, faster compiler with fewer bugs and, in return, better support for the tools that build on its output.
For instance, when developing Woke, we had to write our own documentation for the AST (abstract syntax tree) model that is the output of the compiler 🙂 By the way, it is currently available here under the IR model tab, but in the future this documentation will be integrated into the main development branch (i.e. it will be here).
What are the next steps for these tools? For which users are they intended?
We have big plans for both tools (Tools for Solidity and Woke), which became possible thanks to a grant we received from Coinbase.
We are currently implementing our own testing framework in Woke, which allows us to efficiently write tests for Solidity contracts in Python. By generating type information of Solidity objects (contracts, structor, enums, etc.) into Python, we are able to offer autocompletion when writing tests, so the auditor/developer doesn’t even need to look at the Solidity source files. Speed of transaction execution is also a priority. We currently offer a property-based fuzzer that builds on the Brownie testing framework, but we are not satisfied with its performance. This was also one of the reasons why we decided to develop our own testing framework: we wanted to fix the bugs we saw in Brownie. As far as the performance of our testing framework is concerned, I can reveal that the results are very promising. This is mainly due to the fact that we use anvil as our EVM backend (development chain).
We are also planning to add more detectors to Woke and to extend our extension (or LSP functionality) based on feedback and our own needs. In general, I see extension as a great way to offer Woke’s functionalities to a wider group of users through a friendlier (i.e. non-terminal) environment. This is also related to the target groups of the tools: Woke should be designed more for security analysts, auditors. On the other hand, Solidity developers might appreciate our extension more. However, I personally prefer a combination of both tools.