覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Ethereum - Ethereumに関するメモ

Ethereum(イーサリアム)について本読んだりネット見たりして見知ったことをメモしておきます


Ethereumとは

Ethereum Foundation を中心に開発が進められている分散アプリケーションのプラットフォームです。
2013年に Vitalik Buterin が開発を開始しました。
ビットコインの発想にもとづいてブロックチェーンのネットワーク上でアプリケーションを実行できるスクリプト言語を持つプラットフォームです。

ETH と呼ばれる仮想通貨が用意されており、そのETHを媒介にアプリの開発や利用が可能となっています。
Ethereumで動作するアプリは、前提となる条件を元に動作する処理を事前に決めることで動作するタイミングに規定通り動作するため、
スマートコントラクトと呼ばれています。


Vitalik氏の構想

Vitalik氏が構想したものとは、特定アプリケーションのために開発されたブロックチェーンの代わりに、
汎用的なブロックチェーンを開発し、アプリケーションのソースコードを記述するだけで仕組みを提供することでした。
アプリケーションを実行するためのプラットフォームとして実験的に開発されたものがEthereumです。
Ethereum以前のブロックチェーンプロジェクトは、各々が特定の目的を達成するために開発されたものでしたが、Ethereumはプロトコルを定めて汎用性を持たせました。


スマートコントラクト

Ethereum上で実行可能なスマートコントラクトと呼ばれるプログラムを開発することが可能です。
技術的な視点でいうと、スマートコントラクトはEthereum上で実行されるプログラムという表現が適切といえます。
スマートコントラクトは、大雑把にいうと単なるプログラムでステートや関数を持つことができます。
Ethereumに接続されているノード内のEVMという専用の仮想マシン上で実行されます。
ビットコインネットワークでもスクリプトを書くことができますが、実装できる処理に制限があります。
これに対してスマートコントラクトはチューリング完全な言語であるため、複雑な処理を記述することが可能です。
Solidiyというプログラミング言語等でスマートコントラクトを開発することが可能です。


Ethereum is The World Computer

Vitalik氏は、Ethereumを「ワールドコンピュータ」と説明することがあります。
世界そのものが一つのコンピュータであることを意味しています。
Ethereumブロックチェーンは、世界中に存在するコンピュータ群から構成されており、各々のコンピュータは故障することもあれば停電などで電源が落ちることもあります。
しかし、1台でも動作している限りは分散ネットワークで構築されたブロックチェーンは停止しません。
そのため、ブロックチェーン上で動作するアプリケーションは不具合さえなければ常に動作し続けます。
Ethereumブロックチェーンは国家による規制も受けず、誰に管理されず動作ログや状態をブロックチェーン上に保存し、透明性を保ったまま動き続けます。


Ethereumの内部通貨

ビットコインは暗号通貨のプラットフォームです。反面、Ethereumは通貨ではなく、あらゆるプログラム(スマートコントラクト)をブロックチェーン上で動作させるためのプラットフォームです。
双方の到達目標は異なっており、仕組みや構造も異なっています。
が、Ethereumにも内部通過として「Ether」(イーサ)が存在しています。
Etherは、通貨としての利用も可能であり、かつ、プログラムを実行すためのコストとしても利用可能です。
Ethereumではこのコストのことを「Gas」と呼びます。
通貨の単位として細かな単位がいくつも用意されていますが、一般的に最小単位である「wei」 と 「ether」を把握していれば事足ります。
1 ether = 1,000,000,000,000,000,000 wei の関係にあります。


Gas(手数料)

Ethereumではトランザクションを取り込んでもらうために手数料を支払う必要があります。
しかし、その手数料はプログラムを実行にも使用されるため、明確に計算のための燃料として「Gas」と定義されています。
Ethereumでは全ての処理がトランザクションであるため、Ethereumには手数料の概念として、トランザクションを計算する際にこのGasが必要となります

