Java developer's adventure to analyze go-ethereum(geth): Day 01

in #ethereum3 years ago (edited)

Java developer's adventure to analyze go-ethereum (geth): Day 01

This is an one of series, "Java developer's adventure to analyze go-ethereum(geth)". I have a plan for this seires like the followings:

  1. (This article) Day 01: Getting geth source(1.0), prepare IDE(VS Code) and find the entry point
  2. Day 02: Overall running structure of geth with CLI lib
  3. Day 03: Analyze geth node's startup logic and how to debug geth with VS Code.
  4. TBD

Kor Ver: 자바 개발자의 go-ethereum(geth) 소스 분석기: Day 01

Prerequisite

First of all, This series assumes that readers have been written a code in some programming language (, especially OOP language like Java) at least. This series also requires basic concepts of block chain and ethereum like account, mining, and etc.

Goal

In this article, I am going to cover basic environment to read and analyze geth source and first entry point of geth command. I also simply describe func and Package Intilization concept in golang.

What is geth?

Geth is a one of original implementations written in golang. Geth's internal truly follows ethereum protocol. Therefore, the analysis of geth would be suitable to understand ethereum protocol exactly. Then let's get started to go in the internals of geth.

Getting geth source

The first step to analyze geth is to fetch geth source code. There are two ways to download it. The one is to clone geth source using git. The another way is to download the source within golang development environment . For the first method, you can clone geth source like the following commands.

$ git clone https://github.com/ethereum/go-ethereum.git


If you have set up golang, you can easily download geth with this command.

$ go get -d github.com/ethereum/go-ethereum


You can reference more detailed information in installaiton manual about getting source and building it. If you build your geth source according to the above manula, you will get geth executable binary.

Go to Frontier

We sometimes need to go back to the initial version to analyze open source, because the first version is relatively simpler than the latest version to read the source. So I am going to go back to geth 1.0.0 Frontier. Frontier is a name of the version 1.0.0 of geth. It is already tagged with v1.0.0. You can change the original code to 1.0.0 code with git command.

$ git checkout v1.0.0

Tool Setting for code reading

To read geth source, We need an appropriate tool to support code reading written in golang. There are various IDEs and editors to support golang. In this series, I am going to use VS Code. If you want to install and set up VS Code for golang. Please follow this public guideline.

There are useful extensions for VS Code. I'm familiar with Intellij Key Binding, so installed JetBrains IDE Keymap. This would be helpful to move source code of geth back and forth.

First entry point: main

Every software's first entry point is a main function. Let's check golang's function declaration syntax to find main function in geth.

package main

import (
"fmt"
)

func main() {
fmt.Println("Hello, Golang and Geth")
}


Golang's function sytanx starts with func keyword and followed by function name. If you want to run the above code snippet. Run it within the playgorund provided in this url.

We can find the entry point in geth through what we have just learned. But there is a one problem. There is a lot of func main in geth source.

d01_func_search.png

But, we've got already big hint to find the entry point for geth. That's the executable binary file name, geth. When we try to start geth client, we must use geth command. Finally, We found the main function in cmd/geth folder like the following screenshot.

d01_geth_main.png

Analysis of main function

The main function of gets is like:

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    defer logger.Flush()
    if err := app.Run(os.Args); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}


The first two lines of code is related with runtime environment an logging. So We don't need to consider about them. The most important logic is to invoke app.Run(os.Args) in line 4. Consequently, We can figure out that there is only invoking app.Run() in main function of geth.

Our next questions would be like this:

  • Where is the app declared?
  • Where is the initialization logic forapp instance?

We can quickly find the location of app's declaration with Go to Definition shortcut of VS Code. The app instance's declaration is in line 58. The following is declaration logic in main.go file.

var (
    gitCommit       string // set via linker flag
    nodeNameVersion string
    app             *cli.App
)


We can also easily find initialization logic with Find All Reference shortcut. When you try to find all reference of app, VS Code will shows all reference like the following screenshot.

d01_find_ref.png

In the referense list, the second result is the initialization logic of app. It is in init function. This is head part of init function.

func init() {
    if gitCommit == "" {
        nodeNameVersion = Version
    } else {
        nodeNameVersion = Version + "-" + gitCommit[:8]
    }

    app = utils.NewApp(Version, "the go-ethereum command line interface")
    app.Action = run
    app.HideVersion = true // we have a command to print the version
    app.Commands = []cli.Command{
    ...

/
We can read and understand that app is initialized from invoking utils.NewApp. Then, who is the caller of init function to initialize app instance. That's the role of golang.

Package Initialization

I found that there is a special initialization specification in golang. It is the Package Initialization. In golang , users can declare package level (or scope) variable and initializatio logic of it. The app's declaration and init function we've seen were just golang's syntax. Detailed spec about Package Initialization is in the following link.

Conclusion

Today, I describes code reading environment setup and the main entry point of geth . This is the starting point to analyze go ethereum protocol. geth has a app instance to be ran. The main point of app instance is that it is initialized with utils.NewApp()'s result. Next, we must catch up the utils.NewApp(). I will describe it in next time.

Sort:  

@woojin.joe 우와 영어로 쓰시는거에요? ^_^

@yudong 전부터 영어로 글 써봐야 겠다는 목표가 있어서 시도해 봤는데... 역시 쉽지 않네요 ㅎ

오오 굿굿^.^

If you are trader, try this tool. It simplifies the viewing of courses and notifies about the rise and fall https://usignals.com/?new