EVM | Pawel Bylica | Lecture 17
Ethereum Protocol Fellowship·Thu, Oct 9, 2025, 12:00 AM
https://epf.wiki/#/eps/day17
Transcript
cool um so yeah uh thank you so much all of you for coming we have more than 40 listeners and we have pav here so thank you so much for making the time and joining us today uh we really appreciate it um it's an important part of the study group today after the few weeks of introduction this week we are starting the actual Deep dive of live sessions into different parts of execution and consensus layer so today we are diving into the heart of the execution layer to the evm itself um and we have the one of the best experts to discuss this uh Pavel who is part of the ipsilon team of ethereum foundation the team that is working on the evm itself doing the research and development um shaping the future of the uh of the execution environment in ethereum so uh one of the leading researchers on the topic but also author of evm one a performant uh uh implementation in C++ which like I mean if you implement uh uh evm in C++ like you might must be the expert like that's just so is the is the right person to uh to give us a deep dive here yeah and uh yeah thanks again for being here and the stage is yours okay thank you for introduction uh I'll try my best so yeah how as as Mario mentioned I mostly work on evm at ethereum Foundation it has been around 10 years already that I've been doing this and uh and yeah one of the projects I I work on but it's not only me that's a bigger team the team at ethereum Foundation that works on evm Research is called ipsilon and we maintain one of the implementations in which is in C++ called evm one we also do some like API design for evm Integrations and previously we were even working on um a product called ewm which was I think the idea to bring web assembly to ethereum as the like kind of second execution engine uh but it didn't actually happen in the end I also um um work with Aron Aron Technologies so the company that is behind the Aron client and I help mostly with evm integration there so they experimenting with evm one as the as the uh evm implementation and I'm just helping to make the integration rather smooth um yeah that's about me and uh I'll try to do um explaining if there's anything to answer to okay um yes um so yeah I'll try to explain some like say from high level overview of ethereum virtual machine to uh with' going a bit into more details in some aspects um so we start with uh explaining actually where this execution happens know exactly how it happens but like why it's there and then we'll go from some overview of virtual machines in general to specifics of ethereum virtual machine and in the end I'll try to um kind of focus on some unique features that evm has comparing to some other uh like virtual machines and finally I want to mention um something that is potentially the kind of evolution of evm which is evm object format um so um I I thought that's maybe it's kind of to better glue evm as the component of ethereum is to kind of explain what is executed and where where it actually is and how it happened that some execution happens on blockchain and so I think that two main concept that are interesting here and important which is transactions and state um and I think researchers and some developers like to think uh about execution and in general evolution of blockchain as a some kind of transition function so mostly uh there's some like state of whatever the the ethereum blockchain represents and there's a way to modify the state so mostly we take State as a mathematical object and apply some modifications to it and we get like another state which it's kind of the the same class of objects but is it has different internals and this this transition happens by um mostly collecting transactions uh and combining them into blocks uh I kind of like to think that blocks are just kind of implementation detail why it happens it's related more or less to consensus than the ex actual execution but this unit of of execution that actually in initialize the any execution on blockchain modification the state is a transaction and uh so it's kind of allows you to uh modify what is recorded in a blockchain um and this eum state seems kind of mysterious and seems complicated but but from at least From evm perspective it's actually pretty simple thing uh maybe it's not a small one but it's in the structure it's actually not very complicated to understand once's there so the state of ethereum it's how evm sees it it's it's just a collection of accounts and uh this collection means this some mapping so we the account have addresses which I uniquely identify them so at the first level we have some kind of map that uh assigns accounts to addresses and the account itself is also not a very complicated object um um it's just uh like four items first one is the kind of specialized to ethereum blockchain which is the like amount of E the account hold um so it's specialized in the sense that this makes this um if uh cryptocurrency something unique that um it's kind of the it's kind of the the currency of of this specific blockchain um then we have some number that is called NS and it has actually more than one purpose uh but it's kind of like detail of some aspects which I don't think is super important and finally the account may have code and this is exactly where the evm comes in uh so this code can be interpreted by by evm and finally um this additional storage that account can have uh which is another map from from keys to values um if you what is the the best kind of analog I think browsers have something it's kind of like key value key value database with uh quite heavy restriction so the keys are up to 32 bytes and values are also 32 bytes um so it's not like very generic and sometimes you need to um really hardly pug stuff into it but um yeah I think browsers and JavaScript have something like index DP I think it's kind of similar so it's kind of simple simple um data structure that um the code can access and that's that's mostly it what how how evm actually sees the state of aerum is all this accounts um there is kind of the like second dimension here which is related to Commitment so we need this state is also organized in a hash tree that allows you to kind of summarize what's in the state in the single has and also prove some that some values are in the state but this is actually not what evm cares about this is related to um mostly the the higher level um so we can skip this part and there's one more aspect that is I think interesting to to the state that there kind of of two kinds of accounts um one is called EA which is stands for externally owned account and these are the accounts that people control mostly uh so there's always some private key assigned to it and the address is derivation of the public key and whoever has a uh the private key of of such address is able to initi initialize a transaction to the blockchain um and such accounts don't actually have code and don't actually have storage uh so it's only the amount of e you have it on and the noun is actually related to the to this cryptographic private key and later signature um but I I want to go into detail why um and finally the the other type of accounts are contracts which actually have a code and can access its own storage it also uses the the balance so the the this contracts the the the programs on the blockchain can also uh manipulate the the the balance of he by themselves and this noun number is also used for something but um it's also kind of a detail um but as important aspect of that is that the contracts actually passive so there's no way the contract can initial initiate a a transaction so it's always this externally owned account that have to do it uh otherwise nothing will happen Okay so because that was the first section I kind of Waring up um I wonder if there's any any questions far hi um it's a bit slightly out of the a bit out of context but IID like to understand if later if we have time to actually um dive maybe directly into the G sorry the the Aron's code and then uh just uh run through what we actually learned today and maybe highlight uh how Aron I know there's there has been like articles online that how Aron actually differentiates itself in managing the state so maybe those highlights in the code will actually be quite nice um I'm not sure I'm actually good person to do that um so I quickly explain is that Aron is it's mostly written in go and there's some some pieces that are written in C++ and I mostly work on like this C++ evm so I think it would be kind of probably much in precise to to describe the architecture of Fon uh from my point of view I'm not really very into deep about details uh but maybe that's interest a few uh maybe you can ask some people from the the team actually to to give some overview later nice thank you thank you very much okay thank you thanks okay um so now quick overview of future machines I think there are two actually conflicting terms under the virtual machine what is one is this all this like cloud and stuff which this is exactly what we don't care about about so much so what we mean by virtual machine in this context is I think it's sometimes called process or application virtual machine and if you're familiar with anything like Java net C web assembly as well these are all like different kind of process virtual machines um and this concept this is kind of like computer science evolution of of programming languages mostly and like classic programming languages just Target uh well they have compilers and they target different hardware and different architectures so in in some sense if you have different programming languages um and and multiple Hardware you would like to this programming language to be able to run on you need to kind of implement this Hardware Buck end for for each compiler and uh as we kind of it people notice this a way to add more one more layer to this thing and then you can create some intermediate representation and there like different levels of how this can be done but uh I think Java was kind of the maybe the most popular product that actually emphasized this that you can you can just have some intermediate layer that will handle the we kind of abstract the hardware of the compiler so instead of T getting multiple Hardwares but multiple compilers all of them can Target single single machine that is have some virtual set of instructions that's not exactly what runs on the hardware but how to actually execute this virtual machine on the hardware is the the virtual machine job to solve not the compiler job and classically that's what what usually people describe first when they try to uh say something about specific virtual Machin is if it's stack based and if it's register based um these are kind of like basic concepts how you can organize your your viral machine and all of them have kind of infinite resources it's just the resources are organized into a different structures so um a stack based virtual machine just have a stack which is wow it's a memory when you can only manipulate like the top items and it kind of has infinite number of items you can store but you cannot really access most of them all the time the register based virtual machine have some numbered fixed numbered values that you can manipulate values of um mostly um the the the stock based virtual machines a bit easier to implement and to work with uh it's mostly because the encoding of instruction usually fits into single bite and that's where the bite code term comes from so it's it's this intermediate uh language that virtual machine can execute on which which has and instructions encoded like a single bite for register based uh vi2 machines you mostly need to include what which which are the input registers and when the result in which register the result will end up um it's also not specific to the the technology to the like set of languages for example there's multiple Java virtual machine implementations and some of them are stock based some of them are actually register based so I think this notru which like if if a language actually has like single version of it um for evm we also in the also in the stock based category um I click quick overview how how does it work so for a stack based virtual machine if you have add instruction it usually means that it takes two top items from the stock and this SP marks the like the top of the stack uh it adds the values and then put single value on the stack back so in this case 20 + 7 gives you the top item of the stack of 27 um in case of register example and in this picture uh the instruction has to include which registers are in the input in this case R1 and R2 and the and the result will go to the R3 register um okay so that was quick intro to the virtual machines Concept in general but now let's let's take look on how ethereum version of that works um so as I mentioned it's also stock based and it uses bite code so every instruction it's one bite more or less that's it's you can there are some some aspects of that which kind of differs uh but at least the op code that it codes what's going on is it's a single bite and the the evm has significantly big stack item so it's it's more than the native Hardware actually supports so there's some kind of level of emulation of of arithmetic there's no any validation so whatever the bite code is provided to it it will do some execution of it potentially returning some errors but uh it's yeah in some sense it will produce deterministic results on any sequence of bites it sees um it has also multiple different kind of memories inside and try to explain later and some exotic features and they kind of original goals from evm design from from 10 years ago with s Simplicity total determinism uh compact uh code size and some specialization to to blockchain execution needs um so this mostly this specialization actually is a reason for having this bigger than native uh values inside evm so it uses uh 256 bit values so that's more less four times the size of the Native Hardware supported uh so we need to emulate that in software um and this I think one of the reasons that it came out this way is that um blockchains heavily rely on secure hash functions and the hash functions usually uh have 256 bits of the of the output there some variations but that was the most common at the time so using this bigger values in evm kind of makes the output of the harsh function also natural it's a value that is actually naturally represented inside evm and that was M of the kind of inputs to design that um make it this way okay so now um how how it actually operates so most of the implementations of VM if not all of them publicly known are actually interpreters um so there's some kind of loop that goes over every instruction and tries to execute what what's encoded in the instruction um uh but there's a bit more to that and I think that's usually overlooked on the first side that evm actually do does a bit more than people can imagine uh in terms of execution efficiency um what I mean by that is that there's small steps more kind of work the evm has to do before actually does something what the program wants to do um so it has to fetch the instruction for sure that's that's that's basic but because the bite code can be anything it also has to check if the next instruction even exists so that's another thing that the naive VM implementation has to take count of and because there's no validation step in evm it also has some do some some pre-checks as meaning that the the currently fetched in instraction may cause some failures in the execution for example there might be not enough items on the stack to to operate on or or the result of the instruction can overflow the limit of the of this of the evm stock so all this check has to be done before execution and there is one more thing which is related to the gas cost so gas is kind of one of the unique features of evm and I will go back back to it a bit later but also uh evm also has to check first he has to compute the cost of the execution of an instruction and then check if it actually doesn't doesn't uh go above the the gas limit that has been provided and only after this it can actually start actually executing what the instruction says so this actually contributes to inefficiency of the evm implementations um so these are numbers more less for evm one um and if you go a bit more naive approach so it it can be even worse uh so yeah so there's definitely some efficiency overhead related to the kind of Simplicity of evm and I didn't actually count with how many instructions evm has but this there are some groups uh of instructions that we can well put them into categories there are some like something basic you would expect from it some AR there also some work on modular arithmetic and bit manipulation and some comparisons between values and so on there's some control flow instructions and memory access uh but this this kind of more on the kind of exotic side of think there's a lot of instructions that just bring some external information or data from from the blockchain environment so something that you can query some information about the current transaction on the current block and finally you can access storage with Specific Instructions so this like kind of private data or like data structure that each account has so whatever the code on whatever account the code is it it can access this private data structure it's a private to evm but it's also publicly visible from anyone else who is observing the blockchain but um at least the the code controls the updates to this to this data structure by its own and nobody can do it for it and finally there are some uh ways of interacting with the other accounts so one one contract account with a code can interact with some other code in some other address or even create new contracts with code and finally there is a special instruction that computes secure har function of kak 256 so this is more L to give you overview what can you expect there um okay so I would like to focus on two aspects now that is a bit more unique to evm but um if there are any questions so far I'm happy to take it then hi this is K of uh I understand that you mentioned that we work on the 256 bit uh instructions uh but I I do see online that there is actually a uh a 384bit uh uh I guess a a a research on 384 bit implementation for the easier uh computation for eled curve cryptography uh in particular the BLS 12 381 signature so I want to check if uh there are any uh any uh EVMS out there they actually making use of this uh uh tree I guess it's called evm 38 for well um I think what you mean is that there are some like cryptographic let's say kind of Primitives that use values other than 256 and yeah 250 54 is kind of also used sometimes so we have some we have some pre uh cryptographic Primitives also kind of available to evm that uses a elliptic curve of this size um but I think that mostly affect the only like very narrow aspect of arithmetic which is related to finite fields and and so on so this is not exactly how evm works but yeah it's some sense the abstraction of VM gives you this power of two uh kind of limit so all the values are from zero to two to the power uh 256 minus one uh so it it means it's not exactly fits into into this cryptographic word very very nicely uh one of the issues comes in in a ZK Z implementations of VM maybe that's what you also refer to that uh kind of natively has this a bit lower uh limit of arithmetic which is related to what they said fin not fields and then they have to emulate the kind of the standard evm Behavior somehow so this so evm Al always has this the same the same value size uh in different in different blockchains uh but yeah sometimes it's not natural value and on some level this ZK EVMS try to mitigate that by providing different programming languages where the natural value is actually different than evm natural value I see thank you very much the clarify perfect um yeah I I had a question um you mentioned earlier that um all mostly all operations are one bit length um so what does it mean for like for example the the push operation to be greater than one bite um and uh does that mean that it it overflows into the next uh location into the in the stack could you yeah yeah um so like push push instruction kind of breaks this obstruction but mostly um uh how evm works it's it always checks The Next Bite to know what to do with it and and usually the instructions are just one bite which means it can start executing after that the push instructions are kind of ex uh um yeah different in a sense they will actually have some payload after this single buite that means that it describes the instruction so I think this analogy of the bite code is kind of yeah not really strong uh maybe the substraction and this is also case not only for evm but for uh any other stack based uh VMS that it's not necessarily like single bite that describes everything sometimes there are like followup bites that you need to also process to execute the instruction in this like basic evm there's only push instructions that has this property that there's like followup bites that you need to actually load so what the push instruction does for for people that don't know it's it just kind of push uh puts a a constant value on the stack constant in the sense it's encoded in the code so it cannot be changed during execution and it can be value from zeros to whatever up to 32 bytes the size of the natural value VM and that's that's kind of simpler what what it does but the encoding of the value to be pushed on the stack is actually in the same code so it follows after the the first bite that describes the instruction is a push instruction but also describes the length of the following bites to to read so after you finish push instruction execution the you need to read another bite to to get the next instruction so kind of uh execution of the instruction itself has to handle this payload bytes as well so the next time interpreter Loops from the start it can safely read one bite and then decode it at the next instruction so yeah so this bite code it's it's not precisely described in how the the actual code is structured but it's not specific to to evm actually awesome thanks yeah so um I was just very curious about why uh evm is fundamentally interpreted and not compiled um given that like we have something like just in time compilation or like ahead of time compilation maybe web assembly based execution as well which can significantly improve the performance of BM right maybe by optimizing instructions or like doing this on redundant computations easily so like why has not adopted these yet and why why spefically interpreted so that's what I was curious about yes uh I think there are multiple answers to uh but I think that the easiest is just it's actually a bit hard so evm was actually not designed to be to be just in time compiled and to be actually translated to anything else and it was at the beginning it was so so annoying to to do it because one of the first projects I had was actually to write a a J in time compiler for evm was that it's all it was almost impossible because of the control flow that uh instructions that evm has and I will talk about it later actually um it was so bad that you cannot predict the where the with this control flow instruction will jump to if they if they have to so so in some way evm is very simple but it has kind of unconstrained control flow instructions which are not really compatible with translation and compilation uh because it just like too yeah too kind of weird and uh and that was the kind of the issues uh so on the contrary web what's actually designed in this compilation in mind it's actually the default mode of execution in browsers currently and that was the main kind of goals of the web assembly and the with the evm it wasn't and we actually made it unnecessarily difficult to do so and we also have some constraints on the kind of on the S on the on the level that we expect um not properly behaving inputs right because everyone can deploy the bite code on a blockchain it's kind of permissionless and there's no validation so you can you kind of have to be prepared for really awkward edge cases if if your compilation pipeline is too complicated um but we try to fix that and also come to this topic if I have time um current situations that that's mostly interpreted okay so let me try to uh to move on so we still have time in the end um I want to talk about two more kind of unique features ofm one is um is internal calls so this a way to when the the contracts which I usually think about as a kind of so I think I like the analogy that the contracts are mostly sitting there as a kind of so you can imagine it's blockchain it's a kind of file system and you have a programs in this file system uh so there's some files with a code in it and then can come a user and invoke one of these programs and then this program can actually interact with other programs on its own so this is kind of unique feature in the sense usually programming languages or like virtual machines don't allow it very F uh you can imagine I don't know if you programing python uh you can definitely call other files and other functions from other modules but executing a different process is usually something slightly more complicated so we need to load something from a standard Library when you execute a process you need to specify a lot of parameters to execute you need to specify how the output should come to you like is like standard output this like error output like both of how to yeah what happen if it crashes and a lot of that so if you work like multiprocess applications actually a actually kind of kind of advanced thing mm it's it's relatively easy so it's still complicated because all of these aspects you need to take care of but they are dedicated instructions that just almost like uh execute other contracts in in in kind of isolated um container of a process so they actually cannot really do much to you back so they have different memory they have almost like a new instance of evm so the stack is different the memory is different the storage is private and you cannot see what they doing and then can only uh return some data to you in the end um so so evm has more multiple call instructions they are diff differ by some like details um so the call is kind of the the most say the basic one it's hard to tell it's basic but this is kind of like the basic in a sense it executes other contract as you would imagine it to do and this I think some number of parameters you can pass it to um so definitely you can specify whatever address you want to execute you can also specify how much gas so gas is this uh this kind of resource that limits the the execution uh so we never actually go into some infinite execution so not only the the transaction sender can specify how much the transaction can use but then during this chain of internal code you can also decide how much gas he will pass to the to the Ki and and so there's control over that although we working on a way to actually move this control um potentially in the future you can also send some if with the call and then the contract sending it to can react to it somehow so you can also record how much if you send or do something you can send nonzero value and and many aspects of that that kind of makes this e cryptocurrency special for ethereum because also because it has like direct way of of of sending it to different places in AVM and then finally you can pass some arbitrary data to the col and then it can do something else and there's also like multiple other properties you can specify uh like for example the static call I mentioned at the top is that it works as execute other process but you also restrict this process to do any modification to the ethereum state so it can also give you some information back but cannot modify anything in that to and as a result you get some another set of arbitrary data whatever the contract decided to send you back and also whatever the gas remained after the the execution so it can happen that the the contract you called will not use all of the resources you provided to him uh so whatever is remained it will go back to you and then you can use it to some other computations or processing um yeah so um this is I think one of the complic most compc ated aspect to evm uh as as well for the implementation which does lot of details to and lot of different pre-checks and post check that happens around this but still this is really powerful feature that makes this interaction between accounts and the contracts relatively straightforward um and there are also instructions that instead of calling some existing account can create a new account for a new code and you can also decide how the new account has to how it's supposed to be created and yeah specify the the way of creation of account also as a evm program so it's mostly it's it's clo it works closely to some kind of basic compiler that creates new items in a in a in the state and as I mentioned already this multiple memories evm has so we mentioned the stock where this like basic items reside on and you can the the instructions actually manipulates the value is on the stack but there's also this more free memory so it's it's closer to this classic CPU design when it's like bite addressable infinite in this case uh area where you can put arbitrary arbitrary values in some unrestricted way the only restriction is that accessing this cost you some gas and the size of memory you're using also cost you some gas so um conceptually this is infinite memory but you are limited by the the gas resource how much you can access it and finally the well finally uh the two another memory buffer that's related to the input data from to the call and accessing the the data returned from previous calls um and these are kind of read only memories but because they are different buffers from the the main evm memory it means that has to be some instructions to access different these different buffers and also to move data between these different buffers so that's kind of because evm has this multiple memor means that also like spe specialized instructions that moves data between different kind of buffers and finally this storage which is it's not like con a continuous memory it's just a key value up but that's also dedicated instructions to manipulate these and the this is uh like uh re readable memory so you can modify the values there and gives you some like basic overview uh Rel this call data return data buff they are related to the calls so if you have on the left side the call instruction that targets some other contract um the call the the the amount of the input of of the call instruction becomes a read only buffer on the K side where it can access access as the and it's called call data so there are special instructions to access this but you cannot modify it and finally after the The second contract finish this execution it can also return some data back to the caller and then this data be called return data is also read only but this time for the caller so it can access it read whatever has been returned but also cannot modify it and to Mo to move data between this this buffers you need another set of instruction and whatever actually comes from the transaction itself if you are kind of more or less familiar with the transaction structure then you can also put a arbitrary data in the transaction this is what with the the the top level execution will see as the call data as well okay so that was more less about how calls work and and now uh the second unique thing of evm is this famous gas so the gas has been kind of natively introduced inm as a way of limiting the execution time um so conceptually it works as a as something you subtract values from so we have some let's say evm for execution has some gas counter that is initialized to Del liit the transaction provided and then every every instruction subtract some some some value from it and if it goes to zero it means you has the the execution has run out of the resource to perform computation and then the execution terminates and it terminates with a failure so whatever has been done so far any modifications to the state most I mean the the State matters the most um so any modification to the state is reverted and any other kind of observable effects are also reverted up to [Music] the C War warmups and and logs so there are features that not directly reflected in the state modification but still something you can see for example from the application interface and and this kind of playing of the gas happens on multiple levels so um when you send a transaction you can specify the the limit of the gas and by this also the cost of the transactions computed usually wallets do this so they they kind of try to estimate how much gas you will actually need to successfully execute the transaction and then it puts a value in the transaction for the user mostly and by based on this it's Al the the maximum cost of the transaction is computed um but as I mentioned already when you go into internal Cod level that's also so you can kind of uh control the amount of resources you provide to the to the colleages um and finally the transactions are packed into blocks and the block also has some limit of the gas so that's maybe you actually also heard of but this is this blog gas limit that is sometimes discussed on social media that we should increase it or decrease it or whatever so this is because there also value that the block cannot exceeds uh in terms of evm computation um this kind of like a second dimension of the of the gas um so we have like single unit to also reflect the cost of making changes to the state so it's not about computation it's about to recording the database changes that happens and it's actually reflected in the same unit which has some like kind of bad properties because these costs are not really very well correlated so it's mostly asking a question um if Computing some uh Computing some addition how to how to compare Computing some addition of two numbers and storing 32 bytes of uh of data in blockchain Forever how to actually reflect these two kind of different dimensions into a single unit I think we struggle a bit with this so the idea is to actually split this cost into multi-dimensional uh pricing uh but so far this or reflected in a in a in a single unit and most of basic instructions has some constant cost so for example from the current spec uh pushing new constant value with the push instruction on the evm stack cost a three three unit of gas and sometimes instructions have a bit more complicated uh formula uh so example would be the exponent instruction which computes the exponent of two values and the cost of the depends of of the length of the exponent actually because um there is not like constant time uh implementation of that it's it does more work if the exponent is bigger so the computation is is kind of reflecting the the guscos reflects also uh the values of the arguments coming to the instruction so it can be more complicated uh also the size of memory is so if during execution you actually use more evm memory you also pay for the expansion of the memory and uh and finally something like uh accessing eum state is a bit more complicated prices because it tries to uh compensate from Reading cold and worm data from from the database so this gets complicated um so what I wanted to say it's it's for some pieces of evm this is straightforward simple um value look up for some other things it's actually complicated thing to compute sometimes it actually very much affect effectiveness of evm execution because it's you may actually spend more time Computing the cost of the instruction than actually executing the instruction okay and then I have I think two examples of instructions to maybe kind of summarize what has been said so far so art instruction has the op code value of one so op code is this bite that uniquely identifies the instruction the bite code and as you can imagine it requires two at least two items to be on the stack so if there's less than that the evm will also terminate with a failure but if if everything is good we have these two items on the stack uh what conceptually this instruction does it takes this value from the stack it adds automatically them together because they are 256 bits values it means it will add them but with this wrapping at the two to the power 256 value so well it it it works as rupt addition and this result is pushed back on the stack so mostly two values are replaced with new one new value and the cost of that is also three uh data copy instruction so this is instruction to to get some range of data from this call data which is read only and if comes from transaction or some like higher level internal call and it copies is to this read and write uh accessible evm memory and it takes two uh it takes three items from the stack uh the top one is the opposite of the call data you interested in the second one is the offset of the memory you wanted to copy it to and finally uh this number of bytes you want to copy and uh so first of all you need to make sure I mean evm has to make sure that these three items are actually on the stack uh there's also some edge cases related to what happens this it goes out of the actual physical call data that is available and what you usually evm does in this case I mean it specifically does it in this case but there are some kind of other memories which usually behaves the same way it's kind of fakes the the the user as like infinite number of zero bytes after the actually physical ones so mostly it will P the different overflows with zeros so that's not a failure it's actually determinist behavior of evm and uh well that's yeah so mostly what it does the instruction copies this this range of of of bites from one place to the other and the cost is actually proportional to the to the size of the of the copy so so like base cost is three and there's like another tree for every 32 chunk of of 32 by chunk of data so we need to compute that as well and it's like rounded up so run it up is actually difficult to compute and run it down so we also need to spend some time of computing this and then in finally there's some additional cost to expanding evm memory so if it has been used in this range already that's fine nobody there's no additional calls but if you actually copying this data to some EV memory that hasn't been used before you also have to pay for the expansion of this memory and this is actually quadratic cost okay so uh how are you doing so far uh I read somewhere yeah I read somewhere that like you just told that the instructions are one bite so I read that only the top 16 elements of the stack can be accessed for computation so like how does it work then I'm not sure I I fully fully got the question um so I mean how it happened that for example at distraction is one B how it knows what to compute yes like I read that uh since it's one bite so eight bits for bit for the function and for bit for the position so since there only for bit for the position we can't has more than 16 elements yeah so this is kind of the the basic uh kind of design of the stock virtual machine so you actually don't specify the position the position is implicit and it's always like the first and the second item on the stock so so you so before you do addition you as a kind of compiler or like programmer whatever you you have to make sure that the values you want to add are actually on the top of the stack right so if they are there you're fine and you can add them and then the the result will also be on the top of the stack so that's kind of that's why you don't have to encode the positions of the values you want to add in the instruction so it's enough to have single bu that says this is addition and it means that we'll add the top one and the second the top items and then so it kind of looks that we save a lot of code size this way but it's actually not this this nice because if if the values you want to add are not on the top of the stack then you need to kind of move it there somehow right and the additional instructions that actually are specific uh designed for that so so there's like dup instruction that you can specify which instruction in the range of 16 you want to duplicate on the top of the stack so you can use this so your your axis AIS size is only like 16 elements and there's also a swap instruction which is similar but it will not duplicate it will just move the top item of the stack to the and and swap it with the value that you specif f it also has more or less the 16 16 uh 16 items range so kind of in in in general if you if you look on the compiler generated code and if you even if you would write it by hand you will notice there a lot of this dup and swap instruction actually happening so somehow you can say you can think in it's kind of a faking that that proper encoding so whatever you see some like core computation instruction like addition for example they usually Pro preceded by like two different dup instructions so mostly you're actually encoding of doing addition of two variables it's actually three instructions first you need to duplicate one of these 16 top items then you likely need to duplicate another one and then finally your result will be on the top of the stack and this is also the the this like liit of 16 is also this famous solidity stack to deep uh error it's like when you actually the compiler cannot figure out easy way to to access some value that is on evm stuck it will report an error there different definitely some ways to mitigate that but uh if you if you ever heard about this issue it's it comes from this limitation of evm okay sure just one question so uh as I said that the AVM architecture was defined for 256 because of the most used har functions which were 256 bits so if we were to move to a higher number of bits hash function or crypto any other so we would have to change the architecture also um no I I don't think so uh so I think this is nice abstraction that evm has if it's if it's practical that's kind of different different question but uh I imagine if we want to change the well first of all will not probably replace the C has functions with a new hash functions because replacing means it will break existing code so usually how evm Evolution works and how the upgrade evm happens we we we kind of really pay attention to backwards compatibility so these hash functions will stay where they are and some of them like one of them is actually instruction evm but the two other hash functions relatively easy easily available to evm but they are not uh implemented as the instruction they are implemented as this pre-compiled contract so kind of fake contract that has no code but pretends to have some code and this code actually computes the secure har functions I think this like another topic about this this this thing but uh yeah I think I will not really have time to to explain this currently but mostly we work as the kind of we we mostly work by extending evm so if this new has function needed and if it's even bigger than that I would need to figure out how to actually fit it in but it it can be different ways of doing so it can return just like two stack items for example we don't have an instruction that like practically does it currently but I don't see this is impossible uh you can also work with memory um so you can even if you want new hash function that is instruction you can define it in in a way that it will not output the result of the hash function on the evm stack but you can for example put it in the at the memory index that you specify so if it needs like 50 bytes for example of the output then you can specify the index in memory and it will write this 50 bytes at this index and then you have to kind of process it in m in some way but it's up to the kind of user how to do that so there are definitely ways of of doing so something that will not kind of need to redesign the the basic basic kind of design properties of current evm okay yes okay so I think this is the final topic but it's kind of also Unlimited in some way um so as I mentioned evm kind of doesn't have any validation step and it just executes whatever bites are there and there's no rest sections what you can actually put in a contract code and uh I think that's that's simple but it has a lot of bad properties and we try to fix that in the evm upgrades um in some Future Okay so this goes back to I it goes back so uh because of this missing validation thing of of evm bite code um I think it has accumulated a lot of problems uh during this 10 years and uh there's one of the attempts to fix that which is called evm object format and this is something I've been working on for some years right now and it kind of borrows for weep assembly EXP experiments as well and some other designs uh for for virtual machines and so on uh so what we actually want to do with this um it's it's kind of to structure the bite code in some in some way that it's it's easier to execute but it's also easier to work with and also to analyze and has some other properties but this is done by actually introducing this validation step so mostly on the Practical side is that uh we will Define what a valid bite code means and when you try to deploy a new contract uh it has to pass this validation rules implemented in ethereum nodes and and this means that whatever is deployed on blockchain and whatever code is in the ethereum state we will know that it's already valid so we can actually extract this information later on during execution and some nice quote I recently heard about it is that it prevents bad behavior with complexity and this complexity is the validation and some kind of visualization of that is that okay so because it's a new thing so we started call the old evm as a legacy evm but it's Legacy in a sense that will introduce something new side by side it doesn't mean it will not work uh so in this current evm not to emphasize it worth like everything is kind of mixed together in the bite code so we have some data there which is are not really visible so you can think that the push the push instruction has this payload of bytes it's can you can think about the data but usually what the compilers do it will put something that is executable at the front but then in the end that's some bite that actually never meant to be executed although for the evm it's actually really difficult to distinguish these two so whatever it does some analysis of it it has analyzed everything and it can't know that this B are never executed because it's like fundamentally impossible to decide if for any program you can actually reach some instruction somewhere or not and so this it's all mixed together there some like data that the contract will use later as like the data section but there's also like meta dat that solidity puts in to identify the source codes on blockchain later but is actually never ever meant to be read by uh by evm and so on and so what this evm object format tries to do on this like basic level is to just clean it up a bit so we want to put some like like metadata information up front about the structure of the later code so we specifically want to split the code and the data into separate sections and we want to put a version so like we can upgrade evm more easily and guarantee backwards compatibility and so on it's actually supposed to be like basic stuff but U there lot of details to figure out um to not to over complicated mostly I will not go to into detail how exactly this is done and uh because it might be like probably idea for different topic but uh let's scheme over it for for now but uh what are the proper like the benefits of that first of all during validation we can uh do some checks that will not would normally do and run time so we can guarantee that if the instruction needs two arguments on the stack this two argument on the stack will actually be there uh forever uh whenever like code paff the execution would take um and uh it means that during execution we actually don't have to check these so they are kind of guaranteed by validation so whatever we load the code from account for execution we can actually eliminate this checks at run time so it improves the efficiency of the VM extion a bit it's not like substantial like number of times Improvement but I think it gives like between like 10 to 15 uh% of of speed up okay and and finally it also modifies uh how control flow Works in evm and this uh directly contributes to the this ability to translate VM bite code into some other representation so it kind of goes back to the question why do don't we have jit compilers for evm well because the control flow in the current TVM is pretty bad to reason about and it's difficult to translate it to some other forms um but uh with this modified thing uh you can actually do it relatively easy and I wanted to describe it as a kind of comparison what we currently have and what the the new format potentially will have um but I'm not sure we can actually squeeze it into five minutes uh so uh I'm not sure it's worth to actually go into this right now unless you want to spend a bit more time on it today or we can even Skittle some other thing to talk about it well it's mostly question to to to Mario I think okay yeah yeah I can I can schem over it yeah okay um so let's try do that uh so um so mostly control flow in current TVM is done by two jump instructions they differ mostly by like conditional and conditional so this conditional version just takes another argument and checks if it's zero if it's zero it will not jump to the Target if it's not zero it will jump to the Target so that's the difference from the structure of the program there actually no difference uh but the problem is that it's hard to figure out where the jump will go to because the jump Target is also Dynamic argument of the of the of the jump so it's also taken from the evm stack so this like run like Dynamic value you cannot predict what it will be and that makes it really difficult to reason about the the control like static control flow of the program so we call it like Dynamic jumps because of that and this is like kind of overview of these like abilities how different uh like intermediat presentations and assemblers actually handle that and mostly what I wanted to show here is that for evm is just like single single way of doing all of these different things and that's why it's actually hard to for example translate evm to llvm IR because it actually don't fit really into this restrictive structure of the other representations yeah so have one way of doing jumps while if anyone else has like a more sophisticated ways so it's because of that it's hard to translate generic but really kind of too powerful thing to this more restricted form so how like evm object format tries to uh tries to fix that is mostly replacing this Dynamic jump with static jump so we have we want to have new kind of instructions that that has fixed Target of the jump so we know during analysis and validation where the jump will go to and uh it actually works pretty well in most of the cases and if you analyze the solidity program you will notice that all the conditional jumps are actually static because there's a push instruction for them but it's for this having only ftic jumps make implementation of functions in the contract really difficult so that's why we also have dedicated set of instructions to implement functions so it kind of FS the Gap that was missing from the beginning to match the other representations oh that's actually that's all all of that um so if I go a bit to here we kind of also try to fill the other categories with the dedicated instructions and this allows you to analyze the control flow of the of the contracts pretty easily and translate them to other presentations okay so that was it about the control flow more less [Applause] yeah rash do have a question yeah yeah uh I have question related to the euf uh so in EIP 7620 there is idea to depreciate all old create and create to instructions so how it will affect the current deployed contracts like any Factory contract or some other contracts who using the creative gu to okay so uh I'm not really uh super uh fully remember the EIP numbers but you mean that's like create and it's potentially core instructions are deprecated right depreciated yeah yeah so it's it's not like the okay um so on the first first part of the answer is that we want to replace this instructions with the new instructions so it's kind of the similar story as with the jumps so we also kind of this allow how to use the old jump instructions and we provide the new ways of of doing so and it's the similar story for uh interacting with other contracts what exactly is changed I think I will just leave it for now but they conceptually the new instructions conceptually work the same as the previous ones we just adding some small limitations to them and sometimes we just clean it up because some of the features of the current instructions actually also kind of deprecate uh replaced with a new was so so there will be Replacements uh on the instruction level right so there'll be new instructions to do the same thing um secondly how how this Legacy evm interacts with the eof and the the other way so there we kind of coexist uh on the same blockchain let's say so there will be still VM and and there's a way to distinguish which bite code is legacy and which bite code is the EF and whatever the execution comes to the to the account and then you will read the the code of this account you need to figure out I mean the the evm let's say as a broader uh broader component we figure out okay this is Legacy code so I need to use the old evm to execute it oh this is new eof version whatever and I need this this kind of way of executing it so it will figured out by the version let's say and you can you can conceptually think that the Legacy evm also has a ver version but implicitly so it will know how to ex execute it and this is purely for like backwards compatibility so we not we cannot like modify the existing Cod it will be behave as it is so we provide a kind of new site evm in in some way to deploy new contracts in a new way and pro potentially a kind of better way and hopefully the adoption will catch up with this but still whatever the bite codes is a new for form and the old form they more less will be able to interact in the same way the Cent contracts can inter with there there like small details that are also limited related to delegate calls which are kind of special kind of calls which execute code of different account but in the context of the current account and yeah that's that's some it's it's quite complicated and yeah and there's some restriction on this but besides that all this different bite codes new versions all versions can interact with each other as it as they were um also the if the old old Legacy code has create instructions to span new contracts that also will work and that will create new Legacy contracts so this Legacy contract will be created probably Forever at least for ethereum mayet and the same way the the eof contracts will be able to create e more eof contracts right and so yeah so this that's kind of Separation on some levels but on interaction levels it it Remains the Same as it was thank you thank you and one more question related to EF itself uh as we know that right if we wants to uh F the uh 16 more than the 16 items from the stack then it will show you the stack to deep uh then how how we are solving that in the UF exactly how the things working behind the scene uh this is actually not like ultimately like super clever fix it's just this um there are kind of new instructions that allows you to access deeper in the stack so they kind of equivalent up to one up to one no up to 256 because that's number fit into single bite so not the full stack access but like quarter of the stack access directly and this is simply implemented by having new instruction that has like One op code and the next bite after the op code says like which item of of the stack to access right so this's like dup instruction equivalent this like swap instruction equivalent and there's one more that is called exchange so it's kind of like generic more generic swap when you don't have to swap some deep inst some deep value with the Top Value you can also swap to two deep values with with each other uh so that's that's that's not really clever fix it's kind of the same thing but this is the yeah this is kind of where the validation also helps with because we cannot actually introduce such instructions to Legacy VM um and this this is reason because of this no validation it means we cannot introduce this like two by instructions into Legacy VM the Legacy VM knows about push instructions that they have like followup bites that's have have some special meaning but introducing new instructions can potentially break existing contracts that has this property that it's not single bite and that's why introducing this like more power for dup and swap instruction took so much time and because it was actually not possible in the this Legacy [Music] VM great yeah thank you thank you so much oh I I still I think I I had most of the content I wanted um so but if you if we want to plan next session I think I can next time can be a bit more lighter on the content and we can maybe have more time on the questions uh but yeah uh thanks everyone for attending anyway yeah awesome yeah thank you so much really appreciate it a great lecture great slides with a lot of resources I think we can take some time to uh study the resources and just uh maybe rewatch recording and then and then uh um uh maybe we do some Ama or something later on but uh for now uh you're of the hook P I mean thank you so much much it's really was really great yeah yeah it was pleasure thank you awesome really appreciate it and yeah have a great day everyone
Automatic transcript — names and jargon may be misspelled.