Блокчейн-платформа для сделок торгового финансирования на базе смарт-контрактов

Habrahabr
22 июня 2017 года на Blockchain & Bitcoin Conference в Санкт-Петербурге наш аналитик направления блокчейн, Марина Сманцер, сделала доклад о результатах исследовательского проекта по созданию комплексной платформы для сделок торгового финансирования на основе смарт-контрактов.

20-минутный формат доклада не позволял подробно осветить технические аспекты. Поэтому выход Райффайзенбанка на habrahabr – прекрасная возможность рассказать о наших результатах во всех подробностях.

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

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

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

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

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

В подготовке статьи активно участвовала gelbplaneten

Кратко о целях и результатах

В конце 2016 года блокчейн попал в зону интересов нашего отдела R&D. Некоторое время заняло погружение в теорию, после которого мы решили, что имеет смысл сделать практическую реализацию.

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

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

Аккредитив: теория и бизнес-процесс
Если абстрагироваться от терминов торгового финансирования, аккредитив – вид безналичной формы расчетов. Банк берет на себя обязательство совершить платеж в пользу Продавца, если тот предъявит документы об исполнении своей части условий сделки. Аккредитив решает проблему отсутствия доверия между Покупателем и Продавцом и снижает некоторые риски: например, связанные с финансовым состоянием Покупателя на момент расчетов. В упрощенном виде алгоритм расчетов можно представить следующим образом:
  1. Стороны заключают контракт на поставку товара, где указывают аккредитив в качестве способа расчета.
  2. Покупатель подает в свой банк заявление на открытие аккредитива. Банк проводит внутренние проверки (например, наличие средств на счете). При положительном результате Банк выпускает аккредитив.
  3. После выпуска аккредитива Банк уведомляет Продавца об открытии аккредитива по определенным условиям. Продавец имеет право отклонить аккредитив.
  4. Когда поставка товара будет произведена, Продавец отправляет указанные в условиях аккредитива документы (счет-фактура, торговая накладная, и т.п.) на рассмотрение в Банк.
  5. Банк проверяет документы и при положительном результате проводит платеж.
В этом описании многие моменты упрощены.

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

Мы ориентировались на открытые решения, в частности, в качестве блокчейна был выбран публичный Ethereum. О других технологиях будет подробно рассказано далее в статье.

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

Задачи исследовательского проекта

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

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

Для определения необходимого для реализации платформы функционала были заданы следующие исходные условия:

  • Исполнение сделки сопровождается обменом документами между сторонами
  • Основной расчет по сделке производится через обычные (фиатные) каналы расчета
  • Все операции по сделке должны быть максимально юридически подтверждены исходя из действующих нормативных документов и регуляторных положений (для обеспечения судебной практики «прямо сейчас»)
  • Все операции и сигналы переходов между операциями должны быть максимально автоматизированы

Общая схема платформы и взаимодействие её элементов

Архитектура и взаимодействие компонентов платформы

image

Из анализа исходных условий вытекает необходимость использования следующих функциональных компонентов:

  • Блокчейн — как доверенный реестр операций по сделке и среда исполнения смарт-контрактов, обеспечивающих сделку
  • Децентрализованное файловое хранилище (DFS) — как среда хранения и обмена файлами, связанными со сделкой
  • Сертифицированное СКЗИ — как средство обеспечения дополнительного шифрования, юридически значимых электронных подписей и защищенных временных меток. Кроме того, оно может быть использовано для организации дополнительного виртуального слоя распределения доступа к файлам, если DFS не поддерживает механизмов многопользовательского доступа.
  • Оракулы и провайдеры внешних запросов — для доступа к учетным системам банка и источникам событий внешнего мира (реестры и прочее)
  • Анализаторы документов — для автоматического анализа представляемых сторонами документов для подтверждения условий исполнения сделки.
Учитывая, что основные расчеты и анализ документов в реалиях сегодняшнего дня выполняются вне смарт-контрактов, непосредственно в смарт-контракты передаются только данные, которые те в состоянии обработать. Остальная информация (обосновывающие и распорядительные документы) прикрепляется в виде обычных (для ручной обработки) или формализованных (для автоматической обработки) документов, подписанных усиленной квалифицированной ЭЦП для обеспечения юридической значимости.

При этом на внутреннюю логику смарт-контракта могут быть возложены следующие задачи:

  • Обеспечение следования матрице статусов с учетом текущего статуса и инициатора переключающей транзакции
  • Контроль даты для ограничения периода, в рамках которого могут быть представлены документы
  • Обработка наступления опорных событий, приходящих от Провайдеров внешних запросов
