Hyperledger Composer中交易网络的限制性ACL

时间:2018-04-27 15:48:11

标签: acl hyperledger hyperledger-composer

我无法解决我的问题,所以我试着再解释一下: 有2个参与者(提供者)。他们都拥有自己的钱包和账户,他们想要兑换现金给代币,反之亦然。由于欺诈,安全等原因,他们应该只对自己的资产进行READ访问。但对于交易,他们需要UPDATE-access。这是我的代码:

org.acme.biznet.cto:

namespace org.acme.biznet

abstract participant Member identified by memberId {
o String memberId
o String name
o String email
}
// Sensorbesitzer, z.B private Personen, Haushalte etc.
participant Provider identified by providerId extends Member {
o String providerId
--> SDTWallet sdtWallet
--> Account account
}
// SDT Token Wallet von den Netzwerkteilnehmern.
asset SDTWallet identified by sdtWalletId {
o String sdtWalletId
o Double balance default = 0.0 
--> Member owner 
}
// Geldkonto von den Netzwerkteilnehmern.
asset Account identified by accountId {
o String accountId
o Double balance default = 0.0
--> Member owner 
}
// Cash gegen Tokens getauscht.
transaction TradeCashToTokens {
o Double cashRate default = 2.0
o Double cashValue default = 1.0 range = [1.0,]
--> SDTWallet fromSDT 
--> SDTWallet toSDT
--> Account fromCash
--> Account toCash
}
// Tokens gegen Cash getauscht.
transaction TradeTokensToCash {
o Double tokenRate default = 0.5       
o Double tokenValue default = 2.0 range = [2.0,]    
--> SDTWallet fromSDT
--> SDTWallet toSDT
--> Account fromCash
--> Account toCash
}

和logic.js:

/**
* Cash to tokens transaction
* @param {org.acme.biznet.TradeCashToTokens} UpdateValues
 * @transaction
*/
function TradeCashToTokens(UpdateValues) {

//determine change in tokens value from the rate
var tokensChange = (UpdateValues.cashRate * UpdateValues.cashValue);

if(UpdateValues.fromCash.balance < UpdateValues.cashValue) {
    throw new Error('Insufficient cash funds!');
} else if (tokensChange > UpdateValues.fromSDT.balance) {
    throw new Error('Not enough tokens for this transaction!'); 
}
//alert("Fehler!");

//update values of exchanger1 cash account
console.log('#### exchanger1 cash balance before: ' + UpdateValues.fromCash.balance);
UpdateValues.fromCash.balance -= UpdateValues.cashValue;
console.log('#### exchanger1 cash balance after: ' + UpdateValues.fromCash.balance);
//update values of exchanger2 cash account
console.log('#### exchanger2 cash balance before: ' + UpdateValues.toCash.balance);
UpdateValues.toCash.balance += UpdateValues.cashValue;
console.log('#### exchanger2 cash balance after: ' + UpdateValues.toCash.balance);
//update values of exchanger1 token wallet
console.log('#### exchanger1 token balance before: ' + UpdateValues.toSDT.balance);
UpdateValues.toSDT.balance += tokensChange;
console.log('#### exchanger1 token balance after: ' + UpdateValues.toSDT.balance);
//update values of exchanger2 token wallet
console.log('#### exchanger2 token balance before: ' + UpdateValues.fromSDT.balance);
UpdateValues.fromSDT.balance -= tokensChange;
console.log('#### exchanger2 token balance after: ' + UpdateValues.fromSDT.balance);

console.log(UpdateValues.cashValue + ' EUR exchanged to ' + tokensChange + ' SDT Tokens with actual rate of ' + UpdateValues.cashRate);

return getAssetRegistry('org.acme.biznet.SDTWallet')
    .then(function (assetRegistry) {
        return assetRegistry.updateAll([UpdateValues.toSDT,UpdateValues.fromSDT]);
    })                
    .then(function () {
        return  getAssetRegistry('org.acme.biznet.Account')
        .then(function (assetRegistry) {
            return assetRegistry.updateAll([UpdateValues.toCash,UpdateValues.fromCash]); 
        });            
    });     
}

