Больше года я работал над книгой «Создание смарт-контрактов Solidity для блокчейна Ethereum. Практическое руководство», и вот теперь эта работа завершена, а книга издана и доступна в Литресе.

Надеюсь, моя книга поможет быстро приступить к созданию смарт-контактов Solidity и распределенных приложений DApp для блокчейна Ethereum. Она состоит из 12 уроков с практическими заданиями. Выполнив их, читатель сможет создавать собственные локальные узлы Ethereum, публиковать смарт-контракты и вызывать их методы, обмениваться данными между реальным миром и смарт-контрактами с помощью оракулов, работать с тестовой отладочной сетью Rinkeby.

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

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

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

Эту книгу лучше не просто читать, а работать с ней, выполняя практические задания, описанные в уроках. Для работы вам потребуется локальный компьютер, виртуальный или облачный сервер с установленной ОС Debian или Ubuntu. Также для выполнения многих заданий можно использовать Raspberry Pi.

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

Цель второго урока — создать узел приватного блокчейна Ethereum для дальнейшей работы в рамках этого курса на сервере Ubuntu и Debian. Мы рассмотрим особенности установки основных утилит, таких как geth, обеспечивающего работу узла нашего блокчейна, а также демона децентрализованного хранилища данных swarm.

Третий урок научит вас проводить эксперименты с Ethereum на недорогом микрокомпьютере Raspberry Pi. Вы установите операционную систему (ОС) Rasberian на Raspberry Pi, утилиту Geth, обеспечивающую работу узла блокчейна, а также демон децентрализованного хранилища данных Swarm.

Четвертый урок посвящен аккаунтам и криптовалютным единицам в сети Ethereum, а также способам перевода средств с одного аккаунта на другой из консоли Geth. Вы научитесь создавать аккаунты, инициировать транзакции перевода средств, получать состояние транзакции и ее квитанцию.

На пятом уроке вы познакомитесь со смарт-контрактами в сети Ethereum, узнаете об их выполнении виртуальной машиной Ethereum.

Вы создадите и опубликуете в приватной сети Ethereum свой первый смарт-контракт и научитесь вызывать его функции. Для этого вы будете использовать среду разработки Remix Solidity IDE. Кроме того, вы научитесь устанавливать и использовать пакетный компилятор solc.
Также мы расскажем о так называемом бинарном интерфейсе приложения Application Binary Interface (ABI) и научим его использовать.

Шестой урок посвящен созданию скриптов JavaScript, работающих под управлением Node.js и выполняющих операции со смарт-контрактами Solidity.

Вы установите Node.js в ОС Ubuntu, Debian и Rasberian, напишете скрипты для публикации смарт-контракта в локальной сети Ethereum и вызова его функций.

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

На седьмом уроке вы научитесь устанавливать и использовать популярную среди разработчиков смарт-контрактов Solidity интегрированную среду Truffle. Вы научитесь создавать скрипты JavaScript, вызывающие функции контрактов с помощью модуля truffle-contract, а также выполните тестирование своего смарт-контракта средствами Truffle.

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

На девятом уроке вы приблизитесь еще на шаг к созданию смарт-контрактов для основной сети Ethereum. Вы научитесь публиковать контракты при помощи Truffle в приватной сети Geth, а также в тестовой сети Rinkeby. Отладка смарт-контракта в сети Rinkeby очень полезна перед его публикацией в основной сети — там практически все по-настоящему, но бесплатно.

В рамках урока вы создадите узел тестовой сети Rinkeby, пополните его средствами, и опубликуете смарт-контракт.

Урок 10 посвящен распределенным хранилищам данных Ethereum Swarm. Используя распределенные хранилища, вы экономите на хранении данных большого объема в блокчейне Ethereum.

В рамках этого урока вы создадите локальное хранилище Swarm, выполните операции записи и чтения файлов, а также каталогов с файлами. Далее вы научитесь работать с публичным шлюзом Swarm, напишите скрипты для обращения к Swarm из Node.js, а также с помощью модуля Perl Net::Ethereum::Swarm.

Цель урока 11 — освоить работу со смарт-контрактами Solidity c применением популярного языка программирования Python и фреймворка Web3.py. Вы установите этот фреймворк, напишите скрипты для компиляции и публикации смарт-контракта, а также для вызова его функций. При этом Web3.py будет использован как сам по себе, так и совместно с интегрированной средой разработки Truffle.