С каждым из пользователей платформы связывалась следующая регистрационная информация:
  • Уникальный идентификатор в системе
  • Ethereum-адрес, с которого пользователь направляет транзакции
  • Адрес смарт-контракта, используемого для ведения реестра принадлежащих или направленных пользователю сделок (далее именуется Почтовый ящик)
  • Идентификатор сертификата усиленной квалифицированной ЭЦП и ее открытый ключ
Наиболее простое объяснение концепции оракулов: blockchainhub.net/blockchain-oracles По DFS не нашлось хорошей статьи, оставлю ссылку на документацию Swarm: swarm-guide.readthedocs.io/en/latest/introduction.html И Storj: storj.io

Практическая реализация

На рисунке ниже представлена общая схема платформы и основных потоков обмена данными между ее функциональными компонентами (при этом зеленым выделены «чужие» компоненты, фиолетовым — сертифицированные, белым — ПО Банка):

image В процессе подготовки и исполнения сделки компоненты платформы взаимодействуют следующим образом:

  • Клиентское ПО (например, клиент-банк или мобильный банк). Используется для ввода исходной информации по сделке, создания необходимых смарт-контрактов и управления состоянием смарт-контрактов на ручных этапах бизнес-процесса. Следует отметить, что под ручными этапами бизнес-процесса могут подразумеваться как те этапы, на которых требуется реальные «личные» действия пользователя — например, прикрепление к смарт-контракту документов, так и вообще любые этапы, на которых изменение статуса смарт-контракта производится без использования его внутренней логики — за пределами блокчейна. К последнему случаю можно отнести проверку прилагаемых к смарт-контракту документов по учетным системам банка, которая может происходить автоматически, но снаружи блокчейна.
  • Прикрепляемые к смарт-контракту файлы подписываются усиленной квалифицированной ЭЦП создателя для его (создателя) однозначной юридически значимой идентификации. Далее файлы шифруются с формированием крипто-пакета, доступного к расшифровыванию только участниками сделки. Полученный в итоге крипто-пакет помещается в DFS, при этом на контексте смарт-контракта сохраняется хэш исходного файла, а также адрес (ссылка, манифест) объекта хранения, отданный DFS. Адрес объекта хранения позволяет извлечь крипто-пакет из DFS, расшифровать его (участникам сделки) и обработать надлежащим образом.
  • При обработке транзакций смарт-контракт может пользоваться информацией бродкаст-оракулов, например, контролировать дату получения транзакции по календарю, использовать курсы валют и т.д.
  • При переходе в определенный статус смарт-контракт может направить на исполнение Провайдеру внешних запросов определенный запрос на ожидаемое внешнее событие или распоряжение на исполнение внешнего действия. При наступлении «заказанных» смарт-контрактом внешних событий Провайдер направляет на него транзакцию с информацией о событии. По результатам обработки данной транзакции смарт-контракт может переключится в новое состояние или остаться в прежнем в ожидании наступления последующих событий.
  • Аналогично внешним запросам, при прикреплении к смарт-контракту определенных формализованных документов смарт-контракт может направить их на анализ в Анализатор документов с последующим ожиданием транзакции с результатами анализа.

Реализация смарт-контрактов для аккредитива

Проектирование платформы было решено начать параллельно с проработкой бизнес-кейса для реализации.

