Hyperledger Fabric 1.3 特性调研之key level 背书策略(二)

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才可以读取数据。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容