На 12 уроке вы научитесь передавать данные между смарт-контрактами и реальным миром при помощи оракулов. Это пригодится вам для получения данных с Web-сайтов, устройств интернета вещей IoT, различных приборов и датчиков, и отправки данных из смарт-контрактов на эти устройства. В практической части урока вы создадите оракул и смарт-контракт, получающий актуальный курс обмена USD на рубли с сайта ЦБ РФ.

Урок 1. Кратко о блокчейне и сети Ethereum
Цель урока: познакомиться с принципами работы блокчейна Ethereum, областями его применения и основной терминологией.
Практические задания: в этом уроке не предусмотрены.

Едва ли сегодня есть разработчик программного обеспечения (ПО), который бы ничего не слышал о технологии блокчейн (Blockchain), криптовалютах (Cryptocurrency или Crypto Currency), биткоинах (Bitcoin), первичном размещение монет (ICO, Initial coin offering), смарт-контрактах (Smart Contract), а также других понятиях и терминах, имеющих отношение к блокчейну.

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

Надо сказать, что вокруг криптовалют и блокчейнов возникает много спекуляций. Мы оставим в стороне рассуждения об изменениях курсов криптовалют, о создании пирамид, о тонкостях криптовалютного законодательства и т.п. В нашем учебном курсе мы сосредоточимся главным образом на технических аспектах применения смарт-контрактов блокчейна Ethereum (эфириум, эфир) и разработки так называемых децентрализованных приложений (Distributed Application, DApp).

Что такое блокчейн


Блокчейн (Blockchain, Block Chain) представляет собой цепочку блоков данных, связанных друг с другом определенным образом. В начале цепочки находится первый блок, который называется первичным блоком (genesis block) или блоком генезиса. За ним следует второй, потом третий и так далее.

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

Распределенная база данных


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

Распределенный реестр данных


Блокчейн можно представить себе как это распределенный реестр данных и операций (транзакций). Еще одно название такого реестра — гроссбух.

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

При добавлении блоков и выполнении операций (транзакций) используются приватные и публичные ключи. Они ограничивают пользователей блокчейна, предоставляя им доступ только к своим блокам данных.

Транзакции


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

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

Блокчейн Ethereum содержит так называемые состояния системы. По мере выполнения транзакций состояние изменяется от начального до текущего. Транзакции записываются в блоки.

Публичные и приватные блокчейны


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

Практические применения блокчейна


Для чего может пригодится блокчейн?

Если кратко, блокчейн позволяет безопасным образом проводить операции (сделки) между не доверяющими друг другу персонами или компаниями. Записанные в блокчейн данные (транзакции, персональные данные, документы, свидетельства, договоры, накладные и т.п.) невозможно подделать или заменить после записи. Поэтому на базе блокчейна можно создавать, например, доверенные распределенные реестры различного рода документов.

Конечно, вы знаете, что на базе блокчейнов создаются криптовалютные системы, призванные заменить обычные бумажные деньги. Бумажные деньги еще называют фиатными (от Fiat Money).
Блокчейн обеспечивает хранение и неизменность транзакций, записанных в блоки, поэтому его и можно использовать для создания криптовалютных систем. Он содержит всю историю передачи крипто-средств между различными пользователями (аккаунтами), причем любая операция может быть отслежена.

Хотя операции внутри криптовалютных систем могут быть анонимными, вывод криптовалюты и обмен ее на фиатные деньги обычно приводит к раскрытию личности владельца криптовалютного актива.

Так называемые смарт-контракты, представляющие собой программное обеспечение, работающее в сети Ethereum, позволяют автоматизировать процесс заключения сделок и контроль их выполнения. Особенно это эффективно, если оплата по сделке проводится криптовалютой Ether (эфир).

Блокчейн Ethereum и смарт-контракты Ethereum, написанные на языке программирования Solidity, могут использоваться, например, в таких областях:

  • альтернатива нотариальному заверению документов;
  • хранение реестра объектов недвижимости и сведений об операциях с объектами недвижимости;
  • хранение сведений об авторских правах на объекты интеллектуальной собственности (книги, изображения, музыкальные произведения и т.п.);
  • создание систем независимого голосования;
  • сфера финансов и банковская деятельность;
  • логистика в международных масштабах, отслеживание перемещения грузов;
  • хранение персональных данных как аналог системе удостоверений личности;
  • безопасные сделки в коммерческой области;
  • хранение результатов медицинских обследований, а также истории назначенных процедур

