Hyperledger fabric智能合约编写(三)背书策略

1、背书策略概念

节点通过背书策略来确定一个交易是否被正确背书。当一个peer接受一个交易后,就会调用与该交易Chaincode相关的VSCC(Validation System Chaincode)作为交易验证流程的一部分,确认交易的有效性。因此,一个交易包含一个或者多个来自背书节点的背书,VSCC的背书校验包括:

  • 所有的背书都是有效的(即有效证书做的有效签名)
  • 满足要求的背书数量
  • 背书来自预期的背书节点

本文提到的背书策略则是用于约束上述校验中的第二和第三点。

每一个链码都有一个背书策略,其规定了channel上执行chaincode的节点们必须都认可(背书)执行结果,交易才能被视为有效。背书策略定义了需要哪些组织的认可(背书)才能执行交易。

作为节点执行交易验证步骤时,每个节点都要检查交易是否包括满足策略要求数量的背书,以及这些背书是否来自指定的来源(上文VSCC的背书校验规定2和3)。此外还要检查交易中背书是否有效(即是否来自有效证书的有效签名,上文VSCC的背书校验规定1)

2、Fabric中三种粒度的背书策略

根据Fabric2.0后的官方文档,背书策略共分为以下三类

  • 链码级背书策略
  • 集合级背书策略
  • 键值级背书策略

2.1 如何使用链码级背书策略?

当通道成员为其组织批准链码定义时批准链码级背书策略。需要满足足够数量的通道成员批准链码定义以满足通道背书策略Channel/Application/Endorsement(默认设置为大多数通道成员),定义才能提交到通道。定义提交后,chaincode即可以使用,任何向账本中写入数据的链码调用都需要经过满足数量的通道郑源验证,来满足背书策略的要求。

在使用 Fabric 对等二进制文件批准和提交链码定义时,您可以使用 --signature-policy 标志从 CLI 创建背书策略。

PS:背书策略语法(Org1MSP.member等)将在下一节详细介绍。

peer lifecycle chaincode approveformyorg --channelID mychannel --signature-policy "AND('Org1MSP.member', 'Org2MSP.member')" --name mycc --version 1.0 --package-id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent

上述命令通过AND(Org1MSP.memberOrg2MSP.member)策略批准了mycc的链码定义,该策略要求Org1和Org2均有一名成员签署交易。在足够多的通道成员批准mycc的链码定义后,可以使用一下命令将链码定义和背书策略提交到通道:

peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --signature-policy "AND('Org1MSP.member', 'Org2MSP.member')" --name mycc --version 1.0 --sequence 1 --init-required --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

PS: 如果启用了身份分类,可以进行更细粒度的访问控制和权限管理,比如使用 peer 角色来限制背书仅限于 peer,如:

peer lifecycle chaincode approveformyorg --channelID mychannel --signature-policy "AND('Org1MSP.peer', 'Org2MSP.peer')" --name mycc --version 1.0 --package-id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent

除了通过CLI或SDK指定背书策略外,链码还可以使用通道配置中的策略作为背书策略。如–channel-config-policy标志来选择通道配置和ACLs使用的通道策略,如:

peer lifecycle chaincode approveformyorg --channelID mychannel --channel-config-policy Channel/Application/Admins --name mycc --version 1.0 --package-id mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 --sequence 1 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent

2.2 链码级背书策略的更新

如果不指定策略,链码定义将默认使用Channel/Application/Endorsement策略,即要求交易由大多数通道成员验证。该策略取决于通道成员,因此当组织从通道中删除会添加成员时,该策略会自动更新。

如果使用 --signature-policy 指定背书策略,则需要在组织加入或离开通道时更新策略。在链码定义后加入通道的新组织可以查询链码(前提是查询具有通道策略定义的适当授权和链码执行的任何应用级检查),但不能执行或背书链码。只有背书策略语法中列出的组织才能签署交易。

2.3、背书策略语法

策略是以principals(与角色匹配的身份)来表示的。即MSP.ROLE,其中MSP代表所需的MSP ID,ROLE代表以下四种角色之一:member, admin, client, and peer

例如:
Org0MSP.admin:Org0MSP的任何管理员
Org1MSP.member:Org1MSP的任何成员
Org1MSP.client:Org1MSP的任何客户
Org1MSP.peer:Org1MSP的任何节点

该语言的语法是:EXPR(E[, E...])

其中:EXPR是AND,OR,OutOf,E是principal或另一个EXPR的嵌套调用

