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

Сервисы gRPC, используемые смарт-контрактом

Описанные в этом разделе контрактные gRPC сервисы предназначены для обмена данными между смарт-контрактом и нодой. Эти сервисы доступны только смарт-контрактам. Внешний пользователь не сможет вызвать контрактные сервисы и использовать их функции.

Общие принципы применения gRPC при разработке смарт-контрактов рассмотрены в статье Пример смарт-контракта с использованием gRPC.

Версии API смарт-контрактов

gRPC-методы (в том числе и методы, используемые смарт-контрактами) формируют API, заданное protobuf-файлами. Для четкого определения новых методов и внесения изменений в уже существующие предусмотрено версионирование API. Благодаря присвоенному номеру версии нода при исполнении смарт-контракта определяет соответствующий набор методов для использования.

Актуальная версия gRPC API для версии блокчейн-платформы содержится в файле api_version.proto. Смарт-контракты, которые требуют версию API выше, чем у майнящей ноды, игнорируются при майнинге.

Для создания и обновления смарт-контрактов предусмотрены поля apiVersion в транзакциях 103 CreateContract Transaction и 107 UpdateContract Transaction версии 4. Эти поля указывают майнящей ноде на версию API, используемую смарт-контрактом.

В таблице ниже приведены версии API, соответствующие версиям блокчейн-платформы:

Версия API

Версия платформы

1.0

1.6.0 и 1.6.1

1.1

1.6.2

1.4

1.7.0

1.6

1.11.0

1.7

1.12.0

1.8

1.12.1

1.9

1.12.2

1.10

1.12.3 и 1.13.0

Protobuf-файлы методов

Смарт-контрактам, использующим gRPC для обмена данными с нодой, доступны сервисы, названия protobuf-файлов которых начинаются с contract:

protobuf

Методы

contract_address_service.proto

GetAddresses

GetAddressData

GetAssetBalance

contract_block_service.proto

GetBlockHeader

contract_contract_service.proto

Connect

CommitExecutionSuccess

CommitExecutionError

GetContractKeys

GetContractKey

GetContractBalances

CalculateAssetId

contract_permission_service.proto

GetPermissions

GetPermissionsForAddresses

contract_privacy_service.proto

GetPolicyRecipientss

GetPolicyOwners

contract_transaction_service.proto

TransactionExists

TransactionInfo

contract_util_service.proto

GetNodeTime

contract_pki_service.proto

Verify

Некоторые методы доступны только в корпоративной версии платформы, и не могут быть использованы в opensource версии платформы:

contract_address_service.proto

Набор методов, предназначенных для получения адресов участников из keystore ноды и получения данных, записанных на адресе.

GetAddresses – метод для получения всех адресов участников, ключевые пары которых хранятся в keystore ноды. Метод возвращает массив строк addresses.

GetAddressData – метод для получения всех данных, записанных на аккаунт адресата при помощи транзакций 12. В запросе метода вводятся следующие параметры:

  • address – адрес, данные которого необходимо вывести;

  • limit – ограничение количества выводимых блоков данных;

  • offset – количество блоков данных для пропуска в выводе.

Метод возвращает массив DataEntry, содержащий записанные данные адреса.

GetAssetBalance – метод для получения текущего баланса определенного ассета для определенного пользователя. В запросе метода вводятся следующие параметры:

  • address – адрес, баланс которого необходимо вывести;

  • assetId – идентификатор ассета. Для WEST параметр остается пустым.

contract_block_service.proto

Набор методов, позволяющих контрактам запрашивать у ноды информацию о блоке.

GetBlockHeader – метод для получения заголовка блока по подписи (идентификатору блока) или по высоте.

В запросе метода вводится один из следующих параметров:

  • signature – подпись запрашиваемого блока в виде строки с кодировкой Base58;

  • height — высота запрашиваемого блока.

Метод возвращает следующую информацию о заголовке блока:

  • version — версия блока;

  • height — высота блока;

  • block_signature — подпись блока (она же идентификатор) в виде строки с кодировкой Base58;

  • reference — подпись предыдущего блока, на который ссылается текущий, в виде строки с кодировкой Base58;

  • miner_address — адрес майнера в виде строки с кодировкой Base58;

  • tx_count — количество транзакций в блоке;

  • timestamp — время блока.

