13 практик оптимізації витрат на Gas для смартконтрактів Ethereum

Найкращі практики оптимізації газових витрат смартконтрактів Ethereum

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

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

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

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

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

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

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

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

Газовий збір = одиниці газу, що використані * (базовий збір + пріоритетний збір)

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

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

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

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

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

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

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

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

У EVM вартість наступних операцій є відносно низькою:

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

Операції з високими витратами включають:

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

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

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

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

1. Намагайтеся зменшити використання пам'яті.

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

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

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

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

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

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

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

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

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

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

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

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

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

Наприклад, у 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. Як правило, змінні фіксованого розміру споживають менше Gas, ніж змінні змінного розміру. Якщо довжину байтів можна обмежити, намагайтеся обрати найменшу довжину від bytes1 до bytes32.

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

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

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

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

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

( 6. Використання calldata замість memory

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Додаткові загальні рекомендації

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

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

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

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

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

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

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

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

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

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

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

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

Переглянути оригінал
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Нагородити
  • 7
  • Поділіться
Прокоментувати
0/400
AlgoAlchemistvip
· 4год тому
газ要搞死我了
Переглянути оригіналвідповісти на0
BearEatsAllvip
· 15год тому
високі газові витрати - це ж просто мертва дорога для тих, хто хоче отримати вигоду.
Переглянути оригіналвідповісти на0
MEVHunterWangvip
· 07-11 05:59
газ знову зростає, дивитися боляче
Переглянути оригіналвідповісти на0
CoffeeNFTradervip
· 07-11 05:55
газ знову оптимізували, але це все ще пастка. Справді, краще йти на layer2.
Переглянути оригіналвідповісти на0
StrawberryIcevip
· 07-11 05:54
Застряг на високому газі, вперед!
Переглянути оригіналвідповісти на0
OffchainWinnervip
· 07-11 05:50
Прокручу до того, що я більше не хочу використовувати L2...
Переглянути оригіналвідповісти на0
HalfBuddhaMoneyvip
· 07-11 05:31
газ плата хоча б висока, але потрібно закачати, брате
Переглянути оригіналвідповісти на0
  • Закріпити