和permissions.acl:

//****************PROVIDER_PARTICIPANTS**********************

//Provider has access only to their own profile
rule ProviderAccessOwnProfile {
description: "Allow providers to access only their profile"
participant(p): "org.acme.biznet.Provider"
operation: READ, UPDATE
resource(r): "org.acme.biznet.Provider"
condition: (r.getIdentifier() === p.getIdentifier())
action: ALLOW
}

//Provider has read only access to other Providers
rule ProviderReadAccessProviders {
description: "Allow provider read access to other providers"
participant: "org.acme.biznet.Provider"
operation: READ
resource: "org.acme.biznet.Provider"
action: ALLOW
}

//****************PROVIDER_ASSETS**********************

rule ProvidersReadAccesstoAccount {
description: "Traders see their own BankAccount only"
participant: "org.acme.biznet.Provider"
operation: READ
resource: "org.acme.biznet.Account"
action: ALLOW
}

rule ProvidersReadAccesstoSDTWallet {
description: "Providers see their own SDT Wallet only"
participant: "org.acme.biznet.Provider"
operation: READ
resource: "org.acme.biznet.SDTWallet"
action: ALLOW
}

//Provider can submit CashToToken transaction
rule ProvidercanUpdateAccountthroughTransactionOnly {
        description: "Allow trader to submit trade transactions"
        participant(p): "org.acme.biznet.Provider"
        operation: READ, UPDATE
        resource(r): "org.acme.biznet.Account"
        transaction(tx): "org.acme.biznet.TradeCashToTokens"
        condition: (p.getIdentifier() === r.owner.getIdentifier() && 
r.getIdentifier() === tx.toCash.getIdentifier())
        action: ALLOW
}

//Provider can submit CashToToken transaction
rule ProvidercanUpdateSDTWalletthroughTransactionOnly {
        description: "Allow trader to submit trade transactions"
        participant(p): "org.acme.biznet.Provider"
        operation: READ, UPDATE
        resource(r): "org.acme.biznet.SDTWallet"
        transaction(tx): "org.acme.biznet.TradeCashToTokens"
        condition: (p.getIdentifier() === r.owner.getIdentifier() && 
 r.getIdentifier() === tx.fromSDT.getIdentifier())
        action: ALLOW
 }


//****************PROVIDER_TRANSACTIONS**********************

//Provider can submit CashToTokens transaction
rule ProviderSubmitCashToTokenTransactions {
description: "Allow provider to submit cash to tokens transactions"
participant: "org.acme.biznet.Provider"
operation: CREATE, READ
resource: "org.acme.biznet.TradeCashToTokens"
action: ALLOW
}

//Provider can submit TokenToCash transaction
rule ProviderSubmitTokensToCashTransactions {
description: "Allow provider to submit tokens to cash transactions"
participant: "org.acme.biznet.Provider"
operation: CREATE, READ
resource: "org.acme.biznet.TradeTokensToCash"
action: ALLOW
}

//****************PROVIDER_HISTORY**********************

//Provider can see the history of own transactions only
rule ProviderSeeOwnHistoryOnly {
description: "Proviers should be able to see the history of their own 
transactions only"
participant(p): "org.acme.biznet.Provider"
operation: READ
resource(r): "org.hyperledger.composer.system.HistorianRecord"
condition: (r.participantInvoking.getIdentifier() != p.getIdentifier())
action: DENY
}

//*********************NETWORK***************************
rule SystemACL {
description:  "System ACL to permit all access"
participant: "org.hyperledger.composer.system.Participant"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}

rule NetworkAdminUser {
description: "Grant business network administrators full access to user 
resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "**"
action: ALLOW
}

rule NetworkAdminSystem {
description: "Grant business network administrators full access to system 
resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}

当我想尝试将交易作为提供者时,例如TradeCachToTokens,它说t: Participant 'org.acme.biznet.Provider#P1' does not have 'UPDATE' access to resource 'org.acme.biznet.SDTWallet#SDT1'

请参阅屏幕截图:cash_to_tokens

提供商(P1)应该获得电子钱包和账户的UPDATE访问权限,如果他进行交易,而不仅仅是他自己的交易(对于他的对方(P2))。

