Хабрахабр

Solidity 0.5.0 — что нового он нам несет

5. Хочу рассказать об изменениях языка Solidity, которые ожидаются в версии 0. Сразу отмечу, что я ограничусь только языком — его грамматикой и семантикой. 0.

5. Какого-то вменяемого текста на эту тему нет даже на английском языке, но недавно в репозитории Solidity появился проект.
По нему можно отслеживать прогресс подготовки версии 0. 0.

Точную информацию можно получить из официального changelog'a. Disclaimer: в статье описано текущее состояние проекта, к релизу многое может поменяться.

Окончательный запрет устаревших конструкций

В эту категорию изменений попадают: В Solidity накопилось довольно много устаревших конструкций, которые хотелось бы удалить из языка, но все никак не удается из-за обратной совместимости.

  • Отказ от throw в пользу revert()/assert(...)/require(...). Механизм откатывания транзакции отличается от механизма исключений, и хочется подчеркнуть эту разницу на уровне языка.
  • Отказ от var, который с учетом правил вывода типов легко приводит к ошибкам, например:
    for(var i = 0; i < 100500; i++)
  • Принудительное включение строгого режима для ассемблера. Он и сейчас доступен с опцией компилятора --strict-assembly. В нем ограничены манипуляции со стеком и недоступны метки и переходы — вместо них предлагается использовать более привычные управляющие конструкции вроде for или switch.
  • Запретили использовать адреса без чек-суммы или неправильной длины (отличной от 20 байт). Неплохая идея, хотя с непривычки и вызовет трудности — придется срочно учиться писать адреса с чек-суммой, а вместо привычного 0x0 использовать address(0).
  • Запретили объявлять пустые структуры (struct A {}). Не очень-то и хотелось, но раньше грамматика такое позволяла.

Модификаторы видимости и ABI

Накопилось достаточно много мелких правок, которые должны сделать язык более строгим, убрав эту путаницу.
А поскольку эти модификаторы попадают в ABI контракта, изменения коснулись и его. С модификаторами видимости был легкий бардак, во многом обусловленный наличием значений по умолчанию.

  • Все функции в интерфейсах надо явно помечать как external.
    К сожалению, переопределить потом такую функцию как public в некоторых версиях компилятора нельзя — возникнет ошибка (например, в 0.4.21). Это стало возможным начиная с версии 0.4.22.
    Также обещают разрешить реализовывать external view функции с помощью public переменных.
  • Модификаторы видимости стали обязательными для функций.
    Это изменение долго ждало своего часа. Issue на гитхабе создали сразу после первого хака Parity.
    Дополнительное ограничение — fallback может быть только external.

Функции с произвольным количеством аргументов и упаковка данных

В этом процессе много тонкостей и неочевидных моментов, и сейчас решили с ними разобраться. В Solidity есть несколько функций, которые принимают любое количество аргументов, склеивают их одну бинарную колбасу и дальше работают уже с ней.

  • Новый глобальный объект abi и его методы
    encode, encodePacked, encodeWithSelector и encodeWithSignature, позволяющие контролировать сборку данных для вызова или хэширования.
    Предлагается с их помощью собирать аргументы для keccak256/sha256/ripemd160 и call/delegatecall. Планируется поменять синтаксис этих команд так, чтобы они не могли принимать список аргументов произвольной длины.
  • Изменение в автовыведении типов для констант в конструкциях с плотной упаковкой аргументов: в конструкциях вроде keccak256(1) теперь используется не наименьший достаточный тип (uint8), а uint256. Если такое поведение не устраивает, то придется использовать явное приведение типов (keccak256(uint8(1))).
    Это изменение выглядит логично рядом с отказом от var и высокой (хотя и конечной) точностью вычислений константных выражений.
  • Изменение правил упаковки массивов. Началось все с проблемы мультисиг кошельков, которые не могли выполнять транзакции контрактов, пытавшихся защититься от short address attack. Видимо, текущее поведение посчитали достаточно неочевидным, а может, это подготовка к введению проверки длины msg.data на уровне EVM.

Улучшение "работы с памятью"

В кавычках, потому что речь в основном идет о "неожиданном" доступе к storage без использования assembly.

  • Запрет непроинициализированных ссылок на storage, которые на деле указывали в начало storage, и поэтому пересекались с другими переменными состояния.
  • Может быть запретят прямую работу с <array>.length.
    Изменение длины массива вручную — достаточно низкоуровневая операция. Ее основной плюс — экономия газа при небольших изменениях длины массива. Но такой синтаксис позволяет случайно (или умышленно) создать массив неадекватного размера, что может привести к overlap attack. Для очистки массива давно есть delete, для уменьшения размера предлагается использовать pop(), помимо этого обсуждают операции вроде truncate() и extend(). Ну и по-прежнему есть assembly, если очень надо.

Из сомнительного

В любой бочке меда окажется своя ложка дегтя.

  • Добавляют целую вязанку ключевых слов на все случаи жизни. Часть из них выглядит угрожающе, но пока ничего не понятно. Честно говоря, надеялся увидеть в этом списке revert, assert и require, но с точки зрения грамматики они остаются просто функциями (и их можно переопределить).

Не про язык

Есть несколько очень важных изменений, которые не касаются непосредственно языка, но при этом сильно повлияют на код новых контрактов.

  • Наконец-то появятся числа с дробной частью. Вроде все привыкли обходиться без них, а теперь будем учиться использовать их правильно.
  • На уровне EVM добавится защита от short address attack. Казалось бы, мелочь, но приятно, что об этом не надо больше думать (и вообще знать об этой проблеме). Может быть, она будет даже более строгой, но там есть свои трудности.

Какие-то выводы

5. Хотя дата выхода релиза еще неизвестна, многие новшества уже можно потрогать руками.
Включаются они с помощью
pragma experimental "v0. 0";
и
pragma experimental "ABIEncoderV2";
Компилятор, конечно, выдает предупреждение.

5. В целом, 0. Удалят то, от чего никак не удается избавиться из-за обратной совместимости, плотно отрефакторят пару скользких тем, внесут несколько полезных изменений. 0 воспринимается позитивно. Потом будем ждать рефакторинг наследования, а там, может, и Vyper подоспеет.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть