简介
chaincode即用户链码,它提供了基于区块链分布式账本的状态处理逻辑。
fabric中,chaincode默认运行在docker容器中。
peer通过调用docker api来创建和启动chaincode容器。
chaincode容器启动后跟peer之间创建gRPC连接,双方通过发送ChaincodeMessage来进行交互通信。
chaincode容器利用core.chaincode.shim包提供的接口来向Peer发起请求。
chaincode典型结构
用户只需关注Init()和Invoke()函数的实现,在其中利用shim.ChaincodeStubInterface结构实现跟账本的交互逻辑。
package main
import (
"errors"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
)
type DemoChaincode struct { }
func (t *DemoChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
// more logics using stub here
return stub.Success(nil)
}
func (t *DemoChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response
// more logics using stub here
return stub.Success(nil)
}
func main() {
err := shim.Start(new(DemoChaincode))
if err != nil {
fmt.Printf("Error starting DemoChaincode: %s", err)
}
}
启动过程
chaincode首先是个普通的golang程序,其main方法调用了shim层的Start方法。
首先会进行初始化,包括读取默认配置,创建到Peer的gRPC连接。
主要包括NewChaincodeSupportClient和chaincodeSupportClient.Register两个方法。
初始化完成后,创建有限状态机结构(FSM,github.com/looplab/fsm)。
FSM会根据收到的消息和当前状态来触发状态转移,并执行提前设置的操作。
Peer侧也利用了类似的FSM结构来管理消息响应。
之后,利用创建好的gRPC连接开始向Peer发送第一个gRPC消息:ChaincodeMessage_REGISTER,将自身注册到Peer上。
注册成功后开始消息处理循环,等待接收来自Peer的消息以及自身的状态转移(nextState)消息。
后续过程中,chaincode和Peer利用FSM完成一系列对消息的响应运作:
1、Peer收到来自链码容器的ChaincodeMessage_REGISTER消息,将其注册到本地的一个Handler结构,返回ChaincodeMessage_REGISTERD消息发给链码容器。
之后更新状态为established(已建立),并发送ChaincodeMessage_READY消息给链码侧,更新状态为ready。
2、链码侧收到ChaincodeMessage_REGISTERD消息后,不进行任何操作,注册成功,更新状态为established(已建立)。
收到ChaincodeMessage_READY消息后更新状态为ready。
3、Peer侧发出ChaincodeMessage_INIT消息给链码容器,准备触发链码侧初始化操作。
4、链码容器收到ChaincodeMessage_INIT消息,通过Handler.handleInit()方法进行初始化。
主要包括初始化所需的ChaincodeStub结构,以及调用链码代码中Init()方法。初始化成功后,返回ChaincodeMessage_COMPLETED消息给Peer。
此时链码容器进入可被调用(Invoke)状态。
5、链码被调用时,Peer发出ChaincodeMessage_TRANSACTION消息给链码。
6、链码收到ChaincodeMessage_TRANSACTION消息,会调用Invoke()方法。
根据Invoke方法中用户实现的逻辑,可以发出包括ChaincodeMessage_GET_HISTORY_FOR_KEY、ChaincodeMessage_GET_QUERY_RESULT、
ChaincodeMessage_GET_STATE、ChaincodeMessage_GET_STATE_BY_RANGE、ChaincodeMessage_QUERY_STATE_CLOSE、
ChaincodeMessage_QUERY_STATE_NEXT、ChaincodeMessage_INVOKE_CHAINCODE等消息给Peer侧。
Peer侧收到这些消息,进行相应处理,并回复ChaincodeMessage_RESPONSE消息。
最后链码侧会回复调用完成的消息ChaincodeMessage_COMPLETE给Peer侧。
在上述过程中,Peer和链码还会不定期发送ChaincodeMessage_KEEPALIVE消息给对方,以确保在线。
相关文档
https://github.com/yeasy/hyperledger_code_fabric/blob/master/process/chaincode_start.md
有疑问加站长微信联系(非本文作者)