1. 程式人生 > >fabric原始碼閱讀第一篇

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支援的演算法。如果上面有什麼不妥的地方,請指正,謝謝