После развития и внедрения смарт-контрактов в 2015 году появилась новая модель для построения успешных и масштабируемых технологий — Dapps, или decentralized application. Децентрализованные приложения за несколько лет стали настолько популярными, что из-за постоянной работы начали перегружать сеть Ethereum и замедлять ее работу. Для разгрузки блокчейна Loom Network представил ZombieChain — общий сайдчейн для всех Ethereum-Dapps. В индустрии на данный момент существует 1576 приложений. С каждым разом их становится все больше. Можно ли самостоятельно собрать Dapp?

Dapp это больше, чем смарт-контракт

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

Таким образом, Dapps — это утилиты, с помощью которых можно реализовать и в будущем сопровождать процессы CI/CD (Continuous Integration, или непрерывная интеграция, и Continuous Delivery, или непрерывная доставка).

Чтобы приложение рассматривалось как Dapp, оно должно соответствовать следующим критериям:

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

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

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

 Приложение обязано генерировать токены в соответствии со стандартным криптографическим алгоритмом, действующим в качестве доказательства того, что ноды достоверны (биткоин использует алгоритм Proof-of-Work).

Dapp состоит из двух частей: интерфейс, написанный в HTML, и бэкэнд — «база данных» для интерфейса.

Упрощенная архитектура Dapp. Источник

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

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

Как запустить Dapp. Начальная инструкция

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

Команда Ethereum на своем сайте дает рекомендации по сборке собственного приложения. Мы подготовили перевод инструкции.

Первым вашим шагом будет установка клиента Alethzero с языком C++. После установки на компьютер вы увидите белые окна с браузером.

Специалисты Ethereum обещают выпустить свой браузер Minst, который будет предназначен для работы с Dapps, пока его можно скачать в бета-версии, выглядеть он будет так:

Для создания Dapp лучше всего использовать язык Solidity, так как именно он формально поддерживается командой ETHDEV. Но существует несколько других языков, которые можно внедрять в приложение. Это LLL (аналогичен «языку обработки  списков» Lisp) и Serpent (аналогичен языку программирования общего назначения Python).

После выбора языка необходимо ввести в систему хотя бы одну учетную запись токена, чтобы запустить контракт. Затем нужно нажать функцию «send», аналогичную contract.send (счет, сумма) для перемещения токена.

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

Контракты делятся на методы. Первый — metaCoin. Является специальным методом конструктора, который определяет начальное состояние хранения данных контракта. Функции конструктора всегда имеют то же имя, что и контракт. Этот код инициализации выполняется только один раз при создании договора.

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

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

Обратите внимание, что указано два типа данных: address и uint. В отличие от языка Serpent, Solidity статически типизирует и выполняет проверку типов во время компиляции. Указание типа перед компиляцией также позволяет уменьшить размер переданного транзакциями массива данных, это помогает компилятору создавать более оптимизированный EVM-код.

Это инициализация контракта, который будет запускаться только один раз (так как находится в методе конструктора metaCoin) и выполнять два действия. Во-первых, контракт использует msg.sender для поиска общего адреса отправителя транзакции, то есть вас. Во-вторых, контракт обращается к хранилищу контрактов, используя отображающиеся балансы. Контракты хранят данные как пару ключевых значений длиной 32 байта.

Msg.sender — номер в 160 бит, обозначающий ваш открытый ключ. Это уникальный идентификатор в сети, который нельзя подделать благодаря криптографическим законам, которые реализует Ethereum.

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

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

В первой строке проверяется текущий баланс msg.sender — меньшее количество токенов, которое можно отправить. Для завершения транзакции учетная запись должна иметь достаточное количество токенов.

Подтвердить процесс передачи токенов с одного адреса на другой можно с помощью msg.sender, receiver и amount.

Если баланс проверяется, условие будет оцениваться как ложное, а следующие две строки будут вычитать сумму, отправляемую с баланса отправителя: балансы [msg.sender] = amount; затем добавятся к балансу счета, получающего токены: balances[receiver] += amount;.

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

Как запустить Dapp. Шаг: работа в Alethzero

После того, как вы пропишите последовательность ходов, всю информацию нужно будет перенести в Alethzero. Откройте кошелек и убедитесь, что это личный интерфейс и что у вас открыт блокнот с контрактом, сохраненным внутри. В данном руководстве не нужно подключаться к Testnet, вместо этого выберите «Use Private chain» в меню debug и создайте свою собственную частную цепочку. Благодаря этому вы будете зависить от того, что тестовая сеть находится в онлайне, когда разрабатываете Dapp.

