Как устроена платформа

Смарт-контракты

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

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

Когда смарт-контракт запускается в блокчейн сети, его код нельзя произвольно изменить, заменить или запретить его выполнение без вмешательства в работу всей сети. Это свойство позволяет обеспечить безопасность работы бизнес-приложений.

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

Доступ смарт-контракта к стейту ноды для обмена данными осуществляется посредством gRPC API-интерфейса.

Создавать и вызывать смарт-контракты может любой участник сети.

Разработанный смарт-контракт упаковывается в Docker-образ, который хранится в репозитории, который основан на технологии Docker Registry.

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

В ноду внедрен механизм MVCC (Multiversion concurrency control) – управление параллельным доступом к состоянию смарт-контрактов посредством многоверсионности. Благодаря этому нода позволяет параллельно выполнять несколько транзакций любых смарт-контрактов. При этом гарантируется согласованность данных.

Ниже приведена общая схема работы смарт-контракта:

../../_images/docker-11.png

Создание и установка смарт-контракта

Практические указания по разработке логики смарт-контрактов, а также пример реализации на Python приведены в статье Разработка и применение смарт-контрактов Docker.

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

Создание смарт-контракта начинается с подготовки Docker-образа, который содержит готовый код смарт-контракта, сценарный файл Dockerfile, а также protobuf-файлы, необходимые для обмена данными с нодой через gRPC-интерфейс.

Подготовленный образ собирается при помощи утилиты build, входящей в состав пакета Docker, после чего отправляется в репозиторий.

Для установки смарт-контракта и работы с ним необходима настройка секции docker-engine конфигурационного файла ноды.

Установка смарт-контракта в блокчейне выполняется посредством транзакции 103 CreateContract Transaction, в теле которой указывается ссылка на образ смарт-контракта в репозитории. При работе со смарт-контрактами рекомендуется отправлять транзакции последних версий.

При работе в частной сети транзакция 103 предусматривает загрузку Docker-образа контракта не только из репозиториев, указанных в секции docker-engine конфигурационного файла ноды. Если вам необходимо загрузить смарт-контракт из репозитория, не внесенного в конфигурационный файл, укажите в поле name транзакции 103 полный адрес смарт-контракта в созданном вами репозитории. Пример заполнения полей транзакции 103 приведен в ее описании.

После получения транзакции нода скачивает образ по ссылке, указанной в поле image. Затем скачанный образ проверяется нодой и запускается в Docker-контейнере.

Запуск смарт-контракта и фиксация результатов исполнения

Запуск смарт-контракта инициируется участником сети при помощи транзакции 104 CallContract Transaction. В этой транзакции передается ID Docker-контейнера, в котором запускается смарт-контракт, а также его входные и выходные параметры в виде пар «ключ-значение». Контейнер запускается, если не был запущен ранее.

Смарт-контракт выполняется и отправляет результат через gRPC API-интерфейс на ноду, которая инициировала запуск смарт-контракта. Нода, в свою очередь, генерирует транзакцию о результате выполнения смар-контракта 105 ExecutedContract Transaction. Таким образом результат исполнения смарт-контракта фиксируется в его стейте при помощи транзакции 105 ExecutedContract.

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

Запрет запуска смарт-контракта

Для того, чтобы отключить запуск смарт-контракта в блокчейне, отправьте транзакцию 106 DisableContract Transaction с указанием ID Docker-контейнера, в котором запускается смарт-контракт. Отправить эту транзакцию может только участник с ролью contract_developer.

После отключения смарт-контракт становится недоступен для запуска.

Важно

Транзакция 106. DisableContract Transaction является необратимой, то есть отключенным контрактом нельзя будет пользоваться ни при каких условиях.

Информация об отключенном смарт-контракте продолжает храниться в блокчейне и доступна для gRPC или REST API-методов.

Обновление смарт-контракта

Если вы изменили код вашего смарт-контракта, обновите его. Для этого заново загрузите смарт-контракт в репозиторий, затем отправьте на ноду транзакцию 107 UpdateContract Transaction. Обновляемый смарт-контракт не должен быть отключен при помощи транзакции 106.

После обновления смарт-контракта ноды-майнеры блокчейна скачивают его и проверяют корректность исполнения. Затем информация об обновлении смарт-контракта вносится в его стейт при помощи транзакции 105, содержащей тело исполненной транзакции 107.

Подсказка

Изменять смарт-контракт может только участник, создавший транзакцию 103 для этого смарт-контракта и имеющий роль contract_developer.

Валидация смарт-контрактов

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

  • в сети присутствует хотя бы один участник с активной ролью contract_validator;

  • для загрузки и обновления смарт-контрактов используются транзакции 103 и 107 версии 4.

Политика валидации настраивается при помощи строкового поля validationPolicy.type соответствующей транзакции.

Доступные политики валидации:

  • any – сохраняется действующая в сети общая политика валидации: для майнинга обновляемого смарт-контракта майнер подписывает соответствующую транзакцию 105. Также этот параметр устанавливается, если в сети нет ни одного зарегистрированного валидатора.

  • majority – транзакция считается валидной, если она подтверждена большинством валидаторов: 2/3 от общего числа зарегистрированных адресов с ролью contract_validator.

  • majorityWithOneOf(List[Address]) – транзакция считается валидной, если собрано большинство валидаторов, среди которых присутствует хотя бы один из адресов, включенных в список параметра. Адреса, включаемые в список, должны иметь действующую роль contract_validator.

Предупреждение

При выборе политики валидации majorityWithOneOf(List[Address]), список адресов должен содержать хотя бы один адрес, передача пустого списка запрещена.

Параллельное исполнение контрактов

На платформе Конфидент можно запускать несколько смарт-контрактов одновременно. Для этого на ноде реализован механизм MVCC (Multiversion concurrency control) – управление параллельным доступом посредством многоверсионности. Механизм позволяет параллельно выполнять несколько транзакций контейнеризированных смарт-контрактов и сохранять согласованность данных.

Все транзакции делятся на две группы:

  1. non-executable транзакции – атомарные контейнеры и все классические транзакции: transfer transaction, data transaction и т. п.;

  2. executable транзакции – транзакции всех контейнеризированных смарт-контрактов.

Транзакции первой группы всегда выполняются последовательно (уровень параллелизма равен единице). Для второй группы транзакций параллелизм исполнения определяется значением параметра node.docker-engine.contracts-parallelism в конфигурации ноды, например:

node.docker-engine.contracts-parallelism = 8

По умолчанию используется значение 8. Таким образом все смарт-контракты выполняются параллельно, независимо от Docker-образа.

Примечание

Между двумя группами транзакций присутствует конкуренция: если в UTX-пуле накапливаются разнородные транзакции, то параллельность может снижаться. Такое поведение можно сгладить, увеличив размер pulling буфера, но полностью исключить нельзя.

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

API-инструменты, доступные смарт-контракту

Для обмена данными между смарт-контрактом и нодой предусмотрены методы gRPC API. При использовании этих методов вы можете осуществлять широкий спектр операций с блокчейном.

Подробнее: