May 6, 2022

Memory vs Calldata vs Storage

Всем привет! С вами Тёма!

Сегодня мы попробуем более подробно разобраться с этими тремя базовыми понятиями

Начнем!

Всякий раз, когда вы пишете смарт-контракты в Solidity, вы должны знать, как ваши переменные и данные обрабатываются EVM. Выбор, который вы сделаете, повлияет на затраты на газ (а это очень важно!)

Storage

Storage — вещь простая. Именно там хранятся все переменные состояния. Поскольку состояние может быть изменено в контракте (например, внутри функции), переменные хранения должны быть изменяемыми. Однако их местоположение постоянно, и они хранятся в блокчейне.

Переменные состояния в storage расположены компактно — по возможности несколько значений будут занимать один и тот же слот хранилища. Помимо особых случаев, например массивов и структур с динамическим размером, другие переменные упаковываются вместе в блоки по 32 байта (разбирали это в гайде по EVM)

Memory

Memory зарезервирована для переменных, определенных в рамках функции. Они сохраняются только во время вызова функции и, таким образом, являются временными переменными, к которым нельзя получить доступ за пределами этой функции

Solidity резервирует четыре 32-байтовых слота для memory с определенными диапазонами байтов, состоящими из: 1) 64-байтового временного пространства для методов хеширования; 2) 32 байта для текущего размера выделенной памяти, что является указателем свободной памяти, куда Solidity всегда помещает новые объекты; 3) 32-байтовый нулевой слот, который используется в качестве начального значения для массивов динамической памяти и никогда не должен записываться.

Calldata

Calldata — это неизменяемое временная локация, где хранятся аргументы функции (ведет себя в основном как memory)

Рекомендуется использовать calldata, так как это позволяет избежать ненужных копий и гарантирует неизменность данных. Массивы и структуры с расположением данных calldata также могут быть возвращены из функций

Предполагается, что этот тип данных имеет формат, определенный спецификацией ABI, т. е. дополняется до кратных 32 байтов (что отличается от вызовов внутренних функций). Аргументы для конструкторов немного отличаются, поскольку они добавляются непосредственно в конец кода контракта (также в кодировке ABI)

Gas

  1. storage — это самое дорогое хранилище данных, которое вы можете использовать. Затем есть memory, а самой дешевой из них является calldata
  2. Изменение storage — одна из самых дорогостоящих операций, которые вы можете выполнить. Чтобы эффективно использовать память, постарайтесь свести к минимуму количество изменений переменных storage

Надеюсь статья была интересной и понятной!

Мой телеграмм канал - https://t.me/ortomich_crypto