Gas и memory types
Вчера мы поговорили о внутренней "валюте" EVM - gas, как затраты на вычисление. Но также упомянули, что помимо операций, gas расходуется также и на хранение данных. Сегодня мы кратко рассмотрим, каким образом контракты могут хранить свои данные и как дорого это может стоить.
Введение
Всего EVM предлагает 4 вида памяти:
Storage
Самый дорогой вид памяти. Каждый контракт обладает собственной storage памятью (аналог жесткого диска в понимании). Здесь хранятся все глобальные переменные (state variables), состояние которых постоянно между вызовами функций. Таким образом, между всеми обращения к контракту - эти значения сохраняются. Представляет собой ассоциативный массив (словарь, map), с uint256 ключами и uint256 значениями.
Memory
Второй тип памяти. Намного дешевле, чем storage, очищается между внешними вызовами функций и используется для хранения временных данных: локальные переменные, адреса возврата из функции. Аналог для понимания - оперативная память. По внутреннему устройству - представляет из себя байт-массив. Сначала имеет нулевой размер, но может быть расширена 32-байтовыми порциями (256 бит).
Stack
Как было сказано в прошлых статьях, EVM - язык, основанный на стэке. Стэк используется для хранения локальных переменных и возвращаемых адресов из функции. Каждый элемент стека - 256 бит, максимальная глубина стэка - 1024 элемента. Однако, только верхние 16 элементов доступны для использования. Если стэк переполнить, то выполнение контракта прервется. Цена использования - практически аналогична Memory.
Длина "слова" (элемента стэка) в 256 бит выбрана не случайно - это очень удобно для использования криптографических функций (напр. Keccak-256, secp256k1).
Calldata
Это память только для чтения, которая не хранится постоянно. Используется лишь для хранения аргументов функции. В большинстве источников не упоминается вовсе. Заслуги calldata перекладываются на memory.
Ниже представлена небольшая табличка. которая явно демонстрирует среднюю примерную стоимость операций с памятью для разных типов памяти. Рекомендуем к ознакомлению, дабы сохранить свои кровные.
В Solidity можно явно указать используемый тип память (memory or storage), но не всегда можно это сделать. Когда это может обернуться ошибкой - предлагаем прочитать в замечательных статьях ниже. А мы прощаемся с Вами до завтра, чтобы суметь поискать что-то поучительно и интересное;)
- Статья о сравнении типов памяти и расчетах стоимости
- Еще хорошая статья о типах памяти
- Забавная ситуация, которая может произойти по недостатку теоретической базы
- Приличный список хороших советов по работе с памятью в Solidity
- Статья, послужившая основной идеей текущей заметки
- Прекрасная презентация с иллюстрациями принципов работы Ethereum
- Официальная документация Ethereum
- 8. Большая статья на русском языке от 2017г (в переводе) об Ethereum (можно найти ответы на вопросы, которые могут появиться при изучении презентации из п.1 или при прочтении данной статьи)