Hyperledger Composer已关联资产的合约属性能否更新?
Hey there! I totally get where you're coming from as a new Hyperledger Composer user—this is a common gotcha with how assets and contracts are linked. Let's unpack why your current code isn't working and how to fix it.
The Root Issue
In Hyperledger Composer, Contracts are independent resource types, not embedded within assets. When you link an asset (like your Document) to a Contract, you're just storing a reference (the contract's ID) in the asset—you're not copying the contract's data into the asset.
So when you do document.contract.totalSigners = 3, you're only modifying a local in-memory copy of the contract reference, not the actual Contract resource that lives in the Contract Registry. Updating the Document registry doesn't touch the Contract registry at all, which is why your change doesn't stick.
Step-by-Step Solution
To update a contract's properties, you need to directly interact with the Contract Registry. Here's how to adjust your code:
- Fetch the Contract Registry and locate the specific contract linked to your Document
- Modify the contract's properties directly
- Save the updated contract back to its registry
- (Optional) Update the Document registry only if the Document itself has changed (not needed just for contract updates)
Here's the corrected code example:
// Replace NS with your actual namespace (e.g., 'org.example') return getAssetRegistry(NS + '.Contract') .then(function(contractRegistry) { // Fetch the specific contract using its ID from the Document's reference return contractRegistry.get(document.contract.$identifier); }) .then(function(targetContract) { // Update the contract's property directly targetContract.totalSigners = 3; // Save the updated contract back to its registry return getAssetRegistry(NS + '.Contract') .then(function(contractRegistry) { return contractRegistry.update(targetContract); }); }) .then(function() { // Only update the Document if you made changes to the Document itself // Skip this block if you're just updating the contract return getAssetRegistry(NS + '.Document') .then(function(documentRegistry) { return documentRegistry.update(document); }); }) .catch(function(error) { console.error('Error updating contract:', error); throw error; });
Key Notes to Remember
- Check your CTO model: Ensure your Contract is defined as a separate resource, not an embedded field in the Document. For example:
namespace org.example asset Document identified by documentId { o String documentId --> Contract contract // This is a reference, not embedded } contract Contract identified by contractId { o String contractId o Integer totalSigners } - ACL Permissions: Make sure the participant executing the transaction has permission to update Contract resources. Double-check your
.aclfile for rules allowingUPDATEaccess on the Contract registry. - References vs Embeds: If you had embedded the contract data directly into the Document (using
o Contract contractinstead of--> Contract contract), your original code would work—but embedding is usually not ideal for shared, reusable contracts.
内容的提问来源于stack exchange,提问作者Kokhow Chuang

