Руководство по оптимизации Gas для смарт-контрактов Ethereum: Падение стоимости транзакции и повышение эффективности

Руководство по оптимизации Gas для смарт-контрактов Ethereum

Gas-расходы на основной сети Ethereum всегда были сложной проблемой, особенно это становится очевидным во время перегрузки сети. В периоды пиковых нагрузок пользователи часто должны платить высокие комиссии за транзакции. Поэтому оптимизация Gas-расходов на этапе разработки смарт-контрактов становится жизненно важной. Оптимизация потребления Gas не только позволяет эффективно снизить затраты на транзакции, но также повышает эффективность транзакций, предоставляя пользователям более экономичный и эффективный опыт использования блокчейна.

В данной статье будет рассмотрена механика Gas-стоимости Эфирной виртуальной машины (EVM), основные концепции оптимизации Gas-стоимости, а также лучшие практики оптимизации Gas-стоимости при разработке смарт-контрактов. Надеемся, что эти материалы смогут вдохновить разработчиков и оказать практическую помощь, а также помочь обычным пользователям лучше понять, как функционируют Gas-расходы EVM, чтобы вместе справляться с вызовами в экосистеме блокчейна.

Оптимизация Gas для смарт-контрактов Ethereum: десять лучших практик

Введение в механизм Gas-стоимости EVM

В совместимых с EVM сетях "Gas" является единицей измерения вычислительной мощности, необходимой для выполнения определенных операций.

В структуре EVM потребление газа в основном делится на три части: выполнение операций, вызовы внешних сообщений, а также чтение и запись в память и хранилище.

Поскольку выполнение каждой транзакции требует вычислительных ресурсов, будет взиматься определенная плата, чтобы предотвратить бесконечные циклы и атаки отказа в обслуживании ( DoS ). Плата, необходимая для завершения транзакции, называется "Gas-стоимость".

С момента вступления в силу хардфорка Лондон EIP-1559( ), плата за Gas рассчитывается по следующей формуле:

Газовая плата = использованные единицы газа * ( базовая плата + приоритетная плата )

Базовый сбор будет уничтожен, в то время как приоритетный сбор будет служить в качестве стимула, побуждая валидаторов добавлять транзакции в блокчейн. Установка более высокого приоритетного сбора при отправке транзакции может повысить вероятность того, что транзакция будет включена в следующий блок. Это похоже на "чаевые", которые пользователи платят валидаторам.

Оптимизация газа для смарт-контрактов Ethereum: 10 лучших практик

Понимание оптимизации Gas в EVM

При компиляции смарт-контрактов на Solidity контракт преобразуется в серию "операционных кодов", то есть opcodes.

Любая последовательность операций (, например создание смарт-контракта, выполнение вызова сообщения, доступ к хранилищу аккаунтов и выполнение операций на виртуальной машине ) имеет признанную стоимость потребления газа, эти расходы задокументированы в желтой книге Ethereum.

После многочисленных изменений EIP некоторые операционные коды были скорректированы по стоимости газа, что может отличаться от данных в жёлтой книге.

Основные концепции оптимизации газа

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

В EVM следующие операции имеют низкую стоимость:

  • Чтение и запись переменных в памяти
  • Чтение констант и неизменяемых переменных
  • Чтение и запись локальных переменных
  • Чтение переменной calldata, например, массива и структуры calldata
  • Внутренний вызов функции

Дорогие операции включают:

  • Чтение и запись состояния переменных, хранящихся в смарт-контрактах.
  • Вызов внешней функции
  • Циклическая операция

Оптимизация затрат на газ EVM: лучшие практики

Основываясь на вышеупомянутых основных концепциях, мы подготовили список лучших практик по оптимизации Gas-ставок для сообщества разработчиков. Следуя этим практикам, разработчики могут снизить потребление Gas-ставок смарт-контрактами, уменьшить стоимость транзакций и создать более эффективные и удобные для пользователей приложения.

Газовые оптимизации смарт-контрактов Ethereum: 10 лучших практик

1. Постарайтесь минимизировать использование хранилища

В Solidity, Storage( хранилище) является ограниченным ресурсом, его потребление газа значительно выше, чем у Memory( памяти). Каждый раз, когда смарт-контракт считывает или записывает данные из хранилища, возникают высокие затраты на газ.

Согласно определению из желтой книги Ethereum, стоимость операций хранения более чем в 100 раз выше, чем стоимость операций с памятью. Например, инструкции OPcodesmload и mstore расходуют всего 3 единицы газа, тогда как операции хранения, такие как sload и sstore, даже в самых идеальных условиях, стоят как минимум 100 единиц.

