Amazon Managed Blockchain（Hyperledger Fabric）ハンズオン体験記のフレームワークを2.2に更新してみる

以前、[こちら](https://qiita.com/mine820/items/0639698e7f9b1fe8842f)の記事で、Amazon Managed Blockchain（Hyperledger Fabric）のハンズオン体験記を書いたが、フレームワークのバージョンが1.4でしか動かなかったため、今回2.2で確認しなおしてみました。

基本的には、[こちら](https://docs.aws.amazon.com/ja_jp/managed-blockchain/latest/hyperledger-fabric-dev/managed-blockchain-get-started-tutorial.html)にある手順通りにやれば動くのですが、テキストベースでわかりづらいため、前回からの変更点をわかりやすく書いてみたいと思います。

またせっかくなので、今回はリージョンをバージニア北部（us-east-1）にしてみたいと思います。
（特に見えていませんが ^^;）

# フレームワークのバージョン
今回は、フレームワークのバージョンを2.2にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/55db99fa-a7ef-9aeb-dc44-ee0ef6d30a3f.png)

# クライアント（Cloud9）の設定
## リージョンの設定
今回のバージョンの変更と関係ありませんが、リージョンも変更したので、一応載せておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/3692d140-ee53-4980-67a7-4ee0cbb6dff7.png)

## gitのインストール
新しい手順の方では、goをインストールした後に、再度gitをインストールしていますので、とりあえずやっておきます。

```sh
$ sudo yum install git -y
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/2cc80745-0327-0ff1-5711-e30feca8d7ae.png)

## docker、docker-composeのバージョン
おそらく、最新のバージョンになっているかと思います。
以下のバージョン以上になっていれば良いそうです。
- Docker–17.06.2-ce or later
- Docker-compose–1.14.0 or later
- Go–1.14.x
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/7cc7cbe9-1c85-990d-9bed-cd38429a1600.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/7833f568-30cf-e1c1-f8f2-8e49c95ea455.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/1ef0679f-ba01-67af-e353-5a07886d38ac.png)

## サンプルの取得
このあたりがちょっと違います。
新しいバージョン用のサンプルを取得します。

```sh
$ git clone --branch v2.2.3 https://github.com/hyperledger/fabric-samples.git
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/77b68b48-abe6-a17b-9402-850d6e7dfdbc.png)
ここでは2.2.3用のサンプルを取得しています。

## docker-composeの設定ファイル
こちらも使用するイメージのバージョンのところを修正する必要があります。

```docker-compose-cli.yaml
version: '2'
services:
  cli:
    container_name: cli
    image: hyperledger/fabric-tools:2.2
    tty: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - FABRIC_LOGGING_SPEC=info # Set logging level to debug for more verbose logging
      - CORE_PEER_ID=cli
      - CORE_CHAINCODE_KEEPALIVE=10
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/home/managedblockchain-tls-chain.pem
      - CORE_PEER_LOCALMSPID=MyMemberID
      - CORE_PEER_MSPCONFIGPATH=/opt/home/admin-msp
      - CORE_PEER_ADDRESS=MyPeerNodeEndpoint
    working_dir: /opt/home
    command: /bin/bash
    volumes:
        - /var/run/:/host/var/run/
        - /home/ec2-user/fabric-samples/chaincode:/opt/gopath/src/github.com/
        - /home/ec2-user:/opt/home
```

バージョン以外は変わっていません。
（「MyMemberID」「MyPeerNodeEndpoint」の置き換えを忘れずに）

## 証明書の取得
こちらもバージョンとは関係ないですが、リージョンが変わりましたので、一応載せておきます。