Упрощенно схема процесса на блокчейне представлена на рисунке, а подробное описание процесса приведено ниже

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

  1. Покупатель создает смарт-контракт «Заявка на аккредитив» (далее «Заявка»), который получает статус New. Адрес Заявки помещается в Почтовые ящики Покупателя и Банка.
  2. Покупатель прикрепляет к Заявке формализованный ЭД с описанием реквизитов сделки и необходимые неформализованные документы, например, скан-копию контракта, для расчетов по которому открывается аккредитив. После прикрепления всех необходимых документов Покупатель переводит Заявку в статус InBank.
  3. Банк автоматически (для формализованных ЭД) или с использованием экспертов (для неформализованных ЭД) проверяет сделку. Например, направляется запрос в системы банка для проверки клиентских реквизитов в каталоге клиентских данных, для подтверждения остатка по счету и резервирования средств, для иных проверок (например, проверок для целей комплаенс, валютного контроля и т.п.) Если у Банка есть какие-либо претензии по содержанию сделки или приложенных документов, он отказывает в приеме Заявки и устанавливает ей статус Rejected. Если Банк согласен принять заявку к исполнению ей устанавливается статус Confirmed.
  4. На основе формализованного ЭД, описывающего сделку, в учетных системах Банка выполняются необходимые манипуляции (перевод суммы аккредитива с клиентского счета на «счет покрытия», списание комиссии и т.д.) Банк выпускает смарт-контракт «Аккредитив» (далее Аккредитив), который получает статус New. Адрес Аккредитива помещается в Почтовые ящики Банка и Продавца. В Аккредитиве сохраняется адрес Заявки, что позволяет автоматически «зеркалировать» ключевые статусы Аккредитива на Заявку, чтобы Покупатель мог контролировать состояние сделки.
  5. Банк прикрепляет к Аккредитиву формализованный ЭД (формируется автоматически из условий Заявки) с описанием реквизитов сделки, другие необходимые документы и устанавливает ему статус Released. Статус связанной с Аккредитивом Заявки также переключается в Released. При переходе в статус Released Аккредитив автоматически помещает в очередь Провайдера внешних запросов два запроса:
    • Запрос контроля истечения срока действия Аккредитива (срабатывает, когда текущая дата превысит срок действию Аккредитива)
    • Запрос ожидания исполнения контракта (конкретный шаблон запроса определяется содержанием сделки)
  6. Продавец после изучения выпущенного Аккредитива может отказаться его принять: в этом случае он переводит его в статус Invalid, аккредитив аннулируется, и дальнейшие манипуляции с ним становятся невозможны. Статус связанной с Аккредитивом Заявки также переключается в Invalid.
  7. Если первым сработает событие истечения срока действия Аккредитива — он получает статус Overdue и дальнейшие манипуляции с ним становятся невозможны. Статус связанной с Аккредитивом Заявки также переключается в Overdue. В этом случае в учетные системы Банка отправляются автоматические распоряжения для инициирования проводок, соответствующих аннулированию аккредитива (возврат покрытия, прекращение обязательства банка и т.п.)
  8. Если первым сработает событие исполнение контракта (или когда Продавец прикрепляет ЭД, предусмотренные условиями Аккредитива) — Аккредитив переключается в статус InBank. При переходе в статус InBank Аккредитив автоматически помещает в очередь Провайдера внешних запросов запрос ожидания исполнения платежа и удаляет из очереди запрос контроля срока истечения. Банк на основе формализованного ЭД, приложенного к Аккредитиву, выполняет платеж в пользу Продавца путем передачи распоряжения в свою расчетную систему и исполнения Платежа за пределами блокчейна (информация о фактическом исполнении Платежа возвращается в блокчейн).
  9. После срабатывания события исполнения платежа Аккредитив переключается в статус Closed. Статус связанной с Аккредитивом Заявки также переключается в Closed.
  10. Сделка завершена.

Выбор компонентов платформы

При выборе функциональных компонентов платформы мы ориентировались на открытые решения (Ethereum, Swarm, Storj). Это связано со следующими их преимуществами:
  • Наличие развернутой и «самоподдерживающейся» инфраструктуры
  • Открытость для пользователей и возможность контроля операций через альтернативные источники, а не только через предлагаемый банком интерфейс
  • Высокий уровень доверия со стороны пользователей благодаря наличию конкурентных протоколов консенсуса и качественной «не толерантной» сети независимых узлов

image Таким образом, выбор был сделан в пользу следующих реализаций:

  • Блокчейн и смарт-контракты — Ethereum и язык Solidity;
  • Децентрализованные файловые хранилища — Swarm и Storj.io;
  • Сертифицированные СКЗИ — КриптоПРО и КриптоАРМ;
  • Бродкаст-Оракулы — собственной разработки;
  • Провайдеры внешних запросов — собственной разработки;
  • Анализатор документов — на данном этапе было решено не рассматривать, так как принцип взаимодействия с ним смарт-контракта в общем аналогичен Провайдеру внешних запросов, а ресурсы команды исследования — ограничены.

Инфраструктура

Для развертывания необходимых компонентов:
  • Клиентских частей Ethereum, Swarm и Storj.io,
  • СКЗИ,
  • Провайдера внешних запросов,
  • UI-приложения,
  • Интеграционного ядра платформы
было выделено 2 сервера.

