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.node
やweb3.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ブランチを参照すると良い。
その2 web3.js v0.20.1そのものというわけではない
Gethコンソールで使えるweb3.jsはv0.20.1そのものというわけではなく、いくつか拡張がなされている。
例えば、web3.net
やweb3.eth
はnet
やeth
としてアクセスできたり、net.version
などweb3.js v0.20.1には存在しないAPIが追加されていたりする。
> eth.syncing false > net.version "4" // rinkeby
これは、internal/web3ext/web3ext.go
を見ればなんとなくわかる。admin
やpersonal
などの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.sha3
はcrypro-jsのものを使い、1.x系のweb3.utls.sha3
はeth-libのものを使っているようだ。
おしまい
Gethにはドキュメントされてないことがいっぱいあるので、わからないことは実装から探りましょう🤮