```sh
aws s3 cp s3://us-east-1.managedblockchain/etc/managedblockchain-tls-chain.pem  /home/ec2-user/managedblockchain-tls-chain.pem
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/d892f75b-e0b8-dba9-10ff-eb73647babbb.png)

## チャンネル作成の設定ファイル
ここが大きく変わるところです。

```configtx.yaml
################################################################################
#
#   ORGANIZATIONS
#
#   This section defines the organizational identities that can be referenced
#   in the configuration profiles.
#
################################################################################
Organizations:
    # Org1 defines an MSP using the sampleconfig. It should never be used
    # in production but may be used as a template for other definitions.
    - &Org1
        # Name is the key by which this org will be referenced in channel
        # configuration transactions.
        # Name can include alphanumeric characters as well as dots and dashes.
        Name: MemberID
        # ID is the key by which this org's MSP definition will be referenced.
        # ID can include alphanumeric characters as well as dots and dashes.
        ID: MemberID
        # SkipAsForeign can be set to true for org definitions which are to be
        # inherited from the orderer system channel during channel creation.  This
        # is especially useful when an admin of a single org without access to the
        # MSP directories of the other orgs wishes to create a channel.  Note
        # this property must always be set to false for orgs included in block
        # creation.
        SkipAsForeign: false
        Policies: &Org1Policies
            Readers:
                Type: Signature
                Rule: "OR('Org1.member')"
                # If your MSP is configured with the new NodeOUs, you might
                # want to use a more specific rule like the following:
                # Rule: "OR('Org1.admin', 'Org1.peer', 'Org1.client')"
            Writers:
                Type: Signature
                Rule: "OR('Org1.member')"
                # If your MSP is configured with the new NodeOUs, you might
                # want to use a more specific rule like the following:
                # Rule: "OR('Org1.admin', 'Org1.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org1.admin')"
        # MSPDir is the filesystem path which contains the MSP configuration.
        MSPDir: /opt/home/admin-msp
        # AnchorPeers defines the location of peers which can be used for
        # cross-org gossip communication. Note, this value is only encoded in
        # the genesis block in the Application section context.
        AnchorPeers:
            - Host: 127.0.0.1
              Port: 7051
################################################################################
#
#   CAPABILITIES
#
#   This section defines the capabilities of fabric network. This is a new
#   concept as of v1.1.0 and should not be utilized in mixed networks with
#   v1.0.x peers and orderers.  Capabilities define features which must be
#   present in a fabric binary for that binary to safely participate in the
#   fabric network.  For instance, if a new MSP type is added, newer binaries
#   might recognize and validate the signatures from this type, while older
#   binaries without this support would be unable to validate those
#   transactions.  This could lead to different versions of the fabric binaries
#   having different world states.  Instead, defining a capability for a channel
#   informs those binaries without this capability that they must cease
#   processing transactions until they have been upgraded.  For v1.0.x if any
#   capabilities are defined (including a map with all capabilities turned off)
#   then the v1.0.x peer will deliberately crash.
#
################################################################################
Capabilities:
    # Channel capabilities apply to both the orderers and the peers and must be
    # supported by both.
    # Set the value of the capability to true to require it.
    # Note that setting a later Channel version capability to true will also
    # implicitly set prior Channel version capabilities to true. There is no need
    # to set each version capability to true (prior version capabilities remain
    # in this sample only to provide the list of valid values).
    Channel: &ChannelCapabilities
        # V2.0 for Channel is a catchall flag for behavior which has been
        # determined to be desired for all orderers and peers running at the v2.0.0
        # level, but which would be incompatible with orderers and peers from
        # prior releases.
        # Prior to enabling V2.0 channel capabilities, ensure that all
        # orderers and peers on a channel are at v2.0.0 or later.
        V2_0: true
    # Orderer capabilities apply only to the orderers, and may be safely
    # used with prior release peers.
    # Set the value of the capability to true to require it.
    Orderer: &OrdererCapabilities
        # V1.1 for Orderer is a catchall flag for behavior which has been
        # determined to be desired for all orderers running at the v1.1.x
        # level, but which would be incompatible with orderers from prior releases.
        # Prior to enabling V2.0 orderer capabilities, ensure that all
        # orderers on a channel are at v2.0.0 or later.
        V2_0: true
    # Application capabilities apply only to the peer network, and may be safely
    # used with prior release orderers.
    # Set the value of the capability to true to require it.
    # Note that setting a later Application version capability to true will also
    # implicitly set prior Application version capabilities to true. There is no need
    # to set each version capability to true (prior version capabilities remain
    # in this sample only to provide the list of valid values).
    Application: &ApplicationCapabilities
        # V2.0 for Application enables the new non-backwards compatible
        # features and fixes of fabric v2.0.
        # Prior to enabling V2.0 orderer capabilities, ensure that all
        # orderers on a channel are at v2.0.0 or later.
        V2_0: true
