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

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

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

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

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

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

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

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

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

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

Gas费用 = використані одиниці Gas * ( базова плата + плата за пріоритет )

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Оскільки кожен слот зберігання споживає 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 оптимізації десять найкращих практик

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Однак використання внутрішньої асемблера також може призвести до вітру

Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • 3
  • Поділіться
Прокоментувати
0/400
Deconstructionistvip
· 19год тому
Ця газова плата занадто дорога, не витримую.
Переглянути оригіналвідповісти на0
MissedTheBoatvip
· 19год тому
Їсти локшину економить дві краплі олії, а що ще економить газ
Переглянути оригіналвідповісти на0
OnchainGossipervip
· 19год тому
газ дійсно дуже дорогий аааа
Переглянути оригіналвідповісти на0
  • Закріпити