hyperledger-labs / hyperledger-labs/cc-tools
Support fabric-chaincode-go/v2 + fabric-protos-go-apiv2 (release as cc-tools/v2)
- Dominant language
- Go
- Stars
- 43
- Forks
- 13
- PR merge metrics
- No merged PRs in 30d
Description
**Is your feature request related to a problem? Please describe.**
cc-tools is currently typed against the pre-v2 Fabric Go packages:
```
github.com/hyperledger/fabric-chaincode-go v0.0.0-20210603161043-af0e3898842a
github.com/hyperledger/fabric-protos-go v0.0.0-20210528200356-82833ecdac31
```
This blocks any consumer that has migrated to `fabric-chaincode-go/v2` + `fabric-protos-go-apiv2`, because the two module lines are distinct types to the Go compiler and cannot be mixed.
Concretely, this surfaced in Hyperledger Fabric Private Chaincode. The `confidential-escrow` sample uses cc-tools, and after FPC's v1 -> v2 migration it no longer builds:
```
chaincode/escrow.go:60:14: cannot use err.GetErrorResponse() (value of struct type
"github.com/hyperledger/fabric-protos-go/peer".Response) as
"github.com/hyperledger/fabric-protos-go-apiv2/peer".Response value in assignment
chaincode/escrow.go:99:24: cannot use stub (variable of interface type
"github.com/hyperledger/fabric-chaincode-go/v2/shim".ChaincodeStubInterface) as
"github.com/hyperledger/fabric-chaincode-go/shim".ChaincodeStubInterface
value in argument to tx.Run
```
The mismatch is inside cc-tools' own signatures (`tx.Run(...)`, `TxError.GetErrorResponse()`), so it isn't fixable at the consumer's call sites. I checked every published tag through v1.0.3 and all still pin the 2021-era v1 pseudo-versions.
**Describe the solution you'd like**
Retarget cc-tools to `fabric-chaincode-go/v2` + `fabric-protos-go-apiv2` and release it under the `github.com/hyperledger-labs/cc-tools/v2` module path.
The `/v2` path matters: several signatures change shape, not just import path, e.g. `Init` / `Invoke` / `InvokeChaincode` return `*peer.Response` instead of `pb.Response` **by value**, and `GetTxTimestamp` returns `*timestamppb.Timestamp`. That's a breaking API change, so semantic import versioning requires a new major path. It also means existing users are entirely unaffected: projects pinned at v1.0.x keep resolving v1.0.x and never see v2. The v1 line can stay alive alongside it, the same approach fabric-chaincode-go itself took.
**Describe alternatives you've considered**
- **Fork/patch cc-tools locally in FPC**: works, but fragments the ecosystem and leaves FPC carrying a permanent downstream patch.
- **Exclude `confidential-escrow` from the build**: defers the problem; the sample stays dead and any other v2 consumer hits the same wall.
- **Keep everything on v1**: not viable for FPC, which now targets Fabric 3.1.x.
**Additional context**
Before proposing this I checked whether a v2 move would break deployments on older peers (notably Fabric 2.2), since cc-tools has downstream users there. Full write-up in the FPC thread: https://github.com/hyperledger/fabric-private-chaincode/pull/957#issuecomment-5461174667
Summary of the findings:
1. **Wire format is unchanged.** Diffing the `ChaincodeMessage.Type` enum between `fabric-protos-go v0.0.0-20210528200356` and `fabric-protos-go-apiv2 v0.3.7`, values 0-22 are identical i.e. same names, same numbers, nothing renumbered or removed. Only three additions: `PURGE_PRIVATE_DATA` (23), `WRITE_BATCH_STATE` (24), `GET_STATE_MULTIPLE` (25). Since protobuf encoding depends only on field/enum numbers, `-apiv2` produces byte-identical messages for every pre-existing type. The v1 -> v2 change is Go codegen (gogo -> `google.golang.org/protobuf`), not protocol.
2. **The new message types are all gated.** `PURGE_PRIVATE_DATA` and `GET_STATE_MULTIPLE` are only emitted from `stub.PurgePrivateData()` / `stub.GetMultipleStates()`, opt-in. `WRITE_BATCH_STATE` is negotiated, not assumed: on `REGISTERED` the shim reads `ChaincodeAdditionalParams` from the peer's payload (`handler.go:801-811`) and sets `usePeerWriteBatch`. An older peer predates that field, replies with an empty payload, the flag defaults to `false`, and writes go out as ordinary `PUT_STATE`. Upstream tests this case explicitly (`stub_test.go:647`, `"WriteBatch - Old peer (usePeerWriteBatch false)"`), so old-peer compatibility is a deliberate, tested guarantee in the shim.
3. **Only three of six new APIs carry a newer-peer requirement.** Diffing `ChaincodeStubInterface`: `GetAllStatesCompositeKeyWithPagination` is a convenience wrapper over `GET_STATE_BY_RANGE` (14, present since 1.x) and `StartWriteBatch` / `FinishWriteBatch` are gated by the flag above, all safe. `PurgePrivateData` (2.5+), `GetMultipleStates` and `GetMultiplePrivateData` (3.0) are the ones to avoid. No methods were removed, so cc-tools loses no API it depends on.
4. **cc-tools doesn't call any of them.** The only hit is `mock/mockstub.go` (`MockStub.PurgePrivateData`), an interface-satisfaction stub operating on the in-memory map, never sending a `ChaincodeMessage`, only reachable under `go test`. Zero hits for `GetMultipleStates`, `GetMultiplePrivateData`, `StartWriteBatch`, or `FinishWriteBatch`.
So the port looks mechanical rather than semantic, and shouldn't change runtime behaviour against older peers, provided production paths continue to avoid those three methods. That's worth a note in CONTRIBUTING or a lint rule if older-peer support is a maintained guarantee rather than best-effort.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by auditing cc-tools’ public signatures around tx.Run and TxError.GetErrorResponse, then inspect mock/mockstub.go and the current Fabric module dependencies. Verify the v2 module path, updated Fabric imports, and required return-type changes across the package, while preserving the documented older-peer behavior. Run the project tests and confirm the v2 module builds and can support the confidential-escrow consumer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- blockchain
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100