つーさにブログ

つうさにのメモ用ブログ

Go EthereumのJavaScript Consoleネタ3連発

geth consoleとかgeth attachで使えるJavaScript Consoleの話。

環境: Geth v1.9.15

はじめに

Go Ethereum (Geth)Ethereumクライアントの公式実装の一つ。GethはJavaScript Console機能を内蔵しており、Ethereumノードとして動作中のGethに対してweb3.jsを使って対話することができる。

今回は、GethのJavaScript Consoleについて、実装を見ないとわからないような細かなネタをまとめた。

以下、GethのJavaScript ConsoleのことをGethコンソールと書く。

公式ドキュメント

以下のページに書かれている。

JavaScript Console | Go Ethereum

今回はこれを見るだけではわからないようなネタをまとめた。

Geth JavaScript Consoleネタ3連発

その1 web3.jsが古い

GethコンソールはJavaScript REPLであるが、web3.version.nodeweb3.eth.blockNumberのようなweb3.jsのAPIが使える。

で、これは最近のv1.x系のweb3.jsとは全く異なるAPIである。実はGethコンソール上で使えるweb3.jsはv0.20.1のものであり、かなり古い(web3.js v0.20.1のリリース日は2017年7月1)。

例えば、以下のようにすれば、Gethコンソールでのweb3.jsがv0.20.1であることがわかる。

> web3.version.api
"0.20.1"

そんな古めのweb3.jsはgo-ethereumのリポジトリ内部に置かれていて、internal/jsre/deps/web3.jsにある。このweb3.jsがGethコンソール起動時にロードされるため、Gethコンソール上でweb3.jsのAPIを利用できる、というワケである2

ドキュメント

ちなみにhttps://web3js.readthedocs.io/にはv1.x系のドキュメントしかないので、v0.20.1のような古いweb3.jsのドキュメントを見たい場合はweb3.jsリポジトリ0.20.7ブランチを参照すると良い。

github.com

その2 web3.js v0.20.1そのものというわけではない

Gethコンソールで使えるweb3.jsはv0.20.1そのものというわけではなく、いくつか拡張がなされている。

例えば、web3.netweb3.ethnetethとしてアクセスできたり、net.versionなどweb3.js v0.20.1には存在しないAPIが追加されていたりする。

> eth.syncing
false
> net.version
"4" // rinkeby

これは、internal/web3ext/web3ext.goを見ればなんとなくわかる。adminpersonalなどのAPIもここで追加されていることがわかる。

これらの拡張はGethコンソール起動時にロードされる3

その3 処理系がottoからgojaに変更された

公式ドキュメントWikiには、GethコンソールにはottoというGo言語製JavaScript処理系が使われていると書かれているが、最近ottoの代わりにgojaを使うように変更されたようだ。

参考: console, internal/jsre: use goja by gballet · Pull Request #20470 · ethereum/go-ethereum · GitHub

おまけ web3.js小ネタ

web3.jsの主な役割のひとつは、JSON-RPCサーバとして動作しているEthereumノードにJSON-RPCプロトコルでリクエストを投げて、サーバからのレスポンスをJavaScirpt APIの結果として返すというものである。例えば、web3.net.peerCountというAPIは、端的にいうと内部でEthereumノードに{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":0}のようなJSON-RPCリクエストを投げて、そのJSON-RPCレスポンスのresultをAPIの評価結果として返す。web3.net.peerCountのみならず、web3.jsのAPIの多くがJSON-RPC通信の結果をAPIの結果として返している。

ところで、Gethはweb3_sha3というmethodのJSON-RPCリクエストを受け付けており、これは名の通りparamsのsha3 (keccak) ハッシュを返してくれる。なのでweb.sha3というweb3.jsのAPIもこれとJSON-RPC通信を行った結果を返してるものかと思いきや、これに限ってはそうではない。web.sha3はサーバと通信するのではなくJavaScript実装のsha3を実行しているのだ。

実装を読んだところ、v.20.1のweb3.sha3crypro-jsのものを使い、1.x系のweb3.utls.sha3eth-libのものを使っているようだ。

おしまい

Gethにはドキュメントされてないことがいっぱいあるので、わからないことは実装から探りましょう🤮