このチートシートは何のためのもの?
このチートシートは前の記事の続きです。
前の記事で必要となる諸々のアプリケーションの導入を行った後のインフラ構築部分をこちらに記載しています。
チートシートなので、用語の説明等々はほぼ省略しています。
CentOS用のチートシートはこちら。 作成次第リンクを貼ります。
前提条件
前の記事と同じく、環境が Ubuntu 16.04 LTE であることを前提として作成してあります。
プラットフォームとするHyperledger Fabricのバージョンは 1.2 です。
上記以外のバージョンを利用される場合、インストールする各アプリケーションのバージョンを適切なものに変更してください。
この手順に沿った場合に最終的に出来上がる環境
Githubにある「fabric-samples」の「first-network」をベースに、マルチノードとなるよう構築します。
組織(organization)、ピア、CA、オーダラーは、下記の構成とします。

ホームディレクトリ直下にfabric-samplesをクローンし、それ利用する形で作成します。
この記事ではBNAファイルをインストールための環境構築までの部分を記載します。
BNAファイルは各々実装・作成したものを利用してください。
※管理者以外のアカウントはBNAファイルのインストール後に作成するため、このチートシート内では触れません。
インフラ構築手順
1. 稼働中のDockerコンテナをすべて停止・削除する。
docker kill $(docker ps -q)
docker rm $(docker ps -aq)
docker rmi $(docker images dev-* -q)
docker volume prune  #コンテナの残留ファイルが悪影響を及ぼすことがあるため、このコマンドも必要。
2. Hyperledger Fabric用に環境変数「FABRIC_VERSION」を追加し、環境変数を再読込する。
echo 'export FABRIC_VERSION=hlfv12' >> ~/.profile
source ~/.profile
3. ホームディレクトリ直下に「fabric-sample」のリポジトリをクローンする。
cd ~
git clone https://github.com/mahoney1/fabric-samples.git
cd fabric-samples
4. プラットフォームバイナリをダウンロードする。
curl -sSL http://bit.ly/2ysbOFE | bash -s 1.2.0 1.2.0 0.4.10
5. Gitのブランチを、マルチノード用のものに切り替える。
# multi-orgブランチの、2018年8月9日時点のリポジトリを使用する。Gitの設定ファイルへ問題なくアクセスされるよう、sudoを付けて実行する。
sudo git checkout c0e55d8d40849afa9d1011b8b778b282a8f9e32f
6. サンプルプロジェクト「first-network」に入る。
cd first-network
7. 目的とする組織・ピア・CA・オーダラーの構成に応じて、各設定ファイルを修正する。※デフォルトでは、上記表の構成となる。
詳細は公式ドキュメントを参照してください。各ファイルの概要をざっくり記載すると下記の通りです。
- 
byfn.sh
 ネットワークの生成やDockerコンテナの生成、暗号化キーの生成を行うためのスクリプト。
 チャネル名はこの中で定義されている。
 
- 
crypto-config.yaml
 オーダラーと組織に使用する暗号化キーの生成時に参照される。
 必要に応じて、オーダラーの定義値の修正と、組織の定義値の修正を行う。
 
- 
configtx.yaml
 必要に応じて、オーダラーの定義値の修正と、組織の定義値の修正を行う。
 
- 
docker-compose-cas.yaml
 暗号化キーの内、プライベートキーの生成時に参照される。
 必要に応じて、CA用コンテナの設定値の修正を行う。
 
- 
docker-compose-couch.yaml
 必要に応じて、StateDBと各ピアとの関係に関する設定値の修正を行う。
 
- 
docker-compose-e2e.yaml
 暗号化キーの内、プライベートキーの生成時に参照される。
 必要に応じて、オーダラーとピアとなる各コンテナの定義と設定の修正を行う。
 
- 
docker-compose-cli.yaml
 必要に応じて、オーダラーとピアとなる各コンテナの定義と設定の修正を行う。
 