トランザクション実行の際は Gas Price と Gas Limit を設定します。Prilce × Limit が実際に支払い可能と設定するGasの上限となります。
あくまで上限の設定でしかないため、設定額まですべて使い切るわけではなく、使用されなかったGasは戻ってきます。
Gas不足に陥るとトランザクションは失敗するため、十分なGasを用意することが重要となります。
計算量や更新する情報量が多くなれば、消費されるGasも多くなります。

スマートコントラクトのプログラムの処理のステップ数にしたがって、Gasは都度消費されます。
Gasが存在する限りはプログラムは動作を続けますが、有権な設定であるGasはいつかは底をつきます。
無限ループや終わりがない処理も停止し、トランザクションは失敗します。そのため、Gasは無限ループを回避する目的にもなっています。
トランザクションが失敗した場合、ロールバックされますがGasは消費されたことになります。
そのため、Gasは払ったのに処理は正常終了しなかった という状態になります。
例えば、攻撃者がGas Limitを超えるようなトランザクションを大量に発行してネットワークを妨害しようとしても
自身が保持するEtherが失われるため攻撃のインセンティブを働きにくくするというセキュリティ効果もあります。


アカウント構造

Ethereumは以下2種類のアカウントが存在しています

  • 外部アカウント
    • Ethereumを利用するユーザーのアカウント。アドレスと紐づく残高情報を持つ。
  • コントラクトアカウント
    • コントラクト情報を持つアカウント。アドレスと紐づくコード情報と残高情報を持つ。外部アカウントから作成される。

アカウントを表すデータは State Tree に保持されています。State Tree にはEthereumの中で利用するEtherの残高情報が入っています。
State Tree はブロックの外に保持しておき、各ブロックには State Tree のroot値のみを保持しています。

State Tree に保存されるアカウント内部の構造は以下の通りとなっています。

  • nonce
    • アカウントが送信したトランザクション数。トランザクションを発行するたびに+1される。
  • balance
    • アカウントが所持している残高情報(単位:wei)
  • storageRoot
    • アカウントに紐づく Storage Tree のルートノードを表す256ビットハッシュ値です。デフォルト値は空。
      Storage Tree はマークルパトリシアツリー構造で、各々のアカウントで保持されるデータ(文字列や所有権etc)を持っています。
      コントラクトアカウントの場合、コントラクト自身に保持される文字列や配列の情報をここに記録します。
  • codeHash
    • EVM(Ethereum Virtual Machine) コードのハッシュ値です。コントラクトアカウントの場合、実行コードがここに入ります。


残高照会の方式

Ethereumが採用しているアカウント型のメリットは、データ構造が単純な点です。
ビットコインが採用している方式のUTXOの煩雑な処理がなく、アカウントの残高参照のためには、アカウントが持つ残高だけを参照すれば良いので、
即座に残高を確認することができます。


ブロック生成速度

ビットコインはブロックの承認速度を約10分で1回に調整しています。
また、チェーンが分裂する可能性もあるため、最低でも6ブロック(60分)進むまでは確定しないことにした方が良いとされています。

Ethereumはブロックの承認速度は約15秒となっており、ビットコインよりもトランザクションを承認する処理が高速です。
ただし、ブロック承認速度が上がったことによって、マイナー(採掘者)が同時にブロックを採掘する可能性が高くなる問題があります。
ブロックチェーンは、一続きのチェーンになっており、途中で分岐した場合でも1つのブロックを採用しなければなりません。
採掘しても承認されなければ手数料をもらえないモデルであれば、マイナーのモチベーションが下がり、ネットワーク維持に関わる者が減少します。
Ethereumでは承認されなかったブロックを採掘したマイナーにも分け前を与える方式で本問題を解決しています。
承認されなかったブロックはUncleブロック(孤立したブロック)と呼びます。

Uncleブロックに報酬を与えることで、同時にマイニングの中央集権化を解消しています。
早くブロックを生成できるマイニングプールは次のブロックの生成にも早く取りかかることができるため、さらに次のブロックに関しても成功の可能性が高まります。
特定のマイニングプールがマイニングの富を独占しないためにもUncleブロックの存在が生きています。


