Hyperledger Fabric Private Chaincodeを動かしてみる #1 シミュレーション

# はじめに

株式会社日立製作所 研究開発グループ サービスコンピューティング研究部の池川です。
Blockchainに関する研究をしており、特にHyperledgerが管理するOSSを使っています。

本記事では、Hyperledger Fabric Private Chaincodeの紹介とサンプルを使った実行例について説明します。

## Fabric Private Chaincodeとは

Hyperledger Fabric Private Chaincode（FPC）はLinux Foundationのブロックチェーン技術推進コミュニティであるHyperledgerが管理するOSSプロジェクトの1つです。

https://github.com/hyperledger/fabric-private-chaincode

FPCを使用することによって、Hyperledger FabricにおけるChaincodeをTrusted Execution Environment (TEE)上で動作させることができるようになります。
TEE上でChaincodeを実行することによって、トランザクションおよびデータの内容を秘匿（暗号化）した状態で実行することが可能となり、プライバシー保護が必要なユースケースに適応可能となります。

2021年7月現在のFPCの実装ではIntelのCPUが提供しているTEEであるIntel SGXを用いて動作させることができます。
TEEとはIntel Software Guard Extensions (SGX)やARM TrustZone、AMD Secure Encrypted Virtualization (SEV)などCPUベンダ各社が提供しているセキュリティ技術です。
メモリ上に暗号化領域を生成し、そこにプログラムやデータをロードすることでセンシティブなデータを保護しつつプログラムを実行することが可能となるCPUの機能です。
FPCでは、Intel SGXを利用した実装が進められています。

また、FPCの実装はFabric本体のRFCプロセスを管理するhyperledger/fabric-rfcsにて承認されており、将来Fabric本体に統合されるよう開発が進んでいます。

https://github.com/hyperledger/fabric-rfcs

# ビルド環境の構築

Ubuntu Server 20.04 LTSを搭載したサーバを1台立ち上げます。
なお、筆者はAWS上にm5.4xlargeのEC2インスタンスを立ち上げて作業をしました。

以後、立ち上げたインスタンスにssh接続し構築しました。

## 必要なパッケージのインストール

立ち上げたサーバに以下に記載のコマンドを実行し必要なパッケージをインストールします。
本記事ではshellを複数同時に立ち上げる作業があり、`screen`/`tmux`などもインストールしておくことをおすすめします。

```shell
sudo apt update
sudo apt install -y docker docker-compose golang make
# sudo apt install -y tmux
```

## その他設定

パッケージのインストール後、以下のコマンドを実行し各パッケージの設定や環境変数の設定をします。

```shell
# sudoなしでdockerコマンドを使えるようにする
sudo usermod -aG docker $(whoami)

# GO111MODULEの設定を自動にする
go env -w GO111MODULE=auto

# 環境変数の追加（GOPATH・GOBIN・PATHの設定）
echo 'export GOPATH=$HOME/go' >> .bashrc
echo 'export GOBIN=$GOPATH/bin' >> .bashrc
echo 'export PATH=$PATH:$GOBIN' >> .bashrc

# ここで一旦再起動（設定反映のため）
sudo reboot
```

## Fabric Private Chaincodeのソースをダウンロード

`go get`を用いてFPCのソースをダウンロードします。
なお、`git clone`を用いてダウンロードしても大丈夫です。

```shell
go get github.com/hyperledger/fabric-private-chaincode
echo 'export FPC_PATH=$GOPATH/src/github.com/hyperledger/fabric-private-chaincode' >> .bashrc
```

## FPCをビルドするたの環境を構築

以下のコマンドを実行してDockerイメージのビルドと立ち上げを行います。
マシンのスペックにもよりますが15分弱かかるので気長に待ちましょう。

```shell
cd $FPC_PATH/utils/docker
make run

# 10分ほど待ちます
# fpc-development-mainというコンテナが立ち上がります。

# 一旦コンテナから出ましょう
exit
```
ここまでの手順を終えることで、FPCをビルドするための環境が揃ったコンテナイメージを作成することができます。


# FPCのビルドおよび実行

続いて、FPCをビルドするためのコンテナ上のbashを実行しFPC本体をビルドする作業に入ります。

## fpc-development-mainのスタートおよびbashの実行

```shell
# 一旦コンテナから出たことにより、fpc-development-mainコンテナがストップしているので再度スタートする
docker start fpc-development-main

# ビルド環境に入る
docker exec -i -t fpc-development-main bash
```

以降は`fpc-development-main`コンテナ内部のbash上でコマンドを実行します

# FPCのビルドおよび実行

:warning: ここから先はすべてfpc-development-mainコンテナ内のbash上での操作です

# chaincodeのビルド

はじめに以下の手順により、chaincodeをビルドします。
ここではFPCが準備しているサンプルであるechoというchaincodeを動かす手順を紹介します。

