概述
自 Fabric-1.0 版本开始,链码分为系统链码和普通链码两种。
普通链码(或称之为业务链码、智能合约)用于实现用户项目业务逻辑,系统链码自是用于Fabric系统自身的逻辑,如系统状态管理、交易流程等。
普通链码需要独立沙盒环境来运行,而系统链码在 peer 服务启动时随 peer 节点注册,同 peer 节点一起运行。
Fabric-1.0 版本时, 有5 个系统链码:lscc、qscc、cscc、vscc、escc,这 5 个链码功能固定,分别用于链码生命周期管理、区块/交易查询、通道配置管理、交易背书策略和交易验证流程。
系统链码插件(system chaincode plugin)目前只支持使用 go 语言开发。
system chaincode 和普通 chaincode 一样,需要实现 Chaincode 接口。
type Chaincode interface {
Init(stub ChaincodeStubInterface) pb.Response
Invoke(stub ChaincodeStubInterface) pb.Response
}
与业务链码略微不同的是,由于是 go 的插件,所以这个系统链码的 go 源码必须属于 main 包。
系统链码可以在 peer 节点中与 peer 进程共同运行,不需要沙盒环境,它可以访问比普通 chaincode 更多的资源:比如本地数据、账本信息、配置信息,甚至链外信息。
可以通过系统链码来实现业务链码跟链外的交互,二者里外配合大幅提升智能合约的能力,使得业务链码不再受限于其所运行的沙盒环境。
编译
系统链码代码以 plugin 的形式编译。
go build -buildmode=plugin
GOPATH=/opt/gopath go build -buildmode=plugin -o stelscc.so stelscc.go
重新编译peer镜像
DOCKER_DYNAMIC_LINK=true GO_TAGS+=" pluginsenabled" make peer-docker
部署与配置
peer 服务配置文件core.yaml中,更新跟系统链码插件相关的两处配置:
chaincode.systemPlugin
配置节:系统链码的基本信息
chaincode:
systemPlugins:
- enabled: true
name: stelscc
path: /opt/lib/stelscc.so
invokableExternal: true
invokableCC2CC: true
chaincode.system
配置节:是否启用定制的系统链码
chaincode:
system:
stelscc: enable
注意事项
- ⇒ 系统链码程序的编译,需添加
pluginsenabled
编译选项; - ⇒ 插件编译所用的依赖包必须和主程序所用的依赖包版本相同。
- ⇒ 系统链码的调用生效是在链码模拟执行阶段,跟业务链码略微不同;
- ⇒ Fabric 系统链码构件化设计,可满足不同项目需要实现差异化定制,有效拓展合约的能力,能与链外资源进行交互(如ipfs等),打破业务链码的沙盒局限,实现更多资源的访问与控制。