Оптимізація Gas-витрат смартконтрактів Ethereum: 15 порад

Посібник з оптимізації витрат на газ для смартконтрактів Ethereum

Газові витрати на основній мережі Ethereum завжди були проблемою, особливо під час заторів у мережі. У години пік користувачі часто змушені платити надзвичайно високі комісії за транзакції. Тому оптимізація газових витрат на етапі розробки смартконтрактів є вкрай важливою. Оптимізація споживання газу не тільки може ефективно знизити витрати на транзакції, а й підвищити ефективність транзакцій, забезпечуючи користувачам більш економічний і ефективний досвід використання блокчейну.

Ця стаття висвітлить механізм плати за Gas Етерум віртуальної машини (EVM), основні концепції оптимізації плати за Gas, а також найкращі практики оптимізації плати за Gas під час розробки смартконтрактів. Сподіваємось, що ці матеріали нададуть натхнення та практичну допомогу розробникам, а також допоможуть звичайним користувачам краще зрозуміти, як працюють витрати на Gas в EVM, разом долаючи виклики екосистеми блокчейн.

Ethereum смартконтракти Gas оптимізація десять найкращих практик

Вступ до механізму плати Gas в EVM

На сумісних з EVM мережах, "Gas" є одиницею, що використовується для вимірювання обчислювальної потужності, необхідної для виконання певних операцій.

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

Оскільки виконання кожної транзакції вимагає обчислювальних ресурсів, стягується певна плата для запобігання безкінечним циклам та відмовам у службі ( DoS ) атакам. Плата, яка потрібна для завершення транзакції, називається "Gas-фі".

З моменту набрання чинності лондонським хардфорком EIP-1559( ), плата за газ розраховується за наступною формулою:

Комісія за газ = одиниці газу, що використовуються * (основна комісія + комісія пріоритету)

Базовий збір буде знищено, а пріоритетний збір буде використано як стимул, щоб заохотити валідаторів додавати транзакції до блокчейну. Встановлення більш високого пріоритетного збору під час відправлення транзакції може підвищити ймовірність включення транзакції до наступного блоку. Це подібно до "чаю" , який користувачі платять валідаторам.

Ethereum смартконтракти Gas оптимізації десять найкращих практик

1.Розуміння оптимізації Gas в EVM

Коли компілюється смартконтракт на Solidity, контракт перетворюється на серію "операційних кодів", тобто opcodes.

Будь-яка частина операційного коду (, наприклад, створення смартконтракту, виконання виклику повідомлення, доступ до сховища облікових записів та виконання операцій на віртуальній машині ) має визнану вартість споживання Gas, ці витрати зафіксовані в жовтій книзі Ethereum.

Після кількох змін EIP, деякі коди операцій мали змінену вартість Gas, що може відрізнятися від жовтої книги.

2.Основні поняття оптимізації газу

Основна ідея оптимізації Gas полягає в пріоритетному виборі операцій з високою ефективністю витрат на блокчейні EVM, щоб уникнути операцій з високими витратами на Gas.

У EVM наступні операції мають нижчу вартість:

  • Читання та запис змінних пам'яті
  • Читання констант та незмінних змінних
  • Читати та записувати локальні змінні
  • Читання змінної calldata, наприклад, масиву calldata та структур.
  • Виклик внутрішньої функції

Витратні операції включають:

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

Ethereum смартконтракти Gas оптимізація десять найкращих практик

Оптимізація витрат на газ EVM: найкращі практики

На основі вищезгаданих основних концепцій, ми підготували список найкращих практик оптимізації Gas-витрат для спільноти розробників. Дотримуючись цих практик, розробники можуть знизити споживання Gas для смартконтрактів, зменшити витрати на транзакції та створити більш ефективні та зручні для користувачів програми.

1. Намагайтеся зменшити використання сховища

У Solidity, Storage( зберігання) є обмеженим ресурсом, споживання газу якого значно перевищує Memory( пам'ять). Кожного разу, коли смартконтракт читає або записує дані зі зберігання, виникають значні витрати газу.

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

Обмеження способів використання зберігання включає:

  • Зберігайте непостійні дані в пам'яті
  • Зменшити кількість змін у зберіганні: зберігайте проміжні результати в пам'яті, а після завершення всіх обчислень надайте результати змінним зберігання.

Ethereum смартконтракти Gas оптимізації десять найкращих практик

2. Упаковка змінних

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

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

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

Оскільки кожен слот зберігання споживає Gas, упаковка змінних оптимізує використання Gas, зменшуючи кількість необхідних слотів зберігання.

![Ethereum смартконтракти Gas оптимізації десять найкращих практик])https://img-cdn.gateio.im/webp-social/moments-995905cb414526d4d991899d0c2e6443.webp(

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

Змінна може бути представлена різними типами даних, але вартість операцій, пов'язаних з різними типами даних, також різна. Вибір відповідного типу даних допомагає оптимізувати використання Gas.

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

Окремо, використання uint256 дешевше, ніж uint8. Однак, якщо застосувати раніше запропоновану оптимізацію пакування змінних, ситуація змінюється. Якщо розробник може упакувати чотири змінні uint8 в один слот пам'яті, то загальна вартість ітерації буде нижчою, ніж у випадку з чотирма змінними uint256. Таким чином, смартконтракти зможуть читати та записувати один слот пам'яті, і в одній операції помістити чотири змінні uint8 в пам'ять/сховище.

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

) 4. Використання змінних фіксованого розміру замість динамічних змінних

