# Fabric 1.1源代碼分析之 Fabric 1.1源代碼分析 系統(tǒng)鏈碼初始化過(guò)程
* 鏈碼這一塊的代碼非常的繞。基本上就是一個(gè)大循環(huán)。限于水平或者其它原因,差露可能難免,各位看官包涵則個(gè)...
## 1、系統(tǒng)鏈碼
* 系統(tǒng)鏈碼跟智能合約鏈碼涉及到的文件差不多,流程也差不多。只是智能合約是grpc,系統(tǒng)鏈碼是chan實(shí)現(xiàn)調(diào)用.
LSCC Lifecycle system chaincode,處理生命周期請(qǐng)求。我理解的生命周期請(qǐng)求應(yīng)該指的是一個(gè)chaincode的安裝,實(shí)例化,升級(jí),
卸載等對(duì)其生命周期起關(guān)鍵作用的一系列操作請(qǐng)求。
CSCC Configuration system chaincode,處理在peer程序端的channel配置。
QSCC Query system chaincode,提供賬本查詢接口,如獲取塊和交易信息。
ESCC Endorsement system chaincode,通過(guò)對(duì)交易申請(qǐng)的應(yīng)答信息進(jìn)行簽名,來(lái)提供背書功能。
VSCC Validation system chaincode,處理交易校驗(yàn),包括檢查背書策略和版本在并發(fā)時(shí)的控制。
## 2、系統(tǒng)鏈碼注冊(cè)
* 在/core/chaincode/shim/interfaces_stable.go中實(shí)現(xiàn)了下面的接口
```go
type Chaincode interface {
// Init is called during Instantiate transaction after the chaincode container
// has been established for the first time, allowing the chaincode to
// initialize its internal data
Init(stub ChaincodeStubInterface) pb.Response
// Invoke is called to update or query the ledger in a proposal transaction.
// Updated state variables are not committed to the ledger until the
// transaction is committed.
Invoke(stub ChaincodeStubInterface) pb.Response
}
```
* 在core/scc/sysccapi.go中定義了SystemChaincode結(jié)構(gòu)體,其中定義了 Chaincode接口變量
```go
type SystemChaincode struct {
//Unique name of the system chaincode
Name string
//Path to the system chaincode; currently not used
Path string
//InitArgs initialization arguments to startup the system chaincode
InitArgs [][]byte
// Chaincode is the actual chaincode object
Chaincode shim.Chaincode
// InvokableExternal keeps track of whether
// this system chaincode can be invoked
// through a proposal sent to this peer
InvokableExternal bool
// InvokableCC2CC keeps track of whether
// this system chaincode can be invoked
// by way of a chaincode-to-chaincode
// invocation
InvokableCC2CC bool
// Enabled a convenient switch to enable/disable system chaincode without
// having to remove entry from importsysccs.go
Enabled bool
}
```
* 在 core/scc/importsysccs.go文件中對(duì)系統(tǒng)鏈碼進(jìn)行了初始化,并且每個(gè)Chainoce指定了具體實(shí)現(xiàn)
在
```go
//see systemchaincode_test.go for an example using "sample_syscc"
var systemChaincodes = []*SystemChaincode{
{
Enabled: true,
Name: "cscc",
Path: "github.com/hyperledger/fabric/core/scc/cscc",
InitArgs: [][]byte{[]byte("")},
Chaincode: &cscc.PeerConfiger{},
InvokableExternal: true, // cscc is invoked to join a channel
},
{
Enabled: true,
Name: "lscc",
Path: "github.com/hyperledger/fabric/core/scc/lscc",
InitArgs: [][]byte{[]byte("")},
Chaincode: lscc.NewLifeCycleSysCC(),
InvokableExternal: true, // lscc is invoked to deploy new chaincodes
InvokableCC2CC: true, // lscc can be invoked by other chaincodes
},
{
Enabled: true,
Name: "escc",
Path: "github.com/hyperledger/fabric/core/scc/escc",
InitArgs: [][]byte{[]byte("")},
Chaincode: &escc.EndorserOneValidSignature{},
},
{
Enabled: true,
Name: "vscc",
Path: "github.com/hyperledger/fabric/core/scc/vscc",
InitArgs: [][]byte{[]byte("")},
Chaincode: &vscc.ValidatorOneValidSignature{},
},
{
Enabled: true,
Name: "qscc",
Path: "github.com/hyperledger/fabric/core/chaincode/qscc",
InitArgs: [][]byte{[]byte("")},
Chaincode: &qscc.LedgerQuerier{},
InvokableExternal: true, // qscc can be invoked to retrieve blocks
InvokableCC2CC: true, // qscc can be invoked to retrieve blocks also by a cc
},
}
```
* 注冊(cè)流程圖


## 3、系統(tǒng)鏈碼初始化
* 系統(tǒng)注冊(cè)完成后會(huì)對(duì)鏈碼初始化.跟一般chaincode稍有不同的是chaincode在合約里通過(guò)grpc與peer節(jié)點(diǎn)交互。
而系統(tǒng)鏈碼則是在協(xié)程里通過(guò)chan 實(shí)現(xiàn)交互.下面代碼創(chuàng)建兩個(gè) peerRcvCCSend := make(chan *pb.ChaincodeMessage)
ccRcvPeerSend := make(chan *pb.ChaincodeMessage) ,是客戶端和服務(wù)端共同的參數(shù)
```go
func (ipc *inprocContainer) launchInProc(ctxt context.Context, id string, args []string, env []string, ccSupport ccintf.CCSupport) error {
peerRcvCCSend := make(chan *pb.ChaincodeMessage)
ccRcvPeerSend := make(chan *pb.ChaincodeMessage)
var err error
ccchan := make(chan struct{}, 1)
ccsupportchan := make(chan struct{}, 1)
//啟動(dòng)客戶端處理
go func() {
defer close(ccchan)
inprocLogger.Debugf("chaincode started for %s", id)
if args == nil {
args = ipc.args
}
if env == nil {
env = ipc.env
}
err := _shimStartInProc(env, args, ipc.chaincode, ccRcvPeerSend, peerRcvCCSend)
if err != nil {
err = fmt.Errorf("chaincode-support ended with err: %s", err)
_inprocLoggerErrorf("%s", err)
}
inprocLogger.Debugf("chaincode ended with for %s with err: %s", id, err)
}()
//啟動(dòng)服務(wù)端處理
go func() {
defer close(ccsupportchan)
inprocStream := newInProcStream(peerRcvCCSend, ccRcvPeerSend)
inprocLogger.Debugf("chaincode-support started for %s", id)
err := ccSupport.HandleChaincodeStream(ctxt, inprocStream)
if err != nil {
err = fmt.Errorf("chaincode ended with err: %s", err)
_inprocLoggerErrorf("%s", err)
}
inprocLogger.Debugf("chaincode-support ended with for %s with err: %s", id, err)
}()
select {
case <-ccchan:
close(peerRcvCCSend)
inprocLogger.Debugf("chaincode %s quit", id)
case <-ccsupportchan:
close(ccRcvPeerSend)
inprocLogger.Debugf("chaincode support %s quit", id)
case <-ipc.stopChan:
close(ccRcvPeerSend)
close(peerRcvCCSend)
inprocLogger.Debugf("chaincode %s stopped", id)
}
return err
}
```
* 初始化流程圖


## 4、系統(tǒng)鏈碼的執(zhí)行
...