以降の手順はこれらのファイルに変更を加えていないことを前提に記載しています。
もし変更を加える場合、以降の手順に記載の内容は適宜読み替えて実施してください。
8. first-networkを以下のコマンドでビルドし、最後に大きな文字で「END」と表示されることを確認する。
./byfn.sh -m generate  #このコマンドでスクリプトを実行することよって、各ピアとオーダラーが使用する暗号化キーとGenesisブロック(=ブロックチェーン上の最初のブロック)が生成される。
./byfn.sh -m up -s couchdb -a  #このコマンドによってシェル内で「docker-compose up」コマンドが実行され、docker-compose.yamlで定義されたサービスが開始される。
9. これから追加するカードと重複している既存のカードを確認・削除する。
composer card list  #確認用コマンド
composer card delete -c <カード名>  #このコマンドは、確認用コマンドで見つけた削除対象のカードすべてに対して実行する。
rm -fr ~/.composer
10. 組織Org1とOrg2のコネクションプロファイルを作成するための作業ディレクトリを作成する。
mkdir -p /tmp/composer/org1
mkdir -p /tmp/composer/org2
11. 接続プロファイルの大元となるJSONファイル(tutorial-network.json)を作成する。
touch /tmp/composer/tutorial-network.json
12. tutorial-network.jsonを開き、以下の内容をコピー&ペーストする。
{
    "name": "tutorial-network",
    "x-type": "hlfv1",
    "version": "1.0.0",
    "channels": {
        "mychannel": {
            "orderers": [
                "orderer.example.com"
            ],
            "peers": {
                "peer0.org1.example.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "eventSource": true
                },
                "peer1.org1.example.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "eventSource": true
                },
                "peer0.org2.example.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "eventSource": true
                },
                "peer1.org2.example.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "eventSource": true
                }
            }
        }
    },
    "organizations": {
        "Org1": {
            "mspid": "Org1MSP",
            "peers": [
                "peer0.org1.example.com",
                "peer1.org1.example.com"
            ],
            "certificateAuthorities": [
                "ca.org1.example.com"
            ]
        },
        "Org2": {
            "mspid": "Org2MSP",
            "peers": [
                "peer0.org2.example.com",
                "peer1.org2.example.com"
            ],
            "certificateAuthorities": [
                "ca.org2.example.com"
            ]
        }
    },
    "orderers": {
        "orderer.example.com": {
            "url": "grpcs://★★★ここを自身のホスト・ドメインに書き換える★★★:7050",
            "grpcOptions": {
                "ssl-target-name-override": "orderer.example.com"
            },
            "tlsCACerts": {
                "pem": "INSERT_ORDERER_CA_CERT"
            }
        }
    },
    "peers": {
        "peer0.org1.example.com": {
            "url": "grpcs://★★★ここを自身のホスト・ドメインに書き換える★★★:7051",
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org1.example.com"
            },
            "tlsCACerts": {
                "pem": "INSERT_ORG1_CA_CERT"
            }
        },
        "peer1.org1.example.com": {
            "url": "grpcs://★★★ここを自身のホスト・ドメインに書き換える★★★:8051",
            "grpcOptions": {
                "ssl-target-name-override": "peer1.org1.example.com"
            },
            "tlsCACerts": {
                "pem": "INSERT_ORG1_CA_CERT"
            }
        },
        "peer0.org2.example.com": {
            "url": "grpcs://★★★ここを自身のホスト・ドメインに書き換える★★★:9051",
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org2.example.com"
            },
            "tlsCACerts": {
                "pem": "INSERT_ORG2_CA_CERT"
            }
        },
        "peer1.org2.example.com": {
            "url": "grpcs://★★★ここを自身のホスト・ドメインに書き換える★★★:10051",
            "grpcOptions": {
                "ssl-target-name-override": "peer1.org2.example.com"
            },
            "tlsCACerts": {
                "pem": "INSERT_ORG2_CA_CERT"
            }
        }
    },
    "certificateAuthorities": {
        "ca.org1.example.com": {
            "url": "https://★★★ここを自身のホスト・ドメインに書き換える★★★:7054",
            "caName": "ca-org1",
            "httpOptions": {
                "verify": false
            }
        },
        "ca.org2.example.com": {
            "url": "https://★★★ここを自身のホスト・ドメインに書き換える★★★:8054",
            "caName": "ca-org2",
            "httpOptions": {
                "verify": false
            }
        }
    }
}
「★★★ここを自身のホスト・ドメインに書き換える★★★」と記載している部分は、環境に応じて適切なものに書き換えてください。
localhostにしてしまった場合は外部から接続するときに不便が生じるため、localhostの使用は避けることをお勧めします。
13. 組織「Org1」用の公開鍵情報を、以下のコマンドによって作業用ディレクトリに「ca-org1.txt」というファイル名で書き出す。
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt > /tmp/composer/org1/ca-org1.txt
※ca-org1.txtの出力先ディレクトリは、「/tmp/composer/org1」となります。
14. tutorial-network.json内の「INSERT_ORG1_CA_CERT」となっている部分(2箇所)を、ca-org1.txtの内容で置換し、保存する。
置換後は例えば下記のようになります。
鍵は生成するたびに中身が変わります。以下のものをコピーしても使用できませんので、ご注意ください。
 (省略)
            "tlsCACerts": {
                "pem": "-----BEGIN CERTIFICATE-----\nMIICNTCCAdygAwIBAgIRAMNvmQpnXi7uM19BLdha3MwwCgYIKoZIzj0EAwIwbDEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG\ncmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRowGAYDVQQDExF0bHNjYS5l\neGFtcGxlLmNvbTAeFw0xNzA2MjYxMjQ5MjZaFw0yNzA2MjQxMjQ5MjZaMGwxCzAJ\nBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJh\nbmNpc2NvMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEaMBgGA1UEAxMRdGxzY2EuZXhh\nbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASJn3QUVcKCp+s6lSPE\nP5KlWmE9rEG0kpECsAfW28vZQSIg2Ez+Tp1alA9SYN/5BtL1N6lUUoVhG3lz8uvi\n8zhro18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMB\nAf8EBTADAQH/MCkGA1UdDgQiBCB7ULYTq3+BQqnzwae1RsnwQgJv/HQ5+je2xcDr\nka4MHTAKBggqhkjOPQQDAgNHADBEAiB2hLiS8B1g4J5Qbxu15dVWAZTAXX9xPAvm\n4l25e1oS+gIgBiU/aBwSxY0uambwMB6xtQz0ZE/D4lyTZZcW9SODlOE=\n-----END CERTIFICATE-----\n"
            }
 (省略)
