Skip to main content

@hlf-core/transport-chaincode

This is the mirror half of the client transport — everything that happens on the chaincode side when a command arrives at it. The package takes on the routine of receiving and verification, leaving the developer with only the business logic: it handles authentication, validation, and state access itself.

The entry point is TransportFabricChaincode, which implements ChaincodeInterface from fabric-shim (its Init and Invoke) and is launched with the familiar shim.start. It delegates all the substantive work to the receiver TransportFabricChaincodeReceiver. The receiver parses the incoming envelope, verifies the signature, and dispatches the command to the handler registered by name. The signature verification itself is a chain: the algorithm from the cryptoManagers list, authorization of the public key, the nonce, and cryptographic verification, and each link can reject the command. This chain is covered in detail in the “Security” section.

Access to state inside a handler goes through TransportFabricStub — a wrapper over ChaincodeStub that implements IStub and carries user, requestId, and transaction. And StateProxy is responsible for atomicity: it does not write to the ledger right away but accumulates changes in memory — toPut and toRemove — and commits them with a single commit. A read, meanwhile, first looks into the accumulated cache, so within a single transaction we always see our own, not-yet-committed changes.

For batch mode there is TransportFabricChaincodeReceiverBatch — it receives several commands and executes them in a single transaction, under a separate batch signature. And TransportFabricSeededChaincode solves a separate problem — initializing the state with seed data on the contract’s first launch.

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));

The error codes — for the signature, the nonce, and batch — are defined right here, so from the response code it is always visible at which exact link the command was rejected. The nonce, as a reminder, is stored under the key →${userId}~nonce and must strictly increase, and readonly commands do not touch it.