Методы ограничения использования хранилища включают:

  • Хранение непостоянных данных в памяти
  • Уменьшение количества изменений в хранилище: сохраняйте промежуточные результаты в памяти, а после завершения всех вычислений распределяйте результаты переменным хранения.

Оптимизация Gas для смарт-контрактов Ethereum: 10 лучших практик

2. Упаковка переменных

Количество хранилищ, используемых в смарт-контрактах для хранения slot(, а также способ, которым разработчики представляют данные, будут значительно влиять на потребление газа.

Компилятор Solidity упаковывает последовательные переменные хранения в процессе компиляции и использует 32-байтовый слот хранения в качестве базовой единицы хранения переменных. Упаковка переменных означает разумное распределение переменных, чтобы несколько переменных могли помещаться в один слот хранения.

С помощью этого изменения разработчики могут сэкономить 20 000 единиц газа ) для хранения неиспользуемого слота хранения, которое требовало бы 20 000 газа (, но теперь требуется всего два слота хранения.

Поскольку каждый слот хранения потребляет Газ, упаковка переменных оптимизирует использование Газа за счет уменьшения количества необходимых слотов хранения.

![Газовые оптимизации смарт-контрактов Ethereum: десять лучших практик])https://img-cdn.gateio.im/webp-social/moments-995905cb414526d4d991899d0c2e6443.webp(

) 3. Оптимизация типов данных

Переменная может быть представлена различными типами данных, но стоимость операций для разных типов данных также различна. Выбор подходящего типа данных помогает оптимизировать использование газа.

Например, в Solidity целые числа могут быть разделены на разные размеры: uint8, uint16, uint32 и т.д. Поскольку EVM выполняет операции на основе 256 бит, использование uint8 означает, что EVM сначала должен преобразовать его в uint256, а это преобразование потребует дополнительного расхода газа.

С точки зрения отдельного использования, здесь uint256 дешевле, чем uint8. Однако, если использовать предложенную нами оптимизацию упаковки переменных, дело обстоит иначе. Если разработчик сможет упаковать четыре переменные uint8 в один слот хранения, то общая стоимость их итерации будет ниже, чем у четырех переменных uint256. Таким образом, смарт-контракты смогут читать и записывать в один слот хранения, помещая четыре переменные uint8 в память/хранение за одну операцию.

![Ethereum смарт-контрактов Gas оптимизация десяти лучших практик]###https://img-cdn.gateio.im/webp-social/moments-55fcdb765912ef9cd238c46b1d248cff.webp(

) 4. Используйте переменные фиксированного размера вместо динамических переменных

Если данные могут быть ограничены 32 байтами, рекомендуется использовать тип данных bytes32 вместо bytes или strings. Как правило, переменные фиксированного размера потребляют меньше газа, чем переменные переменного размера. Если длина байтов может быть ограничена, старайтесь выбирать минимальную длину от bytes1 до bytes32.

![Оптимизация Gas для смарт-контрактов Ethereum: 10 лучших практик]###https://img-cdn.gateio.im/webp-social/moments-5f3d7e103e47c886f50599cffe35c707.webp(

) 5. Отображения и массивы

Списки данных Solidity могут быть представлены двумя типами данных: массивами ###Arrays ( и отображениями )Mappings (, но их синтаксис и структура совершенно различны.

В большинстве случаев отображения более эффективны и менее затратны, но массивы обладают итеративностью и поддерживают упаковку типов данных. Поэтому рекомендуется отдавать предпочтение отображениям при управлении списками данных, если не требуется итерация или если можно оптимизировать потребление газа за счет упаковки типов данных.

![Оптимизация Gas для смарт-контрактов Ethereum: десять лучших практик])https://img-cdn.gateio.im/webp-social/moments-9c566626ab499ef65d6f5089a2876ad3.webp(

) 6. Использование calldata вместо памяти

Переменные, объявленные в параметрах функции, могут храниться в calldata или memory. Основное различие между ними заключается в том, что memory может быть изменена функцией, в то время как calldata является неизменяемой.

Запомните этот принцип: если параметры функции являются только для чтения, следует предпочесть использование calldata вместо memory. Это поможет избежать ненужных операций копирования из calldata функции в memory.

![Оптимизация газа смарт-контрактов Ethereum: 10 лучших практик]###https://img-cdn.gateio.im/webp-social/moments-c0701f9e09280a1667495d54e262dd2f.webp(

) 7. Используйте ключевые слова Constant/Immutable по возможности.

Постоянные/Неизменяемые переменные не хранятся в хранилище контракта. Эти переменные вычисляются во время компиляции и хранятся в байт-коде контракта. Поэтому их стоимость доступа гораздо ниже, чем у хранилища, рекомендуется использовать ключевые слова Constant или Immutable по возможности.

