Hyperledger Fabricのチュートリアル触ってみた(FabCar)

# FabCarチュートリアルの内容ほぼそのままになります。
> [!Note]
> Fabricネットワークの基本的なアーキテクチャにまだ慣れていない場合は、先に進む前に[キーコンセプト](https://hyperledger-fabric.readthedocs.io/en/release-1.4/key_concepts.html)セクションにアクセスしてください。
> このチュートリアルは、Fabricアプリケーションの紹介として機能し、シンプルでスマートなコントラクトとアプリケーションを使用することにも注意してください。 Fabricアプリケーションとスマートコントラクトの詳細については、[アプリケーションの開発](https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/developing_applications.html)セクションまたは[コマーシャルペーパーチュートリアル](https://hyperledger-fabric.readthedocs.io/en/release-1.4/tutorial/commercial_paper.html)をご覧ください。

このチュートリアルでは、Fabricアプリがどのように機能するかを確認するために、いくつかのサンプルプログラムを見ていきます。これらのアプリケーションと、それらが使用するスマートコントラクトは、まとめて`FabCar`と呼ばれます。 Hyperledger Fabricブロックチェーンを理解するための素晴らしい出発点となります。アプリケーションとスマートコントラクトを作成して台帳を照会および更新する方法、および認証局を使用して、許可されたブロックチェーンと対話するアプリケーションで使用されるX.509証明書を生成する方法を学習します。

[アプリケーション](https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/application.html)トピックで詳細に説明されているアプリケーションSDKを使用して、スマートコントラクトSDKを使用して台帳を照会および更新するスマートコントラクトを呼び出します。詳細については、[スマートコントラクト](https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/application.html)セクションで説明します。

3つの主要なステップを実行します。
**1. 開発環境のセットアップ**
**2. サンプルスマートコントラクトFabCarについて学習**
**3. FabCarを使用するサンプルアプリケーションの開発**
<img width="565" alt="スクリーンショット 2019-10-30 9.59.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281944/5cf9ddf2-3740-34ba-4f64-60754b3379cc.png">

このチュートリアルを完了すると、Fabricネットワーク内のPeerでホストおよび複製される台帳と対話するためのスマートコントラクトと組み合わせてアプリケーションをプログラムする方法の基本を理解する必要があります。

> [!Note]
> これらのアプリケーションは、[サービスディスカバリー](https://hyperledger-fabric.readthedocs.io/en/release-1.4/discovery-overview.html)および[プライベートデータ](https://hyperledger-fabric.readthedocs.io/en/release-1.4/private-data/private-data.html)とも互換性がありますが、これらの機能を活用するためのアプリの使用方法は明示しません。

## ブロックチェーンネットワークのセットアップ

### サンプルフォルダのインストール
まずはサンプルファイルが入っているフォルダをインストールします。

```bash
$ curl -sSL http://bit.ly/2ysbOFE | bash -s
```

> [!Note]
> この次のセクションでは、`fabric-samples`リポジトリのローカルクローン内の`first-network`サブディレクトリにいる必要があります。

既に[最初のネットワークの構築](https://hyperledger-fabric.readthedocs.io/en/release-1.4/build_network.html)を実行している場合は、このチュートリアルを実行する前に、このネットワークを停止する必要があります。

```bash
$ ./byfn.sh down
```

以前にこのチュートリアルを実行したことがある場合は、次のコマンドを使用して、古くなったコンテナまたはアクティブなコンテナを強制終了します。これにより、Fabric関連であるかどうかにかかわらず、すべてのコンテナが削除されます。

```bash
$ docker rm -f $(docker ps -aq)
$ docker rmi -f $(docker images | grep fabcar | awk '{print $3}')
```

開発環境とそれに付随するネットワークおよびアプリケーションのアーティファクトがない場合は、[前提条件](https://hyperledger-fabric.readthedocs.io/en/release-1.4/prereqs.html)ページにアクセスして、必要な依存関係がマシンにインストールされていることを確認してください。

次に、まだインストールしていない場合は、[サンプル、バイナリ、Dockerイメージのインストール](https://hyperledger-fabric.readthedocs.io/en/release-1.4/install.html)ページにアクセスして、表示される指示に従います。

Mac OSを使用していて、Mojaveを実行している場合は、Xcodeをインストールする必要があります。


## Fabricネットワーク起動
> [!Note]
> この次のセクションでは、`fabric-samples`リポジトリのローカルクローン内の`fabcar`サブディレクトリにいる必要があります。
> このチュートリアルでは、`FabCar`スマートコントラクトとアプリケーションのJavaScriptバージョンを示しますが、fabric-samplesリポジトリには、このサンプルのJavaバージョンとTypeScriptバージョンも含まれています。 JavaまたはTypeScriptバージョンを試すには、以下の`./startFabric.sh`の`javascript`引数を`java`または`typescript`に変更し、ターミナルに書かれた指示に従ってください。

`startFabric.sh`シェルスクリプトを使用してネットワークを起動します。
このコマンドは、ピア、発注者、認証局などで構成されるブロックチェーンネットワークを起動します。また、`FabCar`スマートコントラクトのJavaScriptバージョンをインストールしてインスタンス化します。これは、台帳にアクセスするためにアプリケーションで使用されます。これらのコンポーネントの詳細については、チュートリアルで説明します。

```bash
$ ./startFabric.sh javascript
```

```bash
$ docker ps
CONTAINER ID        IMAGE                                                                                                    COMMAND                  CREATED              STATUS              PORTS                                        NAMES
4bce0c28cb1d        dev-peer1.org2.example.com-fabcar-1.0-a139c9f32bcd86b26c02c1cfecba01c235a9007e24c34b03cb1d82d000696338   "/bin/sh -c 'cd /usr…"   About a minute ago   Up About a minute                                                dev-peer1.org2.example.com-fabcar-1.0
e7f325934e8a        dev-peer0.org2.example.com-fabcar-1.0-264b0a1cb5efbecaac5cf8990339c24474dc8435c6e10f10f2be565d555d0e94   "/bin/sh -c 'cd /usr…"   2 minutes ago        Up 2 minutes                                                     dev-peer0.org2.example.com-fabcar-1.0
da8f05c02a2e        dev-peer1.org1.example.com-fabcar-1.0-791f4e9c59e5c5ae44b5e63c754aaf47cfa4757490019879665238e39ab45594   "/bin/sh -c 'cd /usr…"   3 minutes ago        Up 3 minutes                                                     dev-peer1.org1.example.com-fabcar-1.0
6a58a0bbe601        dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba   "/bin/sh -c 'cd /usr…"   4 minutes ago        Up 4 minutes                                                     dev-peer0.org1.example.com-fabcar-1.0
07cdb4a0529e        hyperledger/fabric-tools:latest                                                                          "/bin/bash"              5 minutes ago        Up 5 minutes                                                     cli
d260218c261a        hyperledger/fabric-peer:latest                                                                           "peer node start"        5 minutes ago        Up 5 minutes        0.0.0.0:8051->8051/tcp                       peer1.org1.example.com
c37d08543b54        hyperledger/fabric-peer:latest                                                                           "peer node start"        5 minutes ago        Up 5 minutes        0.0.0.0:10051->10051/tcp                     peer1.org2.example.com
a38736eb0f8a        hyperledger/fabric-peer:latest                                                                           "peer node start"        5 minutes ago        Up 5 minutes        0.0.0.0:7051->7051/tcp                       peer0.org1.example.com
c0b87033a526        hyperledger/fabric-peer:latest                                                                           "peer node start"        5 minutes ago        Up 5 minutes        0.0.0.0:9051->9051/tcp                       peer0.org2.example.com
3106081772a9        hyperledger/fabric-couchdb                                                                               "tini -- /docker-ent…"   5 minutes ago        Up 5 minutes        4369/tcp, 9100/tcp, 0.0.0.0:6984->5984/tcp   couchdb1
7fd1d0afba67        hyperledger/fabric-ca:latest                                                                             "sh -c 'fabric-ca-se…"   5 minutes ago        Up 5 minutes        7054/tcp, 0.0.0.0:8054->8054/tcp             ca_peerOrg2
8b06bc2b312b        hyperledger/fabric-ca:latest                                                                             "sh -c 'fabric-ca-se…"   5 minutes ago        Up 5 minutes        0.0.0.0:7054->7054/tcp                       ca_peerOrg1
b081773a746c        hyperledger/fabric-couchdb                                                                               "tini -- /docker-ent…"   5 minutes ago        Up 5 minutes        4369/tcp, 9100/tcp, 0.0.0.0:8984->5984/tcp   couchdb3
7d21edf576ab        hyperledger/fabric-couchdb                                                                               "tini -- /docker-ent…"   5 minutes ago        Up 5 minutes        4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp   couchdb0
b4417bb69b19        hyperledger/fabric-orderer:latest                                                                        "orderer"                5 minutes ago        Up 5 minutes        0.0.0.0:7050->7050/tcp                       orderer.example.com
81c6a13d36b7        hyperledger/fabric-couchdb                                                                               "tini -- /docker-ent…"   5 minutes ago        Up 5 minutes        4369/tcp, 9100/tcp, 0.0.0.0:7984->5984/tcp   couchdb2
```
さて、これでサンプルネットワークが稼働し、`FabCar`スマートコントラクトがインストールされ、インスタンス化されました。それを試して、すべてがどのように連携するかを確認するために、アプリケーションの前提条件をインストールしましょう。

## アプリケーションのインストール

次のコマンドを実行して、アプリケーションのFabric依存関係をインストールします。
このプロセスは、`package.json`で定義されている主要なアプリケーションの依存関係をインストールしています。最も重要なのは`fabric-network`クラスです。アプリケーションは、ID、ウォレット、およびゲートウェイを使用して、チャネルに接続し、トランザクションを送信し、通知を待つことができます。
また、このチュートリアルでは、`fabric-ca-client`クラスを使用してユーザーをそれぞれの認証局に登録し、有効なIDを生成してから、`fabric-network`クラスメソッドで使用します。

```bash
$ cd javascript
$ npm install

#　パッケージを最新にする （省略可：場合によっては好ましくないこともある）
$ npm install -g npm-check-updates
$ ncu
$ ncu -u
$ npm install
```


## Adminの記帳実行

ネットワークを作成したとき、管理ユーザー（文字通り`admin`と呼ばれます）が認証局（CA）のレジストラとして作成されました。
最初のステップは、`enrollAdmin.js`プログラムを使用して、`admin`用の秘密鍵、公開鍵、およびX.509証明書を生成することです。
このプロセスでは、証明書署名要求（CSR）を使用します。秘密キーと公開キーが最初にローカルで生成され、次に公開キーがCAに送信されます。
これら3つの資格情報はウォレットに保存されるため、CAの管理者として行動できます。

```bash
$ node enrollAdmin.js
```
出力は次のようになります。

```text
Wallet path: ...fabric-samples/fabcar/javascript/wallet
Successfully enrolled admin user "admin" and imported it into the wallet
```

このコマンドは、ウォレットディレクトリにCA管理者の資格情報を保存しました。
Walletフォルダ内にadminフォルダが作成せれ、その中に秘密鍵・公開鍵・[X.509証明書](https://ja.wikipedia.org/wiki/X.509)が作成されます。


<img width="430" alt="スクリーンショット 2019-10-30 11.00.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281944/39854690-3bba-87db-321c-5376ba3645fa.png">


```plaintext
# admin X.509証明書の内容（例）
{
  "name": "admin",
  "mspid": "Org1MSP",
  "roles": null,
  "affiliation": "",
  "enrollmentSecret": "",
  "enrollment": {
    "signingIdentity": "1fbb7bf5fc5c96ca60a2ba4994c34a05ee035c8f1a5d39866f41eb75daa64f2d",
    "identity": {
      "certificate": "-----BEGIN CERTIFICATE-----\nMIICATCCAaigAwIBAgIUKTPDQzm9jxwmeDfI2QgDsPyqSpIwCgYIKoZIzj0EAwIw\nczELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMT\nE2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTkxMDI3MjI1NzAwWhcNMjAxMDI2MjMw\nMjAwWjAhMQ8wDQYDVQQLEwZjbGllbnQxDjAMBgNVBAMTBWFkbWluMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAEr55bF/LJrkmnaFjsk2RFS35leYYJf08hC3VJGrax\naMtoys5JRtE+Z3iMpcznkBDaQle6IHsBbfiO+FWGcrH5LKNsMGowDgYDVR0PAQH/\nBAQDAgeAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLHwXIroM8Lte2HMBNBpA3Ee\nV/DaMCsGA1UdIwQkMCKAIM1vXyUvKLHv1IcjJII35oHSpeCRgrggKOA62WdRzvyd\nMAoGCCqGSM49BAMCA0cAMEQCIDdJ9un6XpDgxw4vaG04QjQSMlh9/PoDvMs3Ldes\nwOdfAiBxZ8CltM25fnkPRN1C1xucgVNVmK1iuKHtcEpE/FxuaQ==\n-----END CERTIFICATE-----\n"
    }
  }
}
```

## `user1`の登録と記帳

ウォレットに管理者の資格情報が入ったので、台帳のクエリと更新に使用される新しいユーザー`user1`を記帳できます。


```bash
$ node registerUser.js
```

出力は次のようになります。

```
Wallet path: ...fabric-samples/fabcar/javascript/wallet
Successfully registered and enrolled admin user "user1" and imported it into the wallet
```

<img width="435" alt="スクリーンショット 2019-10-30 11.02.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281944/732b5c0e-d8cb-1388-f1d4-abe6bd241330.png">


`admin`の記帳と同様に、このプログラムはCSRを使用して`user1`を記帳し、ウォレットの`admin`の資格情報とともに資格情報を保存します。
これで、2人の個別のユーザー（`admin`と`user1`）のIDが得られ、これらはアプリケーションで使用されます。

台帳と対話する時間…


## 台帳のクエリ

ブロックチェーンネットワークの各Peerは台帳のコピーをホストし、アプリケーションプログラムは台帳の最新の値を照会してアプリケーションに返すスマートコントラクトを呼び出すことで、台帳を照会できます。

クエリの仕組みを簡単に示します。

<img width="570" alt="スクリーンショット 2019-10-30 7.12.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281944/21f9e9de-38b0-d32c-6a13-51696736c1b5.png">

アプリケーションは、クエリを使用して台帳からデータを読み取ります。最も一般的なクエリには、台帳のデータの現在の値、つまり世界の状態が含まれます。ワールドステートはキーと値のペアのセットとして表され、アプリケーションは単一のキーまたは複数のキーのデータを照会できます。さらに、レジャー値の状態は、キー値がJSONデータとしてモデル化されている場合に複雑なクエリをサポートするCouchDBなどのデータベースを使用するように設定できます。これは、特定の値を持つ特定のキーワードに一致するすべてのアセットを探すときに非常に役立ちます。たとえば、特定の所有者がいるすべての車。

まず、`query.js`プログラムを実行して、台帳にあるすべての車のリストを返します。このプログラムは、2番目のID – `user1` –を使用して元帳にアクセスします。


```bash
$ node query.js
```
出力は次のようになります。

```plaintext
Wallet path: ...fabric-samples/fabcar/javascript/wallet
Transaction has been evaluated, result is:
[{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},
{"Key":"CAR1", "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},
{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},
{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},
{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},
{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"205","owner":"Michel"}},
{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},
{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},
{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},
{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]
```

このプログラムを詳しく見てみましょう。エディター（AtomやVisual Studioなど）を使用して、`query.js`を開きます。

アプリケーションは、`fabric-network`モジュールから2つのキークラスをスコープに取り込むことから開始します。 `FileSystemWallet`および`Gateway`。これらのクラスを使用して、ウォレット内の`user1`IDを見つけ、それを使用してネットワークに接続します。

```query.js
const { FileSystemWallet, Gateway } = require('fabric-network');
```
アプリケーションは、ゲートウェイを使用してネットワークに接続します。

```query.js
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: 'user1' });
```

このコードは、新しいゲートウェイを作成し、それを使用してアプリケーションをネットワークに接続します。`ccp`は、ゲートウェイが`wallet`のID`user1`でアクセスするネットワークを示します。`ccp`が`../../basic-network/connection.json`からロードされ、JSONファイルとして解析された方法を確認します。

```query.js
const ccpPath = path.resolve(__dirname, '..', '..', 'basic-network', 'connection.json');
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
```

接続プロファイルの構造と、それがネットワークをどのように定義するかについて詳しく知りたい場合は、[接続プロファイルのトピック](https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/connectionprofile.html)をご覧ください。

ネットワークは複数のチャネルに分割でき、次の重要なコード行はアプリケーションをネットワーク内の特定のチャネル`mychannel`に接続します。

このチャネル内で、スマートコントラクト`fabcar`にアクセスして元帳とやり取りできます。

```query.js
const contract = network.getContract('fabcar');
```

`fabcar`には多くの異なるトランザクションがあり、アプリケーションは最初に`queryAllCars`トランザクションを使用して台帳ワールドステートデータにアクセスします。

```query.js
const result = await contract.evaluateTransaction('queryAllCars');
```

`evaluateTransaction`メソッドは、ブロックチェーンネットワークのスマートコントラクトとの最も単純な相互作用の1つを表します。接続プロファイルで定義されたPeerを選択し、要求を送信するだけで、評価されます。スマートコントラクトは、Peerの台帳のコピーにあるすべての車を照会し、結果をアプリケーションに返します。この相互作用により、台帳は更新されません。

## FabCarスマートコントラクト

`FabCar`スマートコントラクト内のトランザクションを見てみましょう。 `fabric-samples`のルートにある`chaincode/fabcar/javascript/lib`サブディレクトリに移動し、エディターで`fabcar.js`を開きます。

`Contract`クラスを使用してスマートコントラクトがどのように定義されるかを確認します。

```fabcar.js
class FabCar extends Contract {...
```

このクラス構造内で、`initLedger`、`queryCar`、`queryAllCars`、`createCar`、`changeCarOwner`の各トランザクションが定義されていることがわかります。例えば：

```fabcar.js
async queryCar(ctx, carNumber) {...}
async queryAllCars(ctx) {...}
```
`queryAllCars`トランザクションを詳しく見て、台帳とのやり取りを確認しましょう。

```fabcar.js
async queryAllCars(ctx) {

  const startKey = 'CAR0';
  const endKey = 'CAR999';

  const iterator = await ctx.stub.getStateByRange(startKey, endKey);
```

このコードは、`queryAllCars`が台帳から取得する車の範囲を定義します。`CAR0`と`CAR999`の間のすべての車（すべてのキーが適切にタグ付けされていると仮定して、全部で1,000台の車）がクエリによって返されます。残りのコードは、クエリ結果を反復処理し、アプリケーションのJSONにパッケージ化します。

以下は、スマートコントラクトでアプリケーションがさまざまなトランザクションを呼び出す方法を表しています。各トランザクションは、`getStateByRange`などのAPIの広範なセットを使用して、台帳と対話します。これらのAPIについての詳細を[ここ](https://fabric-shim.github.io/master/index.html?redirect=true)から確認できます。
<img width="597" alt="スクリーンショット 2019-10-30 8.42.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281944/45db4dfc-a848-247b-11c0-af628545a666.png">

`queryAllCars`トランザクションと`createCar`という別のトランザクションを確認できます。これをチュートリアルの後半で使用して、台帳を更新し、ブロックチェーンに新しいブロックを追加します。

ただし、最初に`query`プログラムに戻り、`evaluateTransaction`要求を変更して`CAR4`をクエリします。`query`プログラムは次のようになります。


```query.js
const result = await contract.evaluateTransaction('queryCar', 'CAR4');
```

プログラムを保存し、`fabcar/javascript`ディレクトリに戻ります。`query`プログラムを再度実行します。


```bash
$ node query.js
```

以下が表示されるはずです。

```plaintext
Transaction has been evaluated, result is:
{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}
```

戻ってトランザクションが`queryAllCars`だったときの結果を見ると、`CAR4`がAdrianaの黒いTeslaモデルSであり、ここに返された結果であることがわかります。

`queryCar`トランザクションを使用して、キー（`CAR0`など）を使用して任意の車に対してクエリを実行し、その車に対応するメーカー、モデル、色、所有者を取得できます。

この時点で、スマートコントラクトの基本的なクエリトランザクションとクエリプログラムの少数のパラメーターに慣れる必要があります。

台帳を更新する時間…

## 台帳の更新

台帳クエリをいくつか実行し、コードを少し追加したので、台帳を更新する準備ができました。更新の可能性はたくさんありますが、まずは新しい車を作ることから始めましょう。

アプリケーションの観点からは、台帳の更新は簡単です。アプリケーションは、ブロックチェーンネットワークにトランザクションを送信し、検証およびコミットされると、アプリケーションはトランザクションが成功したという通知を受け取ります。これには、ブロックチェーンネットワークのさまざまなコンポーネントが連携して、元帳に対する提案されたすべての更新が有効であり、合意された一貫した順序で実行されるようにするコンセンサスプロセスが含まれます。

<img width="582" alt="スクリーンショット 2019-10-30 9.01.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281944/651747de-f769-1752-0e52-7c0536c7f2b7.png">

上記では、このプロセスを機能させる主要なコンポーネントを確認できます。各台帳のコピー、およびオプションでスマートコントラクトのコピーをホストする複数のPeerと同様に、ネットワークには注文サービスも含まれます。Ordering Serviceは、ネットワークのトランザクションを調整します。ネットワークに接続されているすべての異なるアプリケーションから発生する、明確に定義されたシーケンスでトランザクションを含むブロックを作成します。

台帳の最初の更新により、新しい車が作成されます。 `invoke.js`と呼ばれる別のプログラムがあり、これを使用して台帳を更新します。クエリと同様に、エディターを使用してプログラムを開き、トランザクションを構築してネットワークに送信するコードブロックに移動します。

```invoke.js
await contract.submitTransaction('createCar', 'CAR12', 'Honda', 'Accord', 'Black', 'Tom');
```

アプリケーションがスマートコントラクトトランザクション`createCar`を呼び出して、Tomという所有者と一緒に黒のホンダアコードを作成する方法をご覧ください。ここでは、シーケンシャルキーを使用する必要がないことを示すために、`CAR12`を識別キーとして使用しています。

保存してプログラムを実行します。

```Bash
$ node invoke.js
```

呼び出しが成功すると、次のような出力が表示されます。

```Plaintext
Wallet path: ...fabric-samples/fabcar/javascript/wallet
2018-12-11T14:11:40.935Z - info: [TransactionEventHandler]: _strategySuccess: strategy success for transaction "9076cd4279a71ecf99665aed0ed3590a25bba040fa6b4dd6d010f42bb26ff5d1"
Transaction has been submitted
```

`evaluateTransaction`ではなく`submitTransaction` APIを使用して、`invoke`アプリケーションがブロックチェーンネットワークと対話する方法に注目してください。

```invoke.js
await contract.submitTransaction('createCar', 'CAR12', 'Honda', 'Accord', 'Black', 'Tom');
```

`submitTransaction`は、`evaluateTransaction`よりもはるかに洗練されています。 SDKは、単一のPeerと対話するのではなく、`submitTransaction`提案をブロックチェーンネットワーク内のすべての必要なOrganizationのPeerに送信します。これらの各Peerは、この提案を使用して要求されたスマートコントラクトを実行し、署名してSDKに返すトランザクション応答を生成します。 SDKは、署名されたすべてのトランザクション応答を単一のトランザクションに収集し、それをOrdererに送信します。Ordererは、すべてのアプリケーションからトランザクションを収集してシーケンス化し、トランザクションのブロックにします。次に、これらのブロックをネットワーク内のすべてのピアに配布し、すべてのトランザクションが検証およびコミットされます。最後に、SDKに通知され、アプリケーションに制御を返すことができます。

> [!NOTE]
> `submitTransaction`には、トランザクションが検証されて元帳にコミットされたことを確認するリスナーも含まれています。アプリケーションは、コミットリスナーを利用するか、これを行う`submitTransaction`などのAPIを活用する必要があります。これを行わないと、トランザクションの注文、検証、元帳へのコミットが正常に行われなかった可能性があります。

`submitTransaction`は、アプリケーションに対してこれをすべて行います！ネットワーク全体で元帳の一貫性を保つために、アプリケーション、スマートコントラクト、Peer、およびOrdering Serviceが連携するプロセスはコンセンサスと呼ばれ、この[セクション](https://hyperledger-fabric.readthedocs.io/en/release-1.4/peers/peers.html)で詳しく説明します。

このトランザクションが台帳に書き込まれたことを確認するには、`query.js`に戻り、引数を`CAR4`から`CAR12`に変更します。

つまり、これを変更します。

```query.js
const result = await contract.evaluateTransaction('queryCar', 'CAR4');
```

これに：

```query.js
const result = await contract.evaluateTransaction('queryCar', 'CAR12');
```

もう一度保存して、クエリを実行します。

```bash
$ node query.js
```

これはこれを返すはずです：

```plaintext
Wallet path: ...fabric-samples/fabcar/javascript/wallet
Transaction has been evaluated, result is:
{"colour":"Black","make":"Honda","model":"Accord","owner":"Tom"}
```

おめでとうございます。車を作成し、台帳に記録されていることを確認しました！

それで、私たちはそれをやったので、トムは寛大だと感じており、彼はデイブという名前の人にホンダのアコードを与えたいと考えているとしましょう。

これを行うには、`invoke.js`に戻り、スマートコントラクトトランザクションを`createCar`から`changeCarOwner`に変更し、対応する入力引数を変更します。

```invoke.js
await contract.submitTransaction('changeCarOwner', 'CAR12', 'Dave');
```

最初の引数— `CAR12` —は、所有者を変更する車を識別します。 2番目の引数— `Dave` —は、車の新しい所有者を定義します。 
プログラムを保存して再度実行します。

```bash
$ node invoke.js
```

台帳に再度クエリを実行し、Daveが`CAR12`キーに関連付けられていることを確認します。

```bash
$ node query.js
```

次の結果が返されます。

```plaintext
Wallet path: ...fabric-samples/fabcar/javascript/wallet
Transaction has been evaluated, result is:
{"colour":"Black","make":"Honda","model":"Accord","owner":"Dave"}
```

`CAR12`の所有権は、TomからDaveに変更されました。

> [!NOTE]
> 実際のアプリケーションでは、スマートコントラクトにアクセス制御ロジックが含まれている可能性があります。たとえば、特定の許可されたユーザーのみが新しい車を作成でき、車の所有者のみが他の人に車を転送できます。

##まとめ

いくつかのクエリといくつかの更新を行ったので、スマートコントラクトを使用して台帳をクエリまたは更新することにより、アプリケーションがブロックチェーンネットワークとどのようにやり取りするかについて、かなり良い感覚が得られるはずです。スマートコントラクト、API、SDKがクエリと更新で果たす役割の基本を見てきました。他のビジネスタスクや操作を実行するためにさまざまな種類のアプリケーションをどのように使用できるかを感じる必要があります。

## 追加のリソース
はじめに述べたように、スマートコントラクト、プロセス、データ設計に関する詳細な情報、より詳細なコマーシャルペーパー[チュートリアル](https://hyperledger-fabric.readthedocs.io/en/release-1.4/tutorial/commercial_paper.html)を使用したチュートリアル、およびその他の関連資料を含む[アプリケーション開発](https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/developing_applications.html)に関するセクション全体があります。