Проблемы с блокчейном


Но, разумеется, не все так просто, как могло бы показаться!

Есть проблемы с верификацией данных перед их добавлением в блокчейн (например, не поддельные ли они?), проблемы в безопасности системного и прикладного ПО, применяемого для работы с блокчейном, проблемы с возможностью использования методов социальной инженерии для похищения доступа к кошелькам с криптовалютой и т.п.

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

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

Децентрализованные приложения Ethereum будут удобны, если платить за их использование криптовалютой. Чем больше людей, владеющих криптовалютой или готовых ее приобрести, тем большую популярность получат приложения DApp и смарт-контракты.

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

Еще одна проблема заключается в том, что смарт-контракты блокчейна Ethereum работают в изолированной среде виртуальных машин, и не имеют доступа к данным реального мира. В частности, программа смарт-контракта не может сама прочитать данные с сайтов или каких-либо физических устройств (датчики, контакты и т.п.), а также не может вывести данные на какие-либо внешние устройства. Эту проблему и способы ее решения мы будем обсуждать на уроке, посвященным так называемым Оракулам — информационным посредникам смарт-контрактов.

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

Как формируется цепочка блокчейна


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

На рис. 1.1 мы показали простейший вариант последовательности блоков, где первый блок ссылается на следующий.


Рис. 1.1. Простая последовательность блоков

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

Давайте займемся защитой блоков от подделки. На первом этапе мы попробуем защитить каждый блок контрольной суммой (рис. 1.2).


Рис. 1.2. Добавляем защиту данных блоков контрольной суммой

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

Для вычисления контрольной суммы можно использовать одну из функций хеширования, такую как MD-5, SHA-1, SHA-256 и т.п. Хеш-функции вычисляют некоторое значение (например, в виде текстовой строки постоянной длины) в результате выполнения необратимых операций над блоком данных. Операции зависят от вида хеш-функции.

Даже при небольшом изменении содержимого блока данных значение хеш-функции также изменится. Анализируя значение хеш-функции, невозможно восстановить блок данных, для которого она была вычислена.

Будет ли достаточна такая защита? К сожалению, нет.

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

Чтобы защитить всю цепочку в целом, можно хранить в каждом блоке вместе с данными еще и хеш данных предыдущего блока (рис. 1.3).


Рис. 1.3. Добавляем в блок данных хеш предыдущего блока

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

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

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

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

Блокчейн Ethereum


Блокчейн Ethereum представляет собой платформу, на базе которой можно создавать распределенные приложения DApp. В отличие от других платформ, Ethereum позволяет использовать так называемые умные контракты (смарт-контракты, smart contracts), написанные на языке программирования Solidity.

Эта платформа была создана в 2013 году Виталиком Бутериным, основателем журнала Bitcoin Magazine, и запущена в 2015 году. Все, что мы будем изучать или делать в нашем учебном курсе, имеет отношение именно к блокчейну Ethereum и смарт-контрактам Solidity.

Майнинг или как создаются блоки


Майнинг (mining) представляет собой довольно сложный и ресурсоемкий процесс добавления новых блоков в цепочку блокчейна, а вовсе не «добычу криптовалют». Майнинг обеспечивает работоспособность блокчейна, т.к. именно этот процесс отвечает за добавление транзакций в блокчейн Ethereum.

Люди и организации, занимающиеся добавлением блоков, называются майнерами (miner).
Программное обеспечение (ПО), работающее на узлах майнеров, пытается подобрать для последнего блока параметр хеширования с названием Nonce, чтобы получилось определенное значение хеш-функции, заданной сетью. Алгоритм хеширования Ethash, применяемый в Ethereum, позволяет получить значение Nonce только путем последовательного перебора.

Если узел майнера нашел правильное значение Nonce, то это является так называемым доказательством работы (PoW, Proof-of-work). В этом случае, если блок будет добавлен в сеть Ethereum, майнер получает определенное вознаграждение в валюте сети — Ether. На момент подготовки нашей книги вознаграждение составляет 5 Ether, однако со временем оно будет снижено.

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

