[Примечание: к сожалению, эта серия была прервана тем фактом, что Vyper в то время все еще находился в альфа-версии, а это означало, что язык, а также философское направление, принятое командой разработчиков, претерпевали сильные изменения. Например, я участвовал в дискуссии о github, которая изменила подход к обработке типов в арифметических выражениях. Кроме того, мне очень не хватало некоторых функций, которые я хотел использовать в своем руководстве. Теперь, когда Vyper более или менее затвердел, я могу попробовать еще раз.]

Эта статья является частью серии, которую я пишу о новом языке Vyper для написания смарт-контрактов Ethereum. В предыдущих частях я говорил о том, почему мне не нравится Solidity, и о принципиальном различии философии между Solidity и Vyper. Предлагаю вам просмотреть их:

Итак, после всего этого разговора о том, зачем нужен Vyper и почему это хорошая идея, давайте займемся программированием. Мы будем внедрять токен Tribillium ERC-20, маленький абсурдный токен, который я изобрел для чаевых и подарков.

Настройка среды

Самый простой способ начать кодирование Vyper - использовать онлайн-компилятор по адресу https://vyper.online/. К сожалению, в отличие от Remix for Solidity, это не полнофункциональная IDE со встроенной платформой для выполнения тестов, а просто обычный компилятор, который выдаст вам байт-код и ABI контракта.

Итак, чтобы протестировать наши контракты, нам нужно будет использовать локальную тестовую цепочку блоков. Мы могли бы использовать ganache-cli (ранее известный как testrpc), но проводить тестирование разработчика с консоли немного болезненно, особенно без уровня удобства миграции Truffle ... И хотя вы можете прикрепить графический интерфейс Mist к экземпляру ganache-cli, я не фанат тумана (мне он всегда казался несколько нестабильным)…

Я предлагаю использовать клиент Parity в режиме частной цепочки, поскольку Parity имеет очень приятный пользовательский интерфейс на основе браузера для развертывания и взаимодействия с учетными записями и смарт-контрактами.

Чтобы помочь вам начать работу, я создал образ Docker, который вы можете использовать для запуска среды. Он настроен для целей разработки, с подтверждением полномочий с единой подписью, некоторыми предварительно профинансированными учетными записями, 5-секундным временем блокировки, минимальной ценой на газ 0 wei и лимитом газа для блокировки, установленным на уровне 7 миллионов (немного ниже текущей годовой скользящей средней. Ограничения по блоку газа в основной сети Ethereum.)

Вы можете скачать источник изображения из моего репозитория GitHub по адресу https://github.com/daniel-jozsef/ParityPlayground. Пожалуйста, обратитесь к README.md за инструкциями, я постарался сделать его максимально простым для запуска и работы.

Приступим к кодированию

Итак, я полагаю, что тестовая среда запущена и работает, вам удалось войти в систему с помощью браузера, и вы также нашли онлайн-компилятор Vyper. Тогда давай напишем немного вайпера.

Первая часть контракта с Tribillium, которую я хотел бы реализовать, - это отображение балансов токенов, а также возможность покупать Tribillium за эфир.

Vyper - это подмножество синтаксиса Python, поэтому, если вы знакомы с Python, вы будете чувствовать себя как дома. Для тех, кто не знаком, в Python пробелы - это первоклассный гражданин, блоки кода разделяются отступом, а символы новой строки имеют значение. Комментарии начинаются со знака #.

Контракт Vyper намного проще, чем контракт Solidity: у нас есть единственный контракт для каждого файла, без деклараций «классов». Предлагаемое расширение для Vyper - .vy или, альтернативно, включение подсветки синтаксиса Python в GitHub, .v.py.

Определение хранилища

Итак, давайте создадим наш контракт, tribillium.v.py. Первое, что нам нужно добавить, это поля хранения контрактов, в нашем случае отображение баланса токенов.

balanceOf: public(wei_value[address])

Сначала мы даем имя поля (balanceOf), а после двоеточия определяем тип. public() - это встроенная функция, определяющая поле с одноименной общедоступной функцией получения.

