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

@hlf-core/transport-chaincode

Это зеркальная половина клиентского транспорта — всё то, что происходит на стороне chaincode, когда к нему приходит команда. Пакет берёт на себя рутину приёма и проверки, оставляя разработчику только бизнес-логику: аутентификацию, валидацию и работу с состоянием он делает сам.

Точка входа — TransportFabricChaincode, который реализует ChaincodeInterface из fabric-shim (его Init и Invoke) и запускается привычным shim.start. Всю содержательную работу он делегирует приёмнику TransportFabricChaincodeReceiver. Приёмник парсит входящий конверт, проверяет подпись и диспетчеризует команду зарегистрированному по имени обработчику. Сама проверка подписи — это цепочка: алгоритм из списка cryptoManagers, авторизация публичного ключа, nonce и криптографическая верификация, и каждое звено может команду отклонить. Подробно эта цепочка разобрана в разделе «Безопасность».

Доступ к состоянию внутри обработчика идёт через TransportFabricStub — обёртку над ChaincodeStub, которая реализует IStub и несёт user, requestId и transaction. А за атомарность отвечает StateProxy: он не пишет в ledger сразу, а копит изменения в памяти — toPut и toRemove, и фиксирует их единым commit. Чтение при этом сначала заглядывает в накопленный кэш, так что внутри одной транзакции мы всегда видим собственные, ещё не зафиксированные изменения.

Для batch-режима есть TransportFabricChaincodeReceiverBatch — он принимает несколько команд и исполняет их одной транзакцией, под отдельной подписью пакета. А TransportFabricSeededChaincode решает отдельную задачу — инициализацию состояния начальными данными при первом запуске контракта.

export class MyChaincode extends TransportFabricChaincode<void> {
constructor(logger: ILogger) {
const transport = new TransportFabricChaincodeReceiver({
cryptoManagers: [{algorithm: 'secp256k1', publicKey: '...'}],
nonSignedCommands: ['healthCheck'],
});
super(logger, transport);
}
public get name(): string {
return 'MyChaincode';
}
}
shim.start(new MyChaincode(logger));

Коды ошибок — по подписи, nonce и batch — определены здесь же, так что по коду ответа всегда видно, на каком именно звене команда была отклонена. Nonce, напомню, хранится по ключу →${userId}~nonce и обязан строго возрастать, а readonly-команды его не трогают.