例如:

  • AND('Org1MSP.member','Org2MSP.member','Org3MSP.member')要求三个组织成员各签一次。
  • OR('Org1MSP.member','Org2MSP.member','Org3MSP.member')要求两个组织成员中的任何一个签一次。
  • OR('Org1MSP.member',AND('Org2MSP.member','Org3MSP.member'))要求组织1的人员签名,或者组织2和3的人员各签一次。
  • OutOf('Org1MSP.member','Org2MSP.member')OR('Org1MSP.member', 'Org2MSP.member')相同
  • 同样的OutOf(2, 'Org1MSP.member', 'Org2MSP.member')等同于AND('Org1MSP.member', 'Org2MSP.member'),并且OutOf(2, 'Org1MSP.member', 'Org2.member', 'Org3.member')等同于OR(AND('Org1MSP.member', 'Org2MSP.member'), AND('Org1MSP.member', 'Org3MSP.member'), AND('Org2MSP.member', 'Org3MSP.member'))

2.4、集合级背书策略

与链码级背书策略类似,在批准和提交链码定义时,也可以指定链码的私有数据集合和相应的集合级背书策略。如果设置了集合级认可策略,写入私有数据集合密钥的事务将要求指定的组织节点认可(背书)该事务。

可以使用集合级背书策略来限制哪些组织节点可以写入私有数据集合Key namespace,例如,确保非授权组织不能写入集合,并确信私有数据集合中的任何状态都已获得所需集合组织的背书。

同链码级背书策略相比,集合级背书策略限制性更小些,我们可以二者结合使用,比如即要求大多数组织认可(背书)链码交易,也要求特定组织认可(背书)包含特定集合Key的交易。

如果不指定集合级背书策略,则将使用链码级背书策略来保护对私有数据集合密钥命名空间的写入。如果一组符合链码级背书策略的组织被授权在其他组织的私有数据集中创建数据,是可行的。

集合级背书策略的语法与链码级背书策略的语法完全相同–在集合配置中,您可以用签名策略(signaturePolicy)或通道配置策略(channelConfigPolicy)指定背书策略。

2.5 键值级背书策略

设置常规链码级或集合级背书策略与相应链码的生命周期相关。只有在通道上定义链码时才能设置或修改它们。相比之下,键值级背书策略可以在链码中以更精细的方式进行设置和修改。

shim API 提供以下功能,用于设置和检索键值级背书策略。用ep来代表上文中的背书策略语法,生成二进制版本的背书策略,可供基本的 shim API 使用。
对于账本的键值,提供以下接口:

SetStateValidationParameter(key string, ep []byte) error
GetStateValidationParameter(key string) ([]byte, error)

对于私有数据的键值,提供以下接口:

SetPrivateDataValidationParameter(collection, key string, ep []byte) error
GetPrivateDataValidationParameter(collection, key string) ([]byte, error)

为了助于设置背书策略并将其应用到验证中,Go shim提供了一个便于使用的扩展接口KeyEndorsementPolicy ,允许链码开发人员根据组织的MSP标识符来处理背书策略,如:

type KeyEndorsementPolicy interface {
    // Policy returns the endorsement policy as bytes
    Policy() ([]byte, error)

    // AddOrgs adds the specified orgs to the list of orgs that are required
    // to endorse
    AddOrgs(roleType RoleType, organizations ...string) error

    // DelOrgs delete the specified channel orgs from the existing key-level endorsement
    // policy for this KVS key. If any org is not present, an error will be returned.
    DelOrgs(organizations ...string) error

    // ListOrgs returns an array of channel orgs that are required to endorse changes
    ListOrgs() ([]string)
}

比如,设置需要两个特定组织背书的键值级背书策略,可将两个组织的MSPID传递给AddOrgs(),然后调用Policy()构造认可策略的字节数组,并将其传递给SetStateValidationParameter()

2.6 背书策略生效优先级

在提交时,设置Key的值与设置Key的背书策略并无不同–两者都会更新Key的状态,并根据相同的规则进行验证。

验证无键值级背书策略有键值级背书策略
修改值检查链码级背书策略或集合级背书策略检查键值级背书策略
修改键值级背书策略检查链码级背书策略或集合级背书策略检查键值级背书策略

如果键值被修改且存在键值级背书策略,则键值级背书策略优先于链码级或集合级背书策略。
如果删除了某个键值的背书策略(设置为零),链码级或集合级背书策略将重新成为默认策略。

如果一个交易修改了具有不同关联键值级背书策略的多个键,则需要满足所有键值级策略才能使交易有效。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值