자바 개발자의 go-ethereum 소스 읽기: Day 3
kr·@woojin.joe·
0.000 HBD자바 개발자의 go-ethereum 소스 읽기: Day 3
# 자바 개발자의 go-ethereum 소스 읽기: Day 3  이 글은 자바 개발자의 go-ethereum(geth 클라이언트) 소스 분석기 시리즈의 연재 중 세 번째 글입니다. 앞으로 다음과 같은 내용으로 연재를 계획하고 있습니다. 1. [Day 01: Geth 1.0 소스 받기 및 코드 분석을 위한 개발환경 셋팅(VS Code)](https://steemit.com/kr/@woojin.joe/go-ethereum-geth-day-01) 2. [Day 02: CLI 라이브러리 기반 `geth`의 전체 실행 구조](https://steemit.com/kr/@woojin.joe/go-ethereum-geth-day-02) 3. **(본 글)** Day 03: VS Code를 사용한 `geth ` 디버깅 ... 전체 연재 목록은 아래 페이지에서 확인해 주세요 http://www.notforme.kr/block-chain/geth-code-reading ## 대상 독자 이 연재는 먼저 독자 분들이 적어도 Java와 같은 OOP 계열의 언어로 프로그래밍 경험이 있다는 것을 가정합니다. 또한 계정, 채굴 등 블록체인과 이더리움과 관련된 기초적인 개념을 알고 있다고 가정합니다. ## 다루는 내용 [지난 글](https://steemit.com/kr/@woojin.joe/go-ethereum-geth-day-02)에서 우리는 `geth` 실행과 관련된 코드의 구조를 살펴보았습니다. 오늘은 `geth` 의 실행 로직을 분석하기 위해 실제 `golang`의 `install` 명령을 사용하여 소스를 빌드하여 실행해보고자 합니다. 또한 코드를 수정 후 재빌드하여 우리가 수정한 코드가 반영되는지도 확인해 볼 것입니다. VS Code를 사용하여 수정사항을 확인하기 위하여 빌드하지 않고 디버그하는 방법도 볼 것입니다. ## geth 빌드하기 `golang` 이 설치되어 있고 다음 명령을 사용하여 `$GOPATH`에 `geth`의 소스가 설치되어 있다면 `geth` 의 빌드는 아주 쉽습니다. ```sh $ go get -d github.com/ethereum/go-ethereum ``` \ 소스를 빌드하기 위한 명령은 `golang`에서 제공하는 `install` 명령을 사용하면 됩니다. 이 명령은 소스를 빌드한 후 실행가능한 바이너리를 `GOPATH`의 bin 폴더에 옮기는 일을 합니다. 빌드 전에 다음 명령을 통해서 `geth` 바이너리가 아직 설치되지 않았음을 확인해 봅니다. ```sh $ ls -al (각자의 $GOPATH)/bin | grep geth ``` \ 명령을 실행하면 아무런 결과도 보이지 않습니다. 이제 소스를 빌드해 봅시다. 명령은 다음과 같습니다. ```sh $ go install github.com/ethereum/go-ethereum/cmd/geth ``` \ 정상적으로 소스가 빌드되면 `$GOPATH/bin` 에 `geth` 바이너리가 생성됩니다. 앞의 `ls` 명령을 재실행하여 정상적으로 바이너리가 생성되었는지 확인해 봅니다. 바이너리를 확인했다면 빌드에 성공한 것입니다. ## geth 실행 및 디버깅 `$GOPATH/bin` 의 경로가 `$PATH` 에 등록되어 있다면 이제 터미널에서 `geth` 명령을 실행할 수 있습니다. 아무런 실행옵션 없이 터미널에서 `geth` 명령을 바로 실행하면 몇십 줄의 로그가 올라온 뒤 잠시 대기합니다. 우린 아직 구체적인 코드를 보지 않았으나 추측하기론 이 시간이 메인 네트워크에 접속하다른 노드를 찾는 시간일 겁니다. 잠시의 대기시간이 지나면 우리가 실행한 `geth`는 메인 네트워크에 합류하여 다음과 같이 블럭 정보를 받는 로그를 볼 수 있습니다.  `CTRL-C`로 시그널을 보내면 실행 중인 `geth`가 종료하게 됩니다 ### 테스트 실행을 위한 옵션 `geth`를 공부용으로 매번 실행할 때 마다 메인네트워크에 붙는 것은 부담스러운 일입니다. 몇가지 옵션을 설정하면 손쉽게 별도의 네트워크를 구성할 수 있습니다. 여기서는 간단하게 `--nodiscover` 옵션을 주고 `geth` 실행 시 블럭 정보를 받아오지 않도록 해보려고 합니다. 이 옵션은 네트워크 내 다른 노드에서 우리가 실행한 노드를 검색하지 않도록 하는 옵션입니다. ```sh $ geth --nodiscover ``` \ 위와 같은 명령으로 다시 실행하면 `geth`에서 추가로 블록을 받아오고 싱크하는 일을 하지 않게 됩니다. 독립적인 테스트 네트워크의 구축은 [공식 매뉴얼](http://www.ethdocs.org/en/latest/network/test-networks.html#test-networks)에 안내가 되어 있습니다. 이 부분은 다음에 관련 코드를 읽을 때 다시 살펴볼 예정입니다. ### 수정하고 빌드해 보기 한 걸음 더 나아가서 이제 코드를 수정하고 빌드하여 우리가 수정한 코드가 동작하는지 확인해 봅시다. 우리가 작성한 코드가 반영되었는지 확인하는 가장 쉬운 방법은… 진리의 `printf` 입니다. 지난 시간에 확인했던 최초의 진입점 `cmd/geth/main.go`의 `main` 함수에 우리의 흔적을 남겨봅시다.  `geth` 의 최초 시작 지점에 한 줄의 코드를 추가했습니다. 이제 위에서 진행한 빌드/실행을 해봅시다. 물론 ` --nodiscover` 옵션도 포함합니다.  비록 간단한 print 문이지만 드디어 Java 개발자가 `golang`의 오픈소스를 수정한 순간이네요! 여기까지만 와도 앞으로 코드를 읽고 분석할 때 직접 코드를 수정해서 빌드해서 실행해 볼 수 있는 발판이 마련된 것입니다. 그러나 여전히 아쉬운 점이 하나 있습니다. 그건 바로 디버깅 환경입니다. ### VS Code로 디버깅 상용 툴을 쓸 수 있다면 Jetbranins 사의 [Goland](https://www.jetbrains.com/go/)가 Java 개발자가 많이 쓰는 Intellij와 인터페이스가 동일하여 손쉽게 디버깅할 수 있습니다. 다행히 VS Code로도 `golang` 의 코드를 디버깅할 수 있습니다. [첫 번째 글](https://steemit.com/kr/@woojin.joe/go-ethereum-geth-day-01)에 따라 VS Code를 설치하고 `Go` 확장을 설치했으면 터미널에서 다음 명령을 실행하면 `golang`을 위한 디버깅 환경 준비가 모두 끝납니다. ```Sh $ go get -u github.com/derekparker/delve/cmd/dlv ``` \ 설치가 끝나면 VS Code를 실행하고 `cmd/geth/main.go` 파일을 엽니다. 이제 기존 IDE와 동일한 인터페이스로 `geth` 코드의 디버깅 포인트를 찍을 수 있습니다. 아래 그림과 같이 위에서 추가한 print 문 코드 바로 다음, `app` 인스턴스의 실행 부분에 디버깅 포인트를 찍고 디버깅 명령을 수행해 보겠습니다.  정상적으로 디버그 모드로 `geth` 가 실행되면 다음과 같이 우리에게 익숙한 디버깅 환경이 제공됩니다.  VS Code 내 디버그 콘솔을 보면 앞서 작성한 Println 명령이 실행되어 콘솔에 출력된 것을 확인할 수 있습니다. 이제 이 지점에서 다음 스텝으로 넘어가거나, 그대로 실행하는 등의 작업을 통해서 코드의 실행흐름을 추적할 수 있습니다. > 참고로 디버깅은 반드시 `func main`이 선언된 파일에서만 작동 가능합니다. ### VS Code 디버그 환경 설정 추가 디버그 실행과 관련하여 한가지 설정이 남았습니다. 지금과 같은 환경에서 디버깅을 진행하면 터미널에서 아무런 옵션 없이 `geth`를 실행한 것과 동일합니다. 우리에게 필요한 것은 디버그 모드로 실행할 때 우리가 필요한 인자를 옵션으로 줄 수 있어야 합니다. VS Code의 왼쪽 하단의 디버그 탭을 클릭하면 상단에 톱니바퀴 모양 버튼이 보입니다.  톱니바퀴 모양의 버튼을 클릭하면 에디터에 `launch.json` 파일이 열립니다. 이 파일이 VS Code에서 디버그 모드로 실행할 때의 설정파일 역할을 합니다. 이제 json 파일의 `args`에 실행 시 전달한 인자를 입력하면 됩니다. 그럼 앞에서 사용했던 ` --nodiscover` 옵션을 디버깅 할때도 동일하게 적용해 봅시다.  이제 이전과 동일하게 VS Code 안의 디버그 콘솔에서 최초 터미널에서 실행할 때와 동일한 로그를 발견할 수 있습니다. 또한 `--nodiscover` 옵션이 추가되어 메인 네트워크로부터 블록을 싱크하지도 않을 것입니다. ## 마치며 오늘은 간단히 VS Code를 활용한 `golang` 코드의 디버깅 환경을 셋팅했습니다. 이제 우리는 오늘까지 연재를 통해서 본격적인 `geth` 코드 분석을 위한 모든 준비가 끝났습니다. 다음 글에서 본격적인 소스를 분석한 내용을 함께 나누고자 합니다. 블록체인을 공부하면서 일부러 steem을 통해서 글을 올려보고 있는데 공부한 내용을 함께 나누는 일을 지속적으로 할 수 있도록 보팅으로 응원 부탁드립니다. 감사합니다. ^^!
👍 ubg, hr1, qrwerq, sisicoco, hellocrypto, stoney.kang, jeaimetu, woojin.joe, endiyou, skybluemaru, jeffry82, kdj, noelkim, ingee, dongchang,