重いチェーンの採用

Ethereumではビットコインと比較して短時間でブロックが生成されます。
承認されなかったブロックにも分け前が与えられますが、分岐した場合にどのチェーンを正しい歴史として採用するかといった部分にも、
このブロックを構成要素として採用する仕組みをとっています。

チェーンの分岐が発生した場合、ビットコインではナカモトコンセンサスにより最も長いチェーンが正しい歴史として採用されます。
Ethereumでは、Uncleブロックも含めてもっとも重いチェーンを有効なチェーンとして採用します。
チェーンが分岐した際の選択においても、Uncleブロックが考慮される仕組みになっています。
Ethereumのこの仕組みを、Modified GHOSTと呼びます。


Proof of Work

ビットコインのProof of Work はアルゴリズムがSHA-256ハッシュ関数で、比較的簡単な計算を nonce を変更しながら延々と繰り返します。
そのため、単純計算のための専用機械(ASICなど)を用意すれば、高速な処理が可能となります。
ブロック採掘における報酬が一部の高性能専用機器を所持しているユーザに偏ってしまう欠点が存在しています。

上記問題を解決するためEthereumではProof of Work のアルゴリズムとしてEthash を採用しています。


Ethereum Virtual Machine (EVM)

Ethereumはプログラムを実行する基盤として、チューリング完全である EVM(Ethereum Virtual Machine) を備えています。
スマートコントラクトはコードを記述した後に、EVMで実行可能な状態でEthereumブロックチェーンにデプロイされます。

スマートコントラクトのコードはEVM上で実行され、State Tree や State Tree の中のアカウントが持つ Storage Tree を変更していきます。


トランザクション

Ethereumはビットコインと同様、送金する際にトランザクションを発行します。
Ethereumの場合は、外部アカウントからのコントラクト生成、またコントラクトの関数呼び出しの際にもトランザクションが発行されます。
また、コントラクトから別のコントラクトを呼び出すことが可能で、メッセージと呼ばれます。
トランザクションとメッセージは、アカウントの持つ残高やState Tree, Storage Tree を変更するものですが、
変更を伴わない読み出しだけのコールと呼ばれる処理も存在します。コールの場合は、Gasは発生しません。


関連書籍

ブロックチェーンアプリケーション開発の教科書

ブロックチェーンアプリケーション開発の教科書

PostgreSQL - カラムを色々操作したい

PostgreSQLのテーブルのカラムを色々操作したい(変更したい)ことがあったりするので、 それ用のメモです


カラムの型を変更する

ALTER TABLE {テーブル名} ALTER COLUMN {カラム名} TYPE {新しいカラムの型};

■実行例

ALTER TABLE dummy_table ALTER COLUMN col1 TYPE varchar(10);


カラムの名称を変更する

ALTER TABLE {テーブル名} RENAME COLUMN {旧カラム名} TO {新カラム名};

■実行例

ALTER TABLE dummy_table RENAME COLUMN col_old TO col_new;


カラムのデフォルト値を変更する

ALTER TABLE {テーブル名} ALTER COLUMN {カラム名} SET DEFAULT {デフォルト値};

■実行例

ALTER TABLE dummy_table ALTER COLUMN name SET DEFAULT `UNKNOWN`;



関連エントリ

nmapコマンドで対象ホストがPOODLEの脆弱性を抱えているかチェックする

nmapコマンドを利用してSSL3.0が抱えているPOODLEの脆弱性を対象ホストがかかえているのかどうかをチェックします。

namp の準備

nmapを利用しますので使えない場合はインストールしましょう(Macなら以下のような感じとか)

brew install nmap


実行するコマンド

以下を実行します

nmap -sV --version-light --script ssl-poodle -p 443 {host名}

{host名}部分はチェック対象のホストに合わせて変更してください


実行結果

脆弱性があるパターン

POODLEの脆弱性がある対象に実行した場合の例は以下の通りです (一部ホスト名やアドレスは伏せています)