Итоги урока


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

Блокчейн может применяться для сохранения результатов выполнения транзакций. Его главное назначение — организация безопасного выполнения транзакций между сторонами (персонами и организациями), между которыми нет доверия. Вы узнали, в каких конкретно областях бизнеса и в каких сферах можно использовать блокчейн Ethereum и смарт-контракты Solidity. Это банковская сфера, регистрация прав собственности, документов и т.п.

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

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

Урок 2. Подготовка рабочей среды в ОС Ubuntu и Debian
Выбор операционной системы
Установка необходимых утилит
Установка Geth и Swarm в Ubuntu
Установка Geth и Swarm в Debian
Предварительная подготовка
Загрузка дистрибутива Go
Установка переменных окружения
Проверка версии Go
Установка Geth и Swarm
Создаем приватный блокчейн
Готовим файл genesis.json
Создаем каталог для работы
Создаем аккаунт
Запускаем инициализацию узла
Параметры запуска узла
Подключаемся к нашему узлу
Управление майнингом и проверка баланса
Завершение работы консоли Geth
Итоги урока

Урок 3. Подготовка рабочей среды на Raspberry Pi 3
Подготовка Raspberry Pi 3 к работе
Установка Rasberian
Установка обновлений
Включение доступа SSH
Установка статического адреса IP
Установка необходимых утилит
Установка Go
Загрузка дистрибутива Go
Установка переменных окружения
Проверка версии Go
Установка Geth и Swarm
Создаем приватный блокчейн
Проверка учетной записи и баланса
Итоги урока

Урок 4. Учетные записи и перевод средств между аккаунтами
Просмотр и добавление аккаунтов
Просмотр списка аккаунтов
Добавление аккаунта
Параметры команды geth account
Пароли аккаунтов
Криптовалюта в Ethereum
Денежные единицы Ethereum
Определяем текущий баланс наших аккаунтов
Перевод средств с одного аккаунта на другой
Метод eth.sendTransaction
Просмотр состояния транзакции
Квитанция транзакции
Итоги урока

Урок 5. Публикация первого контракта
Смарт-контракты в Ethereum
Выполнение смарт-контракта
Виртуальная машина Ethereum
Интегрированная среда разработки Remix Solidity IDE
Запуск компиляции
Вызов функций контракта
Публикация контракта в приватной сети
Получаем определение ABI и двоичный код контракта
Публикация контракта
Проверка состояния транзакции публикации контракта
Вызов функций контракта
Пакетный компилятор solc
Установка solc в Ubuntu
Установка solc в Debian
Компиляция контракта HelloSol
Публикация контракта
Установка solc на Rasberian
Итоги урока

Урок 6. Смарт-контракты и Node.js
Установка Node.js
Установка в Ubuntu
Установка в Debian
Установка и запуск Ganache-cli
Установка Web3
Установка solc
Установка Node.js на Rasberian
Скрипт для получения списка аккаунтов в консоли
Скрипт для публикации смарт-контракта
Запуск и получение параметров
Получение параметров запуска
Компиляция контракта
Разблокировка аккаунта
Загрузка ABI и бинарного кода контракта
Оценка необходимого количества газа
Создание объекта и запуск публикации контракта
Запуск скрипта публикации контракта
Вызов функций смарт-контракта
Возможно ли обновление опубликованного смарт-контракта
Работа с Web3 версии 1.0.x
Получаем список аккаунтов
Публикация контракта
Вызов функций контракта
Перевод средств с одного аккаунта на другой
Перевод средств на аккаунт контракта
Обновляем смарт-контракт HelloSol
Создаем скрипт для просмотра баланса аккаунта
Добавляем вызов функции getBalance в скрипт call_contract_get_promise.js
Пополняем счет смарт-контракта
Итоги урока

