Ethereum Virtual Machinefleeting
- Référence externe : https://docs.soliditylang.org/en/v0.8.21/introduction-to-smart-contracts.html
- Référence externe : https://coinsbench.com/solidity-9-memory-storage-and-calldata-9abc86f0b4e
- Référence externe : https://firstname.lastname@example.org_42769/solidity-gotchas-part-2-storage-memory-and-calldata-ca697e49d2a7
- Référence externe : https://docs.alchemy.com/docs/when-to-use-storage-vs-memory-vs-calldata-in-solidity
Ethereum Virtual Machine
address of a contract is determined at the time the contract is created (it is derived from the creator address and the number of transactions sent from that address, the so-called “nonce”).
Every account has a persistent key-value store mapping 256-bit words to 256-bit words called storage.
transaction is a message that is sent from one account to another account (which might be the same or empty, see below). It can include binary data (which is called “payload”) and Ether.
If the target account is not set (the transaction does not have a recipient or the recipient is set to null), the transaction creates a new contract. As already mentioned, the address of that contract is not the zero address but an address derived from the sender and its number of transactions sent (the “nonce”).
payload of such a contract creation transaction is taken to be EVM bytecode and executed. The output data of this execution is permanently stored as the code of the contract.
in order to create a contract, you do not send the actual code of the contract, but in fact code that returns that code when executed.
Upon creation, each transaction is charged with a certain amount of gas that has to be paid for by the originator of the transaction (tx.origin). While the EVM executes the transaction, the gas is gradually depleted according to specific rules. If the gas is used up at any point (i.e. it would be negative), an out-of-gas exception is triggered, which ends execution and reverts all modifications made to the state in the current call frame.
Ethereum Virtual Machine has three areas where it can store data: storage, memory and the stack.
Each account has a data area called storage, which is persistent between function calls and transactions
not possible to enumerate storage from within a contract, it is comparatively costly to read, and even more to initialise and modify storage
second data area is called memory, of which a contract obtains a freshly cleared instance for each message call.
Memory is linear and can be addressed at byte level, but reads are limited to a width of 256 bits, while writes can be either 8 bits or 256 bits wide
At the time of expansion, the cost in gas must be paid. Memory is more costly the larger it grows (it scales quadratically)
EVM is not a register machine but a stack machine, so all computations are performed on a data area called the stack. It has a maximum size of 1024 elements and contains words of 256 bits
Access to the stack is limited to the top end in the following way: It is possible to copy one of the topmost 16 elements to the top of the stack or swap the topmost element with one of the 16 elements below it
possible to move stack elements to storage or memory in order to get deeper access to the stack, but it is not possible to just access arbitrary elements deeper in the stack without first removing the top of the stack.
called contract (which can be the same as the caller) will receive a freshly cleared instance of memory and has access to the call payload - which will be provided in a separate area called the calldata
can return data which will be stored at a location in the caller’s memory preallocated by the caller. All such calls are fully synchronous.
Calls are limited to a depth of 1024, which means that for more complex operations, loops should be preferred over recursive calls.
Memory is used for variables that are only needed temporarily, such as function arguments, local variables, or arrays that are created dynamically during the execution of a function. Once the function execution is complete, the memory space is freed up.
Calldata is used for function arguments that are passed in from an external caller, such as a user or another smart contract. Calldata is read-only, meaning that it cannot be modified by the function
The key difference between memory and calldata is that memory is a temporary data storage location that can be modified by a function, while calldata is a read-only temporary data storage location used to hold function arguments passed in from an external caller
storage — this belongs to the contract and persists between function calls. It is where you store a contract’s state variables. If you allocate something to storage, it persists. A contract can only see its own storage
memory — this is volatile. The EVM hands over a clean slate of memory for each message call. It can be expanded at runtime, but it gets quadratically more expensive the more you ask for. Once the message has been processed it all gets junked.
calldata — this too is memory. It is volatile and a cleared space is allocated by the EVM when a message is being processed. It contains the value of function parameters within the context of a function call. Handy if you ever recursed.
EVM is a stack machine. The computers we normally program are register machine
This difference accounts for much of why the EVM seems weird and Solidity seems to have such obvious limitations
Watch out for allocating huge amounts or memory during your function calls as the gas price of your message will skyrocket.
foo is defined inside the function, so by default it is stored in memory
When the function bar is invoked, a space in memory will be allocated to store the value of the variable foo.