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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

У EVM нижчі витрати на такі операції:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

![Ethereum смартконтракти Gas оптимізації десять найкращих практик])https://img-cdn.gateio.im/webp-social/moments-30f0bc370a7b9ca65f3d623c31262b76.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-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 (, але їхня синтаксична структура абсолютно різна.

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

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

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

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

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

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

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

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

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

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

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

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

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

) 9. Оптимізуйте модифікатор

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

У цьому прикладі, шляхом рефакторингу логіки в внутрішню функцію _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-0.95%
GAS-1.94%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • 7
  • Репост
  • Поділіться
Прокоментувати
0/400
AllInAlicevip
· 07-21 16:10
газ такий дорогий, вже не витримуєш?
Переглянути оригіналвідповісти на0
TopBuyerBottomSellervip
· 07-21 00:35
газ дійсно краде гроші, як же це жахливо.
Переглянути оригіналвідповісти на0
PoetryOnChainvip
· 07-20 06:30
газ дуже дорогий, хто буде торгувати
Переглянути оригіналвідповісти на0
LightningClickervip
· 07-18 19:09
Вночі кодування всі вивчають це
Переглянути оригіналвідповісти на0
PerpetualLongervip
· 07-18 19:05
газ не зменшуйте, будь ласка, не можу більше відкривати позиції...
Переглянути оригіналвідповісти на0
FarmToRichesvip
· 07-18 18:53
Газ занадто дорогий, роздрібний інвестор всі втекли.
Переглянути оригіналвідповісти на0
DeFiCaffeinatorvip
· 07-18 18:46
газ палить мене, я не можу спати...
Переглянути оригіналвідповісти на0
  • Закріпити