Также здесь вы можете увидеть синтаксис определения отображений в Vyper. Это похоже на определение массива: сначала тип значения (в нашем случае wei_value), а затем тип ключа (address) в квадратных скобках. Это примерно * эквивалентно mapping(address => uint256) в Solidity.

(Если вы новичок в программировании Ethereum: отображение в смарт-контрактах Ethereum действует как карта значения ключа со сложностью чтения log (n). Доступны неинициализированные ключи, и их значение 0 / default значений. Итерация по парам "ключ-значение" сопоставления не поддерживается.)

Итак, давайте сделаем небольшое отступление, чтобы поговорить о целых числах Vyper. Он намного более ограничен, чем Solidity, и мне это очень нравится. Есть два целочисленных типа: uint256 и int128. Эти типы были недавно переименованы, и на момент написания онлайн-компилятор все еще знает их по старым именам: соответственно num256 и num.

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

Что касается wei_value, название объясняет само себя. * Однако по какой-то причине в настоящее время он представлен как int128, но рано или поздно это поведение может измениться и вместо этого будет uint256, чтобы соответствовать стандартному де-факто поведению контрактов Ethereum.

Определение методов

Vyper использует синтаксис Python для определения методов контракта, при этом некоторые декораторы, специфичные для Ethereum, доступны из коробки. (Vyper не позволяет определять собственные декораторы из соображений возможности аудита.)

@public
@payable
def buy():
  assert msg.value > 0
  # We sell Tribillium at a rate of 1:1 to Ether
  self.balanceOf[msg.sender] += msg.value

Объект msg аналогичен тому, как мы получаем к нему доступ в Solidity, msg.value дает нам количество эфира, отправленного как часть транзакции, в wei. Его тип - wei_value (подробности см. Выше). В стиле Pythonic сам контракт может называться из методов как self. В отличие от Solidity, Vyper на данный момент имеет один assert оператор, а не отдельные assert и require. Также обратите внимание на его синтаксис, он принимает логическое выражение без скобок.

Что касается декораторов, @public публикует метод в ABI контракта (это означает, что объявленные функции в Vyper по умолчанию являются частными) и позволяет внешним субъектам вызывать его, а @payable аналогичен модификатору payable в Solidity, позволяя контракту получать Эфир через этот звонок.

Когда кто-то вызывает эту функцию, отправляя ненулевое количество эфира, он получает эквивалентное количество Tribillium, переведенное на свой баланс.

Развернуть и протестировать

Приятно видеть, как что-то работает, так что давайте скомпилируем и попробуем. Во-первых, нажатие Compile в онлайн-компиляторе Vyper, как мы надеемся, завершится отметками рядом с вкладками Bytecode, ABI и LLL на экране, как здесь:

Если вместо этого у вас есть восклицательный знак, вы, вероятно, что-то опечатали. Открытие вкладки Bytecode покажет вам сообщение об ошибке от компилятора.

Теперь, чтобы развернуть наши контракты в тестовой цепочке, перейдем на вкладку «Контракты» в пользовательском интерфейсе паритета и нажмем «Развернуть». В следующем диалоговом окне вы можете выбрать учетную запись для развертывания контракта (поскольку минимальная цена газа равна 0, в ней не обязательно должен быть эфир) и указать имя для контракта.

В последних двух полях ввода вам необходимо скопировать ABI и байт-код из соответствующих вкладок компилятора Vyper. Для новичков в умных контрактах ABI определяет открытый интерфейс, который предоставляет контракт, а байт-код - это фактическая скомпилированная программа.

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

Тогда попробуем купить токены. Откройте контракт и перейдите на вкладку Execute, в которой появится диалоговое окно для вызова методов. Поскольку в контракте определен только один метод buy(), это будет нормально. Используя учетную запись с эфиром, давайте отправим сумму в 3 ETH для нового контракта.

После того, как транзакция будет добыта, на вкладке контракта вы сможете запросить публичное поле balanceOf для учетной записи, которая отправила эфир, и вы должны увидеть 3 эквивалента Ether (или 3,000,000,000,000,000,000 wei) токенов:

Будьте на связи

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

Увидимся!