15. 組織「Org2」用の公開鍵情報を、以下のコマンドによって作業用ディレクトリに「ca-org2.txt」というファイル名で書き出す。
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt > /tmp/composer/org2/ca-org2.txt
※ca-org2.txtの出力先ディレクトリは、「/tmp/composer/org2」となります。
16. tutorial-network.json内の「INSERT_ORG2_CA_CERT」の部分(2箇所)を、ca-org2.txtの内容で置換し、保存する。
17. オーダラー用の公開鍵情報を、以下のコマンドによって作業用ディレクトリに「ca-orderer.txt」というファイル名で書き出す。
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt > /tmp/composer/ca-orderer.txt
※ca-orderer.txtの出力先ディレクトリは、「/tmp/composer」となります。
18. tutorial-network.json内の「INSERT_ORDERER_CA_CERT」の部分を、ca-orderer.txtの内容で置換し、保存する。
19. 上の手順で作成・編集したbyfn-network.jsonを、以下の階層・ファイル名となるようコピーする(計2ファイルを作成)。
  ① 	/tmp/composer/org1/tutorial-network-org1.json
  ② 	/tmp/composer/org2/tutorial-network-org2.json
20. tutorial-network-org1.jsonを開き、versionセクションとchannelセクションの間に、以下の通りにclientセクションを追加する。
…(略)…
    "version": "1.0.0",
    "channel": {
…(略)…
…(略)…
    "version": "1.0.0",
    "client": {
        "organization": "Org1",
        "connection": {
            "timeout": {
                "peer": {
                    "endorser": "300",
                    "eventHub": "300",
                    "eventReg": "300"
                },
                "orderer": "300"
            }
        }
    },
    "channel": {
…(略)…
21. tutorial-network-org2.jsonを開き、versionセクションとchannelセクションの間に、以下の通りにclientセクションを追加する。
…(略)…
    "version": "1.0.0",
    "channel": {
…(略)…
…(略)…
    "version": "1.0.0",
    "client": {
        "organization": "Org2",
        "connection": {
            "timeout": {
                "peer": {
                    "endorser": "300",
                    "eventHub": "300",
                    "eventReg": "300"
                },
                "orderer": "300"
            }
        }
    },
    "channel": {
…(略)…
22. 組織Org1のネットワークで使用するAdminアカウント(Admin@org1.example.com)の公開鍵と秘密鍵を、作業用ディレクトリへコピーする。
cd ~/fabric-samples/first-network
rm /tmp/composer/org1/A*.pem /tmp/composer/org1/*_sk
cp -p crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/A*.pem /tmp/composer/org1
cp -p crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/*_sk /tmp/composer/org1
23. 組織Org2のネットワークで使用するAdminアカウント(Admin@org2.example.com)の公開鍵と秘密鍵を、作業用ディレクトリへコピーする。
cd ~/fabric-samples/first-network
rm /tmp/composer/org2/A*.pem /tmp/composer/org2/*_sk
cp -p crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts/A*.pem /tmp/composer/org2
cp -p crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore/*_sk /tmp/composer/org2
24. 組織Org1・Org2それぞれのAdminアカウント用のビジネスネットワークカードを生成する。
composer card create -p /tmp/composer/org1/tutorial-network-org1.json -u PeerAdmin -c /tmp/composer/org1/Admin@org1.example.com-cert.pem -k /tmp/composer/org1/*_sk -r PeerAdmin -r ChannelAdmin -f PeerAdmin@tutorial-network-org1.card
composer card create -p /tmp/composer/org2/tutorial-network-org2.json -u PeerAdmin -c /tmp/composer/org2/Admin@org2.example.com-cert.pem -k /tmp/composer/org2/*_sk -r PeerAdmin -r ChannelAdmin -f PeerAdmin@tutorial-network-org2.card
25. 組織Org1・Org2それぞれのビジネスネットワークカードを、それぞれの組織のウォレットへインポートする。
composer card import -f PeerAdmin@tutorial-network-org1.card --card PeerAdmin@tutorial-network-org1
composer card import -f PeerAdmin@tutorial-network-org2.card --card PeerAdmin@tutorial-network-org2
以上
参考情報