@hlf-core/common
Это нижний слой всей экосистемы — то, что не привязано ни к среде исполнения, ни к конкретной
стороне. @hlf-core/common не знает ни про fabric-shim, ни про fabric-network, и именно
поэтому один и тот же код спокойно работает и в chaincode, и на backend, и во frontend. Проще
говоря, здесь живёт общий словарь, на котором говорят все остальные пакеты.
Центральная вещь здесь — StateKey, сборщик составных ключей состояния. Он вынесен в отдельный
раздел «StateKey и ключи состояния», потому что от того, как строится
ключ, зависит, какие запросы к данным вообще возможны.
Идентичность пользователя описывают UserUtil и интерфейс IUser<S, R> — идентификаторы формата
user_<время>_<hash>, роли, статус, криптоключ. Подробно об этом — в разделе
«Идентификация пользователя». Сам криптоключ это пара «значение и
алгоритм» (CryptoKey / ICryptoKey).
Отсюда же растёт модель команд. HlfTransportCommand<T> и HlfTransportCommandAsync<U, V>
расширяют базовые команды из @ts-core, добавляя признак isReadonly — то самое разделение
чтения и записи, на котором держится весь транспорт. А InitiatedDto добавляет к любому DTO
поле initiatorUid: иногда важно знать не только того, кто подписал транзакцию, но и того, от
чьего имени операция была по-настоящему инициирована, и это не всегда один и тот же пользователь.
Наконец, доменные ошибки. Error<T> поверх ExtendedError из @ts-core несёт машиночитаемый
код (ErrorCode), и благодаря этому ошибка, возникшая в chaincode, доходит до клиента не как
безликий сбой, а как понятная причина с кодом.
const key = new StateKey('→coin~account');
key.key('coin_RUB', 'user_abc'); // →coin~account:coin_RUB~user_abc
key.prefix('coin_RUB'); // →coin~account:coin_RUB~