1. Блокчейн
Сейчас, когда я пишу эту статью курс Bitcoin упал более чем в 5 раз относительно максимального значения и рассказывая о том, что я делал что-то связанное с блокчейн первое, что я слышу это нескрываемый скепсис — “кому теперь нужен весь этот ваш блокчейн”.
Да, действительно хайп вокруг блокчейна прошел. Но технологии лежащие в основе остались, они развиваются и будут продолжать развиваться и использоваться в определенных нишах. В интернете и в частности на Хабре множество материалов, описывающих как общие направления применения технологий (например, habr.com/company/bitfury/blog/353350 так и более частные примеры habr.com/company/raiffeisenbank/blog/332756).
Как известно, блокчейн — это распределенный реестр, т.е. база данных, которая распределена между несколькими узлами при этом каждый узел хранит полную копию реестра. Особенность блокчейн в том, что записи (транзакции) сгруппированы в блоки, а блоки объединены в цепочку блоков. При этом доступны только операции по добавлению данных. Все это приводит к тому, что внести изменения в уже сохраненные в блокчейн транзакции практически невозможно.
Есть множество материалов, о том как работает блокчейн (если вы до этого ничего не слышали про блокчейн, то начать можно с этого простого видео).
В момент максимального всплеска интереса к технологии блокчейн было множество призывов использовать блокчейн абсолютно везде. Однако есть определенные признаки проектов/задач, для реализации которых может потребоваться блокчейн.
Во-первых, участие большого количества игроков (пользователей), которые записывают данные, при этом необходимо предотвратить несоответствия и повысить уровень доверия.
Во-вторых, отсутствие третьей стороны, которой все доверяют.
В-третьих, необходимость наличия механизма для публичной проверки данных.
Если все перечисленные условия выполнены — необходимо задуматься об использовании блокчейна.
Такие задачи могут возникнуть в любых отраслях. Проект www.101blockchains.com собирает информацию как о потенциальных так и о внедренных проектах, а также об особенностях использования блокчейн в разных областях.
Например, в сфере здравоохранения блокчейн может использоваться:
- для безопасного управление данными пациента;
- для борьбы с контрафактными лекарственными препаратами за счет неизменяемых транзакций по всей цепочке поставок;
- для улучшения мониторинга и эффективности клинических испытаний за счет устранения мошенничества и манипулирования данными.
При применении блокчейн в корпоративном сегменте обычно используют частный блокчейн с различным уровнем разрешений (Private Permissioned Blockchain). В таких сетях есть специальный набор узлов для подтверждения транзакций.
Однако при разработке первого адаптера InterSystems IRIS для работы с блокчейн мы выбрали Ethereum, который относится к категории Permissionless Blockchain — открытой платформы без управляющего органа. Такой выбор связан с популярностью Ethereum и достаточно развитой инфраструктурой: наличием различных инструментов и библиотек. Также можно заметить что используя ПО для работы с Ethereum можно создать приватный блокчейн.
2. Адаптер
Теперь пора перейти к собственно адаптеру.
Адаптер в InterSystems IRIS (также как и в Ensemble) — это класс или пакет классов InterSystems IRIS, предоставляющих возможность работы с внешней системой. Адаптеры InterSystems IRIS делятся на входящие (для получения данных от внешней системы, когда внешняя система является инициатором взаимодействия) и исходящие (для работы с внешней системой, когда инициатором взаимодействия является InterSystems IRIS).
IRIS Ethereum адаптер является исходящим адаптером, и немного отличается от большей части других адаптеров InterSystems IRIS, поскольку часть этого адаптера — это пакет классов InterSystems IRIS, но также в адаптер входит небольшой модуль NodeJS. Архитектура приведена на рисунке 1.
Рисунок 1.
Модуль NodeJS адаптера использует существующие библиотеки NodeJS для работы с Ethereum.
Адаптер предоставляет следующие возможности:
- Разместить смарт-контракт в Ethereum (мы планируем подготовить еще одну статью, в которой более подробно расскажем про смарт-контракты, инструменты для разработки и обсудим пример).
- Вызывать методы смарт-контрактов: как методы которые не изменяют состояние блокчейн, так и методы которые изменяют состояние блокчейн
- Сохранение транзакции (перевод средств с кошелька на кошелек)
- Вызов вспомогательных методов, для получение состояния блокчейн
- Логирование всех запросов (выполняет NodeJS модуль, полезно при отладке)
Адаптер доступен с исходными кодами на OpenExchange.
3. Простой пример
Вместе с адаптером устанавливается пример “Hello world”.
Чтобы начать работать с Ethereum (в том числе чтобы запустить этот пример) вам понадобится:
- Выбрать с какой из сетей вы будете работать. Для разработки обычно используют тестовые сети например Ropsten
- Создать в этой сети кошелек и пополнить его
- Установить локальный клиент Ethereum (например, Geth) или получить ключ для работы с облачным провайдером (например, Infura)
При настройке бизнес-операции необходимо задать (рисунок 2):
- Сервер и порт, где запущен модуль NodeJS (по умолчанию порт 3000)
- Настройки провайдера ( в данном случае доступ к Infura)
- Реквизиты доступа ( в реквизитах доступа в качестве имени пользователя необходимо указать ваш кошелек, в качестве пароля — приватный ключ от кошелька. В InterSystems IRIS реквизиты доступа хранятся в отдельной БД, для которой необходимо включить шифрование)
Рисунок 2.
Для работы со смарт контрактами — вам понадобится создать (для каждого смарт-контракта, к которому вы будете обращаться) папку в файловой системе и разместить там 2 файла:
* abi.txt
* bytecode.txt
В этих файлах должны быть ABI смарт-контракта и Bytecode. ABI смарт-контракта — формальное описание интерфейса смарт-контракта в json-формате. ABI и Bytecode создаются в момент компиляции смарт-контракта.
Bytecode необходим только для развертывания контракта.
С помощью службы тестирования можно проверить работу бизнес-операции.
На рисунке 3 с помощью службы тестирования выполняется развертывание (deploy) смарт-контракта. Результат вызова этой бизнес операции — это сообщение содержащее хеш транзакции.
Рисунок 3.
С помощью браузера ropsten.etherscan.io (https://etherscan.io/) можно найти эту транзакцию, и получить адрес размещенного смарт-контракта.
Для выполнения методов смарт-контракта помощью адаптера необходимо указать настройки в конфигурации продукции: ContractFolder и ContractAddress.
Код вызова метода смарт-контракта достаточно прост:
set ..ContractABI = [].%FromJSON(..ContractFolder_"abi.txt")
set contract = ..Adapter.GetContract(
##class(Ethereum.Address).%New(..ContractAddress),
..ContractABI)
set result = contract.hello()
set pResponse = ##class(Ens.StringContainer).%New(result.args)
С помощью метода адаптера GetContract, которому передается адрес смарт-контракта и ABI, создается объект смарт-контракт, которые затем используется для вызова методов. В данном случае в смарт контракте должен быть определен метод hello(), возвращающий строку.
В этом примере метод hello() не изменяет состояние блокчейн, поэтому его вызов может выполняться синхронно. Однако методы изменяющие состояния блокчейн могут выполняться достаточно долго (ожидание подтверждения транзакции).
Для вызова таких методов можно использовать механизм отложенного ответа (deferred response) в InterSystems IRIS. Адаптеру необходимо передать токен отложенного ответа (deferred) и тогда при подтверждении транзакции NodeJS модуль передаст InterSystems IRIS результат ее выполнения. Для этого необходимо сконфигурировать веб-приложение и добавить в продукцию бизнес-операцию, которая будет обрабатывать полученный ответ.
Код для вызова метода, изменяющего состояние блокчейн:
// getting EthereumAccount(wallet) and privateKey
do ##class(Ens.Config.Credentials).GetCredentialsObj(.cred, "Ethereum.Demo.EthereumOperation", "Ens.Config.Credentials", ..Credentials)
set account = ##class(Ethereum.Address).%New(cred.Username)
set privateKey = cred.Password
//reading contract ABI
set ..ContractABI = [].%FromJSON(..ContractFolder_"abi.txt")
// get contract object
set contract = ..Adapter.GetContract(
##class(Ethereum.Address).%New(..ContractAddress),
..ContractABI)
$$$ThrowOnError(..DeferResponse(.deferred))
// estimate gas
do contract.SetOptions(account)
set gasJSON = contract.EstimateGas("setName",pRequest.Name)
$$$TRACE(gasJSON.gas)
do contract.SetOptions(account, privateKey,
##class(Ethereum.Wei).%New(1000000000),
##class(Ethereum.Wei).%New(100*gasJSON.gas),,deferred)
set result = contract.setName(pRequest.Name)
В данном случае перед вызовом метода смарт-контракта setName() необходимо указать ряд параметров, включая токен отложенного ответа.
В нашей следующей статье будет более подробно рассказано о смарт-контрактах и приведен пример решения прикладной задачи с использованием Ethereum-адаптера InterSystems IRIS.