Следуя этим рекомендациям, разработчики могут снизить расход газа в смарт-контрактах, снизить транзакционные издержки и создать более эффективные и удобные приложения.
Комиссии за газ на главной сети Ethereum всегда были серьезной проблемой, особенно в периоды сетевого скопления. В пиковые времена пользователи часто вынуждены платить крайне высокие комиссии за транзакции. Поэтому оптимизация затрат на газ на этапе разработки смарт-контрактов является критически важной. Оптимизация затрат на газ может не только эффективно снизить затраты на транзакции, но и повысить эффективность транзакций, обеспечивая пользователям более экономичный и эффективный блокчейн-опыт.
Эта статья представит механизм оплаты Газа Виртуальной Машины Ethereum (EVM), основные концепции, связанные с оптимизацией оплаты Газа, а также лучшие практики для оптимизации Газовых сборов при разработке смарт-контрактов. Надеется, что этот контент вдохновит и поможет разработчикам, а также поможет обычным пользователям лучше понять, как работает система оплаты Газа EVM, решая вместе вызовы в экосистеме блокчейна.
В сетях, совместимых с EVM, «Газ» относится к единице измерения вычислительной мощности, необходимой для выполнения определенных операций.
Диаграмма ниже иллюстрирует структуру EVM. На диаграмме потребление газа делится на три части: выполнение операций, внешние вызовы сообщений и чтение/запись памяти и хранилища.
Источник: Официальный веб-сайт Ethereum[1]
С момента активации EIP-1559 (London Hard Fork) комиссии за газ рассчитываются по следующей формуле:
Комиссия за газ = количество использованного газа * (базовая комиссия + приоритетная комиссия)
Основная комиссия сжигается, в то время как комиссия за приоритет является стимулом для того, чтобы поощрить валидаторов включить транзакцию в блокчейн. Установка более высокой комиссии за приоритет при отправке транзакции увеличивает вероятность включения транзакции в следующий блок. Это похоже на «чаевые», которые пользователи платят валидаторам.
При компиляции смарт-контракта с помощью Solidity контракт преобразуется в серию «операционных кодов» или опкодов.
Каждая операция (такая как создание контракта, выполнение вызовов сообщений, доступ к хранилищу учетных записей и выполнение операций на виртуальной машине) имеет связанную себестоимость газа, которая документирована в Ethereum Yellow Paper[2].
После нескольких изменений EIP стоимость газа некоторых операций была скорректирована, что может отличаться от значений в Желтой бумаге. Для получения подробной информации о последних затратах на операции обратитесь к этому источнику [3].
Основной концепцией оптимизации Газа является приоритетность экономичных операций в блокчейне EVM и избегание операций, которые влекут высокие затраты на Газ.
В EVM следующие операции относительно недорогие:
Операции с высокой стоимостью включают:
Исходя из вышеуказанных основных концепций, мы составили список лучших практик оптимизации комиссий за газ для сообщества разработчиков. Следуя этим практикам, разработчики могут снизить расход газа смарт-контрактов, снизить затраты на транзакции и создать более эффективные и удобные приложения.
В Solidity хранилище - это ограниченный ресурс, и его потребление газа значительно выше, чем память. Каждый раз, когда смарт-контракт читает или пишет в хранилище, это вызывает высокие затраты газа.
Согласно определению в Ethereum Yellow Paper, стоимость операций хранения более чем в 100 раз выше, чем операций памяти. Например, опкоды, такие как sload и sstore, стоят не менее 100 единиц Газа в лучшем случае, тогда как операции памяти, такие как mload и mstore, потребляют всего 3 единицы Газа.
Методы ограничения использования памяти включают:
Количество используемых слотов хранения в смарт-контракте и способ представления данных разработчиками могут значительно влиять на потребление Газа.
Компилятор Solidity упаковывает последовательные переменные хранилища в процессе компиляции, используя 32-байтовые слоты хранилища в качестве базовой единицы для хранения переменных. Упаковка переменных относится к практике расположения переменных таким образом, чтобы несколько переменных помещались в один слот хранения.
Слева - менее эффективная реализация, которая занимает 3 слота памяти; справа - более эффективная реализация.
Внести эту корректировку позволяет разработчикам сэкономить 20 000 единиц газа (поскольку хранение неиспользуемого слота хранения стоит 20 000 газа), но теперь требуется только два слота хранения.
Поскольку каждый слот хранения потребляет Газ, упаковка переменных оптимизирует использование Газа путем уменьшения количества необходимых слотов хранения.
Переменная может быть представлена с использованием разных типов данных, но затраты на операции варьируются в зависимости от типа. Выбор соответствующего типа данных помогает оптимизировать использование Газа.
Например, в Solidity целые числа могут быть разделены на разные размеры: uint8, uint16, uint32 и т. д. Поскольку EVM работает с 256-битными блоками, использование uint8 означает, что EVM должен сначала преобразовать его в uint256, и это преобразование сопряжено с дополнительными затратами на газ.
Мы можем сравнить затраты газа на uint8 и uint256, используя код на диаграмме. Функция UseUint() потребляет 120,382 газовых единиц, в то время как функция UseUInt8() потребляет 166,111 газовых единиц.
По отдельности использование uint256 дешевле, чем uint8. Однако, если мы применим ранее предложенную оптимизацию упаковки переменных, это будет иметь значение. Если разработчики могут упаковать четыре переменные uint8 в один слот памяти, общая стоимость итерации по ним будет ниже, чем при использовании четырех переменных uint256. В этом случае смарт-контракт может прочитать и записать слот памяти один раз и загрузить все четыре переменные uint8 в память/хранилище одной операцией.
Если данные могут быть ограничены до 32 байт, рекомендуется использовать тип данных bytes32 вместо bytes или strings. Как правило, переменные фиксированного размера потребляют меньше Газа, чем переменные с динамическим размером. Если длина байта может быть ограничена, попробуйте выбрать наименьшую длину от bytes1 до bytes32.
В Solidity списки данных можно представить двумя типами данных: Массивами и Отображениями, каждый из которых имеет отличный синтаксис и структуру.
Отображения обычно более эффективны и экономичны в большинстве случаев, в то время как массивы являются итерируемыми и поддерживают упаковку типов данных. Поэтому рекомендуется отдавать предпочтение использованию отображений при управлении списками данных, если только требуется итерация или расход газа может быть оптимизирован с помощью упаковки типов данных.
Переменные, объявленные в параметрах функции, могут быть сохранены либо в calldata, либо в памяти. Основное отличие заключается в том, что память может быть изменена функцией, в то время как calldata является неизменяемым.
Помните об этом принципе: если параметры функции доступны только для чтения, предпочтительно использовать calldata вместо memory. Это избегает ненужных операций копирования из calldata функции в память.
Пример 1: Использование памяти
При использовании ключевого слова memory значения массива копируются из закодированных calldata в память во время декодирования ABI. Стоимость выполнения этого блока кода составляет 3 694 единицы газа.
Пример 2: Использование calldata
При чтении значений непосредственно из calldata промежуточная операция с памятью пропускается. Эта оптимизация снижает стоимость выполнения до 2 413 газовых единиц, что приводит к улучшению эффективности газа на 35%.
Константные/неизменяемые переменные не хранятся в хранилище контракта. Эти переменные вычисляются во время компиляции и сохраняются в байт-коде контракта. Поэтому стоимость доступа к ним намного ниже по сравнению с переменными хранилища. Рекомендуется использовать ключевые слова Constant или Immutable при возможности.
Когда разработчики могут быть уверены, что арифметические операции не приведут к переполнению или недостатку, они могут использовать ключевое слово unchecked, введенное в Solidity v0.8.0, чтобы избежать лишних проверок на переполнение или недостаток, тем самым экономя затраты на газ.
На схеме ниже условно ограниченный i
Кроме того, версии компилятора 0.8.0 и выше больше не требуют использования библиотеки SafeMath, так как сам компилятор теперь включает встроенную защиту от переполнения и недостатка.
Код модификаторов встроен в функции, которые они модифицируют. Каждый раз, когда используется модификатор, его код дублируется, что увеличивает размер байткода и увеличивает расход Газа. Вот один из способов оптимизации расходов Газа для модификаторов:
До оптимизации:
После оптимизации:
В этом примере, путем рефакторинга логики во внутреннюю функцию _checkOwner(), которая может быть повторно использована в модификаторе, размер байткода сокращается, и снижаются затраты на Газ.
Для операторов || (ИЛИ) и && (И) логические операции вычисляются с использованием краткого замыкания, что означает, что если первое условие достаточно для определения результата логического выражения, второе условие не будет вычисляться.
Для оптимизации расходов на газ следует сначала разместить условия с более низкой вычислительной стоимостью, чтобы возможно было пропустить дорогостоящие вычисления.
Если в контракте есть неиспользуемые функции или переменные, рекомендуется их удалить. Это самый прямой способ снизить затраты на развертывание контракта и сохранить его размер маленьким.
Вот несколько практических предложений:
Используйте наиболее эффективные алгоритмы для вычислений. Если контракт напрямую использует определенные результаты вычислений, избыточные вычисления должны быть удалены. По сути, любые неиспользуемые вычисления должны быть удалены. В Ethereum разработчики могут получать вознаграждение в Газе за освобождение места хранения. Если переменная больше не нужна, она должна быть удалена с использованием ключевого слова delete или установлена в ее значение по умолчанию.
Оптимизация цикла: избегайте дорогостоящих операций в цикле, попытайтесь объединить циклы и переместить повторяющиеся вычисления из тела цикла.
Предварительно скомпилированные контракты предоставляют сложные библиотечные функции, такие как криптографические и хэширования операций. Поскольку код не выполняется на EVM, а запускается локально на узле клиента, требуется меньше газа. Использование предварительно скомпилированных контрактов может сэкономить газ, уменьшив вычислительную нагрузку, необходимую для выполнения смарт-контракта.
Примеры предварительно скомпилированных контрактов включают алгоритм эллиптической кривой цифровой подписи (ECDSA) и алгоритм хеширования SHA2-256. Используя эти предварительно скомпилированные контракты в смарт-контрактах, разработчики могут снизить затраты на газ и улучшить эффективность приложения.
Для полного списка предварительно скомпилированных контрактов, поддерживаемых сетью Ethereum, обратитесь к этой ссылке [4].
Inline assembly позволяет разработчикам писать низкоуровневый, но эффективный код, который может быть непосредственно выполнен EVM, без использования дорогих операций Solidity. Inline assembly также позволяет более точно контролировать использование памяти и хранилища, что дополнительно снижает затраты на Газ. Кроме того, inline assembly может выполнять некоторые сложные операции, которые сложно реализовать только с помощью Solidity, предлагая большую гибкость для оптимизации потребления Газа.
Вот пример использования встроенной сборки для экономии Газа:
Как видно из приведенного выше примера, второй случай, использующий встроенную сборку, обладает более высокой эффективностью Газа по сравнению со стандартным случаем.
Однако использование встроенной сборки также может внести риски и быть подвержено ошибкам. Поэтому рекомендуется использовать ее осторожно и только для опытных разработчиков.
Решения второго уровня могут сократить объем данных, которые необходимо хранить и вычислять на основной сети Ethereum.
Решения Layer 2, такие как rollups, sidechains и state channels, снимают с главной цепочки Ethereum обработку транзакций, обеспечивая более быстрые и дешевые транзакции.
Путем объединения большого количества транзакций вместе эти решения снижают количество транзакций on-chain, что в свою очередь снижает комиссии за газ. Использование решений второго уровня также улучшает масштабируемость Ethereum, позволяя более широкому кругу пользователей и приложений участвовать в сети без вызова перегрузки.
Доступно несколько инструментов оптимизации, таких как оптимизатор solc, оптимизатор сборки Truffle и компилятор Solidity в Remix.
Эти инструменты могут помочь минимизировать размер байткода, удалить неиспользуемый код и уменьшить количество операций, необходимых для выполнения смарт-контрактов. В сочетании с другими библиотеками оптимизации Газа, такими как "solmate," разработчики могут эффективно снизить затраты на Газ и улучшить эффективность смарт-контрактов.
Оптимизация потребления Газа - важный шаг для разработчиков, поскольку это не только минимизирует затраты на транзакции, но и повышает эффективность смарт-контрактов на сетях, совместимых с EVM. Приоритизируя операции по экономии затрат, уменьшая использование памяти, используя встроенную сборку и следуя другим bewt практикам, обсуждаемым в этой статье, разработчики могут эффективно снизить потребление Газа контрактами.
Однако важно отметить, что в процессе оптимизации разработчики должны быть осторожны, чтобы не вводить уязвимости безопасности. При оптимизации кода и сокращении расхода газа, внутренняя безопасность смарт-контракта никогда не должна быть подвергнута риску.
[1]https://ethereum.org/ru/developers/docs/gas/
[2] https://ethereum.github.io/yellowpaper/paper.pdf
[3]https://www.evm.codes/
[4]https://www.evm.codes/precompiled
Следуя этим рекомендациям, разработчики могут снизить расход газа в смарт-контрактах, снизить транзакционные издержки и создать более эффективные и удобные приложения.
Комиссии за газ на главной сети Ethereum всегда были серьезной проблемой, особенно в периоды сетевого скопления. В пиковые времена пользователи часто вынуждены платить крайне высокие комиссии за транзакции. Поэтому оптимизация затрат на газ на этапе разработки смарт-контрактов является критически важной. Оптимизация затрат на газ может не только эффективно снизить затраты на транзакции, но и повысить эффективность транзакций, обеспечивая пользователям более экономичный и эффективный блокчейн-опыт.
Эта статья представит механизм оплаты Газа Виртуальной Машины Ethereum (EVM), основные концепции, связанные с оптимизацией оплаты Газа, а также лучшие практики для оптимизации Газовых сборов при разработке смарт-контрактов. Надеется, что этот контент вдохновит и поможет разработчикам, а также поможет обычным пользователям лучше понять, как работает система оплаты Газа EVM, решая вместе вызовы в экосистеме блокчейна.
В сетях, совместимых с EVM, «Газ» относится к единице измерения вычислительной мощности, необходимой для выполнения определенных операций.
Диаграмма ниже иллюстрирует структуру EVM. На диаграмме потребление газа делится на три части: выполнение операций, внешние вызовы сообщений и чтение/запись памяти и хранилища.
Источник: Официальный веб-сайт Ethereum[1]
С момента активации EIP-1559 (London Hard Fork) комиссии за газ рассчитываются по следующей формуле:
Комиссия за газ = количество использованного газа * (базовая комиссия + приоритетная комиссия)
Основная комиссия сжигается, в то время как комиссия за приоритет является стимулом для того, чтобы поощрить валидаторов включить транзакцию в блокчейн. Установка более высокой комиссии за приоритет при отправке транзакции увеличивает вероятность включения транзакции в следующий блок. Это похоже на «чаевые», которые пользователи платят валидаторам.
При компиляции смарт-контракта с помощью Solidity контракт преобразуется в серию «операционных кодов» или опкодов.
Каждая операция (такая как создание контракта, выполнение вызовов сообщений, доступ к хранилищу учетных записей и выполнение операций на виртуальной машине) имеет связанную себестоимость газа, которая документирована в Ethereum Yellow Paper[2].
После нескольких изменений EIP стоимость газа некоторых операций была скорректирована, что может отличаться от значений в Желтой бумаге. Для получения подробной информации о последних затратах на операции обратитесь к этому источнику [3].
Основной концепцией оптимизации Газа является приоритетность экономичных операций в блокчейне EVM и избегание операций, которые влекут высокие затраты на Газ.
В EVM следующие операции относительно недорогие:
Операции с высокой стоимостью включают:
Исходя из вышеуказанных основных концепций, мы составили список лучших практик оптимизации комиссий за газ для сообщества разработчиков. Следуя этим практикам, разработчики могут снизить расход газа смарт-контрактов, снизить затраты на транзакции и создать более эффективные и удобные приложения.
В Solidity хранилище - это ограниченный ресурс, и его потребление газа значительно выше, чем память. Каждый раз, когда смарт-контракт читает или пишет в хранилище, это вызывает высокие затраты газа.
Согласно определению в Ethereum Yellow Paper, стоимость операций хранения более чем в 100 раз выше, чем операций памяти. Например, опкоды, такие как sload и sstore, стоят не менее 100 единиц Газа в лучшем случае, тогда как операции памяти, такие как mload и mstore, потребляют всего 3 единицы Газа.
Методы ограничения использования памяти включают:
Количество используемых слотов хранения в смарт-контракте и способ представления данных разработчиками могут значительно влиять на потребление Газа.
Компилятор Solidity упаковывает последовательные переменные хранилища в процессе компиляции, используя 32-байтовые слоты хранилища в качестве базовой единицы для хранения переменных. Упаковка переменных относится к практике расположения переменных таким образом, чтобы несколько переменных помещались в один слот хранения.
Слева - менее эффективная реализация, которая занимает 3 слота памяти; справа - более эффективная реализация.
Внести эту корректировку позволяет разработчикам сэкономить 20 000 единиц газа (поскольку хранение неиспользуемого слота хранения стоит 20 000 газа), но теперь требуется только два слота хранения.
Поскольку каждый слот хранения потребляет Газ, упаковка переменных оптимизирует использование Газа путем уменьшения количества необходимых слотов хранения.
Переменная может быть представлена с использованием разных типов данных, но затраты на операции варьируются в зависимости от типа. Выбор соответствующего типа данных помогает оптимизировать использование Газа.
Например, в Solidity целые числа могут быть разделены на разные размеры: uint8, uint16, uint32 и т. д. Поскольку EVM работает с 256-битными блоками, использование uint8 означает, что EVM должен сначала преобразовать его в uint256, и это преобразование сопряжено с дополнительными затратами на газ.
Мы можем сравнить затраты газа на uint8 и uint256, используя код на диаграмме. Функция UseUint() потребляет 120,382 газовых единиц, в то время как функция UseUInt8() потребляет 166,111 газовых единиц.
По отдельности использование uint256 дешевле, чем uint8. Однако, если мы применим ранее предложенную оптимизацию упаковки переменных, это будет иметь значение. Если разработчики могут упаковать четыре переменные uint8 в один слот памяти, общая стоимость итерации по ним будет ниже, чем при использовании четырех переменных uint256. В этом случае смарт-контракт может прочитать и записать слот памяти один раз и загрузить все четыре переменные uint8 в память/хранилище одной операцией.
Если данные могут быть ограничены до 32 байт, рекомендуется использовать тип данных bytes32 вместо bytes или strings. Как правило, переменные фиксированного размера потребляют меньше Газа, чем переменные с динамическим размером. Если длина байта может быть ограничена, попробуйте выбрать наименьшую длину от bytes1 до bytes32.
В Solidity списки данных можно представить двумя типами данных: Массивами и Отображениями, каждый из которых имеет отличный синтаксис и структуру.
Отображения обычно более эффективны и экономичны в большинстве случаев, в то время как массивы являются итерируемыми и поддерживают упаковку типов данных. Поэтому рекомендуется отдавать предпочтение использованию отображений при управлении списками данных, если только требуется итерация или расход газа может быть оптимизирован с помощью упаковки типов данных.
Переменные, объявленные в параметрах функции, могут быть сохранены либо в calldata, либо в памяти. Основное отличие заключается в том, что память может быть изменена функцией, в то время как calldata является неизменяемым.
Помните об этом принципе: если параметры функции доступны только для чтения, предпочтительно использовать calldata вместо memory. Это избегает ненужных операций копирования из calldata функции в память.
Пример 1: Использование памяти
При использовании ключевого слова memory значения массива копируются из закодированных calldata в память во время декодирования ABI. Стоимость выполнения этого блока кода составляет 3 694 единицы газа.
Пример 2: Использование calldata
При чтении значений непосредственно из calldata промежуточная операция с памятью пропускается. Эта оптимизация снижает стоимость выполнения до 2 413 газовых единиц, что приводит к улучшению эффективности газа на 35%.
Константные/неизменяемые переменные не хранятся в хранилище контракта. Эти переменные вычисляются во время компиляции и сохраняются в байт-коде контракта. Поэтому стоимость доступа к ним намного ниже по сравнению с переменными хранилища. Рекомендуется использовать ключевые слова Constant или Immutable при возможности.
Когда разработчики могут быть уверены, что арифметические операции не приведут к переполнению или недостатку, они могут использовать ключевое слово unchecked, введенное в Solidity v0.8.0, чтобы избежать лишних проверок на переполнение или недостаток, тем самым экономя затраты на газ.
На схеме ниже условно ограниченный i
Кроме того, версии компилятора 0.8.0 и выше больше не требуют использования библиотеки SafeMath, так как сам компилятор теперь включает встроенную защиту от переполнения и недостатка.
Код модификаторов встроен в функции, которые они модифицируют. Каждый раз, когда используется модификатор, его код дублируется, что увеличивает размер байткода и увеличивает расход Газа. Вот один из способов оптимизации расходов Газа для модификаторов:
До оптимизации:
После оптимизации:
В этом примере, путем рефакторинга логики во внутреннюю функцию _checkOwner(), которая может быть повторно использована в модификаторе, размер байткода сокращается, и снижаются затраты на Газ.
Для операторов || (ИЛИ) и && (И) логические операции вычисляются с использованием краткого замыкания, что означает, что если первое условие достаточно для определения результата логического выражения, второе условие не будет вычисляться.
Для оптимизации расходов на газ следует сначала разместить условия с более низкой вычислительной стоимостью, чтобы возможно было пропустить дорогостоящие вычисления.
Если в контракте есть неиспользуемые функции или переменные, рекомендуется их удалить. Это самый прямой способ снизить затраты на развертывание контракта и сохранить его размер маленьким.
Вот несколько практических предложений:
Используйте наиболее эффективные алгоритмы для вычислений. Если контракт напрямую использует определенные результаты вычислений, избыточные вычисления должны быть удалены. По сути, любые неиспользуемые вычисления должны быть удалены. В Ethereum разработчики могут получать вознаграждение в Газе за освобождение места хранения. Если переменная больше не нужна, она должна быть удалена с использованием ключевого слова delete или установлена в ее значение по умолчанию.
Оптимизация цикла: избегайте дорогостоящих операций в цикле, попытайтесь объединить циклы и переместить повторяющиеся вычисления из тела цикла.
Предварительно скомпилированные контракты предоставляют сложные библиотечные функции, такие как криптографические и хэширования операций. Поскольку код не выполняется на EVM, а запускается локально на узле клиента, требуется меньше газа. Использование предварительно скомпилированных контрактов может сэкономить газ, уменьшив вычислительную нагрузку, необходимую для выполнения смарт-контракта.
Примеры предварительно скомпилированных контрактов включают алгоритм эллиптической кривой цифровой подписи (ECDSA) и алгоритм хеширования SHA2-256. Используя эти предварительно скомпилированные контракты в смарт-контрактах, разработчики могут снизить затраты на газ и улучшить эффективность приложения.
Для полного списка предварительно скомпилированных контрактов, поддерживаемых сетью Ethereum, обратитесь к этой ссылке [4].
Inline assembly позволяет разработчикам писать низкоуровневый, но эффективный код, который может быть непосредственно выполнен EVM, без использования дорогих операций Solidity. Inline assembly также позволяет более точно контролировать использование памяти и хранилища, что дополнительно снижает затраты на Газ. Кроме того, inline assembly может выполнять некоторые сложные операции, которые сложно реализовать только с помощью Solidity, предлагая большую гибкость для оптимизации потребления Газа.
Вот пример использования встроенной сборки для экономии Газа:
Как видно из приведенного выше примера, второй случай, использующий встроенную сборку, обладает более высокой эффективностью Газа по сравнению со стандартным случаем.
Однако использование встроенной сборки также может внести риски и быть подвержено ошибкам. Поэтому рекомендуется использовать ее осторожно и только для опытных разработчиков.
Решения второго уровня могут сократить объем данных, которые необходимо хранить и вычислять на основной сети Ethereum.
Решения Layer 2, такие как rollups, sidechains и state channels, снимают с главной цепочки Ethereum обработку транзакций, обеспечивая более быстрые и дешевые транзакции.
Путем объединения большого количества транзакций вместе эти решения снижают количество транзакций on-chain, что в свою очередь снижает комиссии за газ. Использование решений второго уровня также улучшает масштабируемость Ethereum, позволяя более широкому кругу пользователей и приложений участвовать в сети без вызова перегрузки.
Доступно несколько инструментов оптимизации, таких как оптимизатор solc, оптимизатор сборки Truffle и компилятор Solidity в Remix.
Эти инструменты могут помочь минимизировать размер байткода, удалить неиспользуемый код и уменьшить количество операций, необходимых для выполнения смарт-контрактов. В сочетании с другими библиотеками оптимизации Газа, такими как "solmate," разработчики могут эффективно снизить затраты на Газ и улучшить эффективность смарт-контрактов.
Оптимизация потребления Газа - важный шаг для разработчиков, поскольку это не только минимизирует затраты на транзакции, но и повышает эффективность смарт-контрактов на сетях, совместимых с EVM. Приоритизируя операции по экономии затрат, уменьшая использование памяти, используя встроенную сборку и следуя другим bewt практикам, обсуждаемым в этой статье, разработчики могут эффективно снизить потребление Газа контрактами.
Однако важно отметить, что в процессе оптимизации разработчики должны быть осторожны, чтобы не вводить уязвимости безопасности. При оптимизации кода и сокращении расхода газа, внутренняя безопасность смарт-контракта никогда не должна быть подвергнута риску.
[1]https://ethereum.org/ru/developers/docs/gas/
[2] https://ethereum.github.io/yellowpaper/paper.pdf
[3]https://www.evm.codes/
[4]https://www.evm.codes/precompiled