前言
從這一節開始,我將開始以太坊代碼全覆蓋講解,講解的流程是:
- 以太坊程序入口
- 基本框架
- 以太坊協議
- 挖礦
- 發送一筆交易後發生了什麼
- 以太坊共識
- p2p 網絡
閱讀本系列文章,將默認讀者具備一定的程序基礎,並對 Go 語言特性有一定的瞭解。如有需要,請自行翻閱 Go 語言相關文檔。go 語言中文網點擊這裏
此外,爲便於更好的理解以太坊運行機制,會在開始少量的介紹一下Go 包 gopkg.in/urfave/cli.v1
。話不多說,現在開始。
一、以太坊程序入口
以太坊的主程是編譯出來的 geth
程序運行時,程序入口跟所有的編譯語言一樣,都是從 main 函數進入。
進入 main 函數路徑:go-ethereum/cmd/geth/main.go,找到 main 函數
func main() {
if err := app.Run(os.Args); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
從這裏,我們就已經進入了閱讀以太坊源碼的主流程中。我們看到函數很簡單,執行 app.Run
函數,如果函數返回錯誤,輸出錯誤,並退出。
熟悉其他主流語言的你看到這裏就會想了,main 中沒有 app 這個變量,難道它是全局變量?是的,不過 go 語言更復雜一點,它類似 C++/ Java / Python 語言的集合體。這些先不不管,找到 app
對象。
app = utils.NewApp(gitCommit, "the go-ethereum command line interface")
繼續進去看
// NewApp creates a new cli Application with some reasonable defaults for Name,
// Usage, Version and Action.
func NewApp() *App {
return &App{
Name: filepath.Base(os.Args[0]),
HelpName: filepath.Base(os.Args[0]),
Usage: "A new cli application",
UsageText: "",
Version: "0.0.0",
BashComplete: DefaultAppComplete,
Action: helpCommand.Action,
Compiled: compileTime(),
Writer: os.Stdout,
}
}
原來,app
對象是 App 類型的指針,而 App 結構體在 gopkg.in/urfave/cli.v1
包中定義,是 app 程序的一系列封裝。這裏我們不展開。