LoginSignup
0
0

More than 1 year has passed since last update.

Gethのコードを理解する①(デバッグ環境構築編)

Posted at

はじめに

Ethereumを理解するには、Geth(Go-ethereum)の理解が必須と感じるので、Gethを勉強する。
第一弾はGethのデバッグ環境構築編。

※間違っている情報があれば、ご指摘いただければ幸いです。

Geth環境構築の目標

  • Gethコードの変数をデバッグする(変数の中身を確認できる状態にする)
  • Gethでプライベートネットワークを起動する

バージョンなど

開発環境

  • OS: Ubuntu20.04
  • Geth Version: 1.9.25-stable (最新バージョンだとエラーが出たため、古いバージョンを選択)
  • Geth Git Commit: e7872729012a4871397307b12cc3f4772ffcbec6

依存ツールのバージョン

  • golang: version go1.19.3 linux/amd64
  • make: GNU Make 4.2.1
  • git: version 2.25.1

Geth環境構築の方針

Gethを動かすOS

以下のOSで動かせる。(Gethのドキュメント)

  • Windows
  • Linux
  • MacOS

後々、AWSのEC2でGethを動かしてみたいので、OSはLinux (Ubuntu) を選択する。

Gethのインストール方法

以下のインストール方法がある。(Gethのドキュメント)

  • パッケージマネージャを利用
  • Standalone bundleをダウンロード
  • ソースコードからビルド

変数のデバッグを行いたいので、ソースコードからビルドする方法を選択する。

Geth環境構築の手順

①依存ツールの準備

Gethをソースコードからビルドする場合、Ubuntuでgolang, make, git を使える必要がある。

ubuntu20.04
// 2022年11月時点の最新版をインストール
$ go version
go version go1.19.3 linux/amd64 
ubuntu20.04
$ make -v
GNU Make 4.2.1
ubuntu20.04
$ git version
git version 2.25.1

②Gethソースコードの取得

任意のディレクトリにGethソースコードをcloneする。
自分の場合は、~/GOPATH/src/github.com/とした。
Gethの最新バージョンだとエラーが発生したため、 Versionv 1.9 をcloneした.
(Ethereumのマージ以降のGethを利用すると、プライベートネットに接続できなかった....)

ubuntu20.04
$ git clone -b release/1.9 https://github.com/ethereum/go-ethereum.git
Cloning into 'go-ethereum'...
remote: Enumerating objects: 111489, done.
remote: Counting objects: 100% (58/58), done.
remote: Compressing objects: 100% (46/46), done.
remote: Total 111489 (delta 17), reused 33 (delta 9), pack-reused 111431
Receiving objects: 100% (111489/111489), 186.75 MiB | 12.98 MiB/s, done.
Resolving deltas: 100% (66865/66865), done.
ubuntu20.04
$ cd go-ethereum
$ git branch
* release/1.9

③Gethソースコードのビルド

go-ethereumディレクトリで、makeを実行する。

ubuntu20.04
$ make geth
env GO111MODULE=on go run build/ci.go install ./cmd/geth
>>> /usr/lib/go-1.19/bin/go build -ldflags -X main.gitCommit=e7872729012a4871397307b12cc3f4772ffcbec6 -X main.gitDate=20201211 -trimpath -v -o /home/USERHOME/GOPATH/src/github.com/go-ethereum/build/bin/geth ./cmd/geth
github.com/ethereum/go-ethereum/crypto/secp256k1
Done building.
Run "./build/bin/geth" to launch geth.

go-ethereum/build/bin/ に、コンパイルされたgethファイルが存在すれば、ビルドは完了している。

ubuntu20.04
$ ls build/bin
geth

④データディレクトリの作成

プライベートネットワークのブロック情報などを格納するデータディレクトリを作成する。
自分の場合は、~/eth_private_net/ に作成した。(ディレクトリ名は自由)

⑤プライベートネットワークの初期化

プライベートネットワークのGenesisブロック(1番最初のブロック)の情報を、genesis.jsonに記載する。
genesis.jsonは、任意のディレクトリに作成する。
自分の場合は、~/GOPATH/src/github.com/go-ethereum/build/bin/ に作成した。

genesis.jsonの中身は、Ethereum入門のサイトを参考にした。
Ethereum入門

genesis.json
{
    "config": {
        "chainId": 15,
        "homesteadBlock": 0,
        "eip150Block": 0,
        "eip155Block": 0,
        "eip158Block": 0,
        "byzantiumBlock": 0,
        "constantinopleBlock": 0,
        "petersburgBlock": 0,
        "istanbulBlock": 0,
        "berlinBlock": 0
    },
    "nonce": "0x0000000000000042",
    "timestamp": "0x0",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "",
    "gasLimit": "0x8000000",
    "difficulty": "0x4000",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x3333333333333333333333333333333333333333",
    "alloc": {}
}

