0

As we know the EVM provides a key/value store which is a 32-byte key pointing to a 32-byte value. We can imagine how integers or even strings can be stored there, but the main question is how solidity compiler provide maps, arrays, and structs at the high-level. how does it store complex data types in this storage? is it a standard between compiler and EVM? or can any compiler do it in its own way? or some predefined type in EVM?

Also, is there any datatype defined in EVM? or is it just interpret data types in runtime or something like that?

1 Answer 1

1

The Ethereum Virtual Machine (EVM) provides a simple key-value store where both keys and values are 32 bytes. Solidity, as a high-level language, abstracts this simplicity and allows developers to use complex data types like arrays, mappings, and structs. Here's how it works:

Storage Layout in Solidity

  1. Storage Slots: In Solidity, each state variable is assigned a storage slot. Simple variables (like integers or addresses) are stored in single storage slots. For more complex data types, Solidity uses a deterministic way to assign and compute the location of each element.

  2. Mappings: Mappings are stored in a way that allows efficient lookups. The value of a mapping at a particular key is stored at a pseudo-random slot derived from keccak256(key . slot), where slot is the position of the mapping in the contract storage and key is the mapping key. This ensures that each key maps to a unique storage location.

  3. Arrays: For dynamic arrays, Solidity stores the length of the array at the slot assigned to the array. The elements of the array are stored at subsequent slots, starting from keccak256(slot), where slot is the position of the array in storage. For fixed-size arrays, the elements are stored contiguously starting from the array's slot.

  4. Structs: Structs are stored by flattening their members and assigning consecutive storage slots to each member. The first member is stored at the slot assigned to the struct, the second member at the next slot, and so on.

Storage Example

Consider the following Solidity contract:

pragma solidity ^0.8.0;

contract Example {
    uint256 public number; // Slot 0
    mapping(address => uint256) public balances; // Slot 1
    uint256[] public numbers; // Slot 2
    struct Person {
        uint256 id;
        string name;
    }
    Person public person; // Slot 3
}
  • number is stored in slot 0.
  • balances is stored at keccak256(abi.encode(address, 1)).
  • numbers has its length stored in slot 2, and elements start at keccak256(2).
  • person has its members stored starting at slot 3 and the next available slots.

Deterministic Storage Layout

Solidity's approach to storage layout is standardized and deterministic, meaning the same source code will always result in the same storage layout, regardless of the compiler version (as long as it follows the Solidity specification). This standardization is necessary for interoperability and contract upgrades.

EVM Data Types

The EVM itself does not define high-level data types. It only understands 256-bit words and provides basic operations to interact with these words. High-level data types like integers, arrays, structs, etc., are abstractions provided by the Solidity compiler. These types are interpreted and managed at runtime by the compiled bytecode, which maps them to the EVM's 256-bit storage.

Summary

  • The Solidity compiler provides the mechanism to store complex data types in the EVM's key-value storage.
  • The storage layout is deterministic and standardized to ensure interoperability.
  • The EVM does not have high-level data types; it uses 256-bit words, with high-level data type management handled by the Solidity compiler and runtime.
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.