Урок 7. Введение в Truffle
Установка Truffle
Создаем проект HelloSol
Создание каталога и файлов проекта
Каталог contracts
Каталог migrations
Каталог test
Файл truffle-config.js
Компиляция контракта HelloSol
Запуск публикации контракта
Вызов функций контракта HelloSol в приглашении Truffle
Вызов функций контракта HelloSol из скрипта JavaScript под управлением Node.js
Установка модуля truffle-contract
Вызов функций контракта getValue и getString
Вызов функций контракта setValue и setString
Изменение контракта и повторная публикация
Работа с Web3 версии 1.0.x
Вносим изменения в смарт-контракт HelloSol
Скрипты для вызова методов контракта
Тестирование в Truffle
Тест на Solidity
Тест на JavaScript
Итоги урока

Урок 8. Типы данных Solidity
Контракт для изучения типов данных
Логические типы данных
Беззнаковые целые числа и целые числа со знаком
Числа с фиксированной запятой
Адрес
Переменные сложных типов
Массивы фиксированного размера
Динамические массивы
Перечисление
Структуры
Словари mapping
Итоги урока

Урок 9. Миграция контрактов в приватную сеть и в сеть Rinkeby
Публикация контракта из Truffle в приватную сеть Geth
Подготовка узла приватной сети
Подготовка контракта для работы
Компиляция и миграция контракта в сеть Truffle
Запуск миграции в локальную сеть geth
Добываем артефакты Truffle
Публикация контракта из Truffle в тестовой сети Rinkeby
Подготовка узла Geth для работы с Rinkeby
Синхронизация узла
Добавление аккаунтов
Пополнение аккаунта Rinkeby эфиром
Запуск миграции контракта в сеть Rinkeby
Просмотр информации о контракте в сети Rinkeby
Консоль Truffle для сети Rinkeby
Более простой способ вызова функций контракта
Вызов методов контракта при помощи Node.js
Перевод средств между аккаунтами в консоли Truffle для Rinkby
Итоги урока

Урок 10. Децентрализованное хранилище данных Ethereum Swarm
Как работает Ethereum Swarm
Установка и запуск Swarm
Операции с файлами и каталогами
Загрузка файла в Ethereum Swarm
Чтение файла из Ethereum Swarm
Просмотр манифеста загруженного файла
Загрузка каталогов с подкаталогами
Чтение файла из загруженного каталога
Использование публичного шлюза Swarm
Обращение к Swarm из скриптов Node.js
Модуль Perl Net::Ethereum::Swarm
Установка модуля Net::Ethereum::Swarm
Запись и чтение данных
Итоги урока

Урок 11. Фреймворк Web3.py для работы с Ethereum на Python
Установка Web3.py
Обновление и установка необходимый пакетов
Установка модуля easysolc
Публикация контракта с помощью Web3.py
Компиляция контракта
Подключение к провайдеру
Выполнение публикации контракта
Сохранение адреса контракта и abi в файле
Запуск скрипта публикации контракта
Вызов методов контракта
Чтение адреса и abi контракта из файла JSON
Подключение к провайдеру
Создание объекта контракта
Вызов методов контракта
Truffle и Web3.py
Итоги урока

Урок 12. Оракулы
Может ли смарт-контракт доверять данным из внешнего мира
Оракулы как информационные посредники блокчейна
Источник данных
Код для представления данных из источника
Оракул для записи обменного курса в блокчейн
Контракт USDRateOracle
Обновление обменного курса в смарт-контракте
Использование провайдера Web Socket
Ожидание события RateUpdate
Обработка события RateUpdate
Инициирование обновления данных в смарт-контракте
Итоги урока

