Fabric Sample improvements
fabric-samples has grown organically over time, without any overall plan or target objectives.
This presentation proposes a set of Objectives to revamp fabric-samples, that is, make it easier to understand Fabric capabilities and application patterns through a logical series of samples and associated tutorials.
Objective 1: Rational suite of asset transfer samples to teach Fabric core concepts - IN PROGRESS
Objective 2: Easy to understand sample that demonstrates ‘secured asset transfer’ - DONE
Objective 3: Improve/Simplify Commercial Paper sample
Objective 4: New samples - token, auction, supply chain, decentralized identity
Objective 5: Improve chaincode API documentation
Objective 6: Identify Fabric improvement areas
1
Objective 1: Rational suite of asset transfer samples to teach Fabric core concepts
Replace overlapping sacc/fabcar/marble asset samples with a series of samples demonstrating a core concepts
Proposed sample series:
Each sample can be driven by CLI or sample application.
Start with one chaincode language, port Basic asset transfer to each chaincode language.
The sample applications will similarly demonstrate a series of good applications patterns, e.g.:
2
Objective 1 (continued): Asset transfer samples
3
| Asset transfer - basic | Asset transfer - ledger queries | Asset transfer - private data | Asset transfer - secured |
Location in fabric-samples | fabric-samples/ asset-transfer-basic | fabric-samples/ asset-transfer-ledger-queries | fabric-samples/ asset-transfer-privatet-data | fabric-samples/ asset-transfer-secured-agreement |
Associated tutorial | Test Network (existing) Chaincode deployment (existing) Write your first application (existing) Write your first chaincode (refactor of Chaincode for Developers) | CouchDB tutorial (existing) | Private data tutorial (existing) | Secured asset transfer (new) |
Replaces old sample | abstore fabcar sacc | marbles02 | marbles02_private | |
CreateAsset(), TransferAsset() | ✅ | ✅ | ✅ | ✅ |
Advanced ledger APIs - Composite key queries in a tran - CouchDB queries and indexes | simple queries | ✅ | simple queries | simple queries |
Owner auth | | | ✅ ownership based on client id | ✅ ownership based on client’s org MSPID |
Private data | | | ✅ explicit collections | ✅ implicit collections |
State-based endorsement | | | | ✅ |
Multi-party agreement | | | | ✅ |
Objective 1 (continued): Asset transfer samples - CRUD Functions
4
| Asset transfer - basic Tiffany/Dereck (based on Fabcar) | Asset transfer - ledger queries Tiffany (based on marbles02) | Asset transfer - private data Nik (based on marbles02_private) | Asset transfer - secured Nik/Dave → Tiffany/Dereck (new transfer chaincode) |
Asset properties | Public: ID color size owner appraisedValue | Public: ObjectType ID color size owner appraisedValue | Private collection 1: ObjectType ID color size owner Private collection2: ObjectType ID appraisedValue | Public ObjectType ID owner Owner’s private Implicit collection: ObjectType ID color size owner |
InitLedger() | InitLedger() creates a few assets (init not enforced to keep cc simple) | InitLedger() creates a few assets (init not enforced to keep cc simple) | No init. Remove Init-required from tutorial | No init. |
CreateAsset() | CreateCar() → CreateAsset() | initMarble() → CreateAsset() Also create color index for queries | initMarble() → CreateAsset()
| IssueAsset() → CreateAsset()
|
ReadAsset() | QueryCar() → ReadAsset() | readMarble() → ReadAsset() | readMarble() → ReadAsset() readMarblePrivateDetails() → GetAssetPrivateDetails() getMarbleHash() → GetAssetHash() | GetAsset() - public → ReadAsset() GetAssetPrivateProperties() - prvt |
UpdateAsset() | na → UpdateAsset() | not needed (support transfer only) | not needed (support transfer only) | not needed (support transfer and description update only) |
DeleteAsset() | na → DeleteAsset() | delete() → DeleteAsset() | delete() → DeleteAsset() | Not needed |
AssetExists() | AssetExists() | AssetExists() | AssetExists() | AssetExists() |
TransferAsset() | ChangeCarOwner() → TransferAsset() Pass new owner name No auth check | transferMarble() → TransferAsset() Pass new owner name No auth check | transferMarble() → TransferAsset() Pass new owner client id Verify current owner against client id | AgreeToSell() / AgreeToBuy() GetAssetSalesPrice() / GetAssetBidPrice() TransferAsset():
|
Objective 1 (continued): Asset transfer samples - Query Functions
5
| Asset transfer - basic Tiffany/Dereck (based on Fabcar) | Asset transfer - ledger queries Tiffany (based on marbles02) | Asset transfer - private data Nik (based on marbles02_private) | Asset transfer - secured Nik/Dave → Tiffany/Dereck (new transfer chaincode) |
GetAllAssets() Simple range query (no start/end keys) | QueryAllCars() → GetAllAssets() | | No pagination | No pagination |
Range query on simple key | | GetAssetsByRange() GetAssetsByRangeWithPagination()
| GetAssetsByRange() No pagination supported | |
Range query on composite key | | transferAssetByColor()
| | QueryAssetSaleAgreements() QueryAssetBuyAgreements() |
CouchDB JSON queries and indexes | | QueryAssetsByOwner() QueryAssets() QueryAssetsWithPaginiation()
| QueryAssetsByOwner() QueryAssets() | |
GetHistoryForAsset() | | getHistoryForMarble() → GetAssetHistory() | | GetAssetHistory() |
| | | | |
Objective 2: Easy to understand sample that demonstrates ‘secured asset transfer’
Secured asset transfer sample that demonstrates
Driveable via CLI and SDK.
Since Commercial Paper is already too complex (per Objective 3), use a simple asset transfer to demonstrate the concepts.
Chaincode and Tutorial Merged:
6
Objective 3: Improve/Simplify Commercial Paper sample
The Commercial Paper business scenario, documentation, and sample take several hours to read and digest due to the length, it is therefore not a good starting point for Fabric beginners.
Additionally, the following feedback has been provided:
Business scenario confusion - feedback from a new user
State management
Ownership check
Converge to a single chaincode
7
Objective 4: New samples
Potential samples
8
Token chaincode samples
Demonstrate how to model fungible tokens in chaincode
Basic sample for account-based model and UTXO model
9
Token chaincode sample - Account-based (ERC-20 model)
Transfer(recipient string, num_tokens int)
Account records
Mint(recipient string, num_tokens int)
BalanceOf(owner string)
Advanced acount-based sample options
10
org1user1 | 10000 |
key
value
org1user1 | 10000 |
org1user1 | 8000 |
org2user1 | 2000 |
Scenario:
- Mint 10000 tokens to org1
- Transfer 2000 tokens to org2
Token chaincode sample - UTXO
Transfer(input_keys []string, outputs []utxo)
UTXO Records
Mint(outputs []utxo)
11
BalanceOf(owner string)
txid1:1 | 10000 | org1user1 |
txid1:1 | 10000 | org1user1 |
txid2:1 | 8000 | org1user1 |
txid2:2 | 2000 | org2user1 |
inputs
outputs
outputs
inputs
none
txid1:1 | 10000 | org1user1 |
key
value
org1user1:txid1:1 | 10000 |
delete/spend inputs
Scenario:
- Mint 10000 tokens to org1
- Transfer 2000 tokens to org2
Token chaincode samples - more advanced options
Advanced sample options (applies to account-based and UTXO)
12
Objective 5: Improve chaincode API documentation
The chaincode API documentation is difficult to find and difficult to understand.
Some APIs are not described at all, e.g. how to use state-based endorsement APIs in node chaincode
Add a ‘cheatsheet’ in Fabric docs
Note - this is not part of ‘samples’ per se, rather it should be a fundamental and easy-to-find part of the base chaincode/SDK documentation.
13
Objective 6: Identify Fabric improvement areas
What is difficult to do in Fabric that needs to be improved?
Application SDK improvements
14
Backup/Other (somewhat outdated)
15
Hyperledger Fabric chaincode/data patterns
Patterns will be turned into sample code.
16
Pattern | Description | Example use cases | Transaction flow | Fabric features/APIs |
Secured asset transfer (aka non-fungible token) | Private transfer of an asset between two organizations without publicly sharing data |
| Two organizations agree on the transfer of an asset from one organization to the other for a certain price. The details of the agreement are stored by each organization in their respective private data collections. The asset transfer is only endorsed by the two organizations. More details: |
|
Auction | Bidders submit private bids, then reveal bids | Can be bolted on the front of asset transfer sample (perhaps two chaincodes that work together). | Bidders submit private bids to their private data collection. Auction closes. Bidders reveal bids. Highest revealed bid wins. | Implicit data collections |
Audit | | | | |
Supply chain | | | | |
Reconciliation | | | | |
see related ibm developer patterns:
Hyperledger Fabric client application patterns
17
Pattern | Description | Example uses cases | Customers | Transaction flow | Fabric features/APIs |
Event listeners | Listen to smart contract events, listen for commit events | | | | setEvent api in chaincodes, addContractListener() in sdks |
Service discovery - find endorsers | Used when application can get ‘any’ endorser | | | | |
Service discovery - find peers of org | Used when application needs to target a specific org, e.g. when state-based endorsement is used. | | | | |
Event strategy | Which set of peers to listen for submission completion (your org vs all orgs) | | | | Gateway setup |
Connection setup and use | | | | | |
see related ibm developer patterns:
Work item plan
18
asset-transfer-basic - port to all chaincode and application languages
asset-transfer-ledger-queries
asset-transfer-private-data
asset-transfer-sbe
asset-transfer-secured-agreement (pvt+sbe+acl)
asset-transfer-events (javascript) Bret DONE
asset-transfer-abac Nik DONE
Misc tasks
Test network
Improve Commercial Paper sample - Paul DONE
Retire replaced/outdated samples - Dave
Improve chaincode reference docs - Matthew
Improve SDK reference docs - Bret
Other potential samples
Auction (simple) Nik and Arnaud - DONE
Auction (dutch) Nik PR
Token ERC-20 (Go) - Dave/Julian DONE
Token ERC-20 (Javascript) Yuki DONE
Token UTXO - Dave DONE (add 2nd recipient to tutorial)
Token ERC-721 - chaincode-javascript - Yuki PR
Token anonymous payment addresses and Identity Mixer extensions - Guarav
Identity deep-dive and SoftHSM tutorial - Bret
Peerless orgs - Client orgs using a namespace within a peer org implicit private data collection
Delivery versus payment (using tokens)
Supply chain sample - Chris
Decentralized Identity sample - Kamlesh/Sanket