Руководство по оптимизации газовых сборов для EVM смарт-контрактов
На сети Ethereum комиссии за газ всегда были проблемой для пользователей, особенно в периоды загруженности сети. В периоды пиковых торгов пользователям часто приходится платить высокие сборы, чтобы завершить транзакцию. Поэтому оптимизация комиссии за газ на этапе разработки смарт-контрактов особенно важна. Оптимизация потребления газа не только может эффективно снизить затраты на транзакции, но и повысить эффективность транзакций, обеспечивая пользователям более экономичный и эффективный опыт использования блокчейна.
В данной статье будет рассмотрен механизм Gas-стоимости Ethereum Virtual Machine (EVM), основные концепции оптимизации Gas-стоимости, а также лучшие практики оптимизации Gas-стоимости при разработке смарт-контрактов. Надеемся, что эти материалы будут полезны для разработчиков и помогут обычным пользователям лучше понять, как работает Gas-стоимость EVM, чтобы вместе справляться с вызовами в экосистеме блокчейна.
Введение в механизм Gas-оплат EVM
В совместимых с EVM сетях Gas является единицей измерения вычислительной мощности, необходимой для выполнения определённых операций.
В структуре EVM расход газа в основном делится на три части: выполнение операций, вызовы внешних сообщений, а также чтение и запись в память и хранилище.
Каждое выполнение транзакции требует использования вычислительных ресурсов, поэтому взимается определенная плата, чтобы предотвратить бесконечные циклы и атаки отказа в обслуживании ( DoS ). Плата, необходимая для завершения транзакции, называется Gas fee.
С момента внедрения EIP-1559, Gas-ставки рассчитываются по следующей формуле:
Базовый сбор будет уничтожен, а приоритетный сбор будет использован в качестве стимула, чтобы поощрять валидаторов добавлять транзакции в блокчейн. Установка более высокого приоритетного сбора может повысить вероятность того, что транзакция будет упакована в следующий блок.
Понимание оптимизации Gas в EVM
При компиляции смарт-контрактов на Solidity контракт преобразуется в ряд операторов (opcodes).
Каждый код операции (, такой как создание смарт-контрактов, выполнение вызовов сообщений, доступ к хранилищу аккаунтов и т.д., ) имеет фиксированную стоимость потребления газа. Эти затраты зафиксированы в "Желтой книге" Ethereum, но с изменениями, внесенными в результате нескольких EIP, стоимость газа для некоторых кодов операций была скорректирована.
Основные концепции оптимизации газа
Основная идея оптимизации Gas заключается в том, чтобы приоритетно выбирать операции с высокой стоимостью эффективности на блокчейне EVM, избегая операций с высокой стоимостью Gas.
В EVM следующие операции имеют низкую стоимость:
Чтение и запись переменных в памяти
Чтение констант и неизменяемых переменных
Чтение и запись локальных переменных
Чтение переменной calldata
Вызов внутренних функций
Операции с высокой стоимостью включают:
Чтение и запись состояния переменных, хранящихся в смарт-контрактах
Вызов внешних функций
Циклические операции
Лучшие практики оптимизации газовых сборов EVM
1. Старайтесь минимизировать использование памяти.
В Solidity хранилище ( является ограниченным ресурсом, потребление газа которого значительно выше, чем у памяти ). Каждый раз, когда смарт-контракт читает или записывает данные в хранилище, возникают высокие затраты на газ.
Согласно желтой книге Ethereum, стоимость операций хранения в 100 раз выше, чем стоимость операций с памятью. Например, инструкции mload и mstore используют всего 3 единицы газа, в то время как sload и sstore даже в самых идеальных условиях требуют как минимум 100 единиц.
Методы ограничения использования хранилища включают:
Хранить непостоянные данные в памяти
Уменьшение количества изменений в хранилище: сохраняйте промежуточные результаты в памяти и только после завершения всех вычислений распределяйте результаты по переменным хранилища.
( 2. Упаковка переменных
Количество и способ представления данных в Storage slot) смарт-контрактов будут сильно влиять на расход Gas.
Компилятор Solidity упаковывает последовательные переменные хранения в процессе компиляции, используя 32-байтный слот хранения в качестве базовой единицы хранения переменных. Упаковка переменных означает разумное размещение переменных, позволяющее нескольким переменным помещаться в один слот хранения.
С помощью этой настройки разработчики могут сэкономить значительное количество единиц газа. Поскольку каждый слот хранения потребляет газ, упаковка переменных оптимизирует использование газа, уменьшая количество необходимых слотов хранения.
![Десять лучших практик оптимизации Gas для смарт-контрактов Ethereum]###https://img-cdn.gateio.im/webp-social/moments-30f0bc370a7b9ca65f3d623c31262b76.webp(
) 3. Оптимизация типов данных
Выбор подходящего типа данных помогает оптимизировать использование Gas.
Например, в Solidity целые числа можно разделить на разные размеры: uint8, uint16, uint32 и т.д. Поскольку EVM выполняет операции с единицами 256 бит, использование uint8 означает, что EVM сначала должен преобразовать его в uint256, и это преобразование будет дополнительно потреблять Gas.
Однако, если удастся упаковать четыре переменные uint8 в один слот хранения, то общая стоимость их итерации будет ниже, чем у четырех переменных uint256. Таким образом, смарт-контракты смогут читать и записывать один слот хранения и за одно действие поместить четыре переменные uint8 в память/хранение.
4. Используйте фиксированные переменные вместо динамических переменных
Если данные можно ограничить 32 байтами, рекомендуется использовать тип данных bytes32 вместо bytes или strings. Как правило, переменные фиксированного размера потребляют меньше газа, чем переменные переменного размера. Если длину байтов можно ограничить, старайтесь выбирать минимальную длину от bytes1 до bytes32.
5. Отображения и массивы
Список данных Solidity может быть представлен двумя типами данных: массивами ( Arrays ) и отображениями ### Mappings (.
В большинстве случаев отображение более эффективно и менее затратно, но массивы имеют итерабельность и поддерживают упаковку типов данных. Поэтому рекомендуется при управлении списками данных в первую очередь использовать отображение, если не требуется итерация или можно оптимизировать потребление газа за счет упаковки типов данных.
![Десять лучших практик оптимизации Gas для смарт-контрактов Ethereum])https://img-cdn.gateio.im/webp-social/moments-5f3d7e103e47c886f50599cffe35c707.webp(
) 6. Используйте calldata вместо memory
Переменные, объявленные в параметрах функции, могут храниться в calldata или memory. Основное различие между ними заключается в том, что memory может быть изменена функцией, тогда как calldata является неизменяемой.
Если параметры функции являются только для чтения, следует предпочесть использование calldata вместо memory. Это поможет избежать ненужных операций копирования из calldata функции в memory.
7. Используйте ключевые слова Constant/Immutable по возможности.
Постоянные/неизменяемые переменные не хранятся в хранилище контракта. Эти переменные вычисляются на этапе компиляции и хранятся в байт-коде контракта. Поэтому их стоимость доступа значительно ниже по сравнению с хранилищем, рекомендуется использовать ключевые слова Constant или Immutable, когда это возможно.
8. Используйте Unchecked, чтобы гарантировать, что переполнение/недостаток не произойдет.
Когда разработчики могут быть уверены, что арифметические операции не приведут к переполнению или недостатку, они могут использовать ключевое слово unchecked, введенное в Solidity v0.8.0, чтобы избежать излишних проверок на переполнение или недостаток, тем самым сэкономив Gas.
Кроме того, компиляторы версии 0.8.0 и выше больше не требуют использования библиотеки SafeMath, так как сам компилятор теперь встроил функции защиты от переполнения и неполного переполнения.
9. Оптимизация модификатора
Код модификатора встроен в изменённые функции, и при каждом использовании модификатора его код копируется. Это увеличивает размер байт-кода и повышает потребление газа.
Путем рефакторинга логики в внутреннюю функцию, которая может быть повторно использована в модификаторах, можно уменьшить размер байт-кода и снизить затраты на газ.
10. Оптимизация короткого замыкания
Для логических операторов || и && происходит короткое замыкание, то есть если первое условие уже может определить результат логического выражения, то второе условие не будет оцениваться.
Чтобы оптимизировать потребление Gas, условия с низкой стоимостью вычислений следует ставить впереди, это может позволить избежать дорогостоящих вычислений.
Дополнительные общие рекомендации
1. Удалить ненужный код
Если в смарт-контракте есть неиспользуемые функции или переменные, рекомендуется их удалить. Это самый прямой способ уменьшить стоимость развертывания контракта и поддерживать небольшой размер контракта.
Некоторые полезные советы:
Используйте наиболее эффективные алгоритмы для вычислений.
Удалить неиспользуемые вычислительные процессы.
Используйте ключевое слово delete, чтобы удалить больше не нужные переменные, или установите их в значение по умолчанию.
Оптимизация циклов: избегайте затратных операций в циклах, по возможности объединяйте циклы и выносите повторные вычисления за пределы тела цикла.
( 2. Использование предсобранных смарт-контрактов
Предварительно скомпилированные контракты предлагают сложные библиотечные функции, такие как операции шифрования и хеширования. Поскольку код выполняется не на EVM, а локально на клиентском узле, требуется меньше газа. Использование предварительно скомпилированных контрактов может сэкономить газ, снижая вычислительную нагрузку, необходимую для выполнения смарт-контрактов.
Примеры предкомпилированных контрактов включают алгоритм цифровой подписи на эллиптической кривой )ECDSA### и хэш-алгоритм SHA2-256.
3. Использование встроенного ассемблера
Инлайн-ассемблер позволяет разработчикам писать низкоуровневый, но эффективный код, который может быть выполнен непосредственно EVM, без необходимости использования дорогих операций Solidity. Инлайн-ассемблер также позволяет более точно контролировать использование памяти и хранилища, тем самым дополнительно снижая затраты на газ. Кроме того, инлайн-ассемблер может выполнять некоторые сложные операции, которые трудно реализовать только с использованием Solidity, что предоставляет больше гибкости для оптимизации потребления газа.
Однако использование встроенного ассемблера также может представлять риск и легко привести к ошибкам. Поэтому следует использовать его с осторожностью и только опытным разработчикам.
( 4. Использование решений Layer 2
Использование решений Layer 2 может уменьшить объем данных, которые необходимо хранить и обрабатывать в основной сети Ethereum.
Решения второго уровня, такие как rollups, сайдчейны и каналы состояния, могут разгружать обработку транзакций с основной цепи Ethereum, обеспечивая более быстрые и дешевые транзакции.
С помощью объединения большого количества транзакций в одну, эти решения уменьшают количество транзакций в сети, тем самым снижая Gas-расходы. Использование решений второго уровня также может повысить масштабируемость Ethereum, позволяя большему числу пользователей и приложений участвовать в сети, не вызывая перегрузки сети.
) 5. Использование инструментов и библиотек оптимизации
Существует несколько доступных инструментов оптимизации, таких как оптимизатор solc, оптимизатор сборки Truffle и компилятор Solidity Remix.
Эти инструменты могут помочь минимизировать размер байт-кода, удалить ненужный код и сократить количество операций, необходимых для выполнения смарт-контрактов. В сочетании с другими библиотеками оптимизации Gas, такими как "solmate", разработчики могут эффективно снизить затраты на Gas и повысить эффективность смарт-контрактов.
![Десять лучших практик оптимизации Gas для смарт-контрактов Ethereum]###https://img-cdn.gateio.im/webp-social/moments-248337b15929868ed1250ffb9fcfa289.webp###
Вывод
Оптимизация потребления газа является важным шагом для разработчиков
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
15 Лайков
Награда
15
9
Репост
Поделиться
комментарий
0/400
NotGonnaMakeIt
· 07-13 18:50
Белая вода Блокчейн-сообщество все понимают, что основное только продажа Газ
Посмотреть ОригиналОтветить0
DeFiGrayling
· 07-13 18:26
Газ так дорог, что чуть не разорился.
Посмотреть ОригиналОтветить0
BearMarketSurvivor
· 07-13 13:49
Газ снова обирает бедных людей, ууу.
Посмотреть ОригиналОтветить0
WalletManager
· 07-12 02:38
Газ слишком дорог, лучше пойти торговать на L2.
Посмотреть ОригиналОтветить0
RugDocDetective
· 07-12 02:36
Не усложняй, газовые сборы - это настоящая проблема.
Посмотреть ОригиналОтветить0
BearMarketGardener
· 07-12 02:21
про снова разыгрывает людей как лохов что покупать для сокращения потерь пришло
Посмотреть ОригиналОтветить0
DataChief
· 07-12 02:18
Боже, опять за водный Газ. Можешь сказать что-нибудь новое?
Посмотреть ОригиналОтветить0
RektCoaster
· 07-12 02:16
Кто может сказать мне, как спасти мой Кошелек, Газовые расходы действительно съедают людей
Руководство по оптимизации Gas-стоимости смарт-контрактов EVM: 10 полезных советов
Руководство по оптимизации газовых сборов для EVM смарт-контрактов
На сети Ethereum комиссии за газ всегда были проблемой для пользователей, особенно в периоды загруженности сети. В периоды пиковых торгов пользователям часто приходится платить высокие сборы, чтобы завершить транзакцию. Поэтому оптимизация комиссии за газ на этапе разработки смарт-контрактов особенно важна. Оптимизация потребления газа не только может эффективно снизить затраты на транзакции, но и повысить эффективность транзакций, обеспечивая пользователям более экономичный и эффективный опыт использования блокчейна.
В данной статье будет рассмотрен механизм Gas-стоимости Ethereum Virtual Machine (EVM), основные концепции оптимизации Gas-стоимости, а также лучшие практики оптимизации Gas-стоимости при разработке смарт-контрактов. Надеемся, что эти материалы будут полезны для разработчиков и помогут обычным пользователям лучше понять, как работает Gas-стоимость EVM, чтобы вместе справляться с вызовами в экосистеме блокчейна.
Введение в механизм Gas-оплат EVM
В совместимых с EVM сетях Gas является единицей измерения вычислительной мощности, необходимой для выполнения определённых операций.
В структуре EVM расход газа в основном делится на три части: выполнение операций, вызовы внешних сообщений, а также чтение и запись в память и хранилище.
Каждое выполнение транзакции требует использования вычислительных ресурсов, поэтому взимается определенная плата, чтобы предотвратить бесконечные циклы и атаки отказа в обслуживании ( DoS ). Плата, необходимая для завершения транзакции, называется Gas fee.
С момента внедрения EIP-1559, Gas-ставки рассчитываются по следующей формуле:
Газовые расходы = Используемые единицы газа * ( базовая ставка + приоритетный сбор )
Базовый сбор будет уничтожен, а приоритетный сбор будет использован в качестве стимула, чтобы поощрять валидаторов добавлять транзакции в блокчейн. Установка более высокого приоритетного сбора может повысить вероятность того, что транзакция будет упакована в следующий блок.
Понимание оптимизации Gas в EVM
При компиляции смарт-контрактов на Solidity контракт преобразуется в ряд операторов (opcodes).
Каждый код операции (, такой как создание смарт-контрактов, выполнение вызовов сообщений, доступ к хранилищу аккаунтов и т.д., ) имеет фиксированную стоимость потребления газа. Эти затраты зафиксированы в "Желтой книге" Ethereum, но с изменениями, внесенными в результате нескольких EIP, стоимость газа для некоторых кодов операций была скорректирована.
Основные концепции оптимизации газа
Основная идея оптимизации Gas заключается в том, чтобы приоритетно выбирать операции с высокой стоимостью эффективности на блокчейне EVM, избегая операций с высокой стоимостью Gas.
В EVM следующие операции имеют низкую стоимость:
Операции с высокой стоимостью включают:
Лучшие практики оптимизации газовых сборов EVM
1. Старайтесь минимизировать использование памяти.
В Solidity хранилище ( является ограниченным ресурсом, потребление газа которого значительно выше, чем у памяти ). Каждый раз, когда смарт-контракт читает или записывает данные в хранилище, возникают высокие затраты на газ.
Согласно желтой книге Ethereum, стоимость операций хранения в 100 раз выше, чем стоимость операций с памятью. Например, инструкции mload и mstore используют всего 3 единицы газа, в то время как sload и sstore даже в самых идеальных условиях требуют как минимум 100 единиц.
Методы ограничения использования хранилища включают:
( 2. Упаковка переменных
Количество и способ представления данных в Storage slot) смарт-контрактов будут сильно влиять на расход Gas.
Компилятор Solidity упаковывает последовательные переменные хранения в процессе компиляции, используя 32-байтный слот хранения в качестве базовой единицы хранения переменных. Упаковка переменных означает разумное размещение переменных, позволяющее нескольким переменным помещаться в один слот хранения.
С помощью этой настройки разработчики могут сэкономить значительное количество единиц газа. Поскольку каждый слот хранения потребляет газ, упаковка переменных оптимизирует использование газа, уменьшая количество необходимых слотов хранения.
![Десять лучших практик оптимизации Gas для смарт-контрактов Ethereum]###https://img-cdn.gateio.im/webp-social/moments-30f0bc370a7b9ca65f3d623c31262b76.webp(
) 3. Оптимизация типов данных
Выбор подходящего типа данных помогает оптимизировать использование Gas.
Например, в Solidity целые числа можно разделить на разные размеры: uint8, uint16, uint32 и т.д. Поскольку EVM выполняет операции с единицами 256 бит, использование uint8 означает, что EVM сначала должен преобразовать его в uint256, и это преобразование будет дополнительно потреблять Gas.
Однако, если удастся упаковать четыре переменные uint8 в один слот хранения, то общая стоимость их итерации будет ниже, чем у четырех переменных uint256. Таким образом, смарт-контракты смогут читать и записывать один слот хранения и за одно действие поместить четыре переменные uint8 в память/хранение.
4. Используйте фиксированные переменные вместо динамических переменных
Если данные можно ограничить 32 байтами, рекомендуется использовать тип данных bytes32 вместо bytes или strings. Как правило, переменные фиксированного размера потребляют меньше газа, чем переменные переменного размера. Если длину байтов можно ограничить, старайтесь выбирать минимальную длину от bytes1 до bytes32.
5. Отображения и массивы
Список данных Solidity может быть представлен двумя типами данных: массивами ( Arrays ) и отображениями ### Mappings (.
В большинстве случаев отображение более эффективно и менее затратно, но массивы имеют итерабельность и поддерживают упаковку типов данных. Поэтому рекомендуется при управлении списками данных в первую очередь использовать отображение, если не требуется итерация или можно оптимизировать потребление газа за счет упаковки типов данных.
![Десять лучших практик оптимизации Gas для смарт-контрактов Ethereum])https://img-cdn.gateio.im/webp-social/moments-5f3d7e103e47c886f50599cffe35c707.webp(
) 6. Используйте calldata вместо memory
Переменные, объявленные в параметрах функции, могут храниться в calldata или memory. Основное различие между ними заключается в том, что memory может быть изменена функцией, тогда как calldata является неизменяемой.
Если параметры функции являются только для чтения, следует предпочесть использование calldata вместо memory. Это поможет избежать ненужных операций копирования из calldata функции в memory.
7. Используйте ключевые слова Constant/Immutable по возможности.
Постоянные/неизменяемые переменные не хранятся в хранилище контракта. Эти переменные вычисляются на этапе компиляции и хранятся в байт-коде контракта. Поэтому их стоимость доступа значительно ниже по сравнению с хранилищем, рекомендуется использовать ключевые слова Constant или Immutable, когда это возможно.
8. Используйте Unchecked, чтобы гарантировать, что переполнение/недостаток не произойдет.
Когда разработчики могут быть уверены, что арифметические операции не приведут к переполнению или недостатку, они могут использовать ключевое слово unchecked, введенное в Solidity v0.8.0, чтобы избежать излишних проверок на переполнение или недостаток, тем самым сэкономив Gas.
Кроме того, компиляторы версии 0.8.0 и выше больше не требуют использования библиотеки SafeMath, так как сам компилятор теперь встроил функции защиты от переполнения и неполного переполнения.
9. Оптимизация модификатора
Код модификатора встроен в изменённые функции, и при каждом использовании модификатора его код копируется. Это увеличивает размер байт-кода и повышает потребление газа.
Путем рефакторинга логики в внутреннюю функцию, которая может быть повторно использована в модификаторах, можно уменьшить размер байт-кода и снизить затраты на газ.
10. Оптимизация короткого замыкания
Для логических операторов || и && происходит короткое замыкание, то есть если первое условие уже может определить результат логического выражения, то второе условие не будет оцениваться.
Чтобы оптимизировать потребление Gas, условия с низкой стоимостью вычислений следует ставить впереди, это может позволить избежать дорогостоящих вычислений.
Дополнительные общие рекомендации
1. Удалить ненужный код
Если в смарт-контракте есть неиспользуемые функции или переменные, рекомендуется их удалить. Это самый прямой способ уменьшить стоимость развертывания контракта и поддерживать небольшой размер контракта.
Некоторые полезные советы:
( 2. Использование предсобранных смарт-контрактов
Предварительно скомпилированные контракты предлагают сложные библиотечные функции, такие как операции шифрования и хеширования. Поскольку код выполняется не на EVM, а локально на клиентском узле, требуется меньше газа. Использование предварительно скомпилированных контрактов может сэкономить газ, снижая вычислительную нагрузку, необходимую для выполнения смарт-контрактов.
Примеры предкомпилированных контрактов включают алгоритм цифровой подписи на эллиптической кривой )ECDSA### и хэш-алгоритм SHA2-256.
3. Использование встроенного ассемблера
Инлайн-ассемблер позволяет разработчикам писать низкоуровневый, но эффективный код, который может быть выполнен непосредственно EVM, без необходимости использования дорогих операций Solidity. Инлайн-ассемблер также позволяет более точно контролировать использование памяти и хранилища, тем самым дополнительно снижая затраты на газ. Кроме того, инлайн-ассемблер может выполнять некоторые сложные операции, которые трудно реализовать только с использованием Solidity, что предоставляет больше гибкости для оптимизации потребления газа.
Однако использование встроенного ассемблера также может представлять риск и легко привести к ошибкам. Поэтому следует использовать его с осторожностью и только опытным разработчикам.
( 4. Использование решений Layer 2
Использование решений Layer 2 может уменьшить объем данных, которые необходимо хранить и обрабатывать в основной сети Ethereum.
Решения второго уровня, такие как rollups, сайдчейны и каналы состояния, могут разгружать обработку транзакций с основной цепи Ethereum, обеспечивая более быстрые и дешевые транзакции.
С помощью объединения большого количества транзакций в одну, эти решения уменьшают количество транзакций в сети, тем самым снижая Gas-расходы. Использование решений второго уровня также может повысить масштабируемость Ethereum, позволяя большему числу пользователей и приложений участвовать в сети, не вызывая перегрузки сети.
) 5. Использование инструментов и библиотек оптимизации
Существует несколько доступных инструментов оптимизации, таких как оптимизатор solc, оптимизатор сборки Truffle и компилятор Solidity Remix.
Эти инструменты могут помочь минимизировать размер байт-кода, удалить ненужный код и сократить количество операций, необходимых для выполнения смарт-контрактов. В сочетании с другими библиотеками оптимизации Gas, такими как "solmate", разработчики могут эффективно снизить затраты на Gas и повысить эффективность смарт-контрактов.
![Десять лучших практик оптимизации Gas для смарт-контрактов Ethereum]###https://img-cdn.gateio.im/webp-social/moments-248337b15929868ed1250ffb9fcfa289.webp###
Вывод
Оптимизация потребления газа является важным шагом для разработчиков