@hlf-core/coin
Работу с токенами hlf-core делит на два пакета, и это то же разделение, что и везде: отдельно
словарь, отдельно исполнение. @hlf-core/coin, о котором здесь речь — это платформо-нейтральные
модели, команды и события, без всякой привязки к Fabric. Их можно использовать и вне блокчейна,
а исполнением на стороне ledger занимается @hlf-core/coin-chaincode.
Основная модель — Coin (токен с полем balance), а состояние владельца описывает CoinAccount.
У счёта два состояния: inUse — то, чем можно распоряжаться, и held — то, что заблокировано
под какую-то операцию, и операции add, remove, hold, unhold, nullify переводят средства
между ними. Все суммы хранятся строками, и это принципиально: финансовую точность нельзя доверять
числам с плавающей точкой, иначе на округлении неизбежно накапливается расхождение.
CoinBalance расширяет счёт аудитом — emitted, burned, total, так что по нему виден полный
учёт выпущенного и сожжённого.
Отдельного слова заслуживает адрес счёта — CoinAccountObject вида {ownerUid, id}. Это объект,
а не две отдельные строки, и сделано так намеренно: у одного владельца по одной монете может быть
несколько счетов (скажем, OWNER и PAYOUT), и в переводе нам важно, чтобы стороны нельзя было
случайно перепутать местами.
Операции описаны командами, наследующими HlfTransportCommandAsync — CoinEmitCommand,
CoinBurnCommand, CoinTransferCommand, CoinHoldCommand, CoinUnholdCommand, CoinNullifyCommand,
и парой readonly-команд CoinGetCommand и CoinBalanceGetCommand. Каждому действию отвечает своё
событие — CoinEmittedEvent, CoinTransferredEvent (где получатель назван target, а не to)
и так далее.
const transfer = new CoinTransferCommand({
object: {ownerUid: 'alice', id: 'OWNER'}, // отправитель
target: {ownerUid: 'bob', id: 'OWNER'}, // получатель
value: '500',
coinUid: 'coin_issuer_8_MYTOKEN',
});
Ключи счетов строит CoinAccountUtil поверх StateKey, и порядок
частей в ключе здесь выбран так, чтобы можно было перечислить все счета владельца по монете одним
диапазонным запросом.