Нажмите кнопку «New transaction» в строке меню, чтобы открыть и начать новую транзакцию. Здесь нужно ввести код контракта и совершить транзакцию, которая состоит из адреса для отправки, параметров для газа и панели ввода кода или данных транзакции.

Для сохранения этого контракта или его работы потребуется эфир, которого пока нет. Получить эфир можно с помощью майнинга.

Так как у вас запущена частная цепочка, и вы не подключены к сети, можно использовать только новые блоки. Нажмите «Mine» на панели инструментов, затем перейдите в меню debug и выберите «Force Mining». В этот момент различные вкладки должны наполняться информацией. На вкладке учетной записи есть визуальное представление процесса разработки блока — когда успешный блок обнаружен, красная отметка достигает пика, и баланс должен увеличиваться. Для просмотра процесса можно воспользоваться вкладкой «Blockchain», где записывается каждое действие.

Остановить майнинг можно в тот момент, когда вы станете держателем каких-либо токенов (в нашем примере описываются монеты Finney) тех проектов, которые основаны на Ethereum. Для этого еще раз нажмите «My» и разверните свой контракт.

Повторно запустите всплывающее окно «New Transaction», скопируйте и вставьте Solidity, которую ранее написали в текстовом поле «Data». Это должно выглядеть примерно так:

Поскольку мы просто создаем тестовый контракт и не собираемся отправлять эфир на другие аккаунты, все незаполненные поля можно оставить по умолчанию. Но в данном примере отправляется 10,000 газа на контракт по цене 10 Szabo за каждый эфир. Szabo — другая единица стоимости, эквивалентная 0.000001 части эфира. Контракт не будет потреблять весь газ, поскольку тестовый код в данном контракте очень простой.

Даже если в вашем контракте есть какие-либо компиляционные ошибки, то можете не волноваться об этом — отладчик сам найдет и укажет на некорректную строку или символ. После этого нужно найти два сообщения в панели под кодом контракта. Первый раздел «Solidity» содержит похожий на фрагмент кода JavaScript (который не используется в системе, а просто имеет некоторые общие составляющие с кодом), список всех исполняемых функций в контракте и ABI (Application Byte Interface) в функции «sendCoin». Выделите эту информацию и скопируйте ее в блокнот. Вторая — серия сборочных инструкций, подобных «PUSH2 0x27 0x10 CALLER…». Это ваш EVM-код контрактов в его скомпилированной форме.

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

Поскольку вы не майните, контракт будет выходить в «Pending» и выглядеть следующим образом:

После нажатия «Execute» в области транзакций обратите внимание на поле «creates» для этой конкретной транзакции на pending-панели, в данном случае «1f530b6b…» (для каждого пользователя будет создан свой уникальный ID).

Теперь, когда есть ожидающий или pending-контракт, нужно зафиксировать его в блочной цепочке путем разработки блока. Нажмите «mine» и дождитесь, пока транзакция исчезнет с pending-панели, и новая запись появится в панели «Contract». Снова выключите майнинг и нажмите на новый контракт в панели контрактов. Вы должны увидеть:

Затем в хранилище данных контрактов должна появиться запись начальной настройки, ее можно увидеть после указания ключевых значений SHA3 общего адреса и номера «10,000». Необходимо проверить, можно ли отправить токены другому открытому ключу. Чтобы запустить функцию sendCoin, нужно отправить транзакцию на адрес контрактов, указав адрес «To», «value» и идентификатор функции в массиве данных транзакций. Найдите область транзакции и вставьте адрес контрактов в поле «Address»:

Теперь в области, где ранее вводили код, впишите идентификатор функции и адрес получателя и значение в отдельных строках. Когда ранее отправляли контракт в сеть, вы должны были сохранить ID sendCoin. Используйте 0xec6d9353ca85eb80076817fa989f8825e136d55d (общий адрес в тестовой сети: p) и любое значение ниже 10,000. Данные должны выглядеть примерно так:

$0x90b98a11

0xec6d9353ca85eb80076817fa989f8825e136d55d

500

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

Нажмите «Execute», и вы должны еще раз увидеть транзакцию в ожидании, нажмите «my», пока не сгенерировали новый блок, а затем прекратите майнинг. Теперь контракт должен выглядеть примерно так:

Выдохните, это финал

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