CentOS 6.8(64bit)でbitcoind 0.10.4.0をインストールする方法

## 概説
ここでは、CentOS6.8の環境で、bitcoin0.10.4.0をインストールする方法を示します。

## 前提
- この検証は[Bento Project](https://github.com/chef/bento)の[CentOS 6.8](https://github.com/chef/bento#64-bit)のVagrant Boxを利用しました。
- インストール作業はvagrantユーザーのホームディレクトリ「/home/vagrant」で行うこととします。
- 基本的には公式ドキュメントの「[UNIX BUILD NOTES](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md)」に沿った形で作業を進めますが、公式ドキュメントはUbuntu(Debian)がベースとなっているため、この資料ではCentOS特有の注意点等を補足します。

## 事前準備

「Development Tools」を指定することで、コンパイルに必要なパッケージを一式インストールすることができます。
不要なパッケージがインストールされるのを避けたいのであれば、「[Dependency Build Instructions: Fedora](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md#dependency-build-instructions-fedora)」を参考に、コンパイル関連のパッケージを1つずつ指定してインストールしてください。

```コマンド:コマンド
$ sudo yum groupinstall -y "Development Tools"
```

次に、bitcoindのインストールに必要な[依存パッケージ](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md#dependencies)をインストールします。

```コマンド:コマンド
$ sudo yum install -y libevent2-devel
```

以下のように指定したいところですが、CentOSの場合これではうまくいきません。
ちなみに[AmazonLinux](http://qiita.com/nori3tsu/items/46cd8fed4702db2d05e2)の場合はこれでOKです。

```コマンド:コマンド
$ sudo yum install -y openssl-devel boost-devel libevent-devel
```

「openssl-devel」をパッケージでインストールするとbitcoindのmake（コンパイル）までうまくいくので、一見正しく動いてそうに感じますが、いざサーバーを起動すると以下のエラーが発生し起動できません。ですので、後でソースからインストールを行います。

```コマンド:コマンド
$ sudo service bitcoind start
Starting bitcoind: Bitcoin server starting
                                                           [  OK  ]
Error: OpenSSL appears to lack support for elliptic curve cryptography. For more information, visit https://en.bitcoin.it/wiki/OpenSSL_and_EC_Libraries
Error: Initialization sanity check failed. Bitcoin Core is shutting down.
```

「boost-devel」をインストールすると、1.41というバージョンが入ります。
yumのリポジトリを検索すると、「boost148-devel」というのが見つかりますが、これは恐らく1.48になるかと思います。

```コマンド:コマンド
$ yum search boost148-devel
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.nara.wide.ad.jp
 * epel: www.ftp.ne.jp
 * extras: ftp.nara.wide.ad.jp
 * updates: ftp.nara.wide.ad.jp
============================================= N/S Matched: boost148-devel ==============================================
boost148-devel.i686 : The Boost C++ headers and shared development libraries
boost148-devel.x86_64 : The Boost C++ headers and shared development libraries
```

いずれにしてもCentOS6.8の環境でboost関連のパッケージをインストールすると、1.48以上は入りません。
この状態でインストールを進めると、bitcoindのconfigureやmakeの際に以下のようなエラーが発生しますので、後でソースからインストールすることにします。

boostのバージョンが低いことに対する警告

```エラー:エラー
configure: WARNING: boost versions < 1.49 are known to have symbol visibility issues. Disabling reduced exports.
```

boost-develの関連パッケージであるboost-chronoがインストールされていないことによるエラー（CentOSではboost-chronoというパッケージが存在しません）

```エラー:エラー
scheduler.h:14:35: error: boost/chrono/chrono.hpp: そのようなファイルやディレクトリはありません
```

AmazonLinuxの場合、boost関連のパッケージは1.53がインストールされ、かつ、boost-chronoもパッケージとして存在するため問題無いようです。

```コマンド:コマンド
$ rpm -qa |grep boost
boost-system-1.53.0-14.21.amzn1.x86_64
boost-filesystem-1.53.0-14.21.amzn1.x86_64
boost-wave-1.53.0-14.21.amzn1.x86_64
boost-signals-1.53.0-14.21.amzn1.x86_64
boost-iostreams-1.53.0-14.21.amzn1.x86_64
boost-math-1.53.0-14.21.amzn1.x86_64
boost-1.53.0-14.21.amzn1.x86_64
boost-chrono-1.53.0-14.21.amzn1.x86_64
boost-thread-1.53.0-14.21.amzn1.x86_64
boost-date-time-1.53.0-14.21.amzn1.x86_64
boost-graph-1.53.0-14.21.amzn1.x86_64
boost-timer-1.53.0-14.21.amzn1.x86_64
boost-context-1.53.0-14.21.amzn1.x86_64
boost-test-1.53.0-14.21.amzn1.x86_64
boost-python-1.53.0-14.21.amzn1.x86_64
boost-atomic-1.53.0-14.21.amzn1.x86_64
boost-random-1.53.0-14.21.amzn1.x86_64
boost-devel-1.53.0-14.21.amzn1.x86_64
boost-regex-1.53.0-14.21.amzn1.x86_64
boost-locale-1.53.0-14.21.amzn1.x86_64
boost-program-options-1.53.0-14.21.amzn1.x86_64
boost-serialization-1.53.0-14.21.amzn1.x86_64
```

「libevent-devel」をインストールすると、bitcoindのconfigureのタイミングで以下のエラーが発生するため、「libevent2-devel」をインストールしておきます。（libeventについてはソースでインストールする必要はありません。）

```エラー:エラー
configure: error: libevent not found.
```

### OpenSSLのインストール

```コマンド:コマンド
$ cd ~
$ wget https://www.openssl.org/source/openssl-1.0.2h.tar.gz
$ tar zxvf openssl-1.0.2h.tar.gz
$ cd openssl-1.0.2h
$ ./config --prefix=/usr/local shared
$ make && sudo make install
```

### Boostのインストール

```コマンド:コマンド
$ cd ~
$ wget https://sourceforge.net/projects/boost/files/boost/1.60.0/boost_1_60_0.tar.gz/download -O boost_1_60_0.tar.gz
$ tar zxvf boost_1_60_0.tar.gz
$ cd boost_1_60_0
$ ./bootstrap.sh
$ sudo ./b2 --prefix=/usr/local link=static runtime-link=static install
```

### Berkeley DB4.8のインストール

Berkeley DBは必須パッケージではありませんが、ウォレットの機能を利用する場合は必須となります。ウォレット機能が不要な場合は、bitcoindのconfigureオプションに「--disable-wallet」を指定してください。

```コマンド:コマンド
./configure --disable-wallet
```

公式ドキュメントに「[Berkeley DB 4.8 must be used.](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md#setup-and-build-example-arch-linux)」とあるように、Berkeley DBをインストールする場合はバージョンを4.8に固定する必要があるようです。

Ubuntuの場合は、4.8の機能に一部手を加えた5.1以降のバージョンがインストールされるようで、「--with-incompatible-bdb」といったコンパイルオプションが必要になるらしいです。

CentOSのyumの場合は4.7が入ってしまうので、OpenSSL、Boostと同様にソースからインストールを行います。

```コマンド:コマンド
$ rpm -qa |grep db4
db4-utils-4.7.25-20.el6_7.x86_64
db4-4.7.25-20.el6_7.x86_64
```

```コマンド:コマンド
$ cd ~
$ wget http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz
$ tar zxvf db-4.8.30.NC.tar.gz
$ cd db-4.8.30.NC/build_unix/
$ ../dist/configure --enable-cxx --disable-shared --with-pic --prefix=/usr/local
$ sudo make install
```

## bitcoindのインストール

事前準備が長くなりましたがようやく本題、bitcoindのインストールです。

最新版の「0.12.1」をインストールしたいところですが、「0.12.1」の場合、makeのタイミングで以下のエラーが発生しコンパイルが完了しません。

```エラー:エラー
/home/vagrant/depends/include/boost/system/error_code.hpp: At global scope:
/home/vagrant/depends/include/boost/system/error_code.hpp:221: 警告: ‘boost::system::posix_category’ defined but not used
/home/vagrant/depends/include/boost/system/error_code.hpp:222: 警告: ‘boost::system::errno_ecat’ defined but not used
/home/vagrant/depends/include/boost/system/error_code.hpp:223: 警告: ‘boost::system::native_ecat’ defined but not used
cc1plus: 警告: unrecognized command line option "-Wno-self-assign"
make[2]: *** [libbitcoin_common_a-chainparams.o] エラー 1
make[2]: ディレクトリ `/home/vagrant/bitcoin-0.12.1/src' から出ます
make[1]: *** [all-recursive] エラー 1
make[1]: ディレクトリ `/home/vagrant/bitcoin-0.12.1/src' から出ます
make: *** [all-recursive] エラー 1
```
なので、ひとつ前の安定バージョンである「0.11.2」でconfigureを実行すると、今度は以下のエラーが発生し先に進めません。

```エラー:エラー
configure: error: cannot find install-sh or install.sh in build-aux "."/build-aux
```

ということで、もう一つ前のバージョンである「0.10.4」をインストールします。

```コマンド:コマンド
$ cd ~
$ wget https://github.com/bitcoin/bitcoin/archive/v0.10.4.tar.gz -O bitcoin-0.10.4.tar.gz
$ tar zxvf bitcoin-0.10.4.tar.gz
$ cd bitcoin-0.10.4
$ ./autogen.sh
```

上記の手順を行い、そのままconfigure、makeを実行すると、以下のエラーが発生します。

```エラー:エラー
g++ -I. -I./include -fno-builtin-memcmp -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX -g -O2 -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter -Wno-self-assign  -Wstack-protector -fstack-protector-all -fPIE -fvisibility=hidden -I/home/vagrant/depends/include -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS  -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -c helpers/memenv/memenv.cc -o helpers/memenv/memenv.o
helpers/memenv/memenv.cc: In member function ‘leveldb::Status leveldb::<unnamed>::FileState::Read(uint64_t, size_t, leveldb::Slice*, char*) const’:
helpers/memenv/memenv.cc:65: error: ‘SIZE_MAX’ was not declared in this scope
At global scope:
cc1plus: 警告: unrecognized command line option "-Wno-self-assign"
make[3]: *** [helpers/memenv/memenv.o] エラー 1
make[3]: ディレクトリ `/home/vagrant/bitcoin-0.10.4/src/leveldb' から出ます
make[2]: *** [leveldb/libmemenv.a] エラー 2
make[2]: ディレクトリ `/home/vagrant/bitcoin-0.10.4/src' から出ます
make[1]: *** [all-recursive] エラー 1
make[1]: ディレクトリ `/home/vagrant/bitcoin-0.10.4/src' から出ます
make: *** [all-recursive] エラー 1
```

[既知の不具合](http://bitcoin.stackexchange.com/questions/38837/bitcoin-compile-error-on-centos-6-6-size-max-was-not-declared-in-this-scope)のようですので、リンク先の[Answer](http://bitcoin.stackexchange.com/questions/38837/bitcoin-compile-error-on-centos-6-6-size-max-was-not-declared-in-this-scope#answers)の説明の通り、「memenv.h」の５行目に以下の内容を追記します。

```コマンド:コマンド
$ vi src/leveldb/helpers/memenv/memenv.h
```

```修正前:修正前
5 #ifndef STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_
6 #define STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_
```

```修正後:修正後
5 #ifndef __STDC_LIMIT_MACROS
6 #define __STDC_LIMIT_MACROS
7 #endif
8 #ifndef STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_
9 #define STORAGE_LEVELDB_HELPERS_MEMENV_MEMENV_H_
```

configureオプションについては、[janx/centos-bitcoind-guide.markdown](https://gist.github.com/janx/10465121)、[sapeish/centos-bitcoind-guide.md](https://gist.github.com/sapeish/d79946d54d57458e40aa)を参考にしました。

```コマンド:コマンド
$ LD_LIBRARY_PATH=/usr/local/lib \
LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH \
LIBS="-lssl -lcrypto" \
CPPFLAGS=-I/usr/local/include \
LDFLAGS="-L/usr/local/lib -L/usr/local/lib64" \
SSL_CFLAGS=-I/usr/local/include \
SSL_LIBS="-L/usr/local/lib -L/usr/local/lib64" \
CRYPTO_CFLAGS=-I/usr/local/include \
CRYPTO_LIBS="-L/usr/local/lib -L/usr/local/lib64" \
PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig \
PKG_CONFIG_LIBDIR=/usr/local/lib64 \
./configure \
--with-boost=/usr/local \
--with-boost-libdir=/usr/local/lib
```

configureが完了すると、ログの最後に以下のような気になるメッセージが表示されます。
「[Fixing libtool for -rpath problems](http://pifuge.com/ubuntu/VAqe-fixing-libtool-for-rpath-problems)」や「[How to build and install Bitcoin on CentOS 7](https://www.ndchost.com/wiki/how-to-install-bitcoin-on-centos-7)」を参考に環境変数LIBSに「`LIBS="-Wl,-rpath,/usr/local/lib -lssl -lcrypto"`」、「`LIBS="-Wl,-rpath,/usr/local/lib64 -lssl -lcrypto"`」のような指定をして試してみましたが、結果変わらず。
「`configure: error:`」が発生している訳ではないので、ひとまずこのまま進めます。

```エラー:エラー
Fixing libtool for -rpath problems.
```

コンパイル

```コマンド:コマンド
$ make
```

インストール

```コマンド:コマンド
$ sudo make install
```

## インストール後の確認

`bitcoin-cli`コマンドでインストールがうまくいったか確認してみると以下のエラーが発生します。

```コマンド:コマンド
$ bitcoin-cli 
bitcoin-cli: error while loading shared libraries: libssl.so.1.0.0: cannot open shared object file: No such file or directory
```

つくづくうまくいきませんが、諦めるのはちょっと早いです。これは `LD_LIBRARY_PATH` が通っていないために発生する問題なのでパスを通してしまえば問題ありません。

インストール時と同様に一時的に `LD_LIBRARY_PATH` を通すのであれば、以下のコマンドでOKです。

```コマンド:コマンド
$ LD_LIBRARY_PATH=/usr/local/lib \
LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH \
bitcoin-cli
```

しかし、今回は恒久的にパスを通したいので、 `/etc/ld.so.conf` に追記します。

```コマンド:コマンド
$ sudo vi /etc/ld.so.conf
```

```修正前:修正前
include ld.so.conf.d/*.conf
```

```修正後:修正後
include ld.so.conf.d/*.conf
/usr/local/lib
/usr/local/lib64
```

設定を反映

```コマンド:コマンド
$ sudo ldconfig
```


反映されたことを確認（以下のような表示が出ればOK）

```コマンド:コマンド
$ sudo ldconfig -v
/usr/local/lib:
	libbitcoinconsensus.so.0 -> libbitcoinconsensus.so.0.0.0
/usr/local/lib64:
	libcrypto.so.1.0.0 -> libcrypto.so.1.0.0
	libssl.so.1.0.0 -> libssl.so.1.0.0
```

再度 `bitcoin-cli` コマンドを実行すると、ようやくインストールがうまくいったことが確認できます。

```コマンド:コマンド
$ bitcoin-cli
Bitcoin Core RPC client version v0.10.4.0-gc2e7baf

Usage:
  bitcoin-cli [options] <command> [params]  Send command to Bitcoin Core
  bitcoin-cli [options] help                List commands
  bitcoin-cli [options] help <command>      Get help for a command

Options:
  -?                     This help message
  -conf=<file>           Specify configuration file (default: bitcoin.conf)
  -datadir=<dir>         Specify data directory
  -testnet               Use the test network
  -regtest               Enter regression test mode, which uses a special chain in which blocks can be solved instantly. This is intended for regression testing tools and app development.
  -rpcconnect=<ip>       Send commands to node running on <ip> (default: 127.0.0.1)
  -rpcport=<port>        Connect to JSON-RPC on <port> (default: 8332 or testnet: 18332)
  -rpcwait               Wait for RPC server to start
  -rpcuser=<user>        Username for JSON-RPC connections
  -rpcpassword=<pw>      Password for JSON-RPC connections

SSL options: (see the Bitcoin Wiki for SSL setup instructions)
  -rpcssl                Use OpenSSL (https) for JSON-RPC connections
```

## 感想

パッケージのバージョンの組み合わせによっては上述した以外にも様々なエラーが発生し、なかなかインストール完了まで辿り着かず、CentOS環境でbitcoindをインストールするのは本当に苦労しました。
なので、これまでの状況を鑑みると「本番環境」としてCentOSを利用するのはベストプラクティスではないのだと思います。
どうしてもbitcoind以外のパッケージはyum（もしくはdnf）でインストールしたいというのであれば、公式ドキュメントにも言及があるし[Fedora](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md#dependency-build-instructions-fedora)であれば動くのかな。。。（試してないです）
AmazonLinuxであれば手元で稼働実績があるのでこっちのほうが確実かもしれません。
はぁ、疲れた。

## おまけ

bitcoindを自動起動させるにはinitスクリプトが必要ですが、残念ながら「0.10.4.0」にはinitスクリプトが同梱されていません。

```コマンド:コマンド
$ cat bitcoin-0.10.4/contrib/init/README.md 
Sample configuration files for:

SystemD: bitcoind.service
Upstart: bitcoind.conf
OpenRC:  bitcoind.openrc
         bitcoind.openrcconf

have been made available to assist packagers in creating node packages here.

See doc/init.md for more information.
```

しかし、「0.11.2」であればCentOS用のinitスクリプトも準備されていますので、これを利用して自動起動させることが可能です。（設定方法については[この投稿](http://qiita.com/nori3tsu/items/46cd8fed4702db2d05e2)が非常に参考になります。）

```コマンド:コマンド
$ cat bitcoin-0.11.2/contrib/init/README.md 
Sample configuration files for:

SystemD: bitcoind.service
Upstart: bitcoind.conf
OpenRC:  bitcoind.openrc
         bitcoind.openrcconf
CentOS:  bitcoind.init

have been made available to assist packagers in creating node packages here.

See doc/init.md for more information.
```

## その他参考URL

- [UNIX BUILD NOTES](https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md)
- [bitcoin compile error on CentOS 6.6: ‘SIZE_MAX’ was not declared in this scope](http://bitcoin.stackexchange.com/questions/38837/bitcoin-compile-error-on-centos-6-6-size-max-was-not-declared-in-this-scope#answers)
- [Fixing libtool for -rpath problems](http://pifuge.com/ubuntu/VAqe-fixing-libtool-for-rpath-problems)
- [How to build and install Bitcoin on CentOS 7](https://www.ndchost.com/wiki/how-to-install-bitcoin-on-centos-7)
- [janx/centos-bitcoind-guide.markdown](https://gist.github.com/janx/10465121)
- [sapeish/centos-bitcoind-guide.md](https://gist.github.com/sapeish/d79946d54d57458e40aa)
- [autogen.sh error: possibly undefined macro: PKG_CONFIG_LIBDIR](https://github.com/bitcoin/bitcoin/issues/6432)
- [boost::system::(…)_category defined but not used](http://stackoverflow.com/questions/1814548/boostsystem-category-defined-but-not-used)
- [bitcoindをAWSのAmazon Linuxにインストール](http://qiita.com/nori3tsu/items/46cd8fed4702db2d05e2)
- [CentOS 6.x に bitcoind デーモンをインストールする方法](http://qiita.com/hshimo/items/ef638d5fcdd4e7409b17)
- [Debian 7.7 に bitcoind をインストール](http://qiita.com/hshimo/items/0c0b917355ec10a0d920)
- [brew から bitcoind をインストールする](http://qiita.com/goking/items/c9cb9597a536fba15323)
- [ビットコイン技術に触れてみよう Vol.1 〜Bitcoin Coreサーバーを立ててみる〜](http://fintechjapan.jp/articles/tec_bitcoind001.html)
- [Bitcoindのセットアップ](http://techmedia-think.hatenablog.com/entry/2015/04/02/181014)
- [CentOSでBitcoindを激しく手抜きインストール](http://neoblog.itniti.net/bitcoind-easy-install-centos/)