Якщо дані можуть бути обмежені до 32 байтів, рекомендується використовувати тип даних bytes32 замість bytes або strings. Як правило, змінні фіксованого розміру споживають менше Gas, ніж змінні змінного розміру. Якщо довжину байтів можна обмежити, намагайтеся вибрати мінімальну довжину від bytes1 до bytes32.

5. Відображення та масиви

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

У більшості випадків відображення є більш ефективним і дешевшим, але масиви мають ітеративність і підтримують упаковку типів даних. Тому рекомендується віддавати перевагу використанню відображення при управлінні списками даних, якщо не потрібно ітерувати або не можна оптимізувати споживання Gas через упаковку типів даних.

![Ethereum смартконтракти Gas оптимізації десять найкращих практик])https://img-cdn.gateio.im/webp-social/moments-5f3d7e103e47c886f50599cffe35c707.webp(

) 6. Використовуйте calldata замість пам'яті

Змінні, оголошені в параметрах функції, можуть зберігатися в calldata або memory. Основна різниця між ними полягає в тому, що memory може бути зміненою функцією, а calldata є незмінною.

Запам'ятайте цей принцип: якщо параметри функції є тільки для читання, слід надавати перевагу використанню calldata, а не memory. Це дозволяє уникнути непотрібних операцій копіювання з calldata функції в memory.

7. Використовуйте ключові слова Constant/Immutable якомога більше

Змінні Constant/Immutable не зберігаються в сховищі контракту. Ці змінні обчислюються під час компіляції та зберігаються в байт-коді контракту. Тому, порівняно зі зберіганням, їх вартість доступу значно нижча, рекомендується використовувати ключові слова Constant або Immutable, коли це можливо.

![Ethereum смартконтракти газові оптимізації десять найкращих практик]###https://img-cdn.gateio.im/webp-social/moments-9c566626ab499ef65d6f5089a2876ad3.webp(

) 8. Використовуйте Unchecked, щоб забезпечити, що не відбудеться переповнення/недоповнення

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

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

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

Код модифікатора вбудовується в змінену функцію, і щоразу при використанні модифікатора його код копіюється. Це збільшує розмір байт-коду та підвищує витрати на Gas.

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

![Ethereum смартконтракти Gas оптимізації десять найкращих практик])https://img-cdn.gateio.im/webp-social/moments-c0701f9e09280a1667495d54e262dd2f.webp(

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

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

Щоб оптимізувати споживання Gas, слід розміщувати умови з низькою вартістю обчислень на початку, так можна пропустити обчислення з високими витратами.

![Ethereum смартконтракти Gas оптимізації десять найкращих практик]###https://img-cdn.gateio.im/webp-social/moments-a823fb7761aafa6529a6c45304e0314b.webp(

Додаткові загальні поради

) 1. Видалити непотрібний код

Якщо в контракті є невикористані функції або змінні, рекомендується їх видалити. Це найпряміший спосіб зменшити вартість розгортання контракту та підтримувати малий обсяг контракту.

Ось кілька корисних порад:

  • Використовуйте найефективніший алгоритм для обчислень. Якщо в контракті безпосередньо використовуються результати певних обчислень, то слід усунути ці зайві обчислювальні процеси. По суті, будь-які невикористовувані обчислення повинні бути видалені.

  • У Ethereum розробники можуть отримати винагороду за Gas, звільняючи пам'ять. Якщо певна змінна більше не потрібна, її слід видалити за допомогою ключового слова delete або встановити на значення за замовчуванням.

  • Оптимізація циклів: уникати витратних циклічних операцій, по можливості об'єднувати цикли та виносити повторні обчислення за межі тіла циклу.

2. Використання попередньо скомпільованих смартконтрактів

Препідготовлені контракти надають складні бібліотечні функції, такі як криптографічні та хешуючі операції. Оскільки код не виконується на EVM, а виконується локально на клієнтському вузлі, необхідно менше Gas. Використання препідготовлених контрактів може заощадити Gas, зменшуючи обсяги обчислень, необхідні для виконання смартконтрактів.

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

![Ethereum смартконтракти Gas оптимізації десять найкращих практик])https://img-cdn.gateio.im/webp-social/moments-839b91e2f02389949aa698d460a497d8.webp(

) 3. Використання вбудованого асемблерного коду

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

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

) 4. Використання рішень Layer 2

Використання рішень Layer 2 може зменшити кількість даних, які потрібно зберігати та обробляти на основній мережі Ethereum.

ETH7.23%
GAS3.35%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • 3
  • Репост
  • Поділіться
Прокоментувати
0/400
SocialFiQueenvip
· 07-10 22:01
Завжди є ті, хто зубами тримається за газові витрати...
Переглянути оригіналвідповісти на0
LostBetweenChainsvip
· 07-08 12:24
Так дістало, газові витрати такі ж, як у невдах, що їх обдурюють.
Переглянути оригіналвідповісти на0
ResearchChadButBrokevip
· 07-08 05:57
Коли ми зможемо не бути обдуреними людьми, як лохів через високий газ?
Переглянути оригіналвідповісти на0
  • Закріпити