Как устроена платформа
Смарт-контракты¶
Смарт-контракт – это отдельное приложение, которое записывает в блокчейн свои входные данные и результаты исполнения заложенного алгоритма. Блокчейн-платформа Конфидент поддерживает разработку и применение Тьюринг-полных смарт-контрактов для создания высокоуровневых бизнес-приложений.
Смарт-контракт может быть разработан на любом языке программирования и не имеет ограничений на реализацию заложенной логики. Для того, чтобы отделить запуск и исполнение смарт-контракта от самой блокчейн-платформы, смарт-контракт исполняется в контейнере Docker.
Когда смарт-контракт запускается в блокчейн сети, его код нельзя произвольно изменить, заменить или запретить его выполнение без вмешательства в работу всей сети. Это свойство позволяет обеспечить безопасность работы бизнес-приложений.
Смарт-контракт может быть разработан на любом языке программирования и не имеет ограничений на реализацию заложенной логики. Для того, чтобы отделить запуск и исполнение смарт-контракта от самой блокчейн-платформы, смарт-контракт исполняется в контейнере Docker.
Доступ смарт-контракта к стейту ноды для обмена данными осуществляется посредством gRPC API-интерфейса.
Создавать и вызывать смарт-контракты может любой участник сети.
Разработанный смарт-контракт упаковывается в Docker-образ, который хранится в репозитории, который основан на технологии Docker Registry.
Если вы планируете использовать смарт-контракты в собственной частной блокчейн-сети, вам потребуется создать собственный репозиторий для загрузки и вызова смарт-контрактов. После того как смарт-контракт будет загружен в репозиторий, вы сможете вызвать его при помощи запроса по REST API к вашей ноде.
В ноду внедрен механизм MVCC (Multiversion concurrency control) – управление параллельным доступом к состоянию смарт-контрактов посредством многоверсионности. Благодаря этому нода позволяет параллельно выполнять несколько транзакций любых смарт-контрактов. При этом гарантируется согласованность данных.
Ниже приведена общая схема работы смарт-контракта:
Создание и установка смарт-контракта¶
Практические указания по разработке логики смарт-контрактов, а также пример реализации на 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) – управление параллельным доступом посредством многоверсионности. Механизм позволяет параллельно выполнять несколько транзакций контейнеризированных смарт-контрактов и сохранять согласованность данных.
Все транзакции делятся на две группы:
non-executable транзакции – атомарные контейнеры и все классические транзакции: transfer transaction, data transaction и т. п.;
executable транзакции – транзакции всех контейнеризированных смарт-контрактов.
Транзакции первой группы всегда выполняются последовательно (уровень параллелизма равен единице).
Для второй группы транзакций параллелизм исполнения определяется значением параметра node.docker-engine.contracts-parallelism
в конфигурации ноды, например:
node.docker-engine.contracts-parallelism = 8
По умолчанию используется значение 8
.
Таким образом все смарт-контракты выполняются параллельно, независимо от Docker-образа.
Примечание
Между двумя группами транзакций присутствует конкуренция: если в UTX-пуле накапливаются разнородные транзакции, то параллельность может снижаться. Такое поведение можно сгладить, увеличив размер pulling буфера, но полностью исключить нельзя.
Логика кода смарт-контракта, как и язык программирования, выбранный для его разработки, должны учитывать специфику параллельного исполнения смарт-контрактов. Например, если смарт-контракт с функцией инкремента переменной при каждой транзакции вызова контракта будет исполняться параллельно, то результат получится некорректным, поскольку используется общий ключ авторизации во время каждого вызова контракта.