fabric原始碼閱讀第一篇
fabric的現在是國內做的最多的,但是沒有實際的應用落地,所以我作為一個初學者,原本是一個java的開發者,卻為了一窺究竟,直接轉go了。
我們從git上獲得fabric的原始碼, 本機先要安裝git。安裝go sdk,程式設計工具用的是GoLand
gti clone https://github.com/hyperledger/fabric.git
然後我們開啟fabric的官方文件,我是沒有找到很好的方法,我就根據官網文件上的操作說明,一步一步的檢視原始碼,如果有更好的方法,請提供一下。
fabric的中文文件地址,根據這個文件差不多就可以
用GoLand開啟專案 專案結構如下:
然後我們再看一下fabric的中文文件,
我們第一步先看一下配置檔案的生成,以及證書的生成。
我們找到
這個目錄就是上面那個檔案所用的命令,這個資料夾包含 ca、csp、metadata、msp、idemixgen、protolator這幾個資料夾
所有的模組的起步都是main 方法。找到main.go檔案。找到main方法
kingpin是一個第三方的包,主要是用於生成cmd 命令。這個mian方法裡面包含 generate、extend、 showtemplate、vesion等方法。
我們看一下kingpin的在這裡是如何使用的。
在main方法上面定了一些變數。
其中生成了一個新的結構體 Application的物件,指定了名稱,並把他新增到一個執行命令的分組中,然後新增一下其他的引數資訊,提供幫助。
產生generate的命令,然後指定output引數,如果沒有,那麼預設值是crypto-config,引數型別是String,指定config的引數 預設的型別是FIle.
產生showtemplate命令,沒有任何引數
產生version命令 沒有任何引數
產生 ext命令 ,然後指定inputDir引數,預設值是crypto-config 型別是String,指定引數config,型別是File。
然後main方法中 解析獲得引數。為了自己更好的理解,特意做了一個例子加深理解:
func main() {
app:=kingpin.New("crptogen","command name")
gen:=app.Command("gen","generate key")//生成一個命令
a:=gen.Flag("param1","param1").String()//新增一個引數,型別string,返回的是這個引數的記憶體地址
//gen.Flag("param2","param2")
fmt.Println(">>>>",*a)//先輸出a的值
fmt.Println(kingpin.MustParse(app.Parse(os.Args[1:])))//解析引數命令,獲得命令名稱,以及所有的引數值
fmt.Println(">>>>",*a)//列印引數值
}
執行結果如下
我們回到正題,
看一下這個方法的具體實現,這個是所有的配置檔案生成的方法,
1.先獲得配置檔案getConfig方法
如果沒有傳檔案,那麼我們讀取預設配置檔案,然後通過yaml檔案解析。返回config 物件。
for _, orgSpec := range config.PeerOrgs {
err = renderOrgSpec(&orgSpec, "peer")
if err != nil {
fmt.Printf("Error processing peer configuration: %s", err)
os.Exit(-1)
}
generatePeerOrg(*outputDir, orgSpec)
}
找到配置檔案的標籤
迴圈所有的PeerOrgs標籤,然後呼叫生成所peerOrgder的單獨檔案
func renderOrgSpec(orgSpec *OrgSpec, prefix string) error {
// First process all of our templated nodes
for i := 0; i < orgSpec.Template.Count; i++ {//迴圈組織節點的個數
data := HostnameData{
Prefix: prefix,//字首
Index: i + orgSpec.Template.Start,//開始的座標
Domain: orgSpec.Domain,//組織域名
}
hostname, err := parseTemplateWithDefault(orgSpec.Template.Hostname, defaultHostnameTemplate, data)
//生成預設的模板
if err != nil {
return err
}
spec := NodeSpec{
Hostname: hostname,
SANS: orgSpec.Template.SANS,
}
orgSpec.Specs = append(orgSpec.Specs, spec)
//新增nodeSpec,構成樹
}
for idx, spec := range orgSpec.Specs {//迴圈所有的組織的Specs
err := renderNodeSpec(orgSpec.Domain, &spec)
if err != nil {
return err
}
orgSpec.Specs[idx] = spec
}
// Process the CA node-spec in the same manner
if len(orgSpec.CA.Hostname) == 0 {//如果組織描述中的CA的hostname為空,那麼就預設ca
orgSpec.CA.Hostname = "ca"
}
err := renderNodeSpec(orgSpec.Domain, &orgSpec.CA)//向模板中新增
if err != nil {
return err
}
return nil
上面主要講的是配置檔案的解析,下次要講證書,生成,以及fabric支援的演算法。如果上面有什麼不妥的地方,請指正,謝謝