Ethereumブロックチェーンと対話し、PythonおよびSQLでデータベースを作成する方法

ブロックチェーンに関する入門ワークショップは、ピアツーピアネットワークと銀行台帳の簡単なダイジェストストーリーから始まり、スマートコントラクトのコーディングに直接ジャンプします。代わりに、自分がジャングルに足を踏み入れて、イーサリアムブロックチェーンを勉強しようとしている奇妙な生き物だと考えてください。今日は、クリーチャーを観察し、それとやり取りし、そのクリーチャーに関するすべてのデータを、ユーザーが使用するために中央ストレージに収集します。

最初の出会いのセットアップ

まず、web3pyをインストールする必要があります。 Web3pyは、Ethereumブロックチェーンに接続するためのPythonライブラリです。事前に知っておく必要があるのは、データをダウンロードできる中央管理システムがないことです。相互にリソースを共有する相互接続されたノード(「ピア」)は、データ(またはその一部)の検証済みコピーを保存します。ネットワークは、Ethereumプロトコルを実行します。これは、ノード間の相互作用および/またはそのネットワーク上のスマートコントラクトのルールを定義します。

トランザクション、残高、ブロックなど、まだ知らないブロックチェーンに書き込まれているものに関する情報にアクセスする場合、プロトコルではノードに接続する必要があります。ノードは継続的に新しいデータを相互に共有し、データを検証します。このようにして、1)改ざんされていないデータと2)最新のデータを確実に取得できます。

クリーチャーへの最初のアプローチで使用できるノードには、ローカルまたはホストの2つの基本的なカテゴリがあります。ローカルノードはマシン上で実行できます。つまり、ブロックチェーンをデバイスに同期し、ストレージを占有して完了するまでに時間がかかるgethなどのクライアントを最初にダウンロードする必要があります。最初に遭遇する場合、ホストされたノードはより良い選択です。他の誰かによって制御されますが、簡単に接続して自分でブロックチェーンをいじることができます。

Infuraに移動し、独自の無料アカウントを作成して、このようなホストされたノードにアクセスします。完了すると、接続できるネットワークのリストが表示されます:メインネット(メインのEthereumブロックチェーン)、および基本的なスマートコントラクトをテストするためにあるテストネットの束コストのかかるコードをメインネットにデプロイする前にそれらを修正します。

最初のアプローチの時間。 Web3オブジェクトをインポートし、HTTP接続を確立します。

web3からWeb3をインポート
web3 = Web3(Web3.HTTPProvider( "https://mainnet.infura.io/your-own-personal-number"))

そして、あなたはすべて設定されています!これで、web3 APIを使用してデータ構造を探索できます。

特定のブロックに関する情報を取得しています…

#現在のブロック番号
>>> web3.eth.blockNumber
5658173
#最後にマイニングされたブロックのコンテンツを取得する
>>> web3.eth.getBlock( 'latest')

このコマンドは、AttributeDictデータ構造を返します。これは、次のようなキーと値のペアの辞書です。

これらの変数のすべてがすぐに役立つわけではありません。いくつかは非常に技術的であり、ブロックチェーンが実際にどのように機能するかをより深く理解して初めて意味が意味を持つためです。いわゆる「Yellow Paper」でそれらについての詳細を読むか、当面の間それらをスキップして、簡単に理解できるもので作業することができます。

要するに、ブロックにはブロックヘッダー、それに書き込まれた検証済みトランザクションのリスト、おじさんのリストが含まれます(メインブロックチェーンに到達するにはブロックが少し遅すぎたが、彼らの計算の努力)。以下では、各変数の意味を読むことができます。これをサブカテゴリに分けます。

全般

鉱業関連

おじさん

テクニカル

…取引と領収書

また、一意の識別子、つまりトランザクションハッシュによってブロック内の単一のトランザクションを検索することもできます。

前述のように、web3pyは属性辞書を返します。次の表は、各キーの意味をまとめたものです。

最後に、トランザクションレシートを調べることもできます。

トランザクションレシートには、いくつかの新しいエントリが繰り返されます。新しいものについては以下で説明します。

参考のために、これらのテーブルをコンパイルするために、イエローペーパー以外にもさまざまな追加リソースを含めました[2、3、4、5]。

ご覧のとおり、いくつかの簡単なコマンドを使用するだけで、既にネットワークに接続し、生の形式でトランザクション、ブロック、または状態に関する基本情報を取得できます。これにより、そのようなデータで何ができるかを示す新しいウィンドウが開きます!

データベースマネージメントシステム

データを適切なデータベースに書き込むことを計画している場合、サーバーレスSQLite、サーバーベースのMySQL、PostgreSQL、Hadoopなど、Python愛好家向けの管理システムには多くのソリューションがあることに気付くでしょう。何をしようとしているのかに応じて、プロジェクトに最適なオプションを決定する必要があります。一般的に、私はこれらのポイントが役立つことを発見しました:

  • データベースの意図したサイズはどのくらいですか(つまり、単一のマシンシステムで処理できますか)?
  • エントリは頻繁に編集されますか、それとも修正されたままですか?
  • データベースは、複数の関係者/アプリによって同時にアクセスおよび編集されることになっていますか?

