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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Обмеження методів використання сховища включає:

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

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

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

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

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

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

Оскільки кожен слот зберігання споживає 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 оптимізація десяти найкращих практик]###https://img-cdn.gateio.im/webp-social/moments-55fcdb765912ef9cd238c46b1d248cff.webp(

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

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

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

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

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

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

![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. Оптимізаційний метод полягає у рефакторингу логіки в внутрішню функцію, що дозволяє повторно використовувати цю внутрішню функцію в модифікаторах, що може зменшити розмір байт-коду та знизити витрати Gas.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

як rollups, бічні ланцюги

ETH1.79%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • 4
  • Поділіться
Прокоментувати
0/400
BlockchainBouncervip
· 08-05 14:56
Зниження газових витрат є дуже необхідним.
Переглянути оригіналвідповісти на0
WalletAnxietyPatientvip
· 08-05 14:56
Провайдери газу — справжні боги розробки
Переглянути оригіналвідповісти на0
AirdropLickervip
· 08-05 14:50
Економте газ, заробляйте великі гроші
Переглянути оригіналвідповісти на0
ContractExplorervip
· 08-05 14:49
оптимізація газу надзвичайно важлива
Переглянути оригіналвідповісти на0
  • Закріпити