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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

![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 смартконтракти Gas оптимізації десять кращих практик])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 оптимізації десять найкращих практик

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

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

ETH0.07%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • 5
  • Репост
  • Поділіться
Прокоментувати
0/400
VirtualRichDreamvip
· 08-06 20:34
Економія газу – це істина
Переглянути оригіналвідповісти на0
GateUser-26d7f434vip
· 08-06 16:04
Комісія GAS занадто висока.
Переглянути оригіналвідповісти на0
PermabullPetevip
· 08-05 21:10
Нарешті є цінні інсайти!
Переглянути оригіналвідповісти на0
MetaverseVagrantvip
· 08-05 20:55
газ вже майже не по кишені
Переглянути оригіналвідповісти на0
GasFeeAssassinvip
· 08-05 20:48
Проблема з газом нарешті вирішена.
Переглянути оригіналвідповісти на0
  • Закріпити