Hyperledger Composer中关联支票簿资产及验证其存在的方法
Hey there! Let's break down your questions about Hyperledger Composer's relationship mechanism and how to validate a cheque book exists when creating a cheque.
First: Tweak Your Model Definitions for Clarity
First, let's adjust your model files to follow common Composer naming conventions (capitalized asset/transaction names) which will make your code easier to work with:
Cheque Book Model (chequeBooks.cto)
namespace org.example.bank.chequeBooks asset ChequeBook identified by chequeBookNumber { o Integer chequeBookNumber }
Cheque Model (cheque.cto)
namespace org.example.bank.cheque import org.example.bank.chequeBooks.ChequeBook asset Cheque identified by chequeNumber { o Integer chequeNumber --> ChequeBook cb // This creates a relationship to the ChequeBook asset } transaction chequeInProcess { o Integer chequeNumber o Integer chequeBookNumber // We'll use this to look up the ChequeBook } event chequeCashed { o Integer chequeNumber o Integer chequeBookNumber }
The --> ChequeBook cb line defines a relationship—this is just a reference to a ChequeBook asset (storing its unique ID, chequeBookNumber), not a copy of the entire asset. This keeps your data consistent and avoids duplication.
Second: Implement Transaction Logic to Validate & Create the Cheque
Now, let's write the transaction processor code that will:
- Look up the
ChequeBookusing the providedchequeBookNumber - Validate that the cheque book actually exists
- Create a new
Chequeasset linked to the valid cheque book - Emit the
chequeCashedevent
Save this as logic.js:
/** * Process a cheque creation transaction * @param {org.example.bank.cheque.chequeInProcess} tx * @transaction */ async function chequeInProcess(tx) { // 1. Get the asset registry for ChequeBook assets const chequeBookRegistry = await getAssetRegistry('org.example.bank.chequeBooks.ChequeBook'); // 2. Try to fetch the ChequeBook using the provided number // Note: We convert the number to a string because Composer uses string IDs internally const chequeBook = await chequeBookRegistry.get(tx.chequeBookNumber.toString()); // 3. Throw an error if the ChequeBook doesn't exist if (!chequeBook) { throw new Error(`Oops! Cheque book with number ${tx.chequeBookNumber} doesn't exist.`); } // 4. Create a new Cheque asset const factory = getFactory(); const newCheque = factory.newResource('org.example.bank.cheque', 'Cheque', tx.chequeNumber.toString()); // 5. Link the new Cheque to the existing ChequeBook using a relationship newCheque.cb = factory.newRelationship( 'org.example.bank.chequeBooks', 'ChequeBook', tx.chequeBookNumber.toString() ); // 6. Add the new Cheque to its asset registry const chequeRegistry = await getAssetRegistry('org.example.bank.cheque.Cheque'); await chequeRegistry.add(newCheque); // 7. Emit the chequeCashed event to notify external systems const event = factory.newEvent('org.example.bank.cheque', 'chequeCashed'); event.chequeNumber = tx.chequeNumber; event.chequeBookNumber = tx.chequeBookNumber; emit(event); }
Key Explanations:
- Validating the ChequeBook: The
chequeBookRegistry.get()method will throw an error if the asset doesn't exist, but we add an explicit check to throw a more user-friendly error message. - Relationships: When creating
newCheque.cb, we usefactory.newRelationship()to create a reference to the existingChequeBook—this ensures the Cheque is always linked to a valid, existing cheque book. - String IDs: Even though your identifiers are integers, Composer stores all asset IDs as strings, so we convert the numbers to strings when fetching or creating assets.
Quick Recap of Composer Relationships
Relationships in Composer are lightweight references between assets/participants. They:
- Store only the unique ID of the target asset (not the full asset data)
- Allow you to easily fetch the linked asset later (using the relationship)
- Ensure data consistency (you can't link to an asset that doesn't exist, as we validate in the transaction)
内容的提问来源于stack exchange,提问作者Saeedi

