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

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

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

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

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

Введение в механизм газовых сборов EVM

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

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

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

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

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

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

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

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

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

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

) 2.Базовые концепции оптимизации газа

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

) 9. Оптимизированный модификатор

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Однако использование встроенной ассемблерной вставки также может представлять риск.

ETH-2.08%
Посмотреть Оригинал
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
  • Награда
  • 3
  • Поделиться
комментарий
0/400
StrawberryIcevip
· 07-31 07:32
Газовые сборы действительно непереносимы
Посмотреть ОригиналОтветить0
OnChainDetectivevip
· 07-31 07:22
Экономия на газе — это уже экономия.
Посмотреть ОригиналОтветить0
JustHodlItvip
· 07-31 07:06
ценные идеи满满太赞了
Посмотреть ОригиналОтветить0
  • Закрепить