На первом сервере было развернут узел Ethereum базового блокчейна смарт-контрактов. Изначально в качестве базового блокчейна использовалась тестовая сеть Ropsten, но на заключительных этапах мы перешли на более стабильный Rinkeby. Причиной этому стал инцидент в марте с DDOS атакой на Ropsten, в ходе которого несколько дней были проблемы с добавлением транзакций. На втором сервере была развернута инфраструктура, обеспечивавшая работу с файлами:

  • Узел DFS Storj.io
  • Узел DFS Swarm с поддерживающим узлом Ropston Ethereum
  • СКЗИ КриптоПРО и КриптоАРМ
Кроме того, из соображений удобства взаимодействия там же было развернуто интеграционное ядро платформы.

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

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

Интеграция компонентов

Ethereum

Интеграция с блокчейном Ethereum осуществлялась с использованием RPC API JSON-RPC, Management-APIs.

Никаких технических проблем с его использованием не возникало.

В качестве внешнего арбитражного ресурса использовался ropsten.etherscan.io или rinkeby.etherscan.io, в зависимости от используемой тестовой сети.

Swarm

Интеграция со Swarm осуществлялась с использованием HTTP API: Swarm-guide, gist.github.com.

Для загрузки файла в SWARM использовался HTTP-запрос PUT /bzz: $PATH$ ($PATH$ — путь к загружаемому файлу) в ответ на который приходил 16-ричный идентификатор манифеста файла, который использовался для его извлечения из SWARM.

Для извлечения файла из SWARM использовался HTTP-запрос GET /bzzi:/$MANIFEST$/ ($MANIFEST$ — 16-ричный идентификатор манифеста извлекаемого файла).

Каких-либо проблем с загрузкой/выгрузкой файлов не возникало.

К сожалению, для Swarm не было найдено внешнего средства мониторинга (типа Etherscan для Ethereum), что определенным образом затрудняло оценку успешности манипуляций с файлами.

Storj.io

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

Для загрузки файла использовалась команда storj upload-file $BUCKET$ $PATH$ (где $BUCKET$ — идентификатор «корзины», а $PATH$ — путь к загружаемому файлу). При успешной загрузке в ответ отдавался идентификатор загруженного файла.

Для выгрузки файла использовалась команда storj download-file $BUCKET$ $FILE$ $PATH$ (где $BUCKET$ — идентификатор «корзины», $FILE$ — идентификатор файла, а $PATH$ — путь к создаваемой локальной копии файла).

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

В качестве внешнего арбитражного ресурса можно использовать https://api.storj.io, который поддерживает API.

КриптоАРМ

Интеграция с КриптоАРМ осуществлялась с использованием предоставляемого им COM-сервиса. Для быстроты реализации интеграционные скрипты были написаны на vbs.

Провайдер внешних запросов

Взаимодействие смарт-контрактов с Провайдером внешних запросов осуществляется по следующей схеме.

image

Подробное описание реализации Провайдера запросов
Перед описанием процесса необходимо определить некоторые основные понятия:
  • Идентификатор запроса — 32-символьное значение (64-значное hex), которое содержит первыми 20 (40 hex) символами адрес контракта, а далее — произвольную информацию, позволяющую контракту при получении ответа построить надлежащую обработку ответа на запрос.
  • Идентификатор ответа — уникальное 32-символьное значение (64-значное hex), позволяющее Провайдеру внешних запросов однозначно идентифицировать ответное сообщение.

Для использования Провайдера внешних запросов смарт-контракт должен поддерживать специальный интерфейс, состоящий из следующих методов: GetExternalRequest, SetExternalResponse и CheckExternalResponse.

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

  1. Контракт транзакцией через метод AddRequest передает идентификатор запроса в смарт-контракт RequestsQueue, адрес которого фиксирован.
  2. Провайдер внешних запросов (ПВЗ) периодически опрашивает смарт-контракт RequestsQueue через метод GetRequests и получает актуальный список подлежащих исполнению запросов.
  3. При получении нового запросаПВЗ через метод GetExternalRequest обращяется к Контракту и по идентификатору запроса получает параметры запроса:
    • Периодичность исполнения запроса (например, «DAILY 10:00» или «PERIOD 20»)
    • Идентификатор шаблон запроса (например, «CALENDAR» или «DADATA_NAME_EXISTS»)
    • Дополнительные параметры, если они необходимы (например, наименование организации для шаблона «DADATA_NAME_EXISTS»)
  4. В порядке общего управления очередью ПВЗ с заданной для данного запроса периодичностью производит опрос внешних ресурсов в соответствии с шаблоном запроса и приложенными параметрами.
  5. Если по логике, заложенной в шаблон, считается, что ответ на запрос получен — ПВЗ передает его транзакцией на Контракт через метод SetExternalResponse в привязке с идентификатором запроса и идентификатором ответа.
    При этом Контракт должен выполнить надлежавшую обработку полученного ответа и зафиксировать идентификатор ответа для дальнейшего контроля.
  6. Далее ПВЗ запрашивает у Контракта через метод CheckExternalResponse, был ли получен и обработан ответ и какова дальнейшая судьба соответствующего запроса.
    Контракт может предложить один из следующих вариантов действий:
    • FAIL — ответ не получен, не обработан или некорректен — необходимо повторить запрос и передачу ответа
    • REPEAT — ответ принят, необходимо продолжить исполнение соответствующего запроса с прежними параметрами
    • DELETE — ответ принят, запрос нужно удалить из очереди
    • DELETE_ALL — ответ принят, нужно удалить из очереди все запросы, поступившие от данного Контракт
  7. В том случае, если в предыдущем пункте Контракт прислал ответ DELETE (DELETE_ALL) — ПВЗ через метод DeleteRequest удаляет запрос (запросы) из смарт-контракта RequestsQueue.

