版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 11/11兄弟連Go語(yǔ)言+區(qū)鏈技術(shù)培訓(xùn)以太坊源碼分析(39)geth啟動(dòng)流程分析geth是我們的go-ethereum最主要的一個(gè)命令行工具。 也是我們的各種網(wǎng)絡(luò)的接入點(diǎn)(主網(wǎng)絡(luò)main-net 測(cè)試網(wǎng)絡(luò)test-net 和私有網(wǎng)絡(luò))。支持運(yùn)行在全節(jié)點(diǎn)模式或者輕量級(jí)節(jié)點(diǎn)模式。 其他程序可以通過(guò)它暴露的JSON RPC調(diào)用來(lái)訪問(wèn)以太坊網(wǎng)絡(luò)的功能。如果什么命令都不輸入直接運(yùn)行g(shù)eth。 就會(huì)默認(rèn)啟動(dòng)一個(gè)全節(jié)點(diǎn)模式的節(jié)點(diǎn)。 連接到主網(wǎng)絡(luò)。 我們看看啟動(dòng)的主要流程是什么,涉及到了那些組件。# 啟動(dòng)的main函數(shù) cmd/geth/main.go看到main函數(shù)一上來(lái)就直接運(yùn)行了。 最開(kāi)始看的時(shí)候是有
2、點(diǎn)懵逼的。 后面發(fā)現(xiàn)go語(yǔ)言里面有兩個(gè)默認(rèn)的函數(shù),一個(gè)是main()函數(shù)。一個(gè)是init()函數(shù)。 go語(yǔ)言會(huì)自動(dòng)按照一定的順序先調(diào)用所有包的init()函數(shù)。然后才會(huì)調(diào)用main()函數(shù)。func main() if err := app.Run(os.Args); err != nil fmt.Fprintln(os.Stderr, err)os.Exit(1)main.go的init函數(shù)app是一個(gè)三方包gopkg.in/urfave/cli.v1的實(shí)例。 這個(gè)三方包的用法大致就是首先構(gòu)造這個(gè)app對(duì)象。 通過(guò)代碼配置app對(duì)象的行為,提供一些回調(diào)函數(shù)。然后運(yùn)行的時(shí)候直接在main函數(shù)里
3、面運(yùn)行 app.Run(os.Args)就行了。import (.gopkg.in/urfave/cli.v1)var (app = utils.NewApp(gitCommit, the go-ethereum command line interface)/ flags that configure the nodenodeFlags = cli.Flagutils.IdentityFlag,utils.UnlockedAccountFlag,utils.PasswordFileFlag,utils.BootnodesFlag,.rpcFlags = cli.Flagutils.RPCEn
4、abledFlag,utils.RPCListenAddrFlag,.whisperFlags = cli.Flagutils.WhisperEnabledFlag,.)func init() / Initialize the CLI app and start Geth/ Action字段表示如果用戶(hù)沒(méi)有輸入其他的子命令的情況下,會(huì)調(diào)用這個(gè)字段指向的函數(shù)。app.Action = gethapp.HideVersion = true / we have a command to print the versionapp.Copyright = Copyright 2013-2017 The
5、go-ethereum Authors/ Commands 是所有支持的子命令app.Commands = cli.Command/ See chaincmd.go:initCommand,importCommand,exportCommand,removedbCommand,dumpCommand,/ See monitorcmd.go:monitorCommand,/ See accountcmd.go:accountCommand,walletCommand,/ See consolecmd.go:consoleCommand,attachCommand,javascriptComman
6、d,/ See misccmd.go:makecacheCommand,makedagCommand,versionCommand,bugCommand,licenseCommand,/ See config.godumpConfigCommand,sort.Sort(cli.CommandsByName(app.Commands)/ 所有能夠解析的Optionsapp.Flags = append(app.Flags, nodeFlags.)app.Flags = append(app.Flags, rpcFlags.)app.Flags = append(app.Flags, consol
7、eFlags.)app.Flags = append(app.Flags, debug.Flags.)app.Flags = append(app.Flags, whisperFlags.)app.Before = func(ctx *cli.Context) error runtime.GOMAXPROCS(runtime.NumCPU()if err := debug.Setup(ctx); err != nil return err/ Start system runtime metrics collectiongo metrics.CollectProcessMetrics(3 * t
8、ime.Second)utils.SetupNetwork(ctx)return nilapp.After = func(ctx *cli.Context) error debug.Exit()console.Stdin.Close() / Resets terminal mode.return nil如果我們沒(méi)有輸入任何的參數(shù),那么會(huì)自動(dòng)調(diào)用geth方法。/ geth is the main entry point into the system if no special subcommand is ran./ It creates a default node based on the
9、command line arguments and runs it in/ blocking mode, waiting for it to be shut down./ 如果沒(méi)有指定特殊的子命令,那么geth是系統(tǒng)主要的入口。/ 它會(huì)根據(jù)提供的參數(shù)創(chuàng)建一個(gè)默認(rèn)的節(jié)點(diǎn)。并且以阻塞的模式運(yùn)行這個(gè)節(jié)點(diǎn),等待著節(jié)點(diǎn)被終止。func geth(ctx *cli.Context) error node := makeFullNode(ctx)startNode(ctx, node)node.Wait()return nilmakeFullNode函數(shù),func makeFullNode(ctx *cl
10、i.Context) *node.Node / 根據(jù)命令行參數(shù)和一些特殊的配置來(lái)創(chuàng)建一個(gè)nodestack, cfg := makeConfigNode(ctx)/ 把eth的服務(wù)注冊(cè)到這個(gè)節(jié)點(diǎn)上面。 eth服務(wù)是以太坊的主要的服務(wù)。 是以太坊功能的提供者。utils.RegisterEthService(stack, &cfg.Eth)/ Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode/ Whisper是一個(gè)新的模塊,用來(lái)進(jìn)行加密通訊的功能。 需要顯式的提供參數(shù)來(lái)啟
11、用,或者是處于開(kāi)發(fā)模式。shhEnabled := enableWhisper(ctx)shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) & ctx.GlobalIsSet(utils.DevModeFlag.Name)if shhEnabled | shhAutoEnabled if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessa
12、geSizeFlag.Name)if ctx.GlobalIsSet(utils.WhisperMinPOWFlag.Name) cfg.Shh.MinimumAcceptedPOW = ctx.Float64(utils.WhisperMinPOWFlag.Name)/ 注冊(cè)Shh服務(wù)utils.RegisterShhService(stack, &cfg.Shh)/ Add the Ethereum Stats daemon if requested.if cfg.Ethstats.URL != / 注冊(cè) 以太坊的狀態(tài)服務(wù)。 默認(rèn)情況下是沒(méi)有啟動(dòng)的。utils.RegisterEthSta
13、tsService(stack, cfg.Ethstats.URL)/ Add the release oracle service so it boots along with node./ release oracle服務(wù)是用來(lái)查看客戶(hù)端版本是否是最新版本的服務(wù)。/ 如果需要更新。 那么會(huì)通過(guò)打印日志來(lái)提示版本更新。/ release 是通過(guò)智能合約的形式來(lái)運(yùn)行的。 后續(xù)會(huì)詳細(xì)討論這個(gè)服務(wù)。if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) config := release.Confi
14、gOracle: relOracle,Major: uint32(params.VersionMajor),Minor: uint32(params.VersionMinor),Patch: uint32(params.VersionPatch),commit, _ := hex.DecodeString(gitCommit)copy(config.Commit:, commit)return release.NewReleaseService(ctx, config); err != nil utils.Fatalf(Failed to register the Geth release o
15、racle service: %v, err)return stackmakeConfigNode。 這個(gè)函數(shù)主要是通過(guò)配置文件和flag來(lái)生成整個(gè)系統(tǒng)的運(yùn)行配置。func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) / Load defaults.cfg := gethConfigEth: eth.DefaultConfig,Shh: whisper.DefaultConfig,Node: defaultNodeConfig(),/ Load config file.if file := ctx.GlobalString
16、(configFileFlag.Name); file != if err := loadConfig(file, &cfg); err != nil utils.Fatalf(%v, err)/ Apply flags.utils.SetNodeConfig(ctx, &cfg.Node)stack, err := node.New(&cfg.Node)if err != nil utils.Fatalf(Failed to create the protocol stack: %v, err)utils.SetEthConfig(ctx, stack, &cfg.Eth)if ctx.Gl
17、obalIsSet(utils.EthStatsURLFlag.Name) cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name)utils.SetShhConfig(ctx, stack, &cfg.Shh)return stack, cfgRegisterEthService/ RegisterEthService adds an Ethereum client to the stack.func RegisterEthService(stack *node.Node, cfg *eth.Config) var err
18、 error/ 如果同步模式是輕量級(jí)的同步模式。 那么啟動(dòng)輕量級(jí)的客戶(hù)端。if cfg.SyncMode = downloader.LightSync err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) return les.New(ctx, cfg) else / 否則會(huì)啟動(dòng)全節(jié)點(diǎn)err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) fullNode, err := eth.New(ctx, cfg)if
19、 fullNode != nil & cfg.LightServ 0 / 默認(rèn)LightServ的大小是0 也就是不會(huì)啟動(dòng)LesServer/ LesServer是給輕量級(jí)節(jié)點(diǎn)提供服務(wù)的。ls, _ := les.NewLesServer(fullNode, cfg)fullNode.AddLesServer(ls)return fullNode, err)if err != nil Fatalf(Failed to register the Ethereum service: %v, err)startNode/ startNode boots up the system node and
20、all registered protocols, after which/ it unlocks any requested accounts, and starts the RPC/IPC interfaces and the/ miner.func startNode(ctx *cli.Context, stack *node.Node) / Start up the node itselfutils.StartNode(stack)/ Unlock any account specifically requestedks := stack.AccountManager().Backen
21、ds(keystore.KeyStoreType)0.(*keystore.KeyStore)passwords := utils.MakePasswordList(ctx)unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ,)for i, account := range unlocks if trimmed := strings.TrimSpace(account); trimmed != unlockAccount(ctx, ks, trimmed, i, passwords)/ Regi
22、ster wallet event handlers to open and auto-derive walletsevents := make(chan accounts.WalletEvent, 16)stack.AccountManager().Subscribe(events)go func() / Create an chain state reader for self-derivationrpcClient, err := stack.Attach()if err != nil utils.Fatalf(Failed to attach to self: %v, err)stat
23、eReader := ethclient.NewClient(rpcClient)/ Open any wallets already attachedfor _, wallet := range stack.AccountManager().Wallets() if err := wallet.Open(); err != nil log.Warn(Failed to open wallet, url, wallet.URL(), err, err)/ Listen for wallet event till terminationfor event := range events swit
24、ch event.Kind case accounts.WalletArrived:if err := event.Wallet.Open(); err != nil log.Warn(New wallet appeared, failed to open, url, event.Wallet.URL(), err, err)case accounts.WalletOpened:status, _ := event.Wallet.Status()log.Info(New wallet appeared, url, event.Wallet.URL(), status, status)if event.Wallet.URL().Scheme = ledger event.Wallet.SelfDerive(accounts.DefaultLedgerBaseDerivationPath, stateReader) else event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader)case accounts.WalletDropped:log.Info(Old wallet dropped, url, event.W
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 船舶管道安裝施工合同
- 國(guó)際展覽中心隔墻施工合同
- 娛樂(lè)機(jī)構(gòu)外來(lái)顧客管理辦法
- 旅游服務(wù)提升招議標(biāo)管理辦法試行
- 環(huán)保項(xiàng)目招投標(biāo)授權(quán)委托書(shū)
- 建筑聲學(xué)浮動(dòng)價(jià)施工合同
- 商標(biāo)轉(zhuǎn)讓保證金協(xié)議書(shū)
- 公共交通加油補(bǔ)貼條例
- 家居建材商務(wù)樓租賃合同
- 租賃合同:公共安全設(shè)備
- 食堂副食品配送服務(wù)物資裝備計(jì)劃
- 社區(qū)警務(wù)工作培訓(xùn)
- 人大代表履職工作總結(jié)
- 難忍之隱-肩頸疼課件
- 屋頂光伏安裝安全施工方案
- 腦梗死的患者的心理護(hù)理
- 《西方經(jīng)濟(jì)學(xué)》-完整全套課件
- 中華律師協(xié)會(huì) 風(fēng)險(xiǎn)代理合同
- 鋰離子電池儲(chǔ)能電站熱失控預(yù)警與防護(hù)研究進(jìn)展
- RIGOL-DS1102CD數(shù)字示波器的使用方法課件
- 自閉兒童創(chuàng)業(yè)計(jì)劃書(shū)
評(píng)論
0/150
提交評(píng)論