$ nmap -sV --version-light --script ssl-poodle -p 443 xxx.dummy-server.xxx
Starting Nmap 7.70 ( https://nmap.org ) at 2018-07-21 20:04 JST
Nmap scan report for xxx.dummy-server.xxx (9x.2xxx.2xx.2xx)
Host is up (0.048s latency).

PORT    STATE SERVICE VERSION
443/tcp open  ssl/ssl Apache httpd (SSL-only mode)
| ssl-poodle: 
|   VULNERABLE:
|   SSL POODLE information leak
|     State: LIKELY VULNERABLE
|     IDs:  CVE:CVE-2014-3566  OSVDB:113251
|           The SSL protocol 3.0, as used in OpenSSL through 1.0.1i and other
|           products, uses nondeterministic CBC padding, which makes it easier
|           for man-in-the-middle attackers to obtain cleartext data via a
|           padding-oracle attack, aka the "POODLE" issue.
|     Disclosure date: 2014-10-14
|     Check results:
|       TLS_RSA_WITH_AES_128_CBC_SHA
|       TLS_FALLBACK_SCSV properly implemented
|     References:
|       http://osvdb.org/113251
|       https://www.imperialviolet.org/2014/10/14/poodle.html
|       https://www.openssl.org/~bodo/ssl-poodle.pdf
|_      https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3566

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.31 seconds

脆弱性が無いパターン

POODLEの脆弱性が無い対象に実行した場合の例は以下の通りです (一部ホスト名やアドレスは伏せています)

$ nmap -sV --version-light --script ssl-poodle -p 443 xxx.dummy-server.com
Starting Nmap 7.70 ( https://nmap.org ) at 2018-07-21 20:08 JST
Nmap scan report for xxx.dummy-server.com (3xx.2xx.2xx.2xx)
Host is up (0.023s latency).

PORT    STATE SERVICE  VERSION
443/tcp open  ssl/http Apache httpd

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.87 seconds


 結論

nmapに頼らずともSSLv3が有効かどうかは、モロバレです。

とりあえず、さっさとSSLv3は無効化しておくのが良いでしょう。

MS-DOSコマンドで処理時間を計測する

Windowsでコマンドの処理時間を計測したい場合、DOSコマンドだけだと面倒なのでPowerShellの力を借ります。


具体的には、以下のようなコマンドを実行すると処理時間を計測できます

powershell -C Measure-Command {計測したいコマンド}


たとえば以下のようにtreeコマンドの処理時間を計測してみると

powershell -C Measure-Command {tree}


処理時間が以下のように表示されます。(ミリ秒、秒、分・・・などいろんな単位で処理時間が表示されます)

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 1
Milliseconds      : 746
Ticks             : 17464202
TotalDays         : 2.02131967592593E-05
TotalHours        : 0.000485116722222222
TotalMinutes      : 0.0291070033333333
TotalSeconds      : 1.7464202
TotalMilliseconds : 1746.4202


場合によってはミリ秒の単位でだけ処理時間を表示してほしいということがあると思います。
そのような場合は以下のように実行します

powershell -C (Measure-Command {計測したいコマンド}).TotalMilliseconds


たとえば以下のようにtreeコマンドの処理時間を計測してみると

powershell -C (Measure-Command {tree}).TotalMilliseconds


ミリ秒単位の処理時間が以下のように表示されます。

1724.2524


無事に、処理時間の計測が実現できました。

IntelliJ IDEA - Ctrl + マウスホイール操作でフォントサイズを変更できるようにする

人にソースコードを見せる時などに、IntelliJ IDEAのエディタ上のフォントをさっと大きくしたい場合があります。
以下の設定をしておくことで実現可能です。


File > Settings > Editor > General を選択し 「Change font size(Zoom) with Ctrl+Mouse Wheel」 にチェックを入れます。

f:id:nini_y:20171017125133p:plain

その後「OK」ボタンをクリックする。


これで、Ctrlキー + マウスのホイール操作 でエディタ上のフォントを大きくしたり小さくしたりできます。