Michal Převrátil, Jan Kalivoda:Enhancing IDEs with RealTime Static Analysis for Solidity Development
EthereumZuri.ch 2024 · April 2024 · 1:26:52
Michal Převrátil and Jan Kalivoda run a workshop on enhancing editors compatible with the Language Server Protocol through real-time static analysis of Solidity code. At EthereumZuri.ch 2024, they show how custom text and visual decorations driven by simple Python scripts can highlight code segments and surface critical analysis results, and explain the basics of Solidity abstract syntax trees for auditors, reviewers and developers.
Speakers
Topics
From EthereumZuri.ch 2024, hosted by EthereumZuri.ch.
Transcript
thank you very much so thank you for joining me in this Workshop I won't even dare to read all like the title it's super huge and like super long so I will just skip oops I'll just skip uh to my introduction my name is Mel I'm the lead developer of security tooling for ethereum at e blockchain I'm also an auditor and we are an auditing company but we are also developing open source tools and wake is one of them we'll be using wake today we'll be using tools for solidity which uses wake in the background and we are also onboarding new students to ethereum and to Solana through school of ethereum and school of salana we work with many well-known projects like for example wi Lio safe
AAR and we've received a grant from coinbase that actually started the W development now just in case you wanted to download my presentation and follow the presentation you can just open this link in the meantime how many of you are developers okay cool amazing so we've got some newcomers so few developers maybe
somehow and how many of you know python or at least saw python good it's that's very good amazing all right so I guess I can continue but before the coding we will need to like uh do some preparations so I will need to make sure you understand what will be going on here so but first of all let's talk about wake I don't know if you've been to my previous talk but just in case you weren't I will quickly introduce wake it's a testing framework so anyone can write unit test using python interact with contract test some invariance on the contract so I think this is pretty useful there's also
the fuzzing engine so anyone can Generate random data they can Generate random sequences of transactions and then they can execute those transactions and observe how the contract behaves and maybe find some bugs because because of the uh uh random generation generating there's also uh a possibility of creating integration test so it's possible to Fork the main net or the test net with predeployment testing after fuzzing or maybe unit testing it's also a static analysis framework anyone can create their own
detectors that should to detect some issues in the code and maybe code quality issues too and there are also printers and I think that not many of you are familiar with parters because it's somehow special to work maybe but it's very the same as detectors in a way that it analyzes the code but it doesn't show some issues in the code but it's used for data extraction so anyone can extract useful information from the solity code using printers it's also about static analysis and there the language server so when someone wants to write something in solidity they will need an extension for vs code because vs code itself doesn't support solidity and there are quite few some like extensions
for vs code and tool for solity is one of them and tools for solidity actually uses wake in the background so wake is a back end for tools for solidity and yeah so that's pretty much it but we'll be focusing today on the static analysis part we'll be creating maybe I may show you some detectors if you want to but we'll be focusing mainly on the printers today so wake as a static analysis framework first of all I need you to understand what abstract syntax stes are and it's a compilation artifact so whenever you compile the solity code you
can get the bite code that you can deploy that's quite obvious I would say but there are some more interesting uh artifacts from the compilation and obstruction T Series are one of them and they are pretty useful they are like it's it's the most important artifact from compilation for static analysis there's a relation that every single file has exactly one abstruct syntax three so uh when there are 20 files like 20 solity files there will be 20 threes in in the compilation output those trees are composed of edges and nodes and those nodes have IDs each node in the tree has an ID which is a number
there's the type like every node has a kind I will talk about that more later and there are some extra data in each of the notes and there's the mapping so each note in the tree can be mapped to to the original source code so it's possible to say like uh what the node in the three defines in in the solid code or how it is related so there are 56 different solidity ASD noes like ASD is is the abbrevation for obstru index 3es so there are 56 different nodes these can be divided into declarations so there's contract definition node which defines
like a contract there's function definition node which just uh somehow uh shows information about the function there's variable declaration that just defines a variable there are expressions Expressions often have like should have value so you can ask what the value is of that expression there are many Expressions an example is a binary operation I think I can actually show you I will give it a try yeah it looks very good so so let's say that we have some code for example u x is a variable
declaration it declares a variable that's simple it is then we may have something like that when I hope you can read it it's u x which may be ah ah I and if I showed you the same on this one would it be better oh I'm not sure if I can do that but I can try definitely yeah it's pretty dark I
see if we just can turn off this thing I I think it would be or just turn on the light so for now I can write that on my laptop and then we can continue with the board maybe oh [Laughter] I'm not really sure I'm not really sure
it's better thank you so much thank you so much amazing so this is a variable declaration it declares a variable this I will finish it so let's say it's 7 + 3 this is a variable declaration statement because it must be like it it may be a variable declaration and at the same time it may be variable declaration statement I don't want to confuse you but what's what I wanted to say here is that 7 + 3 is a binary operation it's uh I think it's quite obvious there's the
plus there's the left side side like the left expression the right expression so it's a binary operation and it has value as I said Expressions have values and it's got a value which is 10 it's 10 in U there are more examples of expressions like a function call I can also show you so a function call may be a a call to a function like f it can take some parameters X but it doesn't need to be only a function call it can be a typ cast it can be payable payable message do sender so it may be a typ cast
too all right but in general there's the name of the function which is called and there maybe parameters and brackets that will always always be the brackets and member access ah I've got the member access example already on the board which is message. sender it's an access to like this is the member and it's a member of message so this whole code is a member access because it accesses uh a member of something through a DOT through a DOT operator there may be some meta uh nodes that don't belong in any other categor
so they are just it can be like anything like helper nodes for example Source unit which is the root of of the tree so each tree will have the root which is the source unit note and there are some more examples you've got statements and the basic structure usually is that uh there's the source unit as I promised Source unit which is the root of the three now typically there are some metal like like Imports and things like that then there's the contract contract
definition so we have some declarations behind like below the source unit a contract definition may have a function definition as a child so this is somehow meta this is this is like the root these are definitions or declarations it's a definition of contract definition of a function and then the body of the function is a statement it's a block it's a block of statements it contains more statements so now after like this function definition we are in statement ver statement so there may be more statement
St ments and in those statements there will be Expressions so the structure is that there's a s Source unit there are some declarations inside functions and modifiers there are statements and inside statements there may be Expressions so anything that ends with a semicolon is a statement but also a function body these are like the brackets is a is a statement to because it contains another statement and inside statements there may be expressions like in this case that 7 + 3 is an expression so this is somehow basic structure how the STD
works there are also type names and there are only a few nodes that are type names like array type name Elementary type name mapping and there may be like one or two more and the type name is this it's the name of the it's a name of a type so in this case it's U it's a name of a type that simple it is there are 16 Julia estd noes Julia or jewel is an inline assembly uh language so there are additionally 16 more notes like like kinds of notes I won't go too deeply into these because there would be too much I believe so there are some
more some more notes and I'd like to show you uh something for the documentation which is very similar to to to this so I will open the link let's see if yeah and there's described basically the same can you see yeah I think it's very good I will Zoom it in and there's there's an example in solidity and this example I've got a the for this example so it has been compiled and we've generated an EST the using compiler and this is how the EST looks like for that simple it's it's very
simple code there's pragma it's a library ma called MAF and there's a single function that accepts a single parameter some keyword here there's if condition return and there are two more function calls to the same function and the parameters so it's very simple code and the ASD looks like this it's not that complex actually it's it's very easy ASD but it may not look like that I will Zoom it in uh out a bit so you can see the whole tree hopefully yeah this is the whole tree and I think should be somehow quite readable so the root is the source unit as I promised Source unit here Source unit as the root
so the root is always the source unit The Source unit may have problem pragmas like in our example there's pragma solidity and it's represented by pragma directive and by the way I've used the same color for the same kinds of nodes so the green is used for declarations the I don't know it's purple Maybe Pink something between so this is for the meta noes the blue one the blue one is for type names this is the purple okay so this is for expressions and the brown is for statements so we've got a single contract here it's actually not a
contract it's library but it's represented by contract definition node and there's a kind inside that contract definition node that says that the kind is a is a library I can show you I can just click on that so this is the documentation for contract definition note we've got like the documentation for every single note that you may uh like encounter and there are the attributes for each node and there's the kind so we we've got the contract definition Noe there's the kind the kind is contract kind and it may be a contract an interface and a library so a contract definition Noe can actually describe a
contract and interface and also a library let's go back to the three back back back and inside that that Library there's a single function called FIP like a Fibonacci and it's possible as you can see there's a single note of the function definition kind that defines that function there are two parameter lists the first one is for input parameters so the first parameter list describes this parameter list and the second one parameter list describes these parameters actually the written parameters are also parameters they contain they contain variables and those
variables may or may not have names there's the function body so we've got function definition there's the body and the body is a block so this part of the code is a statement and it's a block the block contains more statements and yeah there are statements there's the if statement that if statement note represents this part of the code like this one so this is also single statement that's nested in the block and that single if statement contains the true body and as you can
see there are no brackets like like these ones which means that there's no block inside that if statement but there's directly a return statement so this return is represented by this note that return and then we've got another return this one and this is represented by this return and so on and so on so this is how ASD 3es work uh was it too confusing or do you understand at least a bit what I'm trying to talk about and explaining like the trees is it okay all right me
we won't go too deeply into as unless you want to or will to and we will go through function definitions mostly so we will only go to declarations that are very easy to understand but I wanted to show you how it works like in the background back to the presentation okay and in vake we don't work directly with as but with something called IR intermediate representation which is something built on top on the of the so it's the itself but there are many versions of compiler that contain sometimes bucks it like it just happens like we don't want to see
bugs in in the generat white code that would be like pretty bad but there may be bugs even in in the exported ASD and it happens from time to time that there are some bugs and wake IR fixes that bug so when you're are working with ir you won't experience the buxs that are that were introduced in the compiler output at the same time references are resolved and I think that I might go back to to the documentation of V to explain more oops not like that like this so in this example uh there's the function definition called Fibonacci and we are calling Fibonacci
again and there are like we would probably expect those Fibonacci calls to be a function call know because it's a function call so there should be like two I believe two function calls there's the first one and there's the second one and the function call is composed of an identifier that defines the function that is being called and of arguments we will need to focus now on that expression which defines what function is being called and in our case the expression is an identifier and an identifier is exactly this or this so this part of code describes what function is being called and an
identifier has a has like an attribute or parameter or property which is named reference declaration and In The Raw as it's a number it's a number that points back to any part like like to any part of of of the tree because as I said each single node has an ID a number so that reference declaration is a number that points back to the to the tree somewhere but in case of vake those references are automatically resolved so you don't need to resolve those numbers to to notes it's all resolved which is quite nice I believe all right
presentation amazing so you've got those references resolved and there are some extra attributes that are not in the original as just because we found them quite useful yeah and there's also something that somehow related to the compilation before we generate that as I think that I've got an image here prepared so let's say I will use the presenter let's say that we have a common interface for two contracts like two files there's a contract a contract B in two different files and there's this the third file which contains an interface and those contract contracts inherit from that interface
but there's pragma solidity 084 in the first contract but 0820 in the second contract so it's not possible to compile these three file three files with a single version of the solidity compiler because it needs two different versions of solidity which means two different version versions of the compiler so we will need to comp compile it first like maybe like the blue part so we will compile construct a and interface I and then we will need a different version of the compiler and compiler interface a i and the construct B so we will compile that interface two times and we will have two trees two ASD trees that won't
be the same like they will almost be the same but not exactly and the reason for that is that each STD node has that ID which is a number and those numbers in the first three and the secondary of that interface won't be the same they won so if you just worked when with DD itself you would have problem because you would have two representations of the same interface and the same file it's and it's not really nice to work with something like that but in Wake there's unified model which means that for each file in the project you have just one IR presentation and there's only one presentation of that interface so it's very easy to work with projects
like that that need multiple different versions of the compiler so this is a huge benefit okay now let's talk about printers printers are used for source code extra extraction and they use that IR model or that ASD those can be graphs like interance graph control flow graphs cross reference graphs things like that it's Al it also can be an API for a contract it can be a storage layout it can be some interesting numbers about the Sol uh source code like lines of code number of functions things like that it can be actually anything that
you can extract from that ASD and not even ASD but even from the bite Cod because like when you compile the project you you've got that as and then some extra information not only the s but also the bite code so you can analyze the bite code if you want to and then you can print anything about the bite code like numbers like a number of uses of uh push zero uh instruction it can be really anything there's the language server integration that this Workshop actually it's all about so I'm hoping I will get to to this to just show you how super powerful it is and there's API for custom printers and we'll be doing that today that we will create our own custom printers there's an example of a printer
so we've got a function and this graph can be generated using one of one of those printers I think it may be useful for someone it might not be and at least it's useful for debugging when like you don't usually need that graph like to be seen but you may need to work with that graph uh in your printer or your detector for detecting some issues for example there may be some leaves that don't lead to like the finish that the transaction would succeed so there may be some issues easily detected just from the control flow graph and it's
very useful to be able to print that graph to see if it works correctly and maybe just give you a few examples before you start working on your detector for issues yeah yeah sure like it's a good question I think that
it might be possible to transfer it to different language but we are like heavily bound to the which is produced by the solid compiler so we are like strictly following the solidity compiler and it might be possible but like we tried to use that IR even for Viper and the issue here is that Viper is a different language that uses different synta Tex and some syntactic things don't exist in Viper and some may be different so we are heavily bound to solidity it might be possible to come up with something like more abstract but we are trying to focus mainly on solidity and make it easier for developer to like see exactly like the nodes and how they interact with each other and if we if
we've created something more abstract it would be harder to to work with that model I would say so it might be possible but we are heavily bound to solidity it's built in vake and it's a printer like I'm not absolutely sure like it's it's a module in v in that way it's it's built in but there's a printer that uses that module and it it exports the graph so like the API for generating the control flow graph is built in and there's the printer that uses the module which is actually also built in in vake but you could create your own so it's built built in but at the
same time you can work with it and you can use in your own custom printer operations uh sorry uh what operations did you say bitwise operations and what why should it be a problem don't ask okay yeah I I think I I see your point uh the control flow graph is based based on
statements so we're not going deeper than statements yeah because like uh statement somehow is a single Atomic step that is always or never executed like there's there's the conditional which is like an expression like like if x is greater than zero then we want uh then we want three otherwise we want seven so there are still some conditions inside this is like this is an yeah this is an expression but we don't somehow Branch this in the control for graph unless
unless there's some control for logic inside this yeah that there's no built-in feature that would go deeper than statements in a way that we would like analyze more the Expressions but we've got the ASD or
that IR model and uh it it itself is a is a structure that can be easily explored uh can I remove that from the board somehow can I use this use this one yeah okay okay so let's say that we have some more like a complex expression like x + 7 multiplied by 8 or something else a food call something like that then this is like
the that binary or is like the top expression somehow that's a semicolon let's say so we've got a binary expression that represents that binary R there's the fu call there's that multiplication that multiplication can be divided into that eight and another binary expression which is that plus and that plus is composed of X and seven so even the three itself somehow describes how the expression is computed the tool hole is open source so you can
try it there's the analysis module that that that contains that control flow graph module so feel free to try it amazing okay any more questions by the way no okay now this is an example of a very simple like minimal detector and very very simple printer and maybe as you can see there are not that many differences like it's a very simple code so there are some obviously but fundamentally it's very very similar so detector and the printer are always classes in in Wake in Python so detectors detect from base class which is called detector
printer uh inherit from a base class which is called printer and the major difference is that detectors return some detections like issues in the code and printers can just print anything so we need to collect somehow the detections so there's a list it doesn't need to be a list it's just a template but it can be a set or you can just detect perhaps directly in the detect function but this is the template and there's the list so we need to initialize that list and then the detect function Returns the list of all detections that we have found and there's also the C function I will talk about that bit later so there's the detect function in detectors and that
should that should return a list of our detections while in Printers there's the print function but you don't need to do anything in the print function you can print there will be more functions that you will need to Define and you can print just from those functions but you can be sure that that print function exists and it's the last one called so if you need to collect some information then you can just print the result in that print function and as you can see it doesn't return anything and the reason for that is that you just print you can use print or if you don't want to print you don't need to print you can just export anything you can export the graph as a file you don't need to print it to the terminal that wouldn't make sense or it might but you can just
export any files you want to so it's just up to you so this is the major difference between detectors and printers and that's the only difference otherwise it's very the same is it clear okay I hope I've got the link to the documentation which shows a bit more so yeah this is it's it's the same example that I showed you and now let's talk about that c function I will just go maybe just up as you can considers CLI function it doesn't need to be named this way but what's important is that there's detector that command and there's printer. command and that name
defines the name of the printer or of the detector so yeah and we are using a library for common line interface which is called click and it's really powerful and it can be used like this so it's possible that there's the printer which is named my printer and it's possible to Define custom parameters for those detectors and printers so the printer can accept an argument which can be somehow named it perhaps needs to be a string it's required so anyone who uses that printer has to like specify that modifier and there's the help that is printed to the
to the console to the terminal uh when used d d help there can be also options that may be optional uh there may be a default value if it's a flag or not like it if it accepts an extra parameter like a number or something or just or it's just a flag itself there's also help and this way it's easily possible to parameterize uh a detector or a printer and it's not only from the through the command line but it's also possible to like fetch values for those like arguments and options using environmental variables and and a config file a Thal config file
okay and now this is super important so as you saw there are two classes like a detector and printer and those classes are visitors and visitors means that there are many functions defined in those uh uh in those uh printer and detector classes and these are always called visit and something and that something is that underscored name of a node so as I said there are many types of nodes in D or ir and one of those nodes is function definition which is a declaration it defines a function and there's a visit function uh uh fun is
visit function definition function uh that is automatically called by wake and it gives it gives you uh simp uh a single definition of a function and it's called automatically so let's say that you want to collect all the functions that are present in in the project and you don't need to go through all the files through all the fun all the contracts and then to to to all the functions you can just Define that visit function definition function like override it and you've got those functions right here right now and there are like as I said there's 56 soled note kinds + 16 if I remember correctly so there's 56 + 16 different visit
functions in those detector and pror classes and it's possible to override all of them and collect all the information needed does it make sense is is it clear okay let's hope it is we will see better on examples that we will create okay let's see just continue now back from back from detectors back from printers to language server protocol so what language server protocol is it's it defines a communication between a language server and a language client that perhaps makes sense so it's
a communication protocol or a specification for communication protocol between something called a language server and a language client and it defines a set of features that should be supported in integrated development environments like editors for example vs code so it's possible to control click on something and it does something else it's possible to move uh the the mouse over something and it shows some some boxes with some text and so on so this is defined by the language server protocol yeah as I said go to definition or rename rename so it's possible to rename an identifier in the code and it's rame on all the occurrences that
that are present in the source code there's the LSB specification I won't open it it's not that important and why it matters or why I'm talking about that is there's the extension tools for solidity which is developed by a key blockchain it's open source it's free I will install it actually uh later in the demo yeah it's a vs code extension and it uses most of the LSP features or like it it implements it offers most of the LSP most of the LSP Fe features there's a custom UI with uh code quality and varability detectors or detections and it's a language client so
it's a client in that LSP protocol and there must be a server that serves like all the data all the information and those information come from the ASD or actually from the that IR model and in in this scheme is the language server so whenever someone installs that tools for solid extension in vs code it automatically installs wake which is a python tool so and the extension itself is written in typescript or JavaScript while V is written in Python so the extension automatically installs wake as a language server as as as a python package it launches wake and the and that wake serves as a language server
while the extension itself is a client and now what are LSP or vs code printers I showed you that printers can print anything or generate some files but does it make sense to use it in in LSP or in vs code it's like you can print something but not to the vs or why would you do that or what does it mean yes so LSP printers or vs code printers are a combination of printers and LSP which means that it's possible to extract information from the solidity source code and somehow show them or visualize them in vs code so this is
like combination of these two features that are present in in v and to Source solid tooling there are optional callbacks on click on something I will show you later in animations and there are some commands that can be executed on that click those can be go to locations which just moves the the user to to some locations in the code so it moves in the vs code somehow automatically to some locations there are speak locations which is basically the same but there are like two options from vs code so we just follow that but it's somehow it's very similar or maybe almost the same
that is open URI so it's possible from an LSP printer to open any like any address or any link just using LSP printers there's copy to clipboard which is quite useful I think that it's possible to extract some information from the code and then just copy those information to clipboard and that's pretty much it so we will use three different language server features that are somehow supported by LSP printers because it makes sense to support them the first one is hover and it's just by like moving the mouse over something in the code and in this case the mouse is moved
over an assembly like assembly call or instruction and it shows help for that in this case it's m store and as you can see it shows there's memory start there's X and there's also a command stes word to memory and this is achievable using LSP printers so it's possible to Define text that should be shown whenever someone uses Mouse to move it over some text in the solty smart uh smart contract code so this is the first feature that is supported by LSP printers the second one is cod lens the Cod lens are like these clickable button
buttons they can contain custom text in this case it's number of references but actually all these like all of these are Cod lenss the first one is for references the second one is for generating control for graph so it's possible to like generate control for graph and then show it to to the user and these are the same like the first one is for the name name of the function I believe and the others are for parameters this is why there are like more clickable buttons for references so it's possible to define a custom text and it's also possible to create a c custom callback that should be invoked when clicking on that label it's not necessary it's not necessary to Define
that callback but it's possible and it's possible to trigger some actions and those actions can be I will move back these ones at least for now there will be more coming but in the first release that we have released actually yesterday these are the actions that can be invoked and in that example uh it showed some locations in the code and it was perhaps that Peak locations command again it moves Mouse here it clicks and these are some some locations in the code it it can be clicked on over those locations and it's just the peak locations command and it's done automatically in vs code and the last one is it's called
inlay hints I'm not sure why it's called like that but it is what it is and what's that it's very similar to codeland I don't have an animation here because it didn't make it didn't make sense but it's basically an in uh inline text so it's this like yeah that colum and that address or the contract order something that's un 32 uh un 256 and this is just a simple example that shows like the type of a parameter in a function called uh it's also possible to to define a call back whenever someone clicks on that label and it's also possible to create like parts of that label so there
can be many parts like followed like yeah in a single line followed one by each other and not all of them need to have the call back defined so only some of them may have the call back defined others may not and this is the last feature that is supported using in LSP printers and yeah that's pretty it so I think we can finally move to the coding session so how many of you want to follow me oh okay okay I will be super slow to make sure that everyone understands what's going on and I don't want to like lose you so do you have vs code
installed amazing this is the first step if you don't have then if you could please install vs code which is an editor that where you can edit any source code basically now all right so anyone else trying to install vs code still okay I think that I can continue by the way are there any questions yeah yeah first of all uh bake generally
supports solidity in versions 062 and greater so it's not support it doesn't support like super old versions and the reason for that is that the ASD uh wasn't like it contained too many bugs that it wasn't possible to fix it actually so yeah so the minim minimal version supported is 062 and regarding some changes each time there's a change in the source code it has to be recompiled unfortunately because there's the mapping between the As and between the source code so it needs to be recompiled again and again after each change we don't have like G Jon schema
form formalization we have we we using as and we don't have like Json for that but we have an API reference it's on the like on the in the v documentation but if you want to get to V documentation it's best to visit uh get W.O I have the presentation it's get wake. I can show you get wake. this is like the landing page for Wake there's the latest version there's the link to the extension and there's the link to the documentation there should be an API
reference section it this here and there's v. IR section and declarations Expressions as I as I said those are divided into like common like uh groups and let's see declarations let's see function definition and there's the documentation for like every single note that may be present in the ASD and as I it's it's the documentation for IR but IR is heavily based on D and it's like 99% the same as for D
experiment I haven't actually it's absolutely interesting at the same time honestly I'm not very happy about that DST like will be changed like a lot because we will need to update our model and it was quite a lot of work quite a lot lot of
understanding quite a lot of examples but if I believe it needs to be done it needs to be formalized and we will need to update our model or like keep two models like the old one the new one and I think it makes sense it's just more work for us comes in because can yeah yeah what I'm doing right now when there's new version of solity I just look to to the comet lock like all the comits that were done in that version and then check out like the changes in in in the C code and trying to to to find all the changes that happened to the ASD and it works but it's not the best experience like yeah actually some
differ um we are just building above the as so we we yeah perhaps yeah I think I think so we we just don't do like what's like we don't interpret solidity we don't have solid interpret we are just working on the EST thank you very much any other questions I guess no so all right let's go back to vs code we should have we we spend one hour so there's still a half of an hour left for us uh now if you could please install the extension
for V which is called tools for solidity yeah it's got that beautiful logo it should be that simple but I want to make sure that you you are it's even possible to install it because there there may be some issues just because there's the python tool which is behind that extension and so on it's it's complicated so I will wait a few more seconds by the way the extension is quite nice I believe it does the compilation automatically it provides all those interesting features that uh solidity developer developers need and it's heavily based on the ASD on that IR
model and so it can quite easily resolve all the references across the code base and it can show all all those locations of references it can also generate control graphs it can generate inter inheritance graphs and it shows findings from State canalysis detectors automatically in the code and there's a custom UI for detections I won't have any here because I have an empty project but yeah there's a custom UI and it's PR like for compil warnings errors and there's the second section which is just for vague detections like code quality and vulner vulnerability detections so uh any issues with installation of the
extension sorry uh uh uh I see yeah do you have a question sorry it's only for solidity just for solidity yeah it's it's a good question it's a good good question and I will create just an empty solidity contract to have some solidity code here I'll C the demo that's all I will create a contract demo okay that should be enough and yeah it already triggered the
extension and there are some warnings that come from the compiler like there's the missing license there's the missing pragma for for like the the file and I will wait a bit more I can show you in the meantime that UI so there's the UI and there are no detections because there is nothing much like there's nothing to detect it's just an empty contract but there are warnings and I was thinking maybe if I can make it abstract there's a detection and the
detection says that there's abstruct contract which is not used and the reason is quite simple because abstruct contracts cannot be deployed they are abstruct and there's none cont there's no contract that would inherit from that demo contract so it's useless in in our case it's a it's just an informational detection but it can be useful when managing a like really large code base code base so it it would show that there are some contract that can be just deleted because they are useless or at least not used for now so how's the installation going is it good okay and now so I will just remove that abstract
no yeah and it got automatically recompiled the detection just disappeared and yeah so the extension gets activated every time there's solid code in in the open folder or directory and you would see that by looking into there view I can zoom it oh it should be quite visible I think there's view there's possible to click on that output there is that output window and it can be switched between like many extensions and there's tools for solidity and it shows that it launched Wake On the background it launched the we Lake Wake language server with some
port and there's the version of EG which was actually released yesterday and in case there would be an issue it would be printed right into this output window there may be issues so if there are any please just report them so we can fix them we are really trying our best to fix all the issues but there may be some and it's super helpful it's when someone reports those issues all right so I guess I can continue ah there's a question sorry I couldn't hear you yeah while
writing uh there are automatically triggered compiling SE sessions I would say and you can Define how much time you want to wait before the compilation regress so you are typing then you may stop typing for like two seconds and then the compilation triggers or it can just trigger after like milliseconds after stopping typing so it's it runs in the background it can run more or less frequently based on your on your your settings but by default there's like zero delays so it compiles yeah it keeps compiling and it keeps showing results and when you start typing it just starts compiling again and again so it's kind
of life based on how the project big is yeah yeah like the compilation is then like slower slower and the user experience is not that good but it's given by the fact that the compiler needs to recompile again again but what we are doing is is that we split like the code base into the small smallest possible like parts of the project that can can be compiled independently as and as I showed you if you remember that uh picture with like that interface and do contract it's possible to merge like multiple compilations into a single model so we are trying to minimize
compilations in a way that we split the project in into smallest possible sections and those sections can be like matched together thanks to the IR model so we are trying not to compile too much we just compile what is needed to be compiled so anytime some when you type something then we start the compilation or we may we might wait and then start compilation and we will
compile only those files that were modified and like base files in terms of imports so each like uh uh each file that Imports that file that was modified has to be recompiled also so it's we are compiling only what what's really needed to be compiled some other questions no okay okay so we will start with a very simple printer and we won't be using LSP features at least for now we'll just start with the common line printer and there are actually more options but let's use the like the simplest one
there should be a shortcut to launch like the commands panel in vs code in my case it's F1 on the keyboard but it may be different uh on your system I will try to find the command which is right here it should be let's let's see what it how it's called view command P yeah so it's right here under view the first button and when you click on that there are many commands that can be executed and the one we are looking for is called new printer and there are two commands that
match that string the first one is that one that we need because it creates a local printer which is somehow bound or created in the local directory that we have just opened so it's a printer specific for that project or for that uh directory that we have opened so this is the specific one and there's the second option new Global printer which just creates a global printer that will that will be available in each project that you open later in vs code okay so I will create new simple printer I will give it a name my DH printer it's not that important what the name
is enter and there's like log message there's also one more log message that it says that it created a new printer which is called my printer and it created the printer in this path and it automatically opened a template for a printer and as I promised that the the template should be the same as what I showed you previously except for those Imports that are somehow needed because it's python but the template is the same as you as you saw so it's a class I can I think it should be quite fine but I will Zoom it in like a bit so it's a class it inherits from printer there's the print function
there's the CLI which we won't need and so I have some solid code here there a contract called called demo and I will Define a visit function if visit uh contract definition I will remove that line and what we want to do is like we can print anything about the cont actually that simple it is you can just print note. name save that so are we all good or should I wait for
someone I will wait a few seconds so this is very simple structure of a of a printer and yeah there's our first visit function that can be used to collect some useful information and in this case we are collecting information information from contract from contract definition node and these visit functions are invoked automatically you don't need to do anything the project gets automatically compiled and uh that visit function gets automatically invoked or called and it can be invoked many times based on how many constructs you have in your project so if you have five constructs the function will be invoked five times and you shouldn't
rely on on the order of those function invocations you just shouldn't uh like rely on the order of visit functions visit function uh invocations in general so I think that I can continue now I will open my [Music] terminal and what I want to do is I want to run V print and the name was my printer I believe leave my printer it needs to compile the project I said it has to compile uh we are caching the compilation artifact and like there are two different compilation
engines the one which is used in the extension which is like language s compilation engine and the second one which is meant for the command line so there are two different like completion uh engines but it's not that important as a user you just type something in uh in the terminal and it works when when you use the extension it also works but differently inside and it compiled the project it generated that IR model and it printed what he wanted to print which was the name of a contract so this output is related to that print function
call make sense all good it's super easy just the introduction was quite complicated because the things behind are complicated but I'm trying to show it to show just like how simple it is and in the end we've tried to design the interface so it's very easy to to use our tooling but these are just just like normal printers these are not language server printers so I think that we can move on to language server printers because this is why V are are here actually yeah any shoes or not getting any and do you have uh do you have a solid smart contract any like
any in the project ah how's that possible uh so H there needs to be defined the visit function ah y will help you hopefully good amazing thank you amazing yeah typical issue I I always
had that one too because like yeah the command line tool cannot see what's what's what's not safe on the dis yeah amazing uh by the way there are also shell completions so it should be possible to wake and then top to fill in the remaining like commands and it should be possible to my like my and then click or t uh top and it should just fill in the name of the printer but it won't run automatically it's needed uh to change uh the shell config file I can show you in the W documentation as I said you can get there through the web
page get w. there's the documentation link now there's the installation [Music] section and in the installation section there are like uh instructions how to install wag using pip you don't need to do that because it was installed automat automatically with the extension There's the link to the extension there's doer image action uh get up actions and there's shell completion sections yeah sections that show how you can enable those shell completions so if you want those shell completions as well just needed to follow these
instructions yeah not exactly like the name of the printer it's not based on the name of the file like the template like the template does that way but the name of the printer is based on that command name because as I said we are using the click interface like library for command line interactions and it uses this name okay by the way uh those detected printers and even detectors are detected based on the structure there needs to be the printers directory which was created
automatically for you maybe you haven't not even noticed and what's important there's that init file in Python and it's needed to import some it doesn't need to be the printer actually but it can be an EIC but it's needed to import the file that contains contains the printer so we can detect that the printer should be imported and somehow used so this is this was created automatically but the printer the printers are somehow detected based on those Imports in that init file in the printer directory now that would be that now we can move to language server printers I
believe I will close that one I I won't need it because language server printers won't interact with the terminal so I will just close it and we need to change the execution mode to LSP and the reason for that is that we don't want to uh run the printer on the command line but instead we want to run it automatically in uh in uh the vs code so this is the first step let's check if it works or not we won't see those prints because those prints are somehow printed to Virtual console which is not visible because
it's in language server now and we won't see that print but what we can use and hope I I just hope it works is we can use self. logger do something maybe info and hello hello and then save that and it didn't do anything that's sad I'm sad maybe let's just change the level like critical it do nothing ah finally so I needed to change the level because
probably info uh it's not reported by default so this way you can check that the printer was loaded in the language server and it it it's used in the language server so there's the logger and that log can be used to log some helpful debugging messages to that output window as you can see that output window is used for everything like for logging issues in the Lang language server compiler also for logging like that we have created a new printer but also for logging for every every single detector and printer used in the language server okay
now since we know that our language s printer works we can continue with some interesting stuff more interesting stuff I will leave here the print function actually it needs to exist here but it can be just empty so I will remove that line I'll pass and then we've got self. LSP provider and we can use some functions on that LSP provider let's use add Cod lens there's the note that should be bound to that codeland uh if you don't remember Cod Lance is a link that is clickable above something for example above a
contract definition like a name of a contract so we will bind our codeland to note and we are in visit contract definition function so we are binding our Cod to contract definition Noe and in this case it should show that clickable button or just the text above a contract our contract are there any other parameters there's the title that that's not optional we need to define a title by the way I highly recommend when you're writing something in Python to have python extension installed in vs code uh there's just if you type
[Music] python there's python extension I highly recommend using that one because it's super helpful when writing something in Python it can be anything and then you've got the extension installed there's the Bottom bar there's python there are some brackets and there's type checking off and we don't want it turned off you want to turn it on like this and now it should say that we are missing that title well so what can be the title for for that it can be anything but let's let's use node do name which is the name of
the contract there's still some un like red underlined code and the reason for that is that LSP Ser Ser uh LSP provider is optional it can be none and it will be none in that case that execution mode is not LSP which means that the printer is not intended for language Serv but for the command line but we know that the LSP provider won't be n it won't be unset so if we want just to remove that warning or error we can just Asser that self. LSP provider is not none but it's not necessary it it it it will work even without this line let's just save that and what I think is
pretty nice and again I I hope it will work is that when you save your language server printer it's automatically reloaded by the language server you don't need to restart vs code you don't need to do anything you just control like save your file like that and let's see let's see our yeah and it's here so we've got our contract these are like built in codeland from vake but the left one the most left one is from our printer and as you remember if you remember the title was set to note name note is the representation of our contract. name
should be the name of the contract which is demo and the title in the Cod Lance is demo so it worked correct so this is an example of codeland now let's define some functions in the contract to show you uh commands that can be executed on clicking on on the label I will create like two dummy functions that won't do anything function f public empty function bar public empty like that and it got automatically recompiled and and new labels appeared so as I
promised everything is done automatically like the compilation and everything and let's just create a call back or should should I wait for someone we've still got some time so it's not a problem yeah I will wait for you don't don't worry so do you want me to go back to the python code or do you have any issues oh okay okay so back to our python so I've defined two empty functions it's not that important how they are named we just need some functions so we can interact with them so back to my printer now there's the Cod lens and there's
optional on click we will Define a new method let's define like underscore on click cell because it's a function inside uh inside a class and let's just pass for now and and the function expects the name on click so let's say that on click is self doore on a click now we have defined a call back and we should see it right now because it got automatically reloaded as I promised and the difference should be
that yeah as you can see it changes the color once I once I move my mouse above the label it won't do anything because the call back is empty but still the difference is that you can click on it now and hope that it won't crash uh the language server which it didn't so it's good it does not do anything but it doesn't it didn't like completely crash our tool which is also good now let's define a call back move let's move back to our python code and VI we will use uh that LSP provider again so self LSP provider and we will use add
commands because we want to execute some commands after after the click and for that we will need to import some commands that we can execute that import is not very nice at least for now as I said it was released yesterday so we might choose better names but for now it's from fake. core. LSP provider import let's import that go to locations command go to locations command nice uh that as commands function call expect list it's possible to invoke more
more than one command on clicking on the label but we will need only one but still we need to use a list so let's just use these square brackets and in that list we want to create a new go to locations command but we will use a helper function for creating new instance so we will use go to locations command Dot from noes and what we need to do we need to Define where our like focus in vs code will start when we click on that and we want to start from that contract because we
have clicked on a label that's above a contract so our start will be on that contract I can show you how it will behave if we change it to something else but for now we'll just use that contract but the issue here now is that we have lost the context we know that we've defined the call back here but but we don't we don't know what we what we were clicking on when executing that that uh that uh call back function because there's onclick but we don't have that note anymore but we can we can just pass it to the function there are two options I'm not sure which one is easier to understand but I think that you can use
partial for example so from I think it's it's Funk function tools import partial yeah the cile exactly knows what I need and using that paral I can actually REM uh close that window it's not important for us now we can say that on click is a partial from that onclick method I will just close the brackets and we need to accept that node that node which is of that kind IR do contract definition and we we need to
pass that note from here to this function we can do that by just adding adding that node as a parameter so what has changed now is that we still need to Define that callback but we need to pass extra data to that callback from our current function and it can be done in this way now that we have that function uh like the not the function but the contract definition node we can use it in the call back so back to our from nodes uh function call there's the start the start where we want to have
the focus and vs code so we will start on that note which should be the contract note now this is important locations locations that we want to show when someone clicks on that label and let's say that we want to show the locations of functions that are inside the contract and so we need to create those like fetch those locations or find those locations in the IR model and it's very easy actually so it expects and itable it can be list it can be tle but it let's say it's list but basically we can use note do functions and what's that it's a to
which is almost the same as a list and it's it's a list of functions it expects something else expects multiple and it it can be Peak or go to it's not as important now let's just use Peak for now you can just save that it should be reloaded automatically and when we click on that and and actually it changed the name or something like that or there may be an issue in the code let's just see the output now
so maybe let's just restart vs code to see where the problem is yeah it's back I'm not sure why it disappeared but it's back that's good and when we click on the demo it shows locations of functions that are inside the contract definition so what happened here is that we have defined codeland like a clickable button with some title and it's possible to click on that there's the Callback defined on click and when someone clicks on that label
this part of the code executes and it it adds like defines new commands that should be executed and there's only one which just says that we want to move those some locations in the code and those locations are functions that are defined inside that contract and as you can see it's it just works so this is what LSP printers are all about and I think that's pretty much it so thank you for following me any like last questions yeah uh yeah it's a helper function uh from from python I can replace it actually I can replace it with Lambda if
it help I'm not sure if this will help but let me try so I will remove that line I will comment out this one let's use Lambda Lambda function this which is like temporal function created right here right now it doesn't have a name it's just Anonymous function and we can use sound unclick and here we can just invoke that on click function and it should it it it's the same as the previous one but partial is somehow a help helper function from python while this is a different approach that does the same thing and I hope that it will also work same ah ah I ah I see it
didn't disappear it just moved uh its location it was the first and now it's the second so the reason for that is we have too many like labels defined for that contract and uh because of that recompilation and things like that it moved it's location but it should be still possible to use it and it works the same so this is a different approach for calling a function with like custom data passed Now using a Lambda function any other questions I don't think so okay so thank you and see you later [Applause]