pyethappの導入からcontractの実行まで

# 本記事の目的
EthereumをPythonで使用するためのpyethappの導入からcontractの実行までを纏めました。
本記事では、以下の流れでEthereumでcontractを行うところまでを紹介します。

- Pythonの仮想環境構築
- pyethapp、pyethereumのインストール
- serpentのインストール
- contractのコンパイルと実行

また、本記事で実行したコマンドは、ubuntu(16LTS)、CentOS(6.9)で動作確認しています。

# Ethereum
本記事に出てくるEthereumの関連用語をざっくりと説明します。

### Ethereumとは
Ethereum(エセリウム)はブロックチェーンの元帳において、チューリング完全な契約処理と執行を行うプラットフォームで、ビットコインの複製でなく、完全に独立した仕様と実装を持っています。
ether(イーサ)と呼ばれる組み込みの通貨を持っており、契約実行の際に支払いを求められます。

### contractとは
Ethereumのブロックチェーンの記録はcontract(コントラクト)が行います。
contractは低位の言語であり、バイトコードに似たチューリング完全なコードで書かれています。
contractはEthereumシステム上で働くプログラムで、データ保存、etherの支払い、受け取り、保存が出来ます。
また、分散型で自律的なソフトウェアのエージェントとして、計算可能な長さ無制限の処理を実行することも出来ます。