При необходимости Контракт сам может удалять ставшие ненужными запросы, транзакционно используя метод DeleteRequest смарт-контракта RequestsQueue.

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

Для исключения «неправомочных» источников запросов смарт-контракт очереди содержит управляемый список адресов, которые должны быть исходными (txn.origin) адресами транзакций, ставящих запрос в очередь.

Описание методов контракта Requests Queue

AddRequest Добавить запрос в очередь Входные параметры:
  • Идентификатор запроса (bytes32)

DeleteRequest Удаление запроса из очереди Входные параметры:
  • Идентификатор запроса (bytes32)
CheckRequest Проверка наличия запроса в очереди Входные параметры:
  • Идентификатор запроса (bytes32)

GetRequest Выдать список идентификаторов запросов из очереди Входных параметров нет.
Выходные параметры:
  • Список идентификаторов (bytes32[])

AddBank Добавить адрес в список уполномоченных адресов Входные параметры:
  • Адрес (address)

CheckBank Проверить наличие адреса в списке уполномоченных адресов Входные параметры:
  • Адрес (address)

Описание необходимых интерфейсных методов Контрактов

GetExternalRequest Выдать параметры запроса Входные параметры:
  • Идентификатор запроса (bytes32)
    Выходные данные (в виде массива bytes32[]):
  • Спецификация тайминга (когда или с какой периодичностью должен исполняться запрос)
  • Имя шаблона реализации запроса
  • Параметры запроса (могут отсутствовать или их может быть несколько)

SetExternalResponse Принять ответ на запрос Входные параметры:
  • Идентификатор ответа (bytes32)
  • Идентификатор запроса (bytes32)
  • Данные ответа (массив bytes32)
CheckExternalResponse Проверить факт обработки ответа на запрос Входные параметры:
  • Идентификатор ответа (bytes32)
  • Идентификатор запроса (bytes32)

Выходные данные:
  • Статус обработки ответа
  • Для статуса обработки ответа возможен один из следующих вариантов:
  • FAIL — ответ не былк получен или обработан
  • DELETE — ответ получен и обработан, запрос из очереди удалить
  • DELETE_ALL — ответ получен и обработан, все запросы данного контракта из очереди удалить
  • REPEAT — ответ получен и обработан, продолжить исполнять запрос

Пример реализации


Ниже приведен пример реализации методов в составе контракта.
Приводимый контракт предполагает вызов двух внешних запросов — просрочки даты (шаблон OVERDUE) и проверки регистрации организации (DADATA_EXISTS_WAIT).
Код, непосредственно не относящийся к работе с внешними запросами, исключен.

Описание хранимых переменных


bytes32 Status ;
bytes32 ExpireDate ;
bytes32 OrgName ;
address Queue ;
bytes32[] Request_1 ;
bytes32[] Request_2 ;
bytes32 Request_id_1 ;
bytes32 Request_id_2 ;
bytes32 Response_id_1 ;
bytes32 Response_id_2 ;

Конструктор контракта


function SomeContract(..., bytes32[] logics)
{
Owner =msg.sender ;
ExpireDate=logics[0] ;
OrgName =logics[1] ;
Status ="New" ;
Queue =0xd9b076d0b559f70782f379582bd3d54b85fc42cb ;
Request_1.length= 3 ;
Request_1[0] ="DAILY 00:10" ;
Request_1[1] ="OVERDUE" ;
Request_1[2] = ExpireDate ;
Request_2.length= 3 ;
Request_2[0] ="PERIOD 10" ;
Request_2[1] ="DADATA_EXISTS_WAIT" ;
Request_2[2] = OrgName ;
}

