company_banner

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


    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!
    Райффайзенбанк 208,50
    Развеиваем мифы об IT в банках
    Поделиться публикацией
    Похожие публикации
    Комментарии 20
    • 0
      Интересно, даже очень. Было-бы хорошо, если бы вы(как понимающий человек в криптовалютах), на нормальном языке объяснили что из себя представляют контракты эфириума, и как ими пользоваться с помощью RPC API… Я например должен подключить эфириум к сайту, для получения и отправки средств, и я вообще без понятия что да как и где искать) Напишите пожалуйста отдельную статью если не сложно)
      • 0
        Спасибо! Если тема будет интересна, то мы подготовим подборку материалов с нашим опытом разработки смарт-контрактов и использования RPC API Ethereum
      • 0
        а рассматривали развертку своего приватного блокчейна и децентрализованного хранилища вместо Ethereum и Storj?
        • 0
          Использование своего приватного блокчейна не имеет смысла в данном контексте, так как для клиентов он ничем не будет отличаться от обычной БД внутри банка. Если же Вы имеете в виду использование приватного блокчейна с подключением клиентов как узлов (то есть создание своей экосистемы), то сразу встает ряд вопросов о доверии клиентов к такой экосистеме, стимулировании участия в ней в качестве узлов и так далее.
          • 0
            понятно, спасибо. а были на повестке другие платформы для смарт контрактов, кроме Ethereum? В свете последних событий, когда пара ICO забила всю сеть, доверие к нему поуменьшилось
            • 0
              Среди публичных блокчейнов рассматривался только Eth — во-первых, он является крупнейшей действующей платформой для смарт-контрактов (и с большим отрывом), во-вторых, ЦентроБанк на ряде конференций анoнсировал код Eth как исходную базу для разработки Мастер-чейна, в связи с чем там также могут быть применены полученные наработки.
              Среди корпоративных платформ в дальнейшем будет детальному исследованию подвергнут Hyperledger, как основа возможной межбанковской экосистемы.
              Так как поле блокчейн-платформ сейчас развивается очень быстро, то трудно уследить за всеми появляющимися реaлизациями. Поэтому, если Вы сможете указать какого-либо интересного представителя, мы не преминем проанализировать его функциональные возможности.
        • 0
          Суперинтересно! По-моему, это первое описание практического использования блокчейна, которое я вообще читал, с момента возникновения всего этого криптохайпа.
          • 0
            Все начинают с аккредитивов, ибо это самая простая из идей на которую можно натянуть блокчейн. Конечно круто но мне кажется в используемом вами стеке технологий есть лишнее звено «Ethereum, Storj, КриптоПРО, VBS».
            • 0
              Набор технологий определяется их способностью обеспечить решение конкретной технической задачи в заданные сроки при располагаемых ресурсах. И если написание COM-клиентов на нативном языке не является Вашим любимым занятием, то Вы выбираете, например, VBS.
            • 0
              Спасибо. Было интересно. Но мне кажется, что на блокчейн надо «натягивать» процессы, которые требуют участия более трех участников. Например — БКИ или SWIFT...)
              • 0
                Скорее те, что несут экономическую выгоду.
                С этой точки зрения количество участников — разумный, но не единственный критерий. Если пытаться обобщить, это потенциал автоматизировать и поставить на поток те процессы, которые сейчас по ряду причин требуют ручной работы. В торговом финансировании это согласования, проверки и пр.
                Ну и не могу не добавить, что в боевой реализации аккредитивов мы ориентируемся на большее число сторон: в цепочке однозначно будет несколько банков.
                НБКИ — да, это было бы интересно. Реестры вообще органично смотрятся в блокчейне.
                SWIFT — чуть менее вероятно, он «работает и без блокчейна». Но в недалеком будущем есть инициатива SWIFT gpi, в рамках неё тестируется применение распределенных реестров для межбанковских платежей.
                • 0
                  А можно более подробно осветить, какая часть ручной работы ушла в данном случае при оформлении аккредитива с использованием этой технологии. У меня сложилось впечатление, что блокчейн притянут тут за уши, поскольку общая схема работы с созданием простого сервиса в рамках существующего интернет-банка остается прежней:
                  1. покупатель с продавцом договорились о контракте, покупатель принес договор в банк — эту часть можно решить обычным сервисом или разделом личного кабинета в интернет банке, с подписью документов криптографическими ключами (как обычных платежных документов)
                  2. банк должен проверить данный договор — тут нет никакой помощи со стороны блокчейна, поскольку операция не техническая, а лежит больше в юридической плоскости
                  3. банк подтверждает условия договора и дает согласие на акредитив — если сервис из п.1 был связан с АРМ банка — это делается сотрудниками банка в один клик, результаты сразу видит продавец в сервисе из п.1
                  4. продавец выполняет условия контракта и загружает в сервис из п.1 документы, подписывая их своими ключами. Покупатель также может просмотреть эти документы и выставить претензию
                  5. банк получает документы, сотрудник рассматривает все моменты и принимает решение о переводе средств, договор закрывается — все делается в рамках существующей АРМ банка


                  В каком месте использование блокчейна упрощает и автоматизирует операции?
                  • 0
                    Главное достоинство смарт-контрактов — работа с внешними сигналами. Это дает возможность раскрытия аккредитива без предоставления документов. Приведу пример с аккредитивом на недвижимость. Сейчас требуется предоставить документы из Росреестра о переходе права собственности. Смарт-контракт может сам отслеживать информацию по объекту и автоматически исполняться при переходе права собственности.
                    Банк стремится снять с себя обязанности по ручной проверке документов и оставить основную функцию — проведение платежа.

                    Сейчас блокчейн позволяет автоматизировать процесс для аккредитивов, идущих «на потоке». У них относительно простые условия раскрытия, которые можно обработать логикой смарт-контракта.
                    Кроме того, блокчейн хорошо работает, когда в цепочке несколько банков (например, по одному для Продавца и Покупателя). Так проще выстроить взаимодействие.

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

                    Следующий уровень автоматизации — проверка документов на раскрытие аккредитива. Сейчас часть из них имеет специальный формат (счет-фактура, накладная ТОРГ12), часть — нет. Тут ситуация похожая: смарт-контракт проверяет, соответствует ли содержание СФ условиям аккредитива. Если нет — возвращает ответ Продавцу о том, что требуются корректировки.
                    • 0
                      И все же остается непонятна именно роль смарт-контракта. Т.е. в приведенном выше примере по документам из Росреестра — все равно нужно для этого конкретного случая разработать отдельный модуль ПО, который будет с некоторой периодичностью ходить в сайт Росреестра и искать данные определенных объектов, после чего генерировать внешний сигнал для контракта. Что мешало сразу в системе банка закрывать контаркт по этому признаку? Т.е. если бы Росреестр сам работал в системе умных контрактов и генерировал сигналы для вас независимо от вашего ПО — тогда усложнение схемы и введение блокчейна было бы оправдано с моей точки зрения. А так — вы разработаете отдельный модуль для Росреестра, который только с ним и может работать. Получается что именно блокчейн тут не особо и помогает — можно из этого же модуля закрывать контракт непосредственно в банковской учетной системе, минуя промежуточные звенья в виде блок-чейна.

                      Про несколько банков — тоже не очень понятно. Где уверенность, что второй банк поддержит вашу инициативу с блокчейном? Если второй банк не использует вашу систему смарт-контрактов — вам опять нужно разрабатывать отдельное ПО, которое будет по некоторым данным генерировать внешние события для контракта.
                      Сейчас блокчейн позволяет автоматизировать процесс для аккредитивов, идущих «на потоке». У них относительно простые условия раскрытия, которые можно обработать логикой смарт-контракта.

                      Вот именно. А что будет, когда условия усложнятся? придется часть контрактов обрабатывать через смарт, а часть — городить дополнительные костыли? Не слишком ли большой риск для банка?

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

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

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

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

                      Из всех объяснений у меня сложилось впечатление, что в данном случае блокчейн и смарт-контакты используются всего лишь как шина обмена сообщениями типа кафки или rabbitmq. Выгоды в вашем конкретном случае от использования именно блокчейна я не вижу никакой: вам пришлось разработать отдельные модули для проверки каждого из возможных типов контрактов (если вы конечно не только сделки с недвижимостью через них пропускаете); модуль для связи блокчейна с банковским ПО — оформление договоров в ПО банка наверняка же никто не отменяет при заключении смарт-контракта, списание денег и т.п. операции; модуль для ручного управления контрактами — отзыв, выполнение (наверняка в каких-то ситуациях это потребуется) и возможно кучу каких-то еще модулей, предусмотреть которые сходу нельзя. Причем причина привязки этого всего к блокчейну для меня так и не понятна — можно было использовать уже те шины, которые использовались в банке до этого.
                      • 0
                        Да, Вы совершенно правы, чтобы все это имело смысл:
                        — Росреестр и прочии источники событий должен выставить в блокчейн свои сервисы (напрямую или через агента)
                        — форматы документов должны быть стандартизованы (и этим занимаются такие организации, как ICC Russia, например)
                        — банки должны скооперироваться (и количество межбанковский ассоциаций и консорциумов вокруг блокчейн непрерывно растет)
                        Имено это отражено в выводах исследования.

                        В идеале банк хочет оставить себе в сфере торгового финансирования ту роль, которая лучше всего соотвествует его бизнесу — роль финансового гаранта и оператора платежей.
                        Грубо говоря, банк хочет выставить в блокчейн то, что нынче именуется Open API и снять с себя лишние обязанности и связанные с их исполнением расходы.
                        Банк не хочет создавать и поддерживать свою собственную сеть обмена и принятия решений — он хочет присоединиться к существующей. Но для того, чтобы участники сделок решились перейти на «свободную» транспортно-арбитражную платформу она должна обладать свойствами доверия, прозрачности и «обезличенности» решений — это как раз и обеспечивает блокчейн с обвязкой смарт-контрактов.
              • 0
                Еще одно направление для банковского блокчейна: передача кредита коллекторам. Кто первый подсадит на «свой» блокчейн всех коллекторов страны, тот и в дамках!)
                • 0
                  Спасибо за статью, было интересно. Но я так и не понял, в чем смысл усложнения и использования блокчейна в вашем случае? Если я правильно понял, то все ПО, которое Вы используете для работы с аккредитивами, пришлось разрабатывать самостоятельно (не включая готовые компоненты, типа КриптоПро и то, что относится к работе с блокчейном). Т.е., по сути, вы разработали платформу, в которой покупатель и продавец могут предоставить в банк данные о выполнении ими контракта. Сотрудники банка в полу-ручном режиме проверяют эти данные и инициируют перевод денежных средств. Автоматизировать (существенно) этот процесс думаю что не получится, поскольку возрастает риск мошенничества. Повторно использовать какие-либо наработки — тоже (как мне кажется) будет сложно (поскольку другие типы операций требуют других условий проверки и т.п.). Почему использовался блокчейн? Почему не обычный сервис, в котором продавец и покупатель могут оформить сделку, подписав обычными криптографическими ключами свои документы? Ведь, по сути, никому кроме 3-х сторон сделки (банк, продавец и покупатель) документы сделки не интересны и, таким образом, распределенное хранилище данных (в качестве которого выступает блокчейн в данном случае ) никому не нужно? В чем плюс именно вашего решения?
                  • 0

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

                    • 0
                      Поясню этот момент подробнее.

                      Да, бизнес-процесс в текущем состоянии не требует внедрения блокчейна. Расчеты по аккредитиву — это сложный (во многом из-за отсутствия стандартизации), при этом хорошо отлаженный алгоритм.

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

                      Как реагировать на изменения рынка — вопрос выбранной стратегии.
                      В стратегии Райффайзенбанка инновациям уделено большое внимание. Это включает как работу со стартапами, так и проведение внутреннего R&D. Именно в рамках R&D была проведена разработка блокчейн-платформы.

                      Ограничений для внедрения блокчейна осталось не так много, и их преодоление — вопрос времени. Важно успеть создать необходимые условия (организационные, правовые, технические), которые позволят наиболее эффективно эту технологию применять. Часто именно создание «инфраструктурной обвязки» (в широком значении) является наиболее длительным и сложным процессом, обеспечивающим раскрытие возможностей технологии в полном объеме.
                  • 0
                    Интересно и полезно! С нетерпением жду продолжения!

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

                    Самое читаемое