前回の記事から引き続きgo-ethereumから大量データを取得するために、今回はGraphQLを用いる方法について試したことをまとめる。
なお、前回の記事は以下を参照。
y-nakajo.hatenablog.com
go-ethereumのGraphQLについて
GraphQLはgo-ethereumのv1.9.0で導入された。詳しくは以下の公式ブログを参照。
blog.ethereum.org
それ以前にEIP-1767としても提案されていた。こちらのEIPはまだdraftだが、これを受けてgo-ethereumで採用されたと思われる。
eips.ethereum.org
やはり、上記EIP-1767でもJSON-RPCで大量データを取得するのは効率が悪いことが指摘されている。
実際にローカルにgo-ethereumを立てて、JSOn-RPC経由でBlockrとTransactionの情報を取得しようとすると、100 Block分のデータを取得する前にgo-ethereumのJSON-RPCサーバがハングアップしてしまう。その改善策としてのGraphQLの導入ということだ。
なお、GraphQLについて知らない人はGraphQLの公式を参照。
graphql.org
go-ethereumのGraphQLサーバを起動する
GraphQLサーバを起動するには、go-ethereum実行時に--httpと--graphqlの両方のオプションを指定すればよい。
以下にコマンドの例を載せる。
geth --datadir /mnt/j/geth/ --http --graphql
go-ethereumが起動すると、ログに以下のようにGraphQLのエンドポイントが表示される。
また、同時にGraphQLを直接ブラウザから操作できるUIツールも起動してくれる。
INFO [09-11|13:15:38.088] HTTP server started endpoint=127.0.0.1:8545 prefix= cors= vhosts= INFO [09-11|13:15:38.088] GraphQL enabled url=http://127.0.0.1:8545/graphql INFO [09-11|13:15:38.088] GraphQL UI enabled url=http://127.0.0.1:8545/graphql/ui
GraphQLを使ってみる
ログにあるとおり、早速ブラウザから http://localhost:8545/graphql/ui にアクセスする。すると以下のような画面が表示されるはずだ。
右上にある「DOCS」をクリックすると、使用可能なQueryとMutationを確認できる。
実際に100block分のデータを取得するために以下のQueryを実行する。
query GetBlocks() { blocks(from: 13000000, to: 13000100) { number, gasLimit, gasUsed, baseFeePerGas, transactions { gas, gasUsed, gasPrice, maxFeePerGas, maxPriorityFeePerGas, accessList { address, storageKeys } } } }
次のようにすぐに実行結果が表示される。
自分のマシンでためしたところ、100 block程度であれば1~2秒で結果が取得できた。また、1000 blockのデータも十数秒程度で取得できた。さすがに1日分の5,760 blockを取得しようとすると、データ量が多すぎたのか「TypeError: Failed to fetch」エラーが発生した。
とはいえ、JSON-RPCよりも格段に大量のデータが取得可能になった。大量のTransaction情報などを分析したい場合はGraphQLを使うのが良いだろう。
最後に
GraphQLでのアクセスが可能となったことで、いろいろとSaaSの幅も広がっているらしい。The GraphというコントラクトのEventを取得するサービスなども始まったようだ。The Graphについては以下の@naomasabitさんのブログを参照。
www.blockchainengineer.tokyo