################################################################################
#
#   CHANNEL
#
#   This section defines the values to encode into a config transaction or
#   genesis block for channel related parameters.
#
################################################################################
Channel: &ChannelDefaults
    # Policies defines the set of policies at this level of the config tree
    # For Channel policies, their canonical path is
    #   /Channel/<PolicyName>
    Policies:
        # Who may invoke the 'Deliver' API
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        # Who may invoke the 'Broadcast' API
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        # By default, who may modify elements at this config level
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
    # Capabilities describes the channel level capabilities, see the
    # dedicated Capabilities section elsewhere in this file for a full
    # description
    Capabilities:
        <<: *ChannelCapabilities
################################################################################
#
#   APPLICATION
#
#   This section defines the values to encode into a config transaction or
#   genesis block for application-related parameters.
#
################################################################################
Application: &ApplicationDefaults
    # Organizations is the list of orgs which are defined as participants on
    # the application side of the network
    Organizations:
    # Policies defines the set of policies at this level of the config tree
    # For Application policies, their canonical path is
    #   /Channel/Application/<PolicyName>
    Policies: &ApplicationDefaultPolicies
        LifecycleEndorsement:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Endorsement:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"

    Capabilities:
        <<: *ApplicationCapabilities
################################################################################
#
#   PROFILES
#
#   Different configuration profiles may be encoded here to be specified as
#   parameters to the configtxgen tool. The profiles which specify consortiums
#   are to be used for generating the orderer genesis block. With the correct
#   consortium members defined in the orderer genesis block, channel creation
#   requests may be generated with only the org member names and a consortium
#   name.
#
################################################################################
Profiles:
    OneOrgChannel:
        <<: *ChannelDefaults
        Consortium: AWSSystemConsortium
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - <<: *Org1
```

（2ヶ所の「MemberID」の置き換えを忘れずに）

## チェーンコードの登録
ここが全然違います。
手順を追って進めていきます。

### ベンダーの依存関係のインストール
今回は「abstore」というサンプルのチェーンコードを使用します（前回の「chaincode_example02」は無くなっている）が、それが呼び出すモジュール類をインストールします。

```sh
$ sudo chown -R ec2-user:ec2-user fabric-samples/
$ cd fabric-samples/chaincode/abstore/go/
$ GO111MODULE=on go mod vendor
$ cd -
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/c783a64c-7c7c-04f0-4229-6fb9697e147e.png)

### チェーンコードパッケージを作成
使用するチェーンコードをtar.zipにまとめます。

```sh
$ docker exec cli peer lifecycle chaincode package ./abstore.tar.gz \
--path fabric-samples/chaincode/abstore/go/ \
--label abstore_1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/182fc5c6-2996-b878-2241-918e6a38fff8.png)
なお、「abstore_1」というラベルを付けています。

### パッケージをインストール
まとめたtar.zipをインストールします。

```sh
$ docker exec cli peer lifecycle chaincode install abstore.tar.gz
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/6ed83c6a-65e4-aab5-000c-8abe5a9ea91e.png)

### パッケージを確認
ちゃんとインストールできたか、確認します。

