TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Из Solidity в AI и дальше

16 May 2023, 19:41

Открыть в Telegram Поделиться Пожаловаться

Большая заметка по работе с памятью

Несмотря на то, что на канале уже было достаточно материалов по работе с памятью в Solidity, я постоянно путался в некоторых моментах. Поэтому решил объединить все в одном посте-заметке, чтобы иметь быстрый доступ и периодически напоминать себе основные нюансы.


Storage

1. Размер Storage контракта 2**256-1.

2. Слоты в памяти имеют размер в 32 байта. Если переменные меньше 32 байт, то они могут быть "упакованы". Т.е. если есть 4 переменные uint8, то они все будут занимать только один слот.

3. Динамические массивы хранятся следующим образом: сначала определяется слот, в котором массив был обозначен. Там хранится его длина (кол-во элементов), а значение элемента в массиве высчитывается через keccak256(p), где "р" - номер слота инициализации массива. Таким образом, первый элемент массива будет храниться в keccak256(p), второй в keccak256(p)+1, третий в keccak256(p)+2 и т.д.

4. Маппинга хранятся немного по другому. В главном слоте, где был объявлен маппинг, хранится пустое значение (все нули). А значение маппинга находится с помощью keccak256(p CONCAT key), где key - это ключ, к которому нужно найти само значение.

5. Enum, по описанию из комментария на stackexchange: Up to 255 values seems to take up 8 bits of storage, and 256 values seems to take up 16 bits of storage.


Memory

1. Максимальный размер Memory - 2 ** 64 байта.

2. Стоимость хранения считается linearly для первых 724 байтов, и Quadratically - после.

3. Структура памяти:

0x00 - 0x3f (64 bytes): зарезервированное место для хеширования;
0x40 - 0x5f (32 bytes): указатель на свободное место (free memory pointer);
0x60 - 0x7f (32 bytes): пустой слот, который также используется, как изначальное значение для динамических массивов;

Отсчет для хранения новых значений начинается с 128 байта.

4. Слоты всегда по 32 байта.

5. Для динамических массивов в первом слоте хранится его длина, а затем идут сами элементы.

6. Если добавляете значения в Memory через assembly, то также необходимо обновлять и free memory pointer, так как в этом случае он не обновляется автоматически.

7. Все не инициализированные значение будут указывать на слот 0х60 (кроме структур), в то время как строки, байти и динамические массивы будут указывать на следующий free memory location.


Calldata

1. Неизменяемое хранилище данных.

2. Не могут храниться и передаваться маппинги.

3. В отличие от Memory размер не лимитирован.

4. Размер всего calldata можно узнать с помощью опкода CALLDATASIZE.

5. Первые 4 байта всегда занимает селектор функции, который считается через bytes4(keccak256("funcName(args)")).

6. Для динамических массивов и строк сначала идет offset (32 байта), потом длина / размер (32 байта), потом сами значения.


Stack

1. Хранение по принципу LIFO - last in, first out.

2. В стеке доступны только верхние 16 слотов.

3. Базовые опкоды: PUSH, POP, SWAP и DUP.

4. Solidity, как язык, не работает на прямую со стеком.

5. Функции помеченные, как external, занимают два слота в стеке: адрес контракта и селектор вызываемой функции. В этом случае они zero-padded слева, а не справа, как это в других случаях.

6. Для того, чтобы обойти ошибку "stack too deep" можно использовать block scopes {}.


Code

1. Константы и immutable хранятся в байткоде контракта.

2. Если константы на определены по какой-либо причине, то они на попадают в байткод.

3. Immutable нельзя определять в try/catch в версии 0.8.20.

4. Аргументы для конструктора контракта добавляются в конец байтокода самого контракта.

P.S. Можете смело корректировать или добавлять пункты в комментариях.

#storage #memory #calldata #code #stack

716 1 17 16 18
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot