Топ-10 практик оптимізації Gas-кошту смартконтрактів для підвищення ефективності розробки EVM

Десять найкращих практик для оптимізації Gas-кошторису смартконтрактів

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

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

Топ-10 найкращих практик оптимізації Gas для смартконтрактів Ethereum

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Топ-10 найкращих практик оптимізації Gas для смартконтрактів Ethereum

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

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

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

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

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

![Топ-10 найкращих практик оптимізації газу для смартконтрактів Ethereum])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 в пам'ять/сховище.

Топ-10 кращих практик оптимізації Gas для смартконтрактів Ethereum

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

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

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

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

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

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

) 6. Використовуйте calldata замість memory

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

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

( 7. Використовуйте ключові слова Constant/Immutable, наскільки це можливо.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

( 4. Використання рішень Layer 2

Використання рішень Layer 2 може зменшити обсяг даних, які потрібно зберігати та обробляти в основній мережі Ethereum.

такі рішення Layer 2, як rollups, бокові ланцюги та канали стану

Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • 7
  • Поділіться
Прокоментувати
0/400
AirdropATMvip
· 20год тому
газ може стати ще нижчим, cex програє
Переглянути оригіналвідповісти на0
CommunityJanitorvip
· 07-17 02:30
Як старий невдах, ця газова плата справді вражає.
Переглянути оригіналвідповісти на0
GhostWalletSleuthvip
· 07-15 15:28
Падіння газу також нічого не дає, Віталік Бутерін просто хоче обдурювати людей, як лохів.
Переглянути оригіналвідповісти на0
GasFeeNightmarevip
· 07-15 07:31
газ дійсно забирає життя~
Переглянути оригіналвідповісти на0
BrokenDAOvip
· 07-15 07:23
Приклад інерції управління. Чи враховували ви спотворення стимулів при оптимізації витрат у блокчейні? Звичайні користувачі, які часто здійснюють tx, завжди є платниками.
Переглянути оригіналвідповісти на0
DoomCanistervip
· 07-15 07:12
газ не економте на відчутті знищення
Переглянути оригіналвідповісти на0
PumpBeforeRugvip
· 07-15 07:07
газ грошей вже вистачає на пляшку Маотай
Переглянути оригіналвідповісти на0
  • Закріпити