Cмарт-контракты Docker

В дополнение к контрактам, реализованным на базе скриптов RIDE, для смарт-аккаунтов и смарт-ассетов платформа Vostok предоставляет возможность разработки и использования Тьюринг-полных смарт-контрактов. Для реализации Тьюринг-полных контрактов выбран подход, в котором программы запускаются в изолированной среде Docker-контейнера. При этом разработка приложений может выполняться без ограничений на используемый язык программирования. Каждое приложение запускается в Docker-контейнере для возможности изоляции и управления ресурсами, доступными конкретному приложению. Для хранения смарт-контрактов используется Docker Registry с доступом на чтение образов (Docker images) контрактов для машин с нодами. Доступ к состоянию ноды выполняется через REST API ноды.

Важно

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

../../_images/docker-1.png

Создание контракта

Создание смарт-контракта начинается с подготовки Docker-образа, который состоит из программного кода контракта, необходимого окружения и из специального сценарного файла Dockerfile. Подготовленный Docker-образ собирается (build) и отправляется в Docker Registry.

Пример Dockerfile:

FROM python:alpine3.8
ADD contract.py /
ADD run.sh /
RUN chmod +x run.sh
CMD ["/bin/sleep", "6000"]

Установка контракта реализуется через публикацию специальной (CreateContractTransaction) транзакции, содержащей ссылку на образ в Docker Registry. После получения транзакции нода скачивает образ по указанной в поле «image» ссылке, образ проверяется и запускается в виде Docker-контейнера.

Исполнение контракта

Исполнение смарт-контрактов инициируется специальной (CallContractTransaction) транзакцией, в которой содержится идентификатор контракта и параметры для его вызова. По идентификатору транзакции определяется Docker-контейнер. Контейнер запускается, если не был запущен ранее. В контейнер передаются параметры запуска контракта. | Смарт-контракты изменяют своё состояние через обновление пар ключ - значение.

Запрет вызова контракта

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

Описание транзакций

Для реализации взаимодействия между блокчейном и Docker контрактом реализованы следующие транзакции:

Код Тип транзакции Назначение
103 CreateContractTransaction Инициализация контракта. Подписание транзакции производится пользователем с ролью «contract_developer»
104 CallContractTransaction Вызов контракта. Подписание транзакции производится инициатором исполнения контракта
105 ExecutedContractTransaction Запись результата исполнения контракта на стейт контракта.
Подписание транзакции производится нодой, формирующей блок
106 DisableContractTransaction Запрет вызова контракта.
Подписание транзакции производится пользователем с ролью «contract_developer»
107 UpdateContractTransaction Обновление кода контракта.
Подписание транзакции производится пользователем с ролью «contract_developer»

Конфигурация ноды

Скачивание и исполнение Docker-контрактов, инициированных транзакциями с кодами 103 - 107 выполняется на нодах с включенной опцией docker-engine.enable = yes (подробнее в разделе «Установка и настройка» > «Запуск Docker-контрактов»).

REST API

Описание REST API Docker-контрактов приведено в разделе «Использование» > «REST API ноды» > «Contracts».

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