### 参考
- [ビットコインとブロックチェーン　暗号通貨を支える技術 (NTT出版)](http://www.nttpub.co.jp/search/books/detail/100002391)

# Python仮想環境構築
pyethappを起動するためのPython仮想環境を構築します。

- 仮想環境構築

```sh
$ pip install virtualenv
$ pip install virtualenvwrapper

// ターミナルを再起動して、virtualenvwrapper.shを作る
$ reset

// virtualenvwrapper.shの場所を確認
$ which virtualenvwrapper.sh
/usr/bin/virtualenvwrapper.sh

$ source /usr/bin/virtualenvwrapper.sh

$ export WORKON_HOME=~/Envs
$ mkdir -p $WORKON_HOME

$ mkvirtualenv pyethapp
```

- 起動

```sh
$ cd $WORKON_HOME/pyethapp/bin
$ source activate
```
- 終了

```sh
(pyethapp)$ deactivate
```

### 参考
- http://virtualenvwrapper.readthedocs.io/en/latest/
 

# pyethappのインストール
pyethappとは、PythonをベースとしたEthereumが実装されたモジュールです。
gitではubuntuでのインストール手順のみ書いてありますが、CentOSでもインストールが出来ました。

### Ubuntu/Debian
```sh
$ apt-get install build-essential automake pkg-config libtool libffi-dev libgmp-dev
(pyethapp)$ pip install pyethapp
```

### CentOS
```sh
$ yum groupinstall "Development Tools"
(pyethapp)$ yum install kernel-devel kernel-headers
(pyethapp)$ yum install automake libtool libffi libffi-devel gmp
```

### 参考
- https://github.com/ethereum/pyethapp

- 関連パッケージがないよエラー対策(主にCentOS)
http://stackoverflow.com/questions/31508612/pip-install-unable-to-find-ffi-h-even-though-it-recognizes-libffi
http://www.techblogistech.com/2012/03/installing-build-essentials-in-centos-make-gcc-gdb/
http://blog.goo.ne.jp/asakurah/e/7f9cdf8cbada8841c388ece8cd421432

# pyethereumのインストール

pyethereumは、blockchain、ethereum、miningに関する処理のコアとなるライブラリです。
これをpyethappにインストールすることで、各ライブラリの使用が可能になります。

```sh
(pyethapp)$ cd pyethapp
(pyethapp)$ git clone https://github.com/ethereum/pyethereum/
(pyethapp)$ cd pyethereum
(pyethapp)$ python setup.py install
```

### 参考
- https://github.com/ethereum/pyethereum

# pyethappの実行

データディレクトリは、デフォルトでは"~/.config/pyethapp/leveldb"にあります。

### アカウント作成

```sh
(pyethapp)$ cd pyethapp
(pyethapp)$ pyethapp -d "~/.config/pyethapp/leveldb" account new

// 秘密鍵のpasswordを2回入力
Password to encrypt private key:
Repeat for confirmation:
...
Account creation successful
Address: 8d69118ca81b5878ad22d40b701ea9ae88190a60
Id: None
```

### コンソールでの実行

テスト環境で接続を行うため、--profileにtestnetを指定します。
コンソールを引数にして実行することで、IPythonが起動します。

```sh
(pyethapp)$ workon pyethapp
(pyethapp)$ pyethapp -d "~/.config/pyethapp/leveldb" --profile testnet run --console
```

ライブラリのインポートなしで、ethオブジェクトが使用できます。

```sh
$ eth.latest
<CachedBlock(#0 0cd786a2)>

$ eth.latest.get_balance(eth.coinbase)
0
```

pyethereumライブラリは、コンソール上では、IPythonと同じ方法でインポートすることで使えるようになります。

```sh

// Ethereumで使うユーティリティをインポート
$ import ethereum.utils as u

// テスト用モジュールをインポート
$ import ethereum.tester as t

// テスト用アカウント1のアドレス
$ t.a0
'\x82\xa9x\xb3\xf5\x96*[\tW\xd9\xee\x9e\xefG.\xe5[B\xf1'

$ u.is_numeric(t.a0)
False

$ u.is_string(t.a0)
True

// テスト用アカウント1の秘密鍵(k0)からアドレスへ変換
$ u.privtoaddr(t.k0)
'\x82\xa9x\xb3\xf5\x96*[\tW\xd9\xee\x9e\xefG.\xe5[B\xf1'

// ブロックチェーンの状態を新規作成
$ s=t.state()

// 全てのブロックチェーンを確認
$ s.blocks
[<Block(#0 565a32e6)>]

// 採掘でチェーンを増やす
$ s.mine(n=1)

$ s.blocks
[<Block(#0 50ba5c12)>, <Block(#1 6c0f699b)>]
```


### 参考
- https://github.com/ethereum/pyethapp/wiki/The_Console
- https://github.com/ethereum/pyethereum/wiki/Using-pyethereum.tester

# serpentのインストール

serpentとは、Ethereum contractを記述するための高位のプログラミング言語です。
Pythonと記述方法が似ており、綺麗で簡単なコーディングが可能でありながら、平易なプログラミングスタイルで低位の言語の利点が多く組み合わされた、contractプログラミングに特化した言語です。
serpentのコンパイラはC++で記述されています。

### インストール
2つのインストール方法がありますが、どちらでも構いません。

- ソースコードからインストール

```sh
$ git clone https://github.com/ethereum/serpent.git
$ cd serpent
$ git checkout develop
$ make && sudo make install
$ python setup.py install
```

- pyethapp上でインストール

```sh
(pyethapp)$ git clone https://github.com/ethereum/pyethereum.git
(pyethapp)$ cd pyethereum
(pyethapp)$ git checkout develop
(pyethapp)$ pip install -r requirements.txt
(pyethapp)$ python setup.py install
```

### 実行

pyethappのプロジェクト直下に以下のserpentファイルを作成します。

```mul2.se
def double(x):
 return (x*2)
```

serpentを使ってコンパイルします。

```sh
$ serpent compile mul2.se
// バイトコードが返される
6100...
```

pyethappのコンソール上では、コンパイル後、contractはgasを消費して実行することができます。

```sh
$ d=s.abi_contract("mul2.se")
$ s.block.gas_used
98065
$ d.double(2)
4
$ s.block.gas_used
119618
```


### 参考
- https://github.com/ethereum/wiki/wiki/Serpent
- http://mc2-umd.github.io/ethereumlab/docs/serpent_tutorial.pdf

# 参考まとめ
- Ethereum
[ビットコインとブロックチェーン　暗号通貨を支える技術 (NTT出版)](http://www.nttpub.co.jp/search/books/detail/100002391)
https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI

- virtualenvwrapper
http://virtualenvwrapper.readthedocs.io/en/latest/

- pyethapp
https://github.com/ethereum/pyethapp
https://github.com/ethereum/pyethapp/wiki/The_Console

- 関連パッケージがないよエラー対策(主にCentOS)
http://stackoverflow.com/questions/31508612/pip-install-unable-to-find-ffi-h-even-though-it-recognizes-libffi
http://www.techblogistech.com/2012/03/installing-build-essentials-in-centos-make-gcc-gdb/
http://blog.goo.ne.jp/asakurah/e/7f9cdf8cbada8841c388ece8cd421432

- pyethereum
https://github.com/ethereum/pyethereum
https://github.com/ethereum/pyethereum/wiki/Using-pyethereum.tester

- Serpent
https://github.com/ethereum/wiki/wiki/Serpent
http://mc2-umd.github.io/ethereumlab/docs/serpent_tutorial.pdf