genesis.jsonの作成後、プライベートネットワークの初期化を行う。

ubuntu20.04
$ cd go-ethereum/build/bin
$  ./geth --datadir ~/eth_private_net --nousb init ./genesis.json
INFO [11-29|23:15:22.420] Maximum peer count                       ETH=50 LES=0 total=50
INFO [11-29|23:15:22.420] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [11-29|23:15:22.421] Set global gas cap                       cap=25000000
INFO [11-29|23:15:22.421] Allocated cache and file handles         database=/home/USERHOME/eth_private_net/geth/chaindata cache=16.00MiB handles=16
INFO [11-29|23:15:22.427] Writing custom genesis block
INFO [11-29|23:15:22.427] Persisted trie from memory database      nodes=0 size=0.00B time="3.5µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [11-29|23:15:22.428] Successfully wrote genesis state         database=chaindata hash="7b2e8b…7e0432"
INFO [11-29|23:15:22.428] Allocated cache and file handles         database=/home/USERHOME/eth_private_net/geth/lightchaindata cache=16.00MiB handles=16
INFO [11-29|23:15:22.433] Writing custom genesis block
INFO [11-29|23:15:22.433] Persisted trie from memory database      nodes=0 size=0.00B time="16.5µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [11-29|23:15:22.434] Successfully wrote genesis state         database=lightchaindata hash="7b2e8b…7e0432"

データディレクトリに、「geth」「keystore」というディレクトリが作成されていれば、プライベートネットワークの初期化は完了している。

ubuntu20.04
$ ls ~/eth_private_net
geth  keystore

⑥Gethプライベートネットワークの起動

Gethでプライベートネットワークを起動する。

ubuntu20.04
$ ./geth --datadir ~/eth_private_net --networkid 15 --nousb console 2>> ./geth_err.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.9.25-stable-e7872729/linux-amd64/go1.19.3
at block: 0 (Thu Jan 01 1970 09:00:00 GMT+0900 (JST))
 datadir: /home/USERHOME/eth_private_net
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d
>

起動に成功すると、GethのJavascriptコンソールが使えるようになる。
プライベートネットワークの情報を取得してみる。

GethのJavascriptコンソール
> eth.chainId()
"0xf"     // chainIdに15が設定されている
> eth.blockNumber
0         // ブロックの高さは0

⑦変数のデバッグ

デバッグのために、go-thereum/internal/ethapi/api.goのSendTransaction関数を変更する。(SendTransaction関数は2つあるので注意)
SendTransaction関数の先頭に、デバッグのコードを2行追加。

go-thereum/internal/ethapi/api.go
func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
	fmt.Printf("デバッグを挿入!\n") // 追加
	fmt.Printf("SendTransactionのargs: %v\n", args) // 追加 
	
	// Look up the wallet containing the requested signer
	account := accounts.Account{Address: args.From}

	wallet, err := s.b.AccountManager().Find(account)
	if err != nil {
		return common.Hash{}, err
	}

	if args.Nonce == nil {
		// Hold the addresse's mutex around signing to prevent concurrent assignment of
		// the same nonce to multiple accounts.
		s.nonceLock.LockAddr(args.From)
		defer s.nonceLock.UnlockAddr(args.From)
	}

	// Set some sanity defaults and terminate on failure
	if err := args.setDefaults(ctx, s.b); err != nil {
		return common.Hash{}, err
	}
	// Assemble the transaction and sign with the wallet
	tx := args.toTransaction()
    ...
    ...
    ...

ソースコードの変更を反映させるために、Gethを再ビルドしてから、プライベートネットワークを起動し直す。

ubuntu20.04
// ビルドのコマンド
$ make geth

//プライベートネットワークの起動コマンド
$ ./geth --datadir ~/eth_private_net --networkid 15 --nousb console 2>> ./geth_err.log

SendTransaction関数に入れたデバッグが、GethのJavascriptコンソールに表示されるかを確認する。

GethのJavascriptコンソール
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], ChainID: 15, nonce: 8, gas: 0x100000, gasPrice: 0x10
0, value: web3.toWei(2, "ether") })
デバッグを挿入!
SendTransactionのargs: {0x6364294FbF6BAcC9D7A591274A42Ed3fd982436f 0xb76Fbd02341eeaA40e2a5ec472cCDCE69d81944E 0x100000 0x100 0x1bc16d674ec80000 0x8 <nil> <nil>}
"0x3dc6bc6f13123e9b91b69d552766be8f40fbe288d6814a93565d82e503f5ae4f"

「デバッグを挿入!」と表示され、argsの中身を表示させることができた。

まとめ

なんとかGethの変数をデバッグする環境を構築できた。
Gethの動作確認を行い、Ethereumの理解を深めたい。

参考にしたサイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0