```sh
$ docker exec cli peer lifecycle chaincode queryinstalled
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/c9f00b98-803d-34a0-e625-ec0c3b24aaf3.png)
パッケージのIDと、先ほど付けたラベルが表示されます。

### チェーンコードを承認
まず、環境変数に、先ほどのパッケージIDを登録しておきます。

```sh
$ export CC_PACKAGE_ID=abstore_1:3918d0438fd2ebe48ed1bde01533513a14f788846fd2d72ef054482760e73409
```

その後、チェーンコードの承認を行います。

```sh
$ docker exec cli peer lifecycle chaincode approveformyorg \
--orderer $ORDERER --tls --cafile /opt/home/managedblockchain-tls-chain.pem \
--channelID mychannel --name mycc --version v0 --sequence 1 --package-id $CC_PACKAGE_ID
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/dda0a8fe-ca19-5780-018c-032a4e8ec861.png)

### コミットの準備状況を確認
ここでチェーンコードの準備状況を確認します。

```sh
$ docker exec cli peer lifecycle chaincode checkcommitreadiness \
--orderer $ORDERER --tls --cafile /opt/home/managedblockchain-tls-chain.pem \
--channelID mychannel --name mycc --version v0 --sequence 1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/f6c4f8ad-36a6-967b-05dc-91b597065fd6.png)
ちゃんと最後に「true」があることを確認します。

### チェーンコードをコミット
最後にチェーンコードをコミットします。

```sh
$ docker exec cli peer lifecycle chaincode commit \
--orderer $ORDERER --tls --cafile /opt/home/managedblockchain-tls-chain.pem \
--channelID mychannel --name mycc --version v0 --sequence 1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/e76713d5-01da-8ad1-454b-7224bd6c0a46.png)

### チェーンコードを確認
もう一度チェーンコードを確認します。

```sh
$ docker exec cli peer lifecycle chaincode querycommitted \
--channelID mychannel
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/cd305db5-5f07-0063-7c60-6203ebf42890.png)

## チェーンコードの実行
ここも微妙に変わっていますので、順に追っていきます。

### チェーンコードを初期化
チェーンコードの初期化を行います。
初期値として「a」に100、「b」に200を設定します。

```sh
$ docker exec cli peer chaincode invoke \
--tls --cafile /opt/home/managedblockchain-tls-chain.pem \
--channelID mychannel \
--name mycc -c '{"Args":["init", "a", "100", "b", "200"]}'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/69cbd188-847d-86f8-e47f-7b05aab93574.png)
ちゃんと初期化できていれば、statusで200が返ってきます。

### チェーンコードを照会
「a」の値を確認します。

```sh
$ docker exec cli peer chaincode query \
--tls --cafile /opt/home/managedblockchain-tls-chain.pem \
--channelID mychannel \
--name mycc -c '{"Args":["query", "a"]}'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/b48d946b-9ed8-3e9c-bf69-8d9236ac33b2.png)
「100」が返ってきました。

### チェーンコードを呼び出す
「a」から「b」に「10」送金してみます。

```sh
$ docker exec cli peer chaincode invoke \
--tls --cafile /opt/home/managedblockchain-tls-chain.pem \
--channelID mychannel \
--name mycc -c '{"Args":["invoke", "a", "b", "10"]}'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/679efa19-b247-5850-f7d9-f8d1de9f1ded.png)
送金に成功すれば、statusで200が返ってきます。

念のため、「a」の値を確認してみます。

```sh
$ docker exec cli peer chaincode query \
--tls --cafile /opt/home/managedblockchain-tls-chain.pem \
--channelID mychannel \
--name mycc -c '{"Args":["query", "a"]}'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/0e30b89e-af90-186d-a822-4729b51d543c.png)
「90」に減っていることを確認できました。

# まとめ
変更のポイントは以下になるかと思います。
- サンプルのバージョンを変更
- dockerイメージのバージョンの変更
- チャンネル設定ファイル（configtx.yaml）の記述の変更
- チェーンコードの登録／実行方法の変更