Эфир坊смарт-контрактgas优化十大最佳实践

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

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

Введение в механизм оплаты газа EVM

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

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

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

Источник: Официальный сайт Ethereum [1]

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

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

Комиссия за транзакцию = количество использованного Газа * (основная комиссия + приоритетная комиссия)

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

1.Оптимизация Газа в EVM

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

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

Лучшие практики оптимизации газа для смарт-контрактов ETH坊

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

2. Основные понятия оптимизации газа

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

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

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

Операции с высокой стоимостью включают:

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

Оптимальные практики по снижению комиссий EVM Gas

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

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

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

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

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

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

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

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

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

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

Слева представлен способ реализации с низкой эффективностью, требующий использования 3 слотов памяти; справа - более эффективный способ.

Эфир坊смарт-контрактдегазоптимизациядесятьлучшихпрактик

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

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

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

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

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

! [Топ-10 лучших практик оптимизации газа смарт-контрактов Ethereum] (https://cdn-img.panewslab.com/yijian/2024/12/30/images/6e6c47d1fdce232294b30341f5f2ece6.jpg)

Мы можем сравнить стоимость газа uint8 и uint256 по коду на рисунке. Функция UseUint() потребляет 120,382 единиц газа, в то время как функция UseUInt8() потребляет 166,111 единиц газа.

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

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

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

Лучшие практики оптимизации газа для смарт-контрактов ETH坊

Лучшие практики оптимизации смарт-контракта ETH Gas

5. Сопоставление и массивы

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

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

6. Используйте calldata вместо memory

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

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

Пример 1: использование памяти

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

При использовании ключевого слова memory значения массива копируются из закодированного calldata в память в процессе декодирования ABI. Стоимость выполнения этого блока кода составляет 3,694 газовых единицы.

Пример 2: использование calldata

Лучшие практики оптимизации газа для смарт-контрактов ETH

При чтении значения непосредственно из calldata, пропускаются промежуточные операции с памятью. Такая оптимизация позволяет снизить стоимость выполнения до 2 413 газовых единиц, что повышает эффективность газа на 35%.

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

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

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

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

На рисунке, при условии ограничения i

Эфир Ethereum Смарт-контракт Газ оптимизация десять лучших практик

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

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

Код модификатора вставляется в измененную функцию, и при каждом использовании модификатора его код копируется. Это увеличивает размер байт-кода и увеличивает расход Газа. Вот один из способов оптимизации стоимости Газа модификатора:

Перед оптимизацией:

Лучшие практики оптимизации газа для смарт-контракта ETH

После оптимизации:

Лучшие практики оптимизации Gas у смарт-контрактов Ethereum

В данном примере путем перестройки логики во внутреннюю функцию _checkOwner() позволяется повторное использование этой внутренней функции в модификаторе, что позволяет сократить размер байткода и снизить комиссию за транзакцию Газ.

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

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

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

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

1. Удаление ненужного кода

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

Ниже приведены некоторые практические советы:

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

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

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

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

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

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

Для полного списка предварительно скомпилированных контрактов, поддерживаемых сетью Ethereum, ознакомьтесь с этим местом [4].

3. Использование встроенного кода на языке ассемблера

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

Вот пример кода, использующего встроенную сборку для экономии газа:

Десять лучших практик оптимизации газа для смарт-контрактов ETH

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

Однако использование встроенной ассемблерной вставки также может быть рискованным и подверженным ошибкам. Поэтому его следует использовать с осторожностью и только опытными разработчиками.

4. Использование решений Layer 2

Использование решения Layer 2 может уменьшить объем данных, который необходимо хранить и обрабатывать в сети Ethereum.

Решения Layer 2, такие как rollups, боковые цепочки и каналы состояний, позволяют разгрузить обработку транзакций с главной сети Ethereum, что обеспечивает более быстрые и дешевые транзакции.

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

5. Использование оптимизационных инструментов и библиотек

Для оптимизации доступно несколько инструментов, таких как оптимизатор solc, оптимизатор сборки Truffle и компилятор Solidity Remix.

Лучшие практики оптимизации газа для смарт-контрактов Ethereum

Эти инструменты могут помочь уменьшить размер байт-кода, удалить бесполезный код и уменьшить количество операций, необходимых для выполнения смарт-контракта. В сочетании с другими библиотеками оптимизации Газа, такими как "solmate", разработчики могут эффективно снизить комиссию за транзакцию и повысить эффективность смарт-контракта.

Заключение

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

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

[1] :

[2] :

[3] :

[4] :предварительно скомпилированный

ETH2,27%
GAS1,74%
Посмотреть Оригинал
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
  • Награда
  • 1
  • Репост
  • Поделиться
комментарий
Добавить комментарий
Добавить комментарий
Нет комментариев
  • Закреплено