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

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

Важно

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

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

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

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

Пример Dockerfile при использовании REST API:

FROM python:alpine3.8
ADD contract.py /
ADD run.sh /
RUN chmod +x run.sh
RUN apk add --no-cache --update iptables
CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

Пример Dockerfile при использовании gRPC:

FROM python:3.9-rc-buster
RUN pip3 install grpcio-tools
ADD src/contract.py /
ADD src/protobuf/common_pb2.py /protobuf/
ADD src/protobuf/contract_pb2.py /protobuf/
ADD src/protobuf/contract_pb2_grpc.py /protobuf/
ADD run.sh /
RUN chmod +x run.sh
ENTRYPOINT ["/run.sh"]

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

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

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

Изменение контракта

Изменять Docker смарт-контракт может только его разработчик, который создал транзакцию 103 и сохранил свою роль contract_developer в момент изменения смарт-контракта. Изменение смарт-контракта выполняется при помощи транзакции 107. Необходимо, чтобы смарт-контракт был активным.

После включения 107 транзакции в блок ноды-майнеры скачивают образ контракта и запускают его для проверки корректности исполнения. Далее выпускается 105 транзакция с включением в неё 107 транзакции.

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

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

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

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

Код

Тип транзакции

Назначение

103

CreateContractTransaction

Инициализация контракта. Подписание транзакции производится пользователем с ролью «contract_developer»

104

CallContractTransaction

Вызов контракта. Подписание транзакции производится инициатором исполнения контракта

105

ExecutedContractTransaction

Запись результата исполнения контракта на стейт контракта.
Подписание транзакции производится нодой, формирующей блок

106

DisableContractTransaction

Запрет вызова контракта.
Подписание транзакции производится пользователем с ролью «contract_developer»

107

UpdateContractTransaction

Обновление кода контракта.
Подписание транзакции производится пользователем с ролью «contract_developer»
Изменять контракт может только его разработчик и инициатор 103 транзакции

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

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

REST API

Описание методов REST API, которые может использовать Docker-контракт, приведено в разделе Методы API, доступные смарт-контракту.

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