Комментарии (15)


  1. FForth
    15.10.2019 15:23

    Интересно, что книгу про криптоволюту приходится продавать через обычные каналы распространения и за рубли :)

    P.S. Пример проекта организации магазина (работающего через браузер, при запущенном кошельке Litecoin c плагинами из данного проекта) LTCFileShopPlugin


    1. AlexandreFrolov Автор
      15.10.2019 15:33

      Логично, книга ведь для тех, кто только начинает разбираться с криптовалютой) Ну и законодательство у нас пока запрещает использовать криптовалюту как платежное средство


  1. PsyHaSTe
    15.10.2019 18:04

    Ethereum это не про криптовалюту, а про блокчейн.


    К слову, самая отвратительная технология с которой я работал. Язык, в котором нет функций преобразования числа в строку, функции конкатенации строк, возможности получить текст ошибки кроме "что-то пошло не так", в котором нельзя создать функцию которая использует больше 15 переменных (включая аргументы и переменные циклов), что не было бы проблемой, если бы язык разрешал использовать структуры (в качестве параметров методов смарт-контрактов), и много-много других увлекательных особенностей. Ой, это я про солидити, а не про эфир. Впрочем, разница невелика, ибо остальные технологии под эфир еще хуже. Я лично писал свои массивы и хэшмапы для реализации на расте, но в какой-то момент забил, потому что вместо решения рабочих задач я занимался поддержкой чужого проекта.


    Впрочем, эфир тоже неплох, минимальное время генерации блока в 1 секунду, рандомные отваливания внутри блокчейна, периодическая недоступность RPC и выжирания памяти ведущее к OOM, которые не фиксятся годами — всё это ожидает своих героических осваивателей.


    1. Dechjo
      16.10.2019 08:37

      Кстати текст ошибки поллучить, говорят, можно, используя ganache --fork. Но в целом согласен. Хотя geth работает вполне стабильно в моих задачах, может и хорошо, что до parity руки не дошли.


      1. lavilav
        16.10.2019 11:03

        Parity иногда залипает. То не может в пул отправить транзакцию, то статус транзакций не может выдать.
        Впрочем geth примерно также работал пару лет назад. Возможно сейчас лучше.


        Я на parity с kotlin сделал платежный шлюз для трансфера токенов erc20.
        Вроде работает предсказуемо, главное лишний раз не трогать движок и файлы блокчейна.


      1. PsyHaSTe
        16.10.2019 11:42

        Можно, только средствами RPC (а значит, программно во время работы) вы их не увидите. По крайней мере в RPC я текста паники ни разу не видел. Я их использую просто как докуметацию в контракте.


        Например, допустим у нас есть такой контракт.


        contract PanicTest {
            function test() public {
                require(false, "Here be exception message");
            }
        }

        Думаете мы увидем в ответе текст ошибки? Как бы не так:


        2019-10-16 11:37:10.603 +03:00 [VRB] RPC Request: {"id":1,"jsonrpc":"2.0","method":"personal_sendTransaction","params":[{"from":"0x8Ef4fb866d28D87B61229C0740996aD8160A1ecf","to":"0xe0ad0697f443de43b3d576a58f1e9f25f7e231d3","gas":"0x47b760","gasPrice":"0x0","value":"0x0","data":"0xf8a8fd6d"},"MyPassword"]}
        2019-10-16 11:37:10.638 +03:00 [VRB] RPC Response: 0xfbaf7890f9c05ae0b51f3db06ee4e85b9c2895043a9384b307f527dfebce1ae5
        2019-10-16 11:37:15.650 +03:00 [VRB] RPC Request: {"id":1,"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xfbaf7890f9c05ae0b51f3db06ee4e85b9c2895043a9384b307f527dfebce1ae5"]}
        2019-10-16 11:37:15.652 +03:00 [VRB] RPC Response: {
          "blockHash": "0x0739ce497cd5f04272541ccd63df1992fe8180327b6454ffa35b0aee5aa39ff1",
          "blockNumber": "0x2cdf",
          "contractAddress": null,
          "cumulativeGasUsed": "0x541f",
          "from": "0x8ef4fb866d28d87b61229c0740996ad8160a1ecf",
          "gasUsed": "0x541f",
          "logs": [],
          "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
          "root": null,
          "status": "0x0",
          "to": "0xe0ad0697f443de43b3d576a58f1e9f25f7e231d3",
          "transactionHash": "0xfbaf7890f9c05ae0b51f3db06ee4e85b9c2895043a9384b307f527dfebce1ae5",
          "transactionIndex": "0x0"
        }

        есть статус 0x0 — значит, транзакция не смогла смайниться и… И всё. Happy debugging, bitch (шутка).


        Я это обходил через то, что я выставлял все проверки которые делаются в require как публичные bool-функции и проверял их после получения статуса 0:


        protected static async Task<TransactionReceipt> WrapTransactionAsync(
            Func<Task<TransactionReceipt>> operation,
            params (Func<Task<bool>> isBusinessRuleFailed, Func<Exception> businessExceptionFunc)[] checks)
        {
            try
            {
                return await operation();
            }
            catch (TransactionFailedException)
            {
                foreach (var (isBusinessRuleFailedAsync, businessExceptionFunc) in checks)
                {
                    if (await isBusinessRuleFailedAsync())
                    {
                        throw businessExceptionFunc();
                    }
                }
                throw;
            }
        }
        
        ...
        
        [ItemNotNull]
        
        public Task<TransactionReceipt> ValidateTransactionAsync(string transactionHash, RequestStatusUpdate requestStatusUpdate)
        {
            return WrapTransactionAsync(
                () => Web3.Client.GetTransactionReceiptAsync(transactionHash),
                (
                    () => IsNewRequestAsync(requestStatusUpdate.ServiceNumber),
                    () => new RequestNotFoundException(requestStatusUpdate.ServiceNumber)
                ),
                (
                    async () => !await IsNewStatusAsync(requestStatusUpdate),
                    () => new StatusAlreadyExistsException(requestStatusUpdate)
                ));
        }

        Надо ли говорить, что оно капец какое неудобное?.. Да и не работает в общем случае, просто чуть-чуть снижает боль для известных сценариев которые могут вызвать ошибку. В остальных случаях — "нишмагла, 0x0".


        Хотя geth работает вполне стабильно в моих задачах, может и хорошо, что до parity руки не дошли.

        Зависит от сложности ваших задач. У меня щас контракт перевалил за 2000 строчек и он за время работы сжирает под 2 триллиона газа.


        Просто вот это — типичный код на солидити


        А вот это — то, что мне приходится писать:


        1. JekaMas
          16.10.2019 13:41

          Если не секрет, с какими чейнами сейчас стали работать?
          Я так по старинке Ethereum и допиливаю, ну еще Cosmos и компанию.


          1. PsyHaSTe
            16.10.2019 13:47

            Сейчас я вообще ни с какими не работаю, позвали знакомые на интересную продуктовую разработку.


            А перед уходом я посматривал на экзонум. На актиксе, довольно аккуратно, к производительности претензий никаких. Ну и полноценный язык со нормальной экосистемой, а не вот этот огрызок :)


    1. JekaMas
      16.10.2019 13:22

      К сожалению, Parity, по моему мнению, забросило свой клиент. Тут вопросы не к Ethereum, а к Parity.
      Попробуйте другой, более живой клиент.


      1. PsyHaSTe
        16.10.2019 13:41

        б0льшая часть претензий у меня к солидити, потому что solc это реально исчадие ада.


        Вот знаете, что мне выдает компилятор когда я пытаюсь в функцию добавить еще один аргумент?


        Compiler error: Stack too deep, try removing local variables.
        1>     ...  uint128 dateRegNumPair = (uint128(date) << 64) | uint128(regNum); 
        1>                                            ^--^

        И или делай что хочешь. Разобъешь на маленькие функции? Отлично, теперь контракт не получится задеплоить потому что у него слишком большой размер (спасибо виталику). Включишь расширение чтобы нода позволяла обходить этот ЕИП и деплоить больше контракты? Еще что-нибудь отвалится. И так до бесконечности


        1. JekaMas
          16.10.2019 13:49

          Знаю… Работаю над EIP'ами и постоянно всё бьется об обратную совместимость. "Типа, давайте это в солодити исправим? — Низя! Это чьи-то контракты сломает"
          Думаю, это одна из причин, почему ждут Eth 2.0, хотя до него годы...


  1. JekaMas
    16.10.2019 13:13

    Главы про swarm какую версию API включают?
    В этом году оно довольно сильно менялось.
    Есть ли про покупку контента? https://twitter.com/bvanmaarseveen/status/1178744419048181761?s=19


    1. AlexandreFrolov Автор
      16.10.2019 13:25

      Проверялось на версии 0.3.12-stable
      $ swarm version
      Swarm
      Version: 0.3.12-stable
      Git Commit: 4e13a09c5033b4cf073db6aeaaa7d159dcf07f30
      Go Version: go1.10.4
      OS: linux

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


      1. JekaMas
        16.10.2019 13:29

        К сожалению, этому API больше года, текущее 0.5.2. Код из книги вряд ли будет полезен и, скорее всего, не запустится.


        1. AlexandreFrolov Автор
          16.10.2019 15:28

          Если у кого возникнут трудности с запуском кода, пишите сюда, сделаем фикс.