Ethereumブロックチェーンは時間とともに着実に成長しており、2018年6月の時点で1 TBに近づいていますが、これは小さいため、Hadoopのような分散処理システムには最適ではありません。ブロックチェーンデータベースは一度書き込まれ、その後新しいエントリでのみ拡張され、古いエントリは変更されません。このデータベースの使用目的は、1つのチャネルによって書き込まれ、他のチャネルによって読み取り専用でアクセスされるため、サーバーで実際に実行する必要はありません。データベースをマシン上にローカルに保持すると、すぐに読み取りが行われます。これは、SQLiteなどのサーバーレス管理システムで望ましいことです。 Pythonには組み込みのライブラリsqlite3があるため、新しいパッケージをインストールする必要さえありません。

データベース設計

次のステップは、データベースの設計です。どのデータフィールドが分​​析に最も関連しているかを念頭に置き、検索とストレージの両方を最適化することを目指してください。たとえば、stateRootを使用する予定がない場合は、完全にスキップするか、別のテーブルに保存することをお勧めします。少ない列のテーブルはより高速に検索でき、後で実際にstateRootのユースケースがあることに気付いた場合でも、引き続きアクセスできます。ブロック情報をトランザクション情報から分離することもできます。そうしないと、タイムスタンプなどのブロックプロパティがブロック内のすべてのトランザクションに対してN回繰り返され、多くのスペースが無駄になります。トランザクションとそのブロックプロパティのマッチングは、後でJOIN操作を行うと簡単になります。

私が設計したデータベースは、3つのテーブルで構成されています。

  • クイック:迅速なアクセスと分析のための最も関連性のある取引情報、
  • TX:すべての残りのトランザクション情報、
  • ブロック:ブロック固有の情報。

変数の命名規則は、ブロックハッシュとトランザクションハッシュの両方を「ハッシュ」と呼ぶ、列名として「from」/「to」を使用するなど、あいまいさを取り除くために、元のweb3pyに対して若干変更されました。 SQLには別の意味があり、プログラムがクラッシュします。

トランザクションの値、残高、その他の大きな数字は、文字列としてデータベースに保存する必要があります。その理由は、SQLiteが処理できるのは、最大8バイトの符号付き整数のみで、最大値は2720³-1= 9223372036854775807であるためです。

ミニデータベースの構築

完全なコードはGitHubにあります。上位スキーマに従ってブロックチェーン情報を整理し、事前に指定された数のブロックのデータを含むblockchain.dbファイルを出力します。それをテストするには、database.pyファイルに移動し、書き込まれるブロックの数に適切な数を選択します。

Nblocks = 10000

デフォルトでは、web3オブジェクトをInfuraエンドポイントに向ける必要があります。 IPCプロバイダー(ローカルノード)がある場合は、その行のコメントを解除するだけでIPCプロバイダーに切り替えることもできます

#またはVM上のノードを介した接続
#web3 = Web3(Web3.IPCProvider( '/ path-to-geth.ipc /'))

パスを修正します。次に、コマンドラインpython database.pyで実行します。コードは、最後に書き込まれたブロックの番号をファイルlastblock.txtにダンプします。これは、中断したところから再開する必要がある場合に備えています。

データベースの使用方法

データベースに最初のエントリを書き込んだら、ipythonシェルを介してデータベースとの通信を開始できます。たとえば、表「Quick」の最初の5行を印刷するには、次のコードを実行できます。

ローカルノードとInfura

大きなデータベースを構築する場合は、gethをダウンロードしてノードを同期する必要があります。同期は3つの基本モードで実行できます。

過去のアカウント状態が必要ない場合は、ノードを高速モードで同期できます[6]。

以下は、このコードがデータベースに書き込む速度を示したプロットです。ローカルで完全に同期されたノード(IPC)とInfura(Infura)のアドレスと通信します。ご覧のように、ローカルノードでこのコードを実行すると、ほぼ2桁(別名100倍)の速度向上が得られるため、成果があります。

ブロック2000000と2000400の間でトランザクションの10ブロックを書き込むのにかかる時間。時間は対数スケール(10⁰= 1、10¹ = 10など;)です。

概要

ブロックチェーン上で何が起こったのか、何が起こったのかという独自のローカルデータベースができたので、探索を開始できます。たとえば、トランザクションが発生してからの数を数えたり、時間の関数として生成されるアドレスの数を確認したりできます。空は、クリーチャーについて学べることの限界です。データサイエンスの遊び場の準備が整いました。そのため、先に進んで調査するか、潜在的なアプリケーションの次の投稿を確認してください。

Validity Labsのブロックチェーン分析サービスに興味がある場合は、analytics @ validitylabs.orgに連絡してください。