Hyperledger Composer ACL配置:仅允许用户通过交易创建资产
Let's break down why your current setup isn't working and fix it step by step.
Why Your Current Code Fails
The var isInTransaction = true; you set inside your transaction function is a local variable that only exists within that function's scope. The ACL rule's condition function isInTransactionF() runs in a completely separate context—it can't access that local variable at all. That means your condition always returns false, so the ACL rule blocks the create operation every time.
Reliable Solutions
Based on Hyperledger Composer (the framework your code aligns with), here are two solid ways to enforce your requirement:
Option 1: Use Built-in Transaction Context Check
Modify your logic.js function to use the framework's built-in getCurrentTx() method. This method returns the active transaction object only when code is running inside a transaction—otherwise it returns null:
/** @returns {boolean} boolean true/false */ function isInTransactionF(){ // Return true only if we're inside an active transaction return getCurrentTx() !== null; }
Keep your existing ACL rule as-is. Now when you run the transaction, getCurrentTx() will return a valid object, making the condition true and allowing the create operation.
Option 2: Validate Transaction Type & Participant (More Granular)
If you want tighter control (e.g., only allow creation via a specific transaction), use this approach:
- First, update your transaction definition in your
.ctofile to include a creator reference:
transaction CreateUserAssetTx { --> User creator // Add other transaction fields as needed }
- Revise your ACL rule to check that the create operation is tied to your specific transaction, and that the asset creator matches the transaction initiator:
rule UserCanCreateAssetOnlyInTransaction { description: "Allow User to create UserAsset only via CreateUserAssetTx" participant(p): "com.example.User" operation: CREATE resource(r): "com.example.UserAsset" condition:( getCurrentTx().$type === 'com.example.CreateUserAssetTx' && getCurrentTx().creator.getIdentifier() === p.getIdentifier() ) action: ALLOW }
- In your transaction function, add a quick check to ensure only Users can run it, then create the asset:
async function createUserAsset(tx) { const currentUser = getCurrentParticipant(); // Block non-User participants upfront if (!currentUser || currentUser.$type !== 'com.example.User') { throw new Error('Only User participants can create UserAsset via this transaction'); } // Create and save the UserAsset const factory = getFactory(); const newAsset = factory.newResource('com.example', 'UserAsset', 'unique-asset-id'); // Set asset properties here await getAssetRegistry('com.example.UserAsset').add(newAsset); }
Quick Sanity Checks
- Make sure your transaction is properly registered in your business network definition
- Verify that the participant submitting the transaction is indeed a
com.example.Userinstance - Double-check that your ACL rules don't have conflicting deny rules that might override this allow rule
内容的提问来源于stack exchange,提问作者Mr Davron