Если блок не найден, метод возвращает ошибку BlockDoesNotExist.

contract_contract_service.proto

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

Connect – метод для подключения смарт-контракта к ноде.

В запросе метода указываются следующие параметры:

Метод возвращает следующую информацию о транзакции и блоке:

  • transaction — транзакция вызова контракта;

  • auth_token — авторизационный токен;

  • current_block_info — информация о текущем блоке:

    • height — текущая высота;

    • timestamp — время блока;

    • miner_address — адрес майнера в формате строки в кодировке Base58;

    • reference — подпись (идентификатор) предыдущего блока, на который ссылается текущий жидкий блок; в формате строки Base58.

CommitExecutionSuccess – метод для отправки результатов успешного исполнения смарт-контракта на ноду. С помощью этого метода смарт-контракт может отправлять последовательность операций над ассетами.

В запросе метода указываются следующие данные:

  • tx_id — идентификатор транзакции вызова контракта, на которую смарт-контракт даёт результат;

  • results — массив key-value значений, которые смарт-контракт в качестве результата исполнения запишет в свой стейт. Если возвращается ключ, который уже присутствует в стейте, то его значение будет перезаписано;

  • asset_operations — массив действий смарт-контракта с доступными ему ассетами, в том числе выпуск нового ассета, перевыпуск ассета, сжигание ассета или перевод доступного контракту ассета другому пользователю (issue, reissue, burn, transfer).

Ответ метода не предусмотрен.

CommitExecutionError – метод для отправки ошибки исполнения смарт-контракта на ноду.

GetContractKeys – метод для запроса значений из состояния смарт-контракта по переданному фильтру ключей.

В запросе метода указываются следующие данные:

  • contract_id – идентификатор смарт-контракта;

  • limit – ограничение количества выводимых блоков данных;

  • offset – количество блоков данных для пропуска в выводе;

  • matches – опциональный параметр для составления регулярного выражения, по которому фильтруются ключи.

Метод возвращает массив DataEntry, содержащий запрашиваемые ключи со значениями из текущего состояния смарт-контракта.

GetContractKey – метод для получения значения определённого ключа из состояния смарт-контракта.

В запросе метода указываются следующие данные:

  • contract_id – идентификатор смарт-контракта;

  • key – запрашиваемый ключ.

Метод возвращает DataEntry из текущего состояния смарт-контракта, который соответствует переданному ключу.

GetContractBalances – метод для получения текущего баланса(ов) (системный токен и другие токены) смарт-контракта.

В запросе передаётся список идентификаторов ассета (assets_ids); для получения баланса системного токена WEST следует передать в списке пустую строку.

Метод возвращает список с балансами для каждого из запрошенных ассетов.

CalculateAssetId – метод для вычисления assetId при выпуске нового токена смарт-контрактом по переданному параметру:

  • nonce — число, которое можно использовать только один раз; в рамках одного вызова контракта не может быть выпущено несколько ассетов с одинаковым nonce.

contract_permission_service.proto

Набор методов, предназначенный для получения информации о ролях участников.

GetPermissions – метод для получения списка всех ролей участника, чей адрес указан, действительных на указанный момент времени. В запросе передаются следующие данные:

  • address – адрес участника;

  • timestamp – временная метка в формате Unix Timestamp (в миллисекундах), на момент которой запрашиваются действующие роли.

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

GetPermissionsForAddresses – метод для получения списка всех ролей участников, чьи адреса указаны, действительных на указанный момент времени. В запросе передаются следующие данные:

  • addresses – массив строк с адресами участников;

  • timestamp – временная метка в формате Unix Timestamp (в миллисекундах), на момент которой запрашиваются действующие роли.

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

contract_pki_service.proto

В protobuf-файле contract_pki_service.proto описан контрактный метод Verify, предназначенный для проверки отсоединенной электронной подписи для передаваемых данных в сетях, работающих с использованием ГОСТ-криптографии.

Важно

Метод Verify недоступен при использовании PKI, то есть когда в конфигурационном файле ноды параметру node.crypto.pki.mode присвоено значение ON. В тестовом режиме PKI (node.crypto.pki.mode = TEST) или при отключенном PKI (node.crypto.pki.mode = OFF) метод можно использовать.

