Chaincode(1.4的目录结构)
fabric/examples/chaincode/go
├── example02 #一个简单的转账合约
├── eventsender #发送事件通知
├── passthru #调用其他链码(或者其他channel的链码)
一个简单的转账合约。该链码简单实现了两方的转账功能,很适合初学者上手。
展示如何在链码中发送事件通知,以进行交易确认或审计
注意: 每笔交易只能发送一个事件
stub.SetEvent("evtsender", []byte(tosend))
该链码实现了一个简单的链码“网关”,其对外暴露的Invoke接口允许用户调用其他链码(指定ID、方法和参数),并将调用结果返回用户。
调用其他链码需要使用stub.InvokeChaincode
方法。该方法用于调用另一个链码中的Invoke方法,格式为:
InvokeChaincode(chaincodeName string,args[][]byte,channel string)pb.Response
其中,chaincodeName为链码ID;args为调用参数;channel为调用的链码所在通道。如果channel为空,则默认为当前通道。
注意,stub.InvokeChaincode
方法目前仅限于读操作,同时不会生成新的交易。
fabric-samples/chaincode/README.md
├── abac #基于属性的权限控制
├── marbles02 #资产权属管理 (包含 分页范围查询 的用例)
├── marbles02_private #私密数据(允许通道内指定若干组织访问特定私密数据)
以大理石的权属管理为例,介绍如何在链码中定义资产,以及资产的创建、查询、转移所有权等操作。
fabric基于证书属性的权限控制, 官方有使用案例
v1.4.8 https://github.com/hyperledger/fabric-samples/tree/v1.4.8/chaincode/abac
v2.2.1 https://github.com/hyperledger/fabric-samples/tree/v2.2.1/asset-transfer-abac
展示如何在链码中利用证书属性对访问权限进行细粒度控制
链码中进行权限控制需要通过客户端身份库github.com/hyperledger/fabric-chaincode-go/pkg/cid
. 该库提供了获取调用者的MSP ID和身份属性的相关方法
通过调用cid.AssertAttributeValue
方法,确定调用者是否有abac.init
属性。调用者的属性是通过Fabric CA
进行添加的
#通过sdk注册时添加属性
fabric-ca-client register ... --id.attrs 'abac.init=true'
#合约中检查
cid.AssertAttributeValue(stub, "abac.init", "true")
fabric支持私密数据的合约功能, 官方有使用案例
v1.4.8 https://github.com/hyperledger/fabric-samples/tree/v1.4.8/chaincode/marbles02_private
v2.2.1 https://github.com/hyperledger/fabric-samples/tree/v2.2.1/chaincode/marbles02_private
Fabric 1.2版本引入了私密数据功能,允许通道内指定若干组织访问特定私密数据。通过示例介绍如何在链码中使用私密数据
[
{
"name": "collectionMarbles",
"policy": "OR('Org1MSP.member', 'Org2MSP.member')",
"requiredPeerCount": 0,
"maxPeerCount": 3,
"blockToLive":1000000,
"memberOnlyRead": true
},
{
"name": "collectionMarblePrivateDetails",
"policy": "OR('Org1MSP.member')",
"requiredPeerCount": 0,
"maxPeerCount": 3,
"blockToLive":3,
"memberOnlyRead": true
}
]
stub.PutPrivateData
stub.GetPrivateData
在 chaincode更新代码后,需要把新的代码通过install交易安装到正在运行该 chaincode的 peer 上,安装时需注明比先前版本更高的版本号,接下来向任意一个安装了新代码的 peer 发送 upgrade 交易就能更新 chaincode,chaincode 在更新前的状态也会得到保留。
Init
函数会被调用以执行数据相关的操作,或者重新初始化数据;所以要多加小心避免在升级chaincode时重设状态信息。基本每个都是痛点。尤其背书策略的升级,这是目前链码管理最为人诟病的地方。背书策略在链码实例化时指定,一旦通道成员发生变化就必须更新背书策略,而更新背书策略又需要所有成员进行链码升级。现在一个默认的背书策略就可以解决所有问题,有特殊背书需求,也可以仅升级背书策略就行。而去中心化的链码部署/升级过程也更加的”区块链“了,不再是一言堂。