这里的问题是什么?

1 个答案:

答案 0 :(得分:0)

更新答案:答案是(5月10日):

  1. 您正在更新注册管理机构org.acme.biznet.SDTWalletorg.acme.bixnet.Account - 我发现您有规则允许从事务TradeCashToTokensTradeTokensToCash进行更新。我认为问题是条件应该是||而不是&amp;&amp; - 一次评估一个资源,并且资源所有者在条件匹配中可以为TRUE。由于参与者调用了trxn,因此应始终评估为TRUE(除非他当然不是资源所有者),条件的A部分;对于目标资源(toCashtoSDT),您将其与资源所有者进行比较(在事务功能代码中更新 - 如上所述)。请注意,规则是​​基于允许调用参与者更新2个目标资源(基于参与者,而不是帐户 - ps我认为您的SDT规则失败的原因是因为规则说明来自SDT&#39; ;(仅评估一个目标资源)。

    建议一组规则,如:

    
    
    rule UpdateAccountsviaTradeCashToTokens {
        description: "Allow source/target providers defined in trxn (ie 2)- to access/update their Accounts from, trxn TradeCashToTokens only"
        participant(p): "org.acme.biznet.Provider"
        operation: READ, UPDATE
        resource(r): "org.acme.biznet.Account"
        transaction(tx): "org.acme.biznet.TradeCashToTokens"
        condition: ( p.getIdentifier() === r.owner.getIdentifier() || tx.toCash.owner.getIdentifier()  === r.owner.getIdentifier() )
        action: ALLOW
    }
    
    
    rule UpdateSDTWalletsviaTradeCashToTokens {
        description: "Allow source/target providers defined in trxn (ie 2)- to access/update their SDT Wallets from, trxn TradeCashToTokens only"
        participant(p): "org.acme.biznet.Provider"
        operation: READ, UPDATE
        resource(r): "org.acme.biznet.SDTWallet"
        transaction(tx): "org.acme.biznet.TradeCashToTokens"
        condition: ( p.getIdentifier() === r.owner.getIdentifier() || tx.toSDT.owner.getIdentifier()  === r.owner.getIdentifier() ) 
        action: ALLOW
    }
    
  2. 同样 - 对于另一个交易TradeTokenstoCash,您可以

    
    rule UpdateAccountsviaTradeTokensToCash {
        description: "Allow source/target providers defined in trxn (ie 2)- to access/update their Accounts from, trxn TradeTokensToCash only"
        participant(p): "org.acme.biznet.Provider"
        operation: READ, UPDATE
        resource(r): "org.acme.biznet.Account"
        transaction(tx): "org.acme.biznet.TradeTokensToCash"
        condition: ( p.getIdentifier() === r.owner.getIdentifier() || tx.toCash.owner.getIdentifier()  === r.owner.getIdentifier() )
        action: ALLOW
    }
    
    rule UpdateSDTWalletsviaTradeTokenstoCash {
        description: "Allow source/target providers defined in trxn (ie 2)- to access/update their SDT Wallets from, trxn TradeTokenstoCash only"
        participant(p): "org.acme.biznet.Provider"
        operation: READ, UPDATE
        resource(r): "org.acme.biznet.SDTWallet"
        transaction(tx): "org.acme.biznet.TradeTokenstoCash"
        condition: ( p.getIdentifier() === r.owner.getIdentifier() ||  tx.toSDT.owner.getIdentifier()  === r.owner.getIdentifier() )
        action: ALLOW
    }
    
    
    
  3. 您仍需要PROVIDER_TRANSACTIONS规则。

  4. 在基于交易更新的规则(如上所述)之前,你说你需要PROVIDER_ASSETS规则是正确的。

  5. 我已经创建了一个ACL教程 - 我将在适当的时候将其纳入Composer文档中(为了其他人的利益) - 类似于您所做的。

  6. https://github.com/mahoney1/test/blob/master/acl_dynamic.md

    希望这会有所帮助,尝试使用更改完整的规则集并且可以正常工作;如果您希望我发布完整的规则,请告诉我。