![Оптимизация газа смарт-контрактов Ethereum: десять лучших практик]###https://img-cdn.gateio.im/webp-social/moments-a823fb7761aafa6529a6c45304e0314b.webp(

) 8. Используйте Unchecked, чтобы гарантировать, что переполнение/недополнение не произойдет

Когда разработчики могут быть уверены, что арифметические операции не приведут к переполнению или недостатку, они могут использовать ключевое слово unchecked, введенное в Solidity v0.8.0, чтобы избежать избыточных проверок на переполнение или недостаток, тем самым экономя стоимость газа.

Кроме того, компиляторы версии 0.8.0 и выше больше не требуют использования библиотеки SafeMath, так как сам компилятор уже встроил функции защиты от переполнения и недополнения.

![Оптимизация газа для смарт-контрактов Ethereum: десять лучших практик]###https://img-cdn.gateio.im/webp-social/moments-839b91e2f02389949aa698d460a497d8.webp(

) 9. Оптимизация модификатора

Код модификатора внедряется в изменённые функции, и каждый раз при использовании модификатора его код копируется. Это увеличивает размер байт-кода и повышает потребление газа.

Путем преобразования логики в внутреннюю функцию _checkOwner###(, разрешается повторное использование этой внутренней функции в модификаторе, что может уменьшить размер байт-кода и снизить стоимость газа.

![Оптимизация газа для смарт-контрактов Ethereum: десять лучших практик])https://img-cdn.gateio.im/webp-social/moments-a141884dcdcdc56faff12eee2601b7b7.webp(

) 10. Оптимизация короткого замыкания

Для операторов || и && логические операции производят короткое вычисление, то есть если первое условие уже может определить результат логического выражения, второе условие не будет оцениваться.

Чтобы оптимизировать потребление газа, условия с низкой стоимостью вычислений следует размещать в начале, это может позволить избежать дорогостоящих вычислений.

Дополнительные общие рекомендации

1. Удалить ненужный код

Если в смарт-контракте есть неиспользуемые функции или переменные, рекомендуется их удалить. Это самый прямой способ снизить стоимость развертывания контракта и поддерживать его небольшой размер.

Вот несколько полезных советов:

  • Используйте наиболее эффективные алгоритмы для вычислений. Если в смарт-контракте напрямую используются результаты некоторых вычислений, то следует убрать эти избыточные вычислительные процессы. По сути, любые неиспользуемые вычисления должны быть удалены.

  • В Ethereum разработчики могут получать награду в виде Gas, освобождая память. Если переменная больше не нужна, следует удалить её с помощью ключевого слова delete или установить её в значение по умолчанию.

  • Оптимизация циклов: избегайте высокозатратных операций в циклах, по возможности объединяйте циклы и выносите повторные вычисления за пределы тела цикла.

2. Использование предкомпилированных смарт-контрактов

Предварительно скомпилированные контракты предоставляют сложные библиотечные функции, такие как операции шифрования и хеширования. Поскольку код выполняется не на EVM, а локально на клиентском узле, требуется меньше газа. Использование предварительно скомпилированных контрактов может сэкономить газ за счет уменьшения вычислительной нагрузки, необходимой для выполнения смарт-контрактов.

Примеры предкомпилированных контрактов включают алгоритм цифровой подписи на эллиптической кривой ###ECDSA( и хэш-алгоритм SHA2-256. Используя эти предкомпилированные контракты в смарт-контрактах, разработчики могут снизить стоимость газа и повысить эффективность работы приложений.

) 3. Использование встроенного ассемблера

Встраиваемая сборка ### in-line assembly ( позволяет разработчикам писать низкоуровневый, но эффективный код, который может непосредственно выполняться EVM, без необходимости использования дорогих операций Solidity. Встраиваемая сборка также позволяет более точно контролировать использование памяти и хранилища, что дополнительно снижает расходы на Gas. Кроме того, встраиваемая сборка может выполнять некоторые сложные операции, которые трудно реализовать только с помощью Solidity, предоставляя больше гибкости для оптимизации потребления Gas.

Однако использование встроенного ассемблера также может привести к ветру

Посмотреть Оригинал
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
  • Награда
  • 3
  • Поделиться
комментарий
0/400
Deconstructionistvip
· 19ч назад
Эти газовые расходы слишком высокие, я не могу это вынести.
Посмотреть ОригиналОтветить0
MissedTheBoatvip
· 19ч назад
Есть макароны, экономим две капли масла, а еще экономим газ.
Посмотреть ОригиналОтветить0
OnchainGossipervip
· 19ч назад
Газ费真的 очень дорогой а啊啊
Посмотреть ОригиналОтветить0
  • Закрепить