Примечание

gRPC метод Verify недоступен в opensource версии платформы.

Типы данных полей для запросов и ответов указаны в protobuf-файле.

Метод Verify требует ввода следующих параметров:

  • input_data – данные, закрытые ЭП (в виде массива байт в кодировке base64);

  • signature – электронная подпись в виде массива байт в кодировке base64;

  • sig_type – формат ЭП. Поддерживаются значения:

    • 1 – CAdES-BES;

    • 2 – CAdES-X Long Type 1;

    • 3 – CAdES-T.

  • extended_key_usage_list – список объектных идентификаторов (OID) криптографических алгоритмов, которые используются при формировании ЭП; опциональное поле.

Ответ метода Verify содержит поле status с булевым типом данных:

  • true – подпись действительна,

  • false – подпись скомпрометирована.

Проверка УКЭП

Метод Verify предоставляет возможность проверки усиленной квалифицированной электронной подписи (УКЭП). Для корректной проверки УКЭП установите на вашу ноду корневой сертификат ЭЦП удостоверяющего центра (УЦ), при помощи которого будет осуществляться валидация подписи.

Корневой сертификат устанавливается в хранилище сертификатов cacerts используемой вами виртуальной машины Java (JVM) при помощи утилиты keytool:

sudo keytool -import -alias certificate_alias -keystore path_to_your_JVM/lib/security/cacerts -file path_to_the_certificate/cert.cer

После флага -alias укажите произвольное имя сертификата в хранилище.

Хранилище сертификатов cacerts расположено в поддиректории /lib/security/ вашей виртуальной машины Java. Чтобы узнать путь к виртуальной машине на Linux, воспользуйтесь следующей командой:

readlink -f /usr/bin/java | sed "s:bin/java::"

Затем добавьте к полученному пути /lib/security/cacerts и вставьте полученный абсолютный путь к cacerts после флага -keystore.

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

Пароль по умолчанию для cacertschangeit. При необходимости вы можете изменить его при помощи утилиты keytool:

sudo keytool -keystore cacerts -storepasswd

contract_privacy_service.proto

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

Важно

Описанные ниже методы для получения информации о группах для обмена конфиденциальными данными и работы с конфиденциальными данными недоступны при использовании PKI, то есть когда в конфигурационном файле ноды параметру node.crypto.pki.mode присвоено значение ON. Методы можно использовать в тестовом режиме PKI (node.crypto.pki.mode = TEST) или при отключенном PKI (node.crypto.pki.mode = OFF).

Подробнее об обмене конфиденциальными данными и группах доступа см. статью Обмен конфиденциальными данными.

GetPolicyRecipients – метод для получения адресов участников группы доступа к конфиденциальным данным, идентификатор которой передается в запросе как policy_id. В ответе метода выводится массив строк recipients, содержащий адреса участников группы доступа.

GetPolicyOwners – метод для получения адресов владельцев группы для обмена конфиденциальными данными, идентификатор которой передается в запросе как policy_id. В ответе метода выводится массив строк owners, содержащий адреса владельцев группы доступа.

contract_transaction_service.proto

Набор методов, предназначенный для получения информации о транзакциях, отправленных в блокчейн. Аналогичные gRPC методы, доступные внешнему пользователю, описаны в разделе gRPC: работа с транзакциями.

В отличии от методов TransactionExists и TransactionInfo, доступных для интеграции извне, контрактные методы возвращают информацию не только о транзакциях, которые уже записаны в блок, но и о транзакциях, которые только готовятся к упаковке в блок.

TransactionExists – метод для проверки существования транзакции с указанным идентификатором. Метод возвращает true, если транзакция с указанным идентификатором существует, false – если не существует.

TransactionInfo – метод для получения данных о транзакции с указанным идентификатором: название транзакции, версия транзакции, высота блокчейна, на которой была произведена данная транзакция, другие данные о транзакции в зависимости от типа этой транзакции.

contract_util_service.proto

Файл содержит метод GetNodeTime, предназначенный для получения текущего времени ноды. Метод возвращает текущее время ноды в двух форматах:

  • system – системное время на машине ноды;

  • ntp – сетевое время.