Русский
English
RU
Сетка BlockFirst
Картинка BlockFirst
Ссылка
Иконка копировать
Иконка скопированно

Оптимизация газа в Solidity — Memory vs Storage

В статье рассматриваются способы оптимизации газа в Solidity за счёт эффективной работы с памятью. Вместо повторных обращений к storage, которые требуют затратной операции SLOAD, предлагается копировать данные в memory, что особенно выгодно в циклах и при множественных обращениях.

09.07.2025
Перевод
Начинающий уровень
Автор BlockFirst
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопировано
ARTICLE BELOW
Картинка
Превью BlockFirst

uint256 percentage = 30;
function splitAmountToOwnerAndSeller(uint256 amount) internal
view returns (uint256 amountForSender, uint256 amountForOwner)
{ uint256 ownerPercentage = percentage;
amountForSender = (amount * (100 - ownerPercentage)) / 100;
amountForOwner = (amount * ownerPercentage) / 100;
}

(1) Спасибо пользователю CPlusPlusDeveloper с Reddit за замечание, что это не совсем так. С момента внедрения EIP-2929 первая операция SLOAD стоит 2100 газа, но после первого чтения данные кэшируются и считаются "тёплыми", поэтому повторное чтение стоит уже 100 газа. Тем не менее, всё равно выгодно загружать и считывать такую переменную из памяти, особенно если её читают более двух раз.

Это особенно важно при работе с циклами, в которых регулярно происходит чтение из состояния (state). Всегда приводите переменные состояния к memory перед входом в цикл.

Примечания:

Эта функция вычисляет, сколько эфира должно быть отправлено владельцу и продавцу товара. Владелец получает процент, заданный переменной percentage, хранящейся в хранилище (storage). Если разобрать, как это работает, то становится ясно, что переменная percentage считывается из хранилища дважды. В некоторых языках программирования это не проблема, но если понимать, как данные хранятся в блокчейне, то становится очевидным, что чтение переменной amount — это операция в оперативной памяти (memory), а чтение percentage — операция из хранилища (storage). Это разные инструкции на уровне ассемблера.

Рассмотрим пример:

Solidity — это компилируемый язык, в котором каждая операция преобразуется в низкоуровневую инструкцию (opcode), понятную и исполняемую виртуальной машиной Ethereum (EVM). Все операции вашего кода выполняются на каждом компьютере сети, поэтому за каждую операцию взимается "газ", чтобы предотвратить спам и, что ещё важнее, бесконечные циклы. В Solidity понимание машинных операций и их стоимости буквально позволяет экономить деньги.

Итак, код будет выглядеть следующим образом:

Поскольку вы выполняете это дважды, вы потратите 1600 газа только на чтение этой переменной. Чтобы избежать таких затрат, можно сначала сохранить значение из хранилища в оперативную память (memory), а затем считывать его оттуда — это гораздо дешевле (около 3 газа). То есть можно один раз считать из хранилища и записать в память (SLOAD + MSTORE) — это 803 газа, а затем дважды считать из памяти (MLOAD + MLOAD) — ещё 6 газа. В итоге транзакция обойдётся почти вдвое дешевле — около 809 газа вместо 1600.

Каждый раз, когда вы читаете переменную percentage, вы получаете данные из базы данных блокчейна (то есть из сети компьютеров, где каждый должен подтвердить эти данные). Это осуществляется с помощью инструкции SLOAD, которая, согласно Ethereum Yellow Paper, стоит 800 газа за выполнение.

Ассемблер EVM

Если вы знакомы с таким языком, как JavaScript, то, как правило, не задумываетесь о том, как хранятся переменные, за исключением их области видимости. Но при создании программ для распределённой системы, такой как блокчейн, приходится мыслить иначе.

Разработка на блокчейне

uint256 percentage = 30;
function splitAmountToOwnerAndSeller(uint256 amount)
internal
view
returns (uint256 amountForSender, uint256 amountForOwner)
{
amountForSender = (amount * (100 - percentage)) / 100;
amountForOwner = (amount * percentage) / 100;
}

(Перевод)
Виталий Дорожко
Автор
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопированно
Назад в блог
Кнопка назад
Оригинал статьи
кнопка вперед
Поделиться
Иконка поделиться
Ссылка
Иконка копировать
Иконка скопировано
Назад в блог
Кнопка назад
Оригинал статьи
кнопка вперед
сетка BlockFirst
сетка BlockFirst
сетка BlockFirst

Для запросов от пользователей

hello@blockfirst.io

Icon mail

Для бизнес запросов

business@blockfirst.io

Icon mail

Телеграм для быстрых ответов

Icon mail

компания

Сообщество

медиа

Подписываясь на рассылку, вы можете быть уверены, что мы не будем спамить Вам :)

Новости. Скидки. Анонсы

В начало
© 2025-2026 BlockFirst. Все права защищены.
Сетка BlockFirst
hello@blockfirst.io
Для коммерческих предложений
Компания
Телеграм для быстрых ответов
Кнопка копировать
Скопировано