Study CHFD by constructing one canonical transaction trace — client proposal, endorsing peers, read/write set, ordering, validation, commit — and then attach every exam topic to a step in that trace. Worked scenarios below show where lifecycle and privacy decisions typically go wrong, an exercise gives you a self-check rubric, and a comparison table turns privacy options into decisions instead of definitions.
Trace one transaction through execute-order-validate before anything else
Fabric separates simulation, ordering, and validation into different phases run by different components. Learn the pipeline first: every later topic — policies, private data, state — attaches to a specific step in this trace.
Walk the canonical path on paper: a client SDK signs a transaction proposal and sends it to required endorsing peers; each endorser runs chaincode in simulation, produces a read-write set, and signs the endorsement response; the client collects responses, assembles an envelope, and submits it to the ordering service; orderers cut the transactions into blocks; peers validate each transaction — checking the endorsement satisfies the policy and that no read-set version conflicts — before committing valid ones to the ledger and world state. Name the component at every arrow until you can do it from memory.
Use this trace as a drill for separating phases that look similar when defined in isolation. To train the separation, take each pair — simulation versus validation, ordering versus endorsement — and write one sentence stating which component performs it and when. Chaincode execution at an endorser is simulation: nothing is committed, so a failure after endorsement does not roll back a committed state change. Validation happens later, on every peer, independently of the endorser. Ordering does not interpret transaction content; it only sequences. Once you can state which component performs each action, questions about blocks or MVCC failures become questions about a step you already understand.
- Simulation: endorsing peers run chaincode and produce a signed read-write set — nothing is committed.
- Ordering: the ordering service sequences endorsed envelopes into blocks without evaluating their content.
- Validation: every peer rechecks the endorsement policy and read-set versions before committing.
- Commit: valid transactions update the world state; the block is appended to the blockchain regardless.
Endorsement policies decide who must simulate — learn where they act
An endorsement policy specifies the chaincode executions whose signed results the client must collect and validators will re-verify. Trace it to two points: collection by the client, re-check by validating peers.
Distinguish the policy from the act of endorsement. Endorsers do not decide policy; they sign simulation results. The client gathers enough signed responses to satisfy the policy — for example, signatures from peers of two different organizations — and the validators later confirm the envelope actually carries those signatures. To internalize the two points, draw the policy as arrows to two places on your trace: response collection by the client, and re-verification by every validating peer. A trace that stops at 'the peer endorses' cannot explain why a client that submits only one signature out of a required two fails validation even though the transaction simulated successfully.
Practice the distinction with a paper scenario. Suppose a chaincode requires endorsement from Org1 and Org2 peers, and a client submits only Org1's signed response. The transaction still reached the ordering service, so it consumes a transaction slot in a block, but every validator marks it invalid during validation. The better decision when designing an application is to fail fast in the client: check the policy before submission. This matters because the two outcomes look similar in logs but differ in who detects the problem and whether an invalid transaction still appears in a block.
Chaincode lifecycle: separate 2.x package-approve-commit from the 1.x flow
In the current lifecycle, chaincode is packaged, installed, approved per organization, checked for readiness, then committed on a channel. The older lifecycle bundled install and instantiate into one step.
Study the current sequence as a state machine: package the chaincode, install it on peers that will endorse, have each relevant organization approve a chaincode definition (name, version, sequence, endorsement policy, collection configuration), then run a readiness check showing which organizations have approved, and finally commit the definition on the channel. The sequence number is the detail that makes this more than vocabulary: every change to the definition — a new endorsement policy or updated package reference — requires bumping the sequence and getting the required organizations to approve again.
Worked scenario: a two-organization channel where Org1 approves version 1.0 at sequence 1 and attempts commit, but commit fails because readiness shows Org2 has not approved. The plausible mistake is assuming that installing the package on Org2 peers satisfies the definition requirements — installation and approval are separate actions performed by separate identities. The better decision is to read the check-commitreadiness output, have Org2 approve the same definition (same name, version, and sequence), confirm the output shows true for the required orgs, then commit. Why it matters: mixing up install and approval produces errors that name the wrong step, and a question describing 'the package is on the peer but the definition is not approved' tests exactly this separation.
Identity and security: attach MSPs to actors, not to a vague 'network'
An MSP defines the trust anchors and identity rules for one organization. Every signing actor — client, peer, orderer, admin — acts under a specific MSP, and channel policies reference those MSP IDs.
Fix the confusion that an MSP is a network-wide object. An organization's MSP material is distributed to its own peers and to channel configuration, so a peer verifies a signature by checking it against the MSP that identity claims and the trust anchors in the channel config. Policies on channels, chaincode, and resources are written in terms of MSP principals — for example, a policy requiring a signature from an admin of a named organization's MSP. Trace a signature to the actor, the actor's MSP, and the policy that evaluates it, and identity questions become pipeline questions.
Connect this to application development: the SDK or Gateway signs proposals with a client identity whose certificate must belong to an MSP enrolled on that channel, and channel ACLs can restrict who may invoke specific system operations. A paper exercise: a client certificate is valid but its organization was never added to the channel's membership, so even a correctly signed proposal is rejected. The lesson to articulate is that cryptographic validity and channel membership are separate checks — the signature can be mathematically sound while the identity has no standing on that channel.
Choose between channels, private data collections, and transient inputs
These three mechanisms solve different sharing problems: channels scope an entire ledger and membership, collections share selected data among a subset, and transient inputs avoid persisting certain values at all.
Learn them as decisions, not definitions. A channel duplicates full ledger state to every member, so use it when all participants need all data. A private data collection authorizes a subset of channel members to hold the collection's data locally, while other members see only a hash of it on the channel ledger — useful when non-members must verify that something happened without seeing what. Transient fields are stripped from the transaction before ordering and are never written to the ledger, but they are visible to the endorsing peers that received the proposal, so they protect against ledger exposure, not against endorser visibility.
Worked scenario: an application passes a customer's account number as a transient field, and the developer later wants channel members outside the endorsing organizations to run aggregate analytics on it. The mistake is expecting transient data to be queryable by others — it was never persisted, by design. The better decision is a private data collection whose members include the parties that need the value, with chaincode reading it through the collection name and the config controlling who gets the data versus who gets only the hash. Why it matters: the three tools differ in who can read data after the fact, and choosing the wrong one is a design error, not a code fix.
| Mechanism | Who can read the data afterwards | Ledger footprint | Typical use |
|---|---|---|---|
| Channel | All channel members | Full ledger per member | All participants need the same data |
| Private data collection | Collection members; others see only a hash | Private state on member peers; hash on channel ledger | Share a value with a subset, prove it to the rest |
| Implicit collection | Only the owning organization's peers | Per-organization private state | Org-local data on a shared channel |
| Transient input | Endorsing peers that received the proposal; then nobody | None — not persisted | Pass sensitive values during simulation only |
Ledger and state database: two stores, one versioning rule
The ledger is an append-only blockchain plus a key-value world state. The state database indexes current values; read-write sets carry version numbers, and validation rejects transactions whose read versions no longer match.
Understand the world state as a cache of current values derived from committed blocks: it can be rebuilt from the blockchain, and CouchDB is the common alternative to LevelDB when rich JSON queries are needed. Versioning is the rule that ties this to validation. During simulation, chaincode reads a key at the version it currently has; at validation, each peer re-checks that the key still sits at that version. If another committed transaction changed it first, the later transaction is marked invalid — multi-version concurrency control, applied without locks.
Practice the timing distinction: a query inside chaincode during simulation reflects the endorsing peer's current state and is not part of transactional consistency the way reads recorded in the read set are; a query issued by the application after commit reflects committed state. For CouchDB, note that rich queries apply to JSON state — and, where CouchDB is used, to private data state as well — while key-based range and composite-key reads work on either database. A plausible mistake is treating a simulated read as a guarantee; the better decision is to design keys so concurrent writers rarely collide, and to expect MVCC-invalidated transactions as a normal outcome under contention.
Application development: map SDK and Gateway calls onto the trace
Application code mirrors the transaction pipeline: select and endorse proposals, collect responses, submit to ordering, then listen for commit and validation events before treating the result as final.
Study the SDK and Gateway APIs as the programmatic form of the trace rather than as an API list. A submit flow builds a proposal, targets the peers required by the endorsement policy, assembles the endorsed envelope, and sends it through ordering; a Gateway submit handles those hops for you but performs the same phases underneath. Evaluation flows — queries — read state without ordering or commit. The exam-relevant skill is mapping an API call to its pipeline step and knowing which errors belong to which step: an endorsement failure is detected at response collection, a commit result needs an event or status check, and a query never produces a transaction.
Build a final practical exercise with a self-check rubric. Pick a two-organization channel on paper and write the full path of one asset transfer: which identities sign, which peers endorse, what the read set contains, what the ordering service does, what validators check, which stores update. Rubric for your answer: (1) every arrow names a component — client, endorser, orderer, validator; (2) you state that chaincode execution is simulation with no commit; (3) you place endorsement-policy checking at both collection and validation; (4) you say where the version check happens and what an MVCC failure produces; (5) you note that the block is appended even when individual transactions are invalid. Score yourself out of five and repeat until you reach five without notes.
References and further reading
Use these references to explore the concepts and check the latest information from the relevant organizations.
