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

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

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

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

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

Огляд механізму Gas-оплати EVM

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

На основі наведених основних концепцій ми підготували список найкращих практик оптимізації витрат на Gas для спільноти розробників. Дотримуючись цих практик, розробники можуть зменшити споживання 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 оптимізації десять найкращих практик])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, щоб уникнути зайвих перевірок на переповнення або недоповнення, що дозволяє зекономити витрати на Gas.

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

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

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

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

Шляхом перетворення логіки в внутрішню функцію _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 розробники можуть отримувати винагороду за газ, звільняючи місце для зберігання. Якщо змінна більше не потрібна, слід використовувати ключове слово delete для її видалення або встановити її на значення за замовчуванням.

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

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

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

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

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

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

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

ETH-0.38%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • 3
  • Поділіться
Прокоментувати
0/400
SchrodingerWalletvip
· 22год тому
Дійсно стало дешевше, але немає грошей для торгівлі.
Переглянути оригіналвідповісти на0
BearMarketMonkvip
· 23год тому
Дорога газ, бідний, бідний.
Переглянути оригіналвідповісти на0
ApeWithAPlanvip
· 23год тому
Коли стане дешевше, а L2 швидше?
Переглянути оригіналвідповісти на0
  • Закріпити