Вийшла нова версія Solidity, найпопулярнішої мови розробки смарт-контрактів Ethereum

Складання: План перекладу; Джерело: soliditylang.org

Вийшла остання версія компілятора Solidity v0.8.22. Компілятор 0.8.22 включає ряд покращень мови та компілятора, таких як визначення подій на рівні файлу, поступова оптимізація неперевірених циклів, підтримка імпорту JSON збірки EVM тощо.

ВАЖЛИВО

Цей випуск припиняє підтримку EVM нижче Константинополя (Constantinople), підтримку яких стає дедалі складніше. Ці архаїчні версії вже давно застаріли в основній мережі та тестовій мережі Ethereum, і ми підозрюємо, що вони більше не актуальні і для інших мереж. Складні шляхи коду та рішення уповільнюють розробку функцій та тестування нових версій, тому ми очікуємо припинити їх підтримку в майбутніх випусках компіляторів. Якщо ви покладаєтеся на підтримку цих версій EVM, зв'яжіться з нами[6] 。

Основні моменти нових функцій

неперевірений приріст циклу

Використання неперевіреної арифметики при збільшенні лічильника циклу призначено для оптимізації газу[7] Загальноприйнята практика. Проілюструємо на наступному прикладі циклу і лічильника i:

for (uint i = 0; i < array.length; ++i) {
acc += масив[i] ; I не змінюється тілом петлі
}

У багатьох випадках (див. точні умови нижче) операція порівняння гарантує, що i ніколи не досягне максимального значення свого типу, тому можна з упевненістю припустити, що цикл зупиниться до досягнення максимального значення. У цьому випадку перевірка безпеки лічильника буде зайвою і марною тратою газу. Це заохочує користувача використовувати довгий неперевірений шаблон, який поступово обертає лічильник неперевіреним арифметичним блоком всередині циклу, минаючи перевірку:

for (uint i = 0; i < array.length;) {
acc += масив[i] ;
unchecked { i++; } // i збільшується без перевірок переповнення -- використовується менше газу
}

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

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

Точні умови для нещодавно оптимізованої перевірки запобігання розливів такі:

  • Умови циклу мають форму i < ... де i - локальна змінна (далі називається "лічильником циклу").
  • Це порівняння має бути виконано на тому ж типі, що й лічильник циклів, тобто тип праворуч має бути неявно перетворений на тип лічильника циклів, щоб лічильник циклів не був неявно розширений перед порівнянням.
  • Лічильник циклу повинен бути локальною змінною вбудованого цілочисельного типу.
  • Вираз циклу має бути префіксом або суфіксом для лічильника циклу, i++ або ++i.
  • Лічильник циклів не може бути змінений в стані циклу або в тілі циклу.

Щоб уточнити другу умову, розглянемо наступний фрагмент коду:

for (uint8 i = 0; in < UINT16(1000); ++I) {
тіло петлі
}

У цьому випадку i перетворюється на uint16 перед порівнянням, і умова ніколи не є насправді хибною, тому інкрементовану перевірку переповнення не можна видалити.

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

Оптимізація проста і завжди корисна, тому її буде ввімкнено, навіть якщо решту оптимізатора вимкнено за допомогою загальних налаштувань settings.optimizer.enabled. Ви можете явно вимкнути його, встановивши settings.optimizer.details.simpleCounterForLoopUncheckedIncrement на false у стандартному введенні JSON. Його не можна вимкнути за допомогою інтерфейсу командного рядка.

Налаштуйте оптимізатор Yul для повторної генерації нульових літералів

Нова версія ґрунтується на підтримці коду операції PUSH0, запровадженій у версії 0.8.20, шляхом додавання Rematerialiser[8] [9] Етап оптимізації розширено, щоб завжди повторно генерувати нульовий літерал замість того, щоб зберігати його як змінну посилання, що дозволяє використовувати PUSH0 замість DUP для зменшення витрат на газ. Для того, щоб це робилося ефективно, додаються Rematerialiser і UnusedPruner Кроки додаються до типової послідовності очищення оптимізатора Yul.

Додано підтримку імпорту збірки EVM JSON (експериментально)

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

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

Дозволяє визначати події на рівні файлу

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

Крім того, у цьому релізі виправлено помилку, яка спричиняла помилку під час генерації NatSpec під час генерації події, визначеної у зовнішньому контракті або інтерфейсі для коду. У попередньому релізі (0.8.21) компілятор Solidity додав підтримку обмеженого доступу до подій, визначених у контрактах та інтерфейсах, які не успадковані від поточного контракту, але баг перешкоджав повноцінному використанню функції.

Завдяки цьому виправленню помилок і наданню дозволу на визначення подій на рівні файлу, остання версія Solidity дозволяє користувачам компілювати наведені нижче приклади без будь-яких помилок:

інтерфейс I {
подія ForeignEvent();
}
контракт C {
подія ForeignEvent();
}
подія E();
договір D {
function f() public {
Видача сторонньої події призведе до внутрішньої помилки 0.8.21
emit I.ForeignEvent();
випромінювати C.ForeignEvent();
Імітація події на рівні файлу. Нова функція.
випромінювати E();
}
}

Повний список змін

Особливості мови

  • Дозволяє визначати події на рівні файлу.

Можливості компілятора

  • Генератор коду: Вилучено зайві перевірки переповнення для деяких циклів for, коли змінна count не переповнюється.
  • Інтерфейс командного рядка: Додана опція --no-import-callback, щоб компілятор не завантажував вихідні файли, які явно не вказані в CLI або стандартному JSON-введенні.
  • Інтерфейс командного рядка: додано експериментальну опцію --import-asm-json для імпорту збірок EVM у форматі, який використовується --asm-json. Інтерфейс командного рядка: використовуйте відповідну серйозність і забарвлення для повідомлень про помилки, створених поза скомпільованим конвеєром.
  • EVM: Застаріло підтримку версій EVM "homestead", "tangerineWhistle", "spuriousDragon" та "byzantium".
  • Аналізатор: Видалено експериментальний режим відновлення помилок (--error-recovery/settings.parserErrorRecovery).
  • SMTChecker: Підтримує операторів, визначених користувачем.
  • Оптимізатор Yul: Якщо підтримується PUSH0, вважає за краще використовувати нульові літерали замість зберігання нульових значень у змінних.
  • Оптимізатор Yul: запускає кроки Rematerializer і UnusedPruner в кінці послідовності очищення за замовчуванням.

Виправлення помилок

  • Генератор коду: Виправлено проблему, через яку вихід через генератор коду via-IR залежав від файлів, знайдених у зворотних викликах імпорту. У деяких випадках різні призначення ідентифікаторів AST можуть змінювати порядок функцій у внутрішньому плануванні, що призводить до різних, але семантично еквівалентних байт-кодів.
  • NatSpec: Виправлена внутрішня помилка при запиті документації користувача або документації з розробки для контракту, який видав подію, визначену в зовнішньому контракті або інтерфейсі.
  • SMTChecker: Виправлена помилка кодування, яка призводила до розширення циклу після завершення.
  • SMTChecker: Виправлено невідповідності в перевірках константних умов, коли цикл while або for розкручувався перед перевіркою умови.
  • Оптимізатор Yul: Виправлено проблему, через яку імена змінних Yul, згенеровані компілятором під час CSE, впливали на рішення щодо заміни, що призводило до іншого (але еквівалентного) байт-коду в деяких випадках.
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • Прокоментувати
  • Поділіться
Прокоментувати
0/400
Немає коментарів
  • Закріпити