美文网首页区块链研究区块链hyperledger fabric
Hyperledger Fabric 1.3 特性调研之key

Hyperledger Fabric 1.3 特性调研之key

作者: RaeSnow | 来源:发表于2019-07-07 22:29 被阅读2次

    Fabric原先一直使用chaincode level的背书策略,即在合约实例化或者升级的时候指定背书策略。
    现在新增一种针对key设置背书策略的方法,key level背书策略生效后会覆盖chaincode level的背书策略。

    适用场景

    对于合约中某些记录的变更,原有的背书策略不能完全满足其要求,需要特殊的背书策略进行约束。比如车辆交易中,一般车辆的交易只需要交易双方的背书即可,但是如果某辆汽车具有一定的历史意义,则可能还需要鉴定人员的背书【例子源自官网】。

    技术实现

    合约提供的接口针对key设置背书策略,key level背书策略生效后会覆盖chaincode level的背书策略。如果key level背书策略移除,则会重新使用chaincode level背书策略。

    具体代码实现上,验证区块的时候使用如下结构体,对区块中交易的读写集进行背书策略检查:

    // StateBasedValidator is used to validate a transaction that performs changes to
    // KVS keys that use key-level endorsement policies. This interface is supposed to be called
    // by any validator plugin (including the default validator plugin). The functions of this
    // interface are to be called as follows:
    // 1) the validator plugin calls PreValidate (even before determining whether the transaction is
    //    valid)
    // 2) the validator plugin calls Validate before or after having determined the validity of the
    //    transaction based on other considerations
    // 3) the validator plugin determines the overall validity of the transaction and then calls
    //    PostValidate
    type StateBasedValidator interface {
        // PreValidate sets the internal data structures of the validator needed before validation
        // of transaction `txNum` in the specified block can proceed
        PreValidate(txNum uint64, block *common.Block)
    
        // Validate determines whether the transaction on the specified channel at the specified height
        // is valid according to its chaincode-level endorsement policy and any key-level validation
        // parametres
        Validate(cc string, blockNum, txNum uint64, rwset, prp, ep []byte, endorsements []*peer.Endorsement) commonerrors.TxValidationError
    
        // PostValidate sets the internal data structures of the validator needed after the validation
        // code was determined for a transaction on the specified channel at the specified height
        PostValidate(cc string, blockNum, txNum uint64, err error)
    }
    

    其中Validate函数使用checkSBAndCCEP函数检查key的背书策略,首先会获取key level的背书策略进行检查,如果没有设置则使用chaincode level的背书策略。

    接口

    合约可以使用如下函数对key设置背书策略:

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

    可以使用如下函数对私密数据设置背书策略:

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

    背书策略的配置可以使用如下接口:

    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)
    }
    

    实际操作

    【此处使用fabric-sample中提供的interest_rate_swaps示例进行说明,代码稍加改动】

    合约通过如下代码对audit_limit设置背书策略,只允许指定身份的peer对其进行背书。即如需再对audit_limit进行修改,必须由该peer进行背书;查询audit_limit的值,任何安装合约的peer都可以。

    err := stub.PutState("audit_limit", args[2])if err != nil {   return shim.Error(err.Error())}
    
    // 新建背书策略auditorEP, err := statebased.NewStateEP(nil)if err != nil {   return shim.Error(err.Error())}
    
    // 添加需要背书的组织成员,身份可以为RoleTypePeer或RoleTypeMember;
    // 如果添加了多个组织成员,则该背书策略需要所有这些成员的背书,即是AND关系err = auditorEP.AddOrgs(statebased.RoleTypePeer, string(args[1]))if err != nil {   return shim.Error(err.Error())}
    
    // 生成背书策略epBytes, err := auditorEP.Policy()if err != nil {   return shim.Error(err.Error())}
    
    // 为指定key添加key-level背书策略err = stub.SetStateValidationParameter("audit_limit", epBytes)if err != nil {   return shim.Error(err.Error())}
    

    client端发送交易时,需要指定对应的peer进行背书,用--peerAddress参数指定,如下所示:

    peer chaincode invoke -o irs-orderer:7050 -C irs --waitForEvent -n irscc --peerAddresses irs-rrprovider:7051 -c '{"Args":["setReferenceRate","myrr","300"]}'
    

    如果需要多个peer进行背书,可以用--peerAddress参数指定多个peer,如下所示:

    peer chaincode invoke -o irs-orderer:7050 -C irs --waitForEvent -n irscc --peerAddresses irs-partya:7051 --peerAddresses irs-partyb:7051 --peerAddresses irs-auditor:7051 -c '{"Args":["createSwap","myswap","{\"StartDate\":\"2018-09-27T15:04:05Z\",\"EndDate\":\"2018-09-30T15:04:05Z\",\"PaymentInterval\":395,\"PrincipalAmount\":10,\"FixedRate\":400,\"FloatingRate\":500,\"ReferenceRate\":\"myrr\"}", "partya", "partyb"]}'
    

    如果指定的peer不满足key level背书策略时会出现ENDORSEMENT_POLICY_FAILURE错误,交易仍会被写入区块,但是交易无效。如下所示:

    // 查看区块高度为8
    root@177bc827f9f5:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel getinfo -c irs
    2019-06-04 03:24:17.241 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
    Blockchain info: {"height":8,"currentBlockHash":"EcyCJc20MKN1oRposS/epixmIz9FNkVHPC5OlylLC5U=","previousBlockHash":"6+1+vatI334Y3KkaLSEMZBEXcNxEVtSJ5duj0VWtcfw="}
    
    // 使用不正确的peer背书,交易状态为ENDORSEMENT_POLICY_FAILURE,显示invoke成功
    root@177bc827f9f5:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode invoke -o irs-orderer:7050 -C irs --waitForEvent -n irscc --peerAddresses irs-partya:7051 -c '{"Args":["setReferenceRate","myrr","200"]}'
    2019-06-04 03:24:29.277 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [1424925664ebad2d2ce39e31e02c83b74d98d080a01acdac07f35284360f73ea] committed with status (ENDORSEMENT_POLICY_FAILURE) at irs-partya:7051
    2019-06-04 03:24:29.279 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 002 Chaincode invoke successful. result: status:200
    
    // 查询区块高度为9,说明交易写入区块
    root@177bc827f9f5:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel getinfo -c irs
    2019-06-04 03:24:31.934 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
    Blockchain info: {"height":9,"currentBlockHash":"+bzi7o1Gk6h1dkYVI690ZKlNzTsDI3k2WCT/DQFpt+4=","previousBlockHash":"EcyCJc20MKN1oRposS/epixmIz9FNkVHPC5OlylLC5U="}
    
    // 查看key的值,并没有被更改
    root@177bc827f9f5:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C irs -n irscc --peerAddresses irs-partya:7051 -c '{"Args":["getReferenceRate","myrr"]}'
    300
    

    第一次设置key level背书策略时,必须满足chaincode level的背书策略;以后对key level背书策略进行修改时,必须满足先前的key level背书策略。即key level背书策略生效后会覆盖chaincode level的背书策略。
    将key level背书策略设置为nil时,chaincode level背书策略重新生效,代码如下:

    err := stub.SetStateValidationParameter(key, nil)
    if err != nil {
        return shim.Error(err.Error())
    }
    

    Fabric 1.4的功能改进

    私密数据的功能改进主要包括以下两点:

    • 对账:新加入collection的节点可以获取该collection先前交易的私密数据。
    • 客户端权限控制:增加对client身份的验证:增加memberOnlyRead参数,设置为true时可以限制只有属于collection的组织的client才可以读取数据。

    相关文章

      网友评论

        本文标题:Hyperledger Fabric 1.3 特性调研之key

        本文链接:https://www.haomeiwen.com/subject/xptwhctx.html