Перейти к основному содержимому

@hlf-core/transport-common

Этот пакет содержит ровно то, что обязано совпадать у обеих сторон — у клиента и у chaincode. Он не зависит ни от fabric-network, ни от fabric-shim, и живёт и там, и там одним и тем же кодом. Иными словами, это сам протокол, вынесенный отдельно, чтобы его нельзя было случайно реализовать на двух сторонах по-разному.

Ключевая идея всего транспорта формулируется именно здесь: взаимодействие построено не на наборе функций контракта, а на одной. Любая команда упаковывается в конверт и идёт через единственный метод transportFabricExecute (эта и соседние константы заданы в пакете). Что именно вызвано — определяет поле name в конверте. Отсюда важное следствие: добавление новой команды не требует переустановки chaincode, достаточно зарегистрировать обработчик по имени.

Базовый класс команды — TransportFabricCommandAsync<U, V> с флагом isReadonly. Сам запрос едет в TransportFabricRequestPayload<U> — конверте с полями id, name, request, options, isReadonly и isNeedReply. У конверта есть метод parse, который на стороне chaincode проверяет имя функции и число параметров, десериализует данные, восстанавливает умолчания и валидирует их, и метод clear, который перед отправкой очищает значения по умолчанию. Последнее — не оптимизация ради оптимизации: всё, что уедет в конверте, ляжет в ledger навсегда, поэтому лишнего там быть не должно. Характерная деталь: алгоритм Ed25519 считается умолчанием и по сети не передаётся вовсе.

Ответ возвращается в TransportFabricResponsePayload<V>, и здесь результат и ошибка живут в одном поле response. Благодаря этому ошибка chaincode доходит до клиента как объект с кодом и деталями, а не как потерянный контекст.

Опции команды (TransportFabricCommandOptions) добавляют к стандартным опциям @ts-core поля userId и signature — ту самую подпись на уровне приложения:

export interface ITransportFabricCommandOptions extends ITransportCommandOptions {
userId?: string;
signature?: ISignature;
}

За свежий nonce отвечает readonly-команда NonceGetCommand — клиент берёт текущее значение, увеличивает и подписывает им следующую команду:

export class NonceGetCommand extends TransportFabricCommandAsync<string, string> {
public static readonly NAME = 'NonceGetCommand';
constructor(uid: UID) {
super(NonceGetCommand.NAME, getUid(uid), null, true); // последний аргумент — isReadonly
}
}

Подробнее о проверке подписи — в разделе «Безопасность».

Сюда же вынесены метаданные chaincode — ChaincodeMode, IChaincodeMetadata, ChaincodeMetadataGetCommand, по которым клиент может, например, узнать, включён ли у контракта batch-режим, и выбрать нужный транспорт.