Hyperledger Composer交易网络限制性ACL配置问题求助
解决方案:实现Provider的资产权限控制与双向兑换
我来帮你搞定这个权限控制的问题!核心思路是通过资产关联所有者+ACL访问控制规则来实现「日常只读、交易时可更新」的需求,同时配合交易逻辑完成现金与代币的双向兑换。
1. 完善业务模型文件(.cto)
先把你没写完的模型补全,给每个资产加上owner关联到所属Provider,同时定义兑换交易:
namespace org.acme.biznet abstract participant Member identified by memberId { o String memberId o String name o String email } // Provider参与者,继承自Member,关联自己的Wallet和Account participant Provider extends Member { --> Wallet wallet --> Account account } // 代币钱包资产,关联所属Provider asset Wallet identified by walletId { o String walletId o Double tokenBalance default=0.0 --> Provider owner } // 现金账户资产,关联所属Provider asset Account identified by accountId { o String accountId o Double cashBalance default=0.0 --> Provider owner } // 现金兑换代币的交易 transaction CashToToken { o Double amount --> Provider provider } // 代币兑换现金的交易 transaction TokenToCash { o Double amount --> Provider provider }
2. 配置ACL访问控制规则(permissions.acl)
这是实现权限控制的核心,我们分规则定义:
// 规则1:Provider只能读取自己的Wallet和Account rule ProviderCanReadOwnAssets { description: "Provider has READ access only to their own assets" participant(p): "org.acme.biznet.Provider" operation: READ resource(r): "org.acme.biznet.Wallet" OR "org.acme.biznet.Account" condition: (r.owner.getIdentifier() == p.getIdentifier()) action: ALLOW } // 规则2:禁止Provider读取其他Provider的资产 rule ProviderCannotReadOthersAssets { description: "Provider cannot access assets belonging to others" participant(p): "org.acme.biznet.Provider" operation: READ resource(r): "org.acme.biznet.Wallet" OR "org.acme.biznet.Account" condition: (r.owner.getIdentifier() != p.getIdentifier()) action: DENY } // 规则3:默认禁止所有Provider更新资产 rule DenyDefaultAssetUpdate { description: "No Provider can update assets outside of authorized transactions" participant(p): "org.acme.biznet.Provider" operation: UPDATE resource(r): "org.acme.biznet.Wallet" OR "org.acme.biznet.Account" action: DENY } // 规则4:允许发起CashToToken交易的Provider更新自己的资产 rule AllowCashToTokenUpdate { description: "Allow Provider to update their assets when executing CashToToken transaction" participant(p): "org.acme.biznet.Provider" operation: UPDATE resource(r): "org.acme.biznet.Wallet" OR "org.acme.biznet.Account" transaction(tx): "org.acme.biznet.CashToToken" condition: (tx.provider.getIdentifier() == p.getIdentifier()) && (r.owner.getIdentifier() == p.getIdentifier()) action: ALLOW } // 规则5:允许发起TokenToCash交易的Provider更新自己的资产 rule AllowTokenToCashUpdate { description: "Allow Provider to update their assets when executing TokenToCash transaction" participant(p): "org.acme.biznet.Provider" operation: UPDATE resource(r): "org.acme.biznet.Wallet" OR "org.acme.biznet.Account" transaction(tx): "org.acme.biznet.TokenToCash" condition: (tx.provider.getIdentifier() == p.getIdentifier()) && (r.owner.getIdentifier() == p.getIdentifier()) action: ALLOW }
3. 编写交易处理器逻辑(script.js)
实现兑换的业务逻辑,同时做余额校验防欺诈:
/** * 处理现金兑换代币的交易 * @param {org.acme.biznet.CashToToken} tx * @transaction */ async function cashToToken(tx) { const { provider, amount } = tx; const account = provider.account; const wallet = provider.wallet; // 校验现金余额是否充足 if (account.cashBalance < amount) { throw new Error(`Insufficient cash balance: ${account.cashBalance} < ${amount}`); } // 这里可以自定义兑换汇率,比如1现金=1.2代币 const exchangeRate = 1; const tokenAmount = amount * exchangeRate; // 更新资产余额 account.cashBalance -= amount; wallet.tokenBalance += tokenAmount; // 保存更新到账本 const accountRegistry = await getAssetRegistry('org.acme.biznet.Account'); await accountRegistry.update(account); const walletRegistry = await getAssetRegistry('org.acme.biznet.Wallet'); await walletRegistry.update(wallet); } /** * 处理代币兑换现金的交易 * @param {org.acme.biznet.TokenToCash} tx * @transaction */ async function tokenToCash(tx) { const { provider, amount } = tx; const account = provider.account; const wallet = provider.wallet; // 校验代币余额是否充足 if (wallet.tokenBalance < amount) { throw new Error(`Insufficient token balance: ${wallet.tokenBalance} < ${amount}`); } const exchangeRate = 1; const cashAmount = amount * exchangeRate; // 更新资产余额 wallet.tokenBalance -= amount; account.cashBalance += cashAmount; // 保存更新到账本 const accountRegistry = await getAssetRegistry('org.acme.biznet.Account'); await accountRegistry.update(account); const walletRegistry = await getAssetRegistry('org.acme.biznet.Wallet'); await walletRegistry.update(wallet); }
关键说明
- 权限控制逻辑:通过ACL规则,平时Provider只能读自己的资产,无法修改;只有当他们发起对应的兑换交易时,才临时获得自己资产的UPDATE权限,完全符合你的防欺诈、安全需求。
- 资产关联:每个Wallet和Account都明确关联到
owner,这是ACL规则判断的核心依据,创建资产时一定要正确设置这个字段。 - 欺诈防护:交易处理器里做了余额校验,防止用户发起余额不足的无效交易。
内容的提问来源于stack exchange,提问作者kerberos17
相关产品推荐
相关产品推荐