なお、通常のFabricではChaincodeの実装にgolangやnodejsを用いますが、FPCではIntel SGX上で動作させるためにもC/C++でのChaincode実装が必要となります。

```shell
cd $FPC_PATH/samples/deployment/test-network
export TEST_CC_ID=echo
export TEST_CC_PATH=${FPC_PATH}/samples/chaincode/echo
make build
```

# fabric-samplesの取得

本記事の手順ではfabric-samplesを元にネットワークの起動を試します。
以下の手順によりfabric-samplesのソースと必要なバイナリを取得しましょう。

```shell
cd $FPC_PATH/samples/deployment/test-network
git clone https://github.com/hyperledger/fabric-samples -b v2.3.0
cd $FPC_PATH/samples/deployment/test-network/fabric-samples
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.3.0 1.4.9 -s
```

# core.yamlの書き換え

Fabricのネットワーク起動に必要となる設定ファイルである`core.yaml`を書き換えます。
FPC側で書き換えのスクリプトが準備されているので、以下の手順で実行します。

```shell
cd $FPC_PATH/samples/deployment/test-network
./setup.sh
```

# fabric-networkの立ち上げ

以下の手順でネットワークの立ち上げおよびchannelのcreate/joinを実施します。
起動できない場合は`up`をする前に一度`down`を実行しておくことにより、初期化され正しく起動できる可能性が高いです。

```shell
cd $FPC_PATH/samples/deployment/test-network/fabric-samples/test-network
#./network.sh down
./network.sh up
./network.sh createChannel -c mychannel -ca -cai 1.4.9 -i 2.3.0
```

# chaincodeのインストール

以下のコマンドにより、chaincodeのインストールを実行します。
実行結果を読み、以下の手順を必ず実施してください。

```shell
cd $FPC_PATH/samples/deployment/test-network
./installFPC.sh
```

:warning: 以下のような結果が出力されるので必ず環境変数に設定しましょう

```shell:結果（動作環境によって必ず異なりますので、各自実行した結果に基づいて環境変数の設定をしてください）
︙
# define (i.e., copy/paste into shell) following environment-variables
# for docker-compose and then start it by calling 'make ercc-ecc-start'
export \
  ORG1_ECC_PKG_ID=echo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
  ORG1_ERCC_PKG_ID=ercc_1.0:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\  
  ORG2_ECC_PKG_ID=echo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
  ORG2_ERCC_PKG_ID=ercc_1.0:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```


# FPCコンテナのスタート

```shell
cd $FPC_PATH/samples/deployment/test-network
export TEST_CC_ID=echo
make ercc-ecc-start
```

# networkファイルのアップデート

tmux等を使って新たに並列でbashを立ち上げ、`docker exec -i -t fpc-development-main bash`を実行し`fpc-development-main`のbashに入ってください

```shell
cd $FPC_PATH/samples/deployment/test-network
./update-connection.sh
```

## clientアプリケーションを用いたの動作確認

```shell
# make fpcclient
cd $FPC_PATH/samples/application/simple-cli-go
make

# export fpcclient settings
export CC_NAME=echo
export CHANNEL_NAME=mychannel
export CORE_PEER_ADDRESS=localhost:7051
export CORE_PEER_ID=peer0.org1.example.com
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_MSPCONFIGPATH=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_CERT_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
export CORE_PEER_TLS_ENABLED="true"
export CORE_PEER_TLS_KEY_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export ORDERER_CA=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export GATEWAY_CONFIG=$FPC_PATH/samples/deployment/test-network/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/connection-org1.yaml

# init our enclave
./fpcclient init $CORE_PEER_ID

# interact with the FPC Chaincode
./fpcclient invoke foo
./fpcclient query foo
```

なお、echoでは実際に台帳に書き込む処理（put_state）を行わず、単純にトランザクションの送信および結果の返却のみを行うものです。
よって、Invokeを実行したとしてもState DBの更新等も発生しません。
実際にLedgerへの書き込みおよびState DBの更新が発生するようなChaincodeに関する記事は別の機会に紹介したいと考えています。

## ネットワークのシャットダウン方法

以下のコマンドを実行することで、chaincodeを終了しfabricネットワークを構成するコンテナをシャットダウンできます。
このコマンド実行後は、ネットワーク起動の手順から順に実行することで再度起動が可能です。

```shell
make -C $FPC_PATH/samples/deployment/test-network ercc-ecc-stop
cd $FPC_PATH/samples/deployment/test-network/fabric-samples/test-network
./network.sh down
```


# さいごに
今回はFabric Private Chaincodeの概要とサンプルの動かし方を紹介しました。
Fabric Private Chaincodeは現在も開発が進んでいますので、引き続きその動向や使い方などを紹介していきたいと思います。