Регистрация запросов в очереди (при переходе контракта в соотвествующий статус)


function SetStatus(bytes32 status_, ...)
{
address self_addr ;
Status=status_ ;
if(status_=="Released_") {
self_addr=this ;
Request_id_1=bytes32(bytes20(self_addr)) | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001" ;
Request_id_2=bytes32(bytes20(self_addr)) | "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002" ;
Queue.call.gas(0x30000).value(0)(bytes4(sha3("AddRequest(bytes32)")), Request_id_1) ;
Queue.call.gas(0x30000).value(0)(bytes4(sha3("AddRequest(bytes32)")), Request_id_2) ;
}
}

Выдать параметры запроса


function GetExternalRequest(bytes32 request_id_) constant returns (bytes32[] retVal)
{
if(request_id_==Request_id_1) return(Request_1) ;
if(request_id_==Request_id_2) return(Request_2) ;
}

Принять ответ на запрос


function SetExternalResponse(bytes32 response_id_, bytes32 request_id_, bytes32[] response_)
{
if(tx.origin!=Owner) return ;
if(Status!="Released_") return ;
if(request_id_==Request_id_1) {
Response_id_1=response_id_ ;
Status ="Overdue__" ;
}
if(request_id_==Request_id_2) {
Response_id_2=response_id_ ;
Status ="ToBank___" ;
}
}

На пользу сообщества

Для желающих попробовать технологии слежения за внешними событиями и работу с оракулами и провайдерами внешних запросов нами в сети Ethereum Rinkeby развернуты:
  • Календарный оракул (отдает текущую дату по Москве)
  • Портал внешних запросов

Календарный оракул

Календарный Оракул расположен в тестовой сети Rinkeby по адресу 79548a65e3ce179ec8d208c22ee84435dc34058f и выдает текущую календарную дату по Москве в формате YYYY/MM/DD.

Пример обращения к Оракулу:

contract Check_request
{
Calendar Oracle ; // Оракул-переменная
bytes32 Date ;
function Check_request()
{
// Инициализация Оракул-переменной на адрес Оракула
Oracle=Calendar(0x79548a65e3ce179ec8d208c22ee84435dc34058f) ;
// Получение информации из Оракула
Date=Oracle.GetDate() ;
}
}

//
// Описание абстрактного метода с интерфейсами Оракула
//
contract Calendar
{
function GetDate() constant returns (bytes32 retVal) ;
}

Портал внешних запросов

Очередь смарт-контракта Портала внешних запросов расположена в тестовой сети Rinkeby по адресу d9b076d0b559f70782f379582bd3d54b85fc42cb.

Протокол взаимодействия с Порталом внешних запросов описан выше. На текущий момент публично открыты следующие шаблоны запросов:

  • OVERDUE — контроль просрочки даты, параметр запроса — дата просрочки в формате YYYY/MM/DD Транзакция события передается на запрашивавший смарт-контракт в момент обнаружения просрочки даты и содержит текущую дату.
  • WEATHER_TEMP — Запрос текущей температуры (через портал api.openweathermap.org), параметр запроса — название города, например Moscow (подробности можно посмотреть на портале-источники). Транзакция события передается на запрашивавший смарт-контракт в момент получения ответа от портала-источника.
Для доступа к очереди Портала внешних запросов необходимо сообщить нам (в комментарии или в личку) адрес счета Ethereum, с которого будут направлены транзакции постановки в очередь. Желательно прикладывать к транзакции 0.1 Ether (это бесплатно, мы в тестовой сети) для отладки механизма платных услуг. В Rinkeby получить эфир можно только с помощью faucet, из-за отсутствия возможности майнинга ввиду протокола PoA.

Некоторые замечания по опыту интеграции сторонних компонентов

Ethereum

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

Ethereum Solidity

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

Ethereum Swarm

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

Сборка из исходников и развертывание узла Swarm под Windows – крайне нетривиальная задача. Разработчики тестировались и готовили документацию только под linux и OSX, о чем честно признаются.

Storj.io

Крайне сложный для использования, слишком детальный API. Для простой интеграции желательно иметь «укрупненный» API, аналогичный реализованному в Ethereum Swarm — положить файл, извлечь файл.

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

Выводы исследования

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

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

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

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

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

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

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

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

Stay tuned!