伊藤  直子

伊藤 直子

1647352920

許可されたブロックチェーンスマートコントラクトを開発する

 Hyperledgerは、分散型台帳、オープンソースのブロックチェーン実装、および分散型台帳フレームワーク、スマートコントラクトエンジン、クライアントライブラリ、グラフィカルインターフェイス、ユーティリティライブラリ、サンプルアプリケーションなどの関連ツールを提供するLinuxFoundationによる包括的なプロジェクトです。

ブロックチェーンは、スマートコントラクトやその他の支援技術のシステムと組み合わせて、コンセンサスによって作成されたトランザクションのピアツーピア分散型台帳です。これらのトランザクションは複製され、ブロックチェーン上の参加しているコンピューターシステムのネットワーク全体に分散されます。言い換えれば、ブロックチェーンは、市場、データ共有ネットワーク、マイクロ通貨、および分散型デジタルコミュニティの法的に準拠したオペレーティングシステムです。

Hyperledger Fabricは、分散型台帳テクノロジー(DLT)が必要な統合プロジェクトを主な目的とした許可されたブロックチェーンインフラストラクチャです。Node.js、JavaScript、およびGo用のSDK以外のユーザー向けサービスは提供していません。ノード間のモジュラーアーキテクチャ、スマートコントラクトの実行、構成可能なコンセンサスおよびメンバーシップサービスを提供します。

この記事では、最初の許可されたブロックチェーンアプリケーションを作成し、スマートコントラクトを調査し、HyperledgerFabricのいくつかの重要な機能について説明します。始めましょう!

HyperledgerFabricについて

Hyperledger Fabric Networkは、3つの主要コンポーネントで構成されています。

ピアノードは、チェーンコードを実行し、元帳データにアクセスし、トランザクションを承認し、アプリケーションとインターフェイスします。ピアノードは、ブロックチェーンライフサイクルの任意の時点で開始、停止、再構成、および削除できます。

注文ノードは、ブロックチェーンの一貫性を確保し、承認されたトランザクションをネットワークのピアに配信します。注文者ノードは、トランザクションの注文、注文サービスの形成、トランザクションのブロックへのパッケージ化、およびこれらのブロックをネットワーク全体のアンカーピアに配布する役割を果たします。

メンバーシップサービスプロバイダー(MSP)ノードは、通常、認証局として実装されます。認証局は、X.509証明書を管理し、メンバーのIDとロールを認証するために使用されます。MSPノードは、証明書の発行、証明書の検証、およびユーザーの認証の背後にあるすべての暗号化メカニズムとプロトコルの抽象化レイヤーです。

ピアノード、スマートコントラクト、元帳、およびブロックチェーンネットワーク間の相互接続

Hyperledger Fabricでは、さまざまなコンセンサスアルゴリズムを使用できますが、実用的なビザンチンフォールトトレランス(PBFT)が最も一般的に使用されます。

機能性

HyperledgerFabricには5つの主要な機能があります。

ID管理

許可されたネットワークの場合、メンバーシップIDサービスはユーザーIDを管理し、ブロックチェーンネットワーク上の参加者を認証します。さらに、開発者は、アクセス制御リストを使用して、追加のレイヤーを介して特定のネットワーク操作を有効にし、制限することができます。たとえば、特定のユーザーIDがチェーンコードアプリケーションの呼び出しを許可されていても、新しいチェーンコードの展開をブロックされている可能性があります。

効率的な処理

ネットワークに同時実行性と並列性を提供するために、Hyperledger Fabricには、たとえばノードオーソリティのタイプによるトランザクションの順序付けが含まれています。開発者は、同じノードで複数のトランザクションを実行し、ノードタイプごとにネットワークロールを割り当てることができます。

モジュール設計

Hyperledger Fabricは、モジュラーアーキテクチャを実装して、ネットワーク設計者に機能的な選択肢を提供します。たとえば、さまざまな暗号化アルゴリズム、アルゴリズムまたはID、暗号化、順序付け、暗号化を利用できるため、ユニバーサルデザインが可能になります。

プライバシーと守秘義務

Hyperledger Fabricを使用すると、競合する企業や、プライベートで機密性の高いトランザクションを必要とするグループを、同じ許可されたネットワーク上で共存させることができます。ネットワークメンバーの特定のサブセットに対する制限付きメッセージングパスなどの機能をサポートします。たとえば、トランザクション、メンバー、チャネル情報などのデータは、明示的にアクセスを許可されていないネットワークメンバーには表示されず、アクセスできません。

チェーンコード機能

エンコーディングロジックは、システムチェーンコード、ライフサイクルと構成システムチェーンコード、承認と検証システムチェーンコードなど、チャネル上の特定のタイプのトランザクションによって呼び出されます。

Hyperledgerファブリックアーキテクチャ

Hyperledger Fabricの機能に慣れてきたので、それを構成するコンポーネントを確認しましょう。

ノード

Hyperledger Fabricでは、ネットワーク上で通信するコンピューティングデバイスはノードと呼ばれます。

クライアント

クライアントは、エンドユーザーに代わって動作できるノードです。

ピア

Hyperledger Fabricには、ピアノードが元帳の状態とパフォーマンスの最適化を担当するピアツーピアネットワークがあります。ピアには2つのタイプがあります。1つは、承認者がトランザクションをシミュレートして承認することです。トランザクションの承認は、シミュレートされたトランザクションの結果に対する署名された応答です。一方、コミッターは、トランザクションをブロックチェーンにコミットする前に、承認を検証し、トランザクションの結果を検証します

トランザクション

HyperledgerFabricトランザクションには2つのタイプがあります。デプロイトランザクションは、パラメータをプログラムとして使用して新しいチェーンコードを作成し、ブロックチェーンにチェーンコードをインストールします。呼び出しトランザクションは、以前のチェーンコードまたはスマートコントラクトの展開のコンテキストで実行されます。

データ構造

Key-Value Store(KVS)は、ブロックチェーンの基本的なデータ構造です。多くの場合、キーは名前であり、値はblobです。KVSは2つの操作、PUTおよびをサポートしGETます。データ構造は、特定の時点での状態と見なされます。デフォルトの状態データベースであるLevelDBは、 CouchDBに置き換えることができます。

元帳

トランザクションの順序付きハッシュチェーンブロックと呼ばれるものでは、状態の変化が発生順に保存されるため、後で簡単に参照できます。ブロックチェーンは、元帳内のトランザクションを記録します。元帳には、順序付けされたトランザクション配列を含む順序付けられたブロックが含まれています。元帳は、成功したか失敗したかにかかわらず、すべての状態変更を保存します。

ファブリックデータベース

Hyperledger Fabricでは、データは状態データベースと元帳データベースの2か所に保存されます。

現在の状態データは、元帳内のすべての資産の最新の値を表します。現在の状態は、チャネル上でコミットされたすべてのトランザクションを表すため、ワールド状態と呼ばれることもあります。

元帳データベースには、各ブロックに1つ以上のトランザクションがあるシリアル化されたブロックが格納されます。各トランザクションには、1つ以上のキーと値のペアを変更する読み取り/書き込みセットが含まれています。元帳はデータの決定的なソースであり、不変です。

注文メカニズム

Hyperledger Fabricは、3つの順序付けメカニズムを提供します。

単一の順序付けノードを含むSOLO順序付けメカニズムは、HyperledgerFabricネットワークを実験している開発者によって最も一般的に使用されます。

Kafkaの注文メカニズムは、実稼働での使用をお勧めします。データは、承認されたトランザクションとRWセットで構成されます。Apache Kafkaを使用しているため、このタイプの順序付けはクラッシュフォールトトレラントです。

最後に、Simplified Byzantine Fault Toleranceの順序付けメカニズムは、クラッシュフォールトトレラントとビザンチンフォールトトレラントの両方であり、悪意のあるノードや障害のあるノードが存在する場合でも合意に達することができます。

コンセンサス

分散型台帳システムでは、コンセンサスは、元帳に追加される次の一連のトランザクションについて合意に達するプロセスです。Hyperledger Fabricは、3つの異なるステップで構成されています。

まず、トランザクション承認ステップで、承認ピアがチェーンコードを実行します。チェーンコードが成功すると、元帳の実際のトランザクションが生成されます。次に、承認ピアがトランザクションに署名し、提案者に返します。

順序付けサービスは厳密な順序付けをサポートします。つまり、トランザクションT1がすでにブロック内に書き込まれている場合B1、同じトランザクションをまたはのT1ような別のブロックに再書き込みすることはできませB2B3。最後に、検証とコミットメントには、トランザクション検証と元帳コミットメントが含まれます。

スマートコントラクト

スマートコントラクトは、グローバル状態に含まれるビジネスオブジェクトのライフサイクルを制御するトランザクションロジックを定義します。Hyperledger Fabricでは、スマートコントラクトの実行はチェーンコードと呼ばれます。Hyperledger Fabricユーザーは、スマートコントラクトとチェーンコードという用語を同じ意味で使用することがよくあります。

Hyperledger Fabricのスマートコントラクトはチェーンコードとも呼ばれ、Goで記述されています。チェーンコードはHyperledgerFabricネットワークのビジネスロジックとして機能し、スマートコントラクトは関与するノードがネットワーク内のアセットを操作する方法を指示します。

アプリケーションがネットワークとどのように相互作用するか

Hyperledger Fabricでは、スマートコントラクトとチェーンコードがネットワーク上でホストされ、名前とバージョンで識別されます。チェーンコードまたはスマートコントラクトを実行するために、アプリケーションはSDKによって実装されるSDKAPIを使用します。

Hyperledger Fabricには、開発者がアプリケーションを作成するための3つのオプション、Node.js SDK、Java SDK、およびCLIがあります。さらに、Hyperledgerは、ユーザーがHyperledgerFabricの機能を探索するためのHyperledgerFabricサンプルを提供します。

許可されたブロックチェーンアプリケーションの開発

Hyperledger Fabricアーキテクチャを理解したので、許可されたブロックチェーンアプリケーションを作成しましょう。まず、HyperledgerFabricアプリケーションを開発するときに実行する主な手順を明確にしましょう。

まず、スマートコントラクトが実行されるネットワークのインストールを含め、開発環境をセットアップする必要があります。次に、Node.jsSDKとアプリケーションの背後にあるコアプログラミングを理解する必要があります。Hyperledger Fabricは、Go、JavaScript、Javaなどの複数のSDKを提供します。このチュートリアルでは、少しのGoとたくさんのJavaScriptを使用します。

さらに、トランザクションを含むサンプルのスマートコントラクトを理解する必要があります。アプリによってシミュレートされたクエリを実行し、元帳も更新します。最後に、スマートコントラクトを使用してサンプルブロックチェーンアプリケーションを開発します。

開発環境をセットアップする

前提条件

Hyperledger Fabricを使用して開発環境をセットアップするには、次のものが必要です。

  1. cURLの最新バージョン
  2. DockerおよびDockerCompose≥v17.06.2-ce
  3. v1.12.xに移動
  4. Node.js≥v8.9または≥v10.15.3

インストール

この例では、LinuxベースのディストリビューションUbuntu20.04および18.04を使用します。まず、現在のマシンをで更新しますsudo apt-get update。次に、以下に示すように、でcURLをインストールしsudo apt instal curl、でcURLのバージョンを確認しcurl --versionます。

 curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

Docker

必要なDockerパッケージを次のようにインストールする必要があります。

sudo apt-get install apt-transport-https ca-certificates gnupg-agent software-properties-common

次に、Dockerの公式GPGキーを追加します。

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -Check OK

Dockerをセットアップするには、次のコードを実行します。

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs)  stable"

以下のコードでDockerをインストールします。

sudo apt-get install docker-ce docker-ce-cli containerd.io`

docker --version次のコードスニペットでDockerのバージョンを確認します。

logrocket:~$ docker --version
Docker version 20.10.12, build e91ed57

次に、Dockerエンジンをテスト実行します。

docker run hello-world

DockerCompose

Docker Composeの最新バージョンをダウンロードするには、次のコードを実行します。

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

権限を実行可能ファイルに変更しsudo chmod +x /usr/local/bin/docker-composeます。Docker Composeのバージョンを確認するには、次のように実行docker-compose --versionします。

logrocket:~$ docker-compose --version
docker-compose version 1.25.5, build 8a1c60f6

行け

ファイルをダウンロードしtarます。

curl -O https://storage.googleapis.com/golang/go1.12.9.linux-amd64.tar.gz

Goディレクトリを移動します。

sudo mv go1.12.9.linux-amd64.tar.gz /usr/local/

tar以下のコードでファイルを抽出します。

sudo tar -xvzpf /usr/local/go1.12.9.linux-amd64.tar.gz

tar次のコードでファイルを削除できます。

sudo rm -rf /usr/local/go1.12.9.linux-amd64.tar.gz

環境変数

でプロファイルを開き、ファイルの最後に変数をvim .profile追加します。PATH.profile

export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin

でソースプロファイルにsource ~/.profile移動し、次のコードで現在のGoバージョンを確認します。

logrocket:~$ go version
go version go1.12.9 linux/amd64

Node.js

以下のコードを実行して、Node.jsv10.xを取得します。

curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -`

以下のコマンドでNode.jsをインストールします。

sudo apt-get install -y nodejs

Node.jsの現在のバージョンを確認するには、次のコードを実行します。

nodejs --version
logrocket:~$ nodejs --version
v10.19.0

ここで、npmのバージョンを次のように確認しますnpm -v

logrocket:~$ npm -v
6.14.4

Hyperledgerファブリック

以下のコードを実行して、新しいディレクトリを作成します。

mkdir hyperledger-fabric && cd hyperledger-fabric

Docker権限を追加します:

sudo usermod -aG docker $USER

権限を確認し、ターミナルを更新します。

logrocket:~$ id -nG
tapasweni adm cdrom sudo dip plugdev lpadmin lxd sambashare
newgrp docker

Fabricv1.4.7をダウンロードします。

curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh  | bash -s -- 1.4.7 1.4.7 0.4.20


logrocket:~$ curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh  | bash -s -- 1.4.7 1.4.7 0.4.20

Clone hyperledger/fabric-samples repo

===> Cloning hyperledger/fabric-samples repo
Cloning into 'fabric-samples'...
remote: Enumerating objects: 9165, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 9165 (delta 0), reused 1 (delta 0), pack-reused 9164
Receiving objects: 100% (9165/9165), 5.21 MiB | 3.71 MiB/s, done.
Resolving deltas: 100% (4898/4898), done.
===> Checking out v1.4.7 of hyperledger/fabric-samples

Pull Hyperledger Fabric binaries

===> Downloading version 1.4.7 platform specific fabric binaries
===> Downloading:  https://github.com/hyperledger/fabric/releases/download/v1.4.7/hyperledger-fabric-linux-amd64-1.4.7.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   680  100   680    0     0   1683      0 --:--:-- --:--:-- --:--:--  1679
100 79.3M  100 79.3M    0     0  4614k      0  0:00:17  0:00:17 --:--:-- 4762k
==> Done.
===> Downloading version 1.4.7 platform specific fabric-ca-client binary
===> Downloading:  https://github.com/hyperledger/fabric-ca/releases/download/v1.4.7/hyperledger-fabric-ca-linux-amd64-1.4.7.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   683  100   683    0     0   1876      0 --:--:-- --:--:-- --:--:--  1876
100 23.6M  100 23.6M    0     0  3962k      0  0:00:06  0:00:06 --:--:-- 4904k
==> Done.

Pull Hyperledger Fabric docker images

FABRIC_IMAGES: peer orderer ccenv tools
===> Pulling fabric Images
====> hyperledger/fabric-peer:1.4.7
1.4.7: Pulling from hyperledger/fabric-peer
Digest: sha256:a395036c83125ccf3820eb1752ac9ba8017e4432768b59d658bfba91a311d154
Status: Image is up to date for hyperledger/fabric-peer:1.4.7
docker.io/hyperledger/fabric-peer:1.4.7
====> hyperledger/fabric-orderer:1.4.7
1.4.7: Pulling from hyperledger/fabric-orderer
Digest: sha256:aef31580eee468e08eb8354bb5f2ec23e0fc12f9b638bd41d207dd5e4d6c6e60
Status: Image is up to date for hyperledger/fabric-orderer:1.4.7
docker.io/hyperledger/fabric-orderer:1.4.7
====> hyperledger/fabric-ccenv:1.4.7
1.4.7: Pulling from hyperledger/fabric-ccenv
Digest: sha256:11dbbdce7f3f789d7bbc758b593005e9aeccd991ed64a3f296e824aaf67f07c6
Status: Image is up to date for hyperledger/fabric-ccenv:1.4.7
docker.io/hyperledger/fabric-ccenv:1.4.7
====> hyperledger/fabric-tools:1.4.7
1.4.7: Pulling from hyperledger/fabric-tools
Digest: sha256:59328549b3384f565cb5bd19b74c977820781e4709158666ead74fcd970c11e1
Status: Image is up to date for hyperledger/fabric-tools:1.4.7
docker.io/hyperledger/fabric-tools:1.4.7
===> Pulling fabric ca Image
====> hyperledger/fabric-ca:1.4.7
1.4.7: Pulling from hyperledger/fabric-ca
Digest: sha256:9418ea351bfbef4bf2bca34bcd77305bdb9a45d2c1aab3237c08c17da0b4d1dd
Status: Image is up to date for hyperledger/fabric-ca:1.4.7
docker.io/hyperledger/fabric-ca:1.4.7
===> List out hyperledger docker images
hyperledger/fabric-ca        1.4            743a758fae29   19 months ago   154MB
hyperledger/fabric-ca        1.4.7          743a758fae29   19 months ago   154MB
hyperledger/fabric-ca        latest         743a758fae29   19 months ago   154MB
hyperledger/fabric-tools     1.4            a026b435e575   19 months ago   1.49GB
hyperledger/fabric-tools     1.4.7          a026b435e575   19 months ago   1.49GB
hyperledger/fabric-tools     latest         a026b435e575   19 months ago   1.49GB
hyperledger/fabric-ccenv     1.4            c5fbec1827ad   19 months ago   1.36GB
hyperledger/fabric-ccenv     1.4.7          c5fbec1827ad   19 months ago   1.36GB
hyperledger/fabric-ccenv     latest         c5fbec1827ad   19 months ago   1.36GB
hyperledger/fabric-orderer   1.4            df155b01ed80   19 months ago   123MB
hyperledger/fabric-orderer   1.4.7          df155b01ed80   19 months ago   123MB
hyperledger/fabric-orderer   latest         df155b01ed80   19 months ago   123MB
hyperledger/fabric-peer      1.4            5d5fbecd1efe   19 months ago   131MB
hyperledger/fabric-peer      1.4.7          5d5fbecd1efe   19 months ago   131MB
hyperledger/fabric-peer      latest         5d5fbecd1efe   19 months ago   131MB
hyperledger/fabric-baseos    amd64-0.4.20   121a92cc3fc0   22 months ago   85MB
logrocket:~$ cURL hyperledger/fabric-samples

次に、環境変数を更新します。

vim .profile
export PATH=/home/$USER/hyperledger/fabric-samples/bin:$PATH
source ~/.profile

HyperledgerFabricを実行する

中に入るfabric-samples/first-network

HyperledgerFabricの最初のネットワークディレクトリ

ネットワークを立ち上げる./byfn.sh up

logrocket:~$ cd first-network/
logrocket:~$ ls
base               channel-artifacts     connection-org2.yaml    docker-compose-cli.yaml           docker-compose-kafka.yaml  scripts
byfn.sh            configtx.yaml         connection-org3.json    docker-compose-couch-org3.yaml    docker-compose-org3.yaml
ccp-generate.sh    connection-org1.json  connection-org3.yaml    docker-compose-couch.yaml         eyfn.sh
ccp-template.json  connection-org1.yaml  crypto-config.yaml      docker-compose-e2e-template.yaml  org3-artifacts
ccp-template.yaml  connection-org2.json  docker-compose-ca.yaml  docker-compose-etcdraft2.yaml     README.md
logrocket:~$ ./byfn.sh -m up
Starting for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds
Continue? [Y/n] 
proceeding ...
LOCAL_VERSION=1.4.7
DOCKER_IMAGE_VERSION=1.4.7
/home/tapasweni/hyperledger/fabric-samples/first-network/../bin/cryptogen

##########################################################
##### Generate certificates using cryptogen tool #########
##########################################################
+ cryptogen generate --config=./crypto-config.yaml
org1.example.com
org2.example.com
+ res=0
+ set +x

Generate CCP files for Org1 and Org2
/home/tapasweni/hyperledger/fabric-samples/first-network/../bin/configtxgen
##########################################################
#########  Generating Orderer Genesis block ##############
##########################################################
CONSENSUS_TYPE=solo
+ '[' solo == solo ']'
+ configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
2021-12-31 17:52:52.853 IST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-12-31 17:52:53.051 IST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: solo
2021-12-31 17:52:53.051 IST [common.tools.configtxgen.localconfig] Load -> INFO 003 Loaded configuration: /home/tapasweni/hyperledger/fabric-samples/first-network/configtx.yaml

Dockerを次のように確認しdocker ps -aます:

logrocket:~$ docker ps -a
CONTAINER ID   IMAGE                                                                                                  COMMAND                  CREATED              STATUS              PORTS                                           NAMES
ef86361332c7   dev-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab   "chaincode -peer.add…"   About a minute ago   Up About a minute                                                   dev-peer1.org2.example.com-mycc-1.0
c9008d040273   dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb25174305fce8f53f4e94d45ee3b6cab0ce9   "chaincode -peer.add…"   2 minutes ago        Up 2 minutes                                                        dev-peer0.org1.example.com-mycc-1.0
9ad7861a975c   dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b   "chaincode -peer.add…"   4 minutes ago        Up 4 minutes                                                        dev-peer0.org2.example.com-mycc-1.0
91ce4e6cfaf5   hyperledger/fabric-tools:latest                                                                        "/bin/bash"              5 minutes ago        Up 5 minutes                                                        cli
c4e3238a2301   hyperledger/fabric-orderer:latest                                                                      "orderer"                6 minutes ago        Up 5 minutes        0.0.0.0:7050->7050/tcp, :::7050->7050/tcp       orderer.example.com
416a0f98cb6b   hyperledger/fabric-peer:latest                                                                         "peer node start"        6 minutes ago        Up 5 minutes        0.0.0.0:10051->10051/tcp, :::10051->10051/tcp   peer1.org2.example.com
84e42d29fab9   hyperledger/fabric-peer:latest                                                                         "peer node start"        6 minutes ago        Up 5 minutes        0.0.0.0:7051->7051/tcp, :::7051->7051/tcp       peer0.org1.example.com
7ad2e6e34292   hyperledger/fabric-peer:latest                                                                         "peer node start"        6 minutes ago        Up 5 minutes        0.0.0.0:8051->8051/tcp, :::8051->8051/tcp       peer1.org1.example.com
9ff94883cacf   hyperledger/fabric-peer:latest                                                                         "peer node start"        6 minutes ago        Up 5 minutes        0.0.0.0:9051->9051/tcp, :::9051->9051/tcp       peer0.org2.example.com
logrocket:~$ 

次のコマンドでネットワークを停止し./byfn.sh downます。

logrocket:~$ ./byfn.sh -m down
Stopping for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds
Continue? [Y/n] 
proceeding ...
WARNING: The BYFN_CA1_PRIVATE_KEY variable is not set. Defaulting to a blank string.
WARNING: The BYFN_CA2_PRIVATE_KEY variable is not set. Defaulting to a blank string.
Stopping cli                    ... done
Stopping peer0.org2.example.com ... done
Stopping peer0.org1.example.com ... done
Stopping peer1.org2.example.com ... done
Stopping peer1.org1.example.com ... done
Stopping orderer.example.com    ... done
Removing cli                    ... done
Removing peer0.org2.example.com ... done
Removing peer0.org1.example.com ... done
Removing peer1.org2.example.com ... done
Removing peer1.org1.example.com ... done
Removing orderer.example.com    ... done
Removing network net_byfn
Removing volume net_orderer.example.com
Removing volume net_peer0.org1.example.com
Removing volume net_peer1.org1.example.com
Removing volume net_peer0.org2.example.com
Removing volume net_peer1.org2.example.com
Removing volume net_orderer2.example.com
WARNING: Volume net_orderer2.example.com not found.
Removing volume net_orderer3.example.com
WARNING: Volume net_orderer3.example.com not found.
Removing volume net_orderer4.example.com
WARNING: Volume net_orderer4.example.com not found.
Removing volume net_orderer5.example.com
WARNING: Volume net_orderer5.example.com not found.
Removing volume net_peer0.org3.example.com
WARNING: Volume net_peer0.org3.example.com not found.
Removing volume net_peer1.org3.example.com
WARNING: Volume net_peer1.org3.example.com not found.
1c1c3bd27578
052b542e408f
2371102e3fa1
Untagged: dev-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab:latest
Deleted: sha256:574b46ed09496b052b9963d79362fa3e15d5430d6f7e227c8edccfe37a94a54d
Deleted: sha256:89856e5feb7feafde31a15decf9d2657f7344e38ee90bc8e73f7c0e189a0422c
Deleted: sha256:570373df622999f59a978635db23a4ce6f6f3c6b1067aeafd3d2a64b4b1020b0
Deleted: sha256:31ce9090622db38830dfdc3209c4044d70f7345e863fcd54c40ac2d2a2abbf03
Untagged: dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb25174305fce8f53f4e94d45ee3b6cab0ce9:latest
Deleted: sha256:c40d025bb22f74cfa14568a70257964d94b557e23811c9bfb5d4591200f64b62
Deleted: sha256:b9e1d83750424813abf0fe6f96fbc3904680bf0ae23474b4939e60596b77f1d9
Deleted: sha256:a5dc79ea636789a36962fcac872a77a86235f95fa9f3714c8bd8da42237b51f3
Deleted: sha256:8b9a4e82ec7825be4e6f52b7192c2b76fc5ab671a871dcc9c3423f23713009da
Untagged: dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b:latest
Deleted: sha256:599b2ad18745375616a97b3a99411571aeb456b0c320f853bdd9d15d19a5c875
Deleted: sha256:65a03c40d4a982f5b6589a8fd2e6aac66b70a295d68b3c8892a8fe5bf41f3edc
Deleted: sha256:ab76526d7091a8511de05ae2c91f0279f10aa0b07ad4a62c5cc105c454d79894
Deleted: sha256:6d5781813eb41dfc57917af52d5c4e7234864d005b8d38c07f51a759fa8790f0
logrocket:~$

mychannelで名前を付けたチャネルを作成します./network.sh up createChannel

    ========= Channel successfully joined ===========

Hyperledger Fabric Node.js SDK

このチュートリアルでは、Hyperledger Node.js SDKを使用します。これを使用して、ネットワークと対話し、ネットワーク、元帳、およびAPIを介してスマートコントラクトをデプロイします。

SDK

Fabricネットワーククライアントと対話するには、FabricCAの傘下にあるFabric -CAClientを使用します。Fabric CAコンポーネントを使用すると、アプリケーションはピアとアプリケーションユーザーを登録して、ブロックチェーンネットワーク上に信頼できるIDを確立できます。また、トランザクション証明書を使用した仮名トランザクション送信のサポートも提供します。

Fabric Commonパッケージは、すべてのfabric-sdk-nodeパッケージで使用される共通コードをカプセル化し、トランザクション呼び出しを送信するためのFabricネットワークとのきめ細かい相互作用をサポートします。

ファブリックネットワークは、ファブリックブロックチェーンネットワークとの接続を確立する責任があります。このパッケージは、APIをカプセル化して、Fabricネットワークに接続し、トランザクションを送信し、FabricCommonよりも高いレベルの抽象化で元帳に対してクエリを実行します。

最後に、fabric-protosパッケージは、gRPCを介した通信に使用されるprotobuffersをカプセル化します。

APIのインストール

ネットワークAPIをインストールします。

npm install fabric-network

クライアントAPIをインストールします。

npm install fabric-ca-client

共通APIをインストールします。

npm install fabric-common

protobuffersAPIをインストールします。

npm install fabric-protos

SDKの使用を開始する

Gatewayクラスは、Hyperledger Fabricブロックチェーンネットワークと対話するために使用されるエントリポイントであり、最初に開始されます。長寿命オブジェクトは、Fabricブロックチェーンネットワーク内のピアへの再利用可能な接続を提供し、その特定のピアがメンバーになっているブロックチェーンネットワークまたはチャネルへのアクセスを可能にします。

次に、そのブロックチェーンネットワーク内で実行および展開されているスマートコントラクト/チェーンコードにアクセスします。トランザクションがトリガーされ、クエリがこのブロックチェーンネットワークに対して評価されます。

スマートコントラクトイベントリスナーを使用すると、クライアントアプリケーションは、スマートコントラクトトランザクションによって発行されたチェーンコードイベントに応答してアクションまたはビジネスプロセスを開始できます。元帳へのすべての更新は、ブロックイベントリスナーを使用して監視できます。

キーチェーンコードAPI

ChaincodeStubは、開発者が基礎となる元帳と対話してアセットを照会、更新、および削除できるようにする機能を提供します。

func (stub *ChaincodeStub) GetState(key string) ([]byte, error)

上記のコードは、指定されたキーの値を元帳から返します。キーが状態データベースに存在しない場合は、nil, nil次が返されます。

func (stub *ChaincodeStub) PutState(key string, value []byte) error 

上記のコードは、指定されたキーと値をトランザクションに入れ、データ書き込みプロポーザルとして書き込みます。PutStateトランザクションが検証されて正常にコミットされるまで、元帳には影響しません。

func (stub *ChaincodeStub) DelState(key string) error

上記のコードWriteは、トランザクション提案のセットで削除される指定されたキーを記録します。トランザクションが検証され、正常にコミットされると、キーとその値が元帳から削除されます。

fabric-contract-apiスマートコントラクトまたはチェーンコードの技術用語でビジネスロジックを記述するコントラクトインターフェイスを提供します。

このCommercialPaperContract extends Contract {...}クラスには、コマーシャルペーパー、発行、購入、および償還のトランザクション定義が含まれています。

Initチェーンコード内にとInvokeメソッドの両方を作成する必要があります。チェーンコードを呼び出す前に、ピアチェーンコードinstallinstantiateコマンドをそれぞれ使用してチェーンコードをインストールおよびインスタンス化する必要があります。

これまでのところ、Hyperledger Fabric、そのアーキテクチャ、セットアップ、機能、およびSDKについての理解はこれで完了です。記事の次のパートでは、アプリケーションをインストールし、スマートコントラクトについて詳しく説明します。

サンプルのスマートコントラクトを理解する

In Hyperledger Fabric, the core business logic and rules are defined by smart contracts or chaincode. End users interact with the blockchain network and blockchain ledger by calling a smart contract’s defined rules, invoking smart contracts or chaincode.

Let’s assume that user U has implemented smart contract SC. Anyone who wants to participate, whether an organization or group, has to validate transactions or query the blockchain ledger, which can be accomplished by installing the chaincode on their peers.

After installing or deploying the smart contract or chaincode, peers join the channel. Channel members can then deploy the chaincode to the channel and use the smart contract business logic or rules in the chaincode to create or update assets on the channel ledger.

So far, we’ve already successfully created the channel. We will not use the Peer CLI provided by Hyperledger Fabric to deploy the assets-transfer package chaincode to the channel. Instead, first, let’s package the smart contract. To be installed on any participating machine, the chaincode should be packaged in the .tar.gz file. In other words, a peer that is a participating unit on the network can interact with other machines and computing devices on the blockchain network.

Next, we install the chaincode package, which has to be installed on every peer of the participating organization to follow each others’ rules or business logic. Before participating with these organization on the blockchain network, a certain threshold of peers who are a part of the organization must approve the chaincode definition. Finally, to further invoke the business logic or rules set for interaction, each channel should have the chaincode committed.

Package smart contract

Let’s review our sample JavaScript chaincode. In fabric-samples, you’ll go to the basic Go version of the asset-transfer chaincode with cd fabric-samples/asset-transfer-basic/chaincode-javascript.

The sample uses node modules to install and deploy the chaincode. package.json describes the dependencies required to package and install our chaincode. If you’ve thoroughly understood the first part, these dependencies will be familiar to you:

$ cat package.json

"dependencies": {
        "fabric-contract-api": "^2.0.0",
        "fabric-shim": "^2.0.0"

Let’s review the fabric-contract-api of our sample smart contract:

const { Contract } = require('fabric-contract-api');

class AssetTransfer extends Contract {
    ...
}

The code above will enable basic CRUD operations on our ledger, or in other words, read and write to the blockchain ledger using different function calls:

async CreateAsset(ctx, id, color, size, owner, appraisedValue) {
        const asset = {
            ID: id,
            Color: color,
            Size: size,
            Owner: owner,
            AppraisedValue: appraisedValue,
        };

        await ctx.stub.putState(id, Buffer.from(JSON.stringify(asset)));
    }

 

Inside this directory, run npm install to install any dependencies required by our chaincode package before installing or deploying chaincode on the ledger. To create a chaincode package, go to test-network and set config paths as follows:

cd ../../test-network
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/

Run peer version to make sure you’re able to interact with the peer CLI:

logrocket:~$ peer version
peer:
 Version: 1.4.7
 Commit SHA: e0afaa741
 Go version: go1.13.9
 OS/Arch: linux/amd64
 Chaincode:
  Base Image Version: 0.4.20
  Base Docker Namespace: hyperledger
  Base Docker Label: org.hyperledger.fabric
  Docker Namespace: hyperledger

Let’s package our chaincode using the command below:

peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-javascript/ --lang node --label basic_1.0

Now, you can install the basic.tar.gz file on the network of your choice. Your chaincode or smart contract is ready to be installed, establish interactions with the ledger, and eventually become one of them by abiding by the smart contract.

Install the chaincode package

Let’s install the basic, packaged asset-transfer smart contract/chaincode on our peers. Think about our user U and smart contract SC. Let’s create two organizations, Org1 and Org2. As in our example, both organizations require endorsements from each other, so chaincode will be installed on every peer operated by both organizations:

peer0.org1.example.com
peer0.org2.example.com

Let’s install the chaincode on the Org1 peer first. Set the following environment variables to operate the peer CLI as the Org1 admin user. The CORE_PEER_ADDRESS will be set to point to the Org1 peer, peer0.org1.example.com:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

Now, install the peer lifecycle chaincode on the peer. Issue the peer lifecycle chaincode install command to install the chaincode on the peer. You will not get the chaincode package identifier. In the next step, we’ll use this package ID to approve the chaincode:

peer lifecycle chaincode install basic.tar.gz
2021-02-06 09:09:27.534 IST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nJbasic_1.0:e2db7f693d4dfwi9599953fnd00300dd0232323e9ebb88c5721cb8248c3aead8123\022\tbasic_1.0" >
2021-02-06 09:09:27.534 IST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: basic_1.0:e2db7f693d4aa6156e652741dwi487575730de9ebb88c5721cb8248c3aead8123

Next, we’ll install the chaincode package on the Org2 peer using peer lifecycle chaincode install basic.tar.gz. As we did earlier, set the required environment variables and install the chaincode package. Our Org2 peer is peer0.org2.example.com:

export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

peer lifecycle chaincode install basic.tar.gz

Approve a chaincode definition

Each participating organization has to agree on a chaincode package, which has a unique hash value and a label. Each organization may get the chaincode package from a developer; if someone tries to change something on the chaincode, that chaincode package will give a different hash value compares to others.

Next, we’ll approve the chaincode, which includes the important parameters of chaincode governance, like the name, version, and the chaincode endorsement policy for your organization.

Each organization gets an identical Package ID, which is a combination of that chaincode package’s hash value and label. Approve this identical Package ID with channelID, name, version, init-required, etc. for your organization. Run the code below:

peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: basic_1.0:63828323nvsb3283283ss283932bb6cb291df20aa39542c3ef94008615704007f3, Label: basic_1.0

Set this package ID as an environment variable and use the package ID below to approve:

export CC_PACKAGE_ID=basic_1.0:63828323nvsb3283283ss283932bb6cb291df20aa39542c3ef94008615704007f3

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

There are multiple options that can be supplied with the command as parameter. For one, the --package-id flag includes the package identifier in the chaincode definition. The --sequence flag is an integer value that keeps track of the number of times a chaincode has been defined or updated. When the chaincode package is installed for first time, the sequence number is set to 1. Lastly, the --signature-policy flag is used to specify a chaincode endorsement policy.

Now, let approve for Org1:

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

It’s recommended that all channel members approve a chaincode before committing the chaincode definition.

Committing the chaincode definition to the channel

After a sufficient number of organizations have approved a chaincode definition, one organization can commit the chaincode definition to the channel. If a majority of channel members have approved the definition, the commit transaction will be successful, and the parameters agreed to in the chaincode definition will be implemented on the channel.

Before committing, we need to check commit readiness to channel using the code below:

peer lifecycle chaincode checkcommitreadiness [flags]

Flags:
      --channel-config-policy string   The endorsement policy associated to this chaincode specified as a channel config policy reference
  -C, --channelID string               The channel on which this command should be executed
      --collections-config string      The fully qualified path to the collection JSON file including the file name
      --connectionProfile string       The fully qualified path to the connection profile that provides the necessary connection information for the network. Note: currently only supported for providing peer connection information
  -E, --endorsement-plugin string      The name of the endorsement plugin to be used for this chaincode
  -h, --help                           help for checkcommitreadiness
      --init-required                  Whether the chaincode requires invoking 'init'
  -n, --name string                    Name of the chaincode
  -O, --output string                  The output format for query results. Default is human-readable plain-text. json is currently the only supported format.
      --peerAddresses stringArray      The addresses of the peers to connect to
      --sequence int                   The sequence number of the chaincode definition for the channel (default 1)
      --signature-policy string        The endorsement policy associated to this chaincode specified as a signature policy
      --tlsRootCertFiles stringArray   If TLS is enabled, the paths to the TLS root cert files of the peers to connect to. The order and number of certs specified should match the --peerAddresses flag
  -V, --validation-plugin string       The name of the validation plugin to be used for this chaincode
  -v, --version string                 Version of the chaincode

Global Flags:
      --cafile string                       Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
      --certfile string                     Path to file containing PEM-encoded X509 public key to use for mutual TLS communication with the orderer endpoint
      --clientauth                          Use mutual TLS when communicating with the orderer endpoint
      --connTimeout duration                Timeout for client to connect (default 3s)
      --keyfile string                      Path to file containing PEM-encoded private key to use for mutual TLS communication with the orderer endpoint
  -o, --orderer string                      Ordering service endpoint
      --ordererTLSHostnameOverride string   The hostname override to use when validating the TLS connection to the orderer.
      --tls                                 Use TLS when communicating with the orderer endpoint

`
We’ll see the flags and option parameters later in this tutorial. Let’s check commit readiness:

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json

    {
            "Approvals": {
                    "Org1MSP": true,
                    "Org2MSP": true
            }
    }

When both Org1MSP and Org2MSP are set to true, it means it’s ready! Let’s commit:

peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

Using our chaincode

Now, our chaincode is installed and ready to be used by our clients. Let’s use the chaincode to create an initial set of assets on the ledger and query the chaincode:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitLedger","Args":[]}'

2021-02-06 10:09:27.534 IST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200

peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

[{"Key":"asset1","Record":{"ID":"asset1","color":"blue","size":5,"owner":"Tomoko","appraisedValue":300}},
{"Key":"asset2","Record":{"ID":"asset2","color":"red","size":5,"owner":"Brad","appraisedValue":400}},
{"Key":"asset3","Record":{"ID":"asset3","color":"green","size":10,"owner":"Jin Soo","appraisedValue":500}},
{"Key":"asset4","Record":{"ID":"asset4","color":"yellow","size":10,"owner":"Max","appraisedValue":600}},
{"Key":"asset5","Record":{"ID":"asset5","color":"black","size":15,"owner":"Adriana","appraisedValue":700}},
{"Key":"asset6","Record":{"ID":"asset6","color":"white","size":15,"owner":"Michel","appraisedValue":800}}]

Use the docker ps command to further see our smart contract running:

$ docker ps
CONTAINER ID        IMAGE                                                                                                                                                                    COMMAND                  CREATED             STATUS              PORTS                              NAMES
7bf2f1bf792b        dev-peer0.org1.example.com-basic_2.0-572cafd6a972a9b6aa3fa4f6a944efb6648d363c0ba4602f56bc8b3f9e66f46c-69c9e3e44ed18cafd1e58de37a70e2ec54cd49c7da0cd461fbd5e333de32879b   "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes                                           dev-peer0.org1.example.com-basic_2.0-572cafd6a972a9b6aa3fa4f6a944efb6648d363c0ba4602f56bc8b3f9e66f46c
985e0967c27a        dev-peer0.org2.example.com-basic_2.0-572cafd6a972a9b6aa3fa4f6a944efb6648d363c0ba4602f56bc8b3f9e66f46c-158e9c6a4cb51dea043461fc4d3580e7df4c74a52b41e69a25705ce85405d760   "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes                                           dev-peer0.org2.example.com-basic_2.0-572cafd6a972a9b6aa3fa4f6a944efb6648d363c0ba4602f56bc8b3f9e66f46c
31fdd19c3be7        hyperledger/fabric-peer:latest                                                                                                                                           "peer node start"        About an hour ago   Up About an hour    0.0.0.0:7051->7051/tcp             peer0.org1.example.com
1b17ff866fe0        hyperledger/fabric-peer:latest                                                                                                                                           "peer node start"        About an hour ago   Up About an hour    7051/tcp, 0.0.0.0:9051->9051/tcp   peer0.org2.example.com
4cf170c7ae9b        hyperledger/fabric-orderer:latest

Write your first application

Now, let’s install and run our sample JavaScript application, which is a simple Node.js application:

cd asset-transfer-basic/application-javascript
npm install
ls
app.js                  node_modules            package.json       package-lock.json
node app.js

Our app.js has the following main components:

  • Enrolls the admin user:
async function main() {
  try {
    // build an in memory object with the network configuration (also known as a connection profile)
    const ccp = buildCCP();

    // build an instance of the fabric ca services client based on
    // the information in the network configuration
    const caClient = buildCAClient(FabricCAServices, ccp);

    // setup the wallet to hold the credentials of the application user
    const wallet = await buildWallet(Wallets, walletPath);

    // in a real application this would be done on an administrative flow, and only once
    await enrollAdmin(caClient, wallet);
  • Registers and enrolls an application user:
// in a real application this would be done only when a new user was required to be added
// and would be part of an administrative flow
await registerAndEnrollUser(caClient, wallet, mspOrg1, org1UserId, 'org1.department1');

Successfully registered and enrolled user appUser and imported it into the wallet
  • Prepares a connection to the channel and smart contract:
// Create a new gateway instance for interacting with the fabric network.
// In a real application this would be done as the backend server session is setup for
// a user that has been verified.
const gateway = new Gateway();

try {
  // setup the gateway instance
  // The user will now be able to create connections to the fabric network and be able to
  // submit transactions and query. All transactions submitted by this gateway will be
  // signed by this user using the credentials stored in the wallet.
  await gateway.connect(ccp, {
    wallet,
    identity: userId,
    discovery: {enabled: true, asLocalhost: true} // using asLocalhost as this gateway is using a fabric network deployed locally
  });

  // Build a network instance based on the channel where the smart contract is deployed
  const network = await gateway.getNetwork(channelName);


  // Get the contract from the network.
  const contract = network.getContract(chaincodeName);
  • Initializes the ledger with some sample data:
// Initialize a set of asset data on the channel using the chaincode 'InitLedger' function.
// This type of transaction would only be run once by an application the first time it was started after it
// deployed the first time. Any updates to the chaincode deployed later would likely not need to run
// an "init" type function.
console.log('\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger');
await contract.submitTransaction('InitLedger');
console.log('*** Result: committed');

Submit Transaction: InitLedger, function creates the initial set of assets on the ledger
  • Invokes each of the chaincode functions:
// GetAllAssets returns all assets found in the world state.
 async GetAllAssets(ctx) {
     const allResults = [];
     // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace.
     const iterator = await ctx.stub.getStateByRange('', '');
     let result = await iterator.next();
     while (!result.done) {
         const strValue = Buffer.from(result.value.value.toString()).toString('utf8');
         let record;
         try {
             record = JSON.parse(strValue);
         } catch (err) {
             console.log(err);
             record = strValue;
         }
         allResults.push({ Key: result.value.key, Record: record });
         result = await iterator.next();
     }
     return JSON.stringify(allResults);
 }  Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger
  Result: [
  {
    "Key": "asset1",
    "Record": {
      "ID": "asset1",
      "Color": "blue",
      "Size": 5,
      "Owner": "Tomoko",
      "AppraisedValue": 300,
      "docType": "asset"
    }
  },
  {
    "Key": "asset2",
    "Record": {
      "ID": "asset2",
      "Color": "red",
      "Size": 5,
      "Owner": "Brad",
      "AppraisedValue": 400,
      "docType": "asset"
    }
  },
  {
    "Key": "asset3",
    "Record": {
      "ID": "asset3",
      "Color": "green",
      "Size": 10,
      "Owner": "Jin Soo",
      "AppraisedValue": 500,
      "docType": "asset"
    }
  },
  {
    "Key": "asset4",
    "Record": {
      "ID": "asset4",
      "Color": "yellow",
      "Size": 10,
      "Owner": "Max",
      "AppraisedValue": 600,
      "docType": "asset"
    }
  },
  {
    "Key": "asset5",
    "Record": {
      "ID": "asset5",
      "Color": "black",
      "Size": 15,
      "Owner": "Adriana",
      "AppraisedValue": 700,
      "docType": "asset"
    }
  },
  {
    "Key": "asset6",
    "Record": {
      "ID": "asset6",
      "Color": "white",
      "Size": 15,
      "Owner": "Michel",
      "AppraisedValue": 800,
      "docType": "asset"
    }
  }// CreateAsset issues a new asset to the world state with given details.
async CreateAsset(ctx, id, color, size, owner, appraisedValue) {
  const asset = {
      ID: id,
      Color: color,
      Size: size,
      Owner: owner,
      AppraisedValue: appraisedValue,
  };
  return ctx.stub.putState(id, Buffer.from(JSON.stringify(asset)));
}

Submit Transaction: CreateAsset, creates new asset with ID, color, owner, size, and appraisedValue arguments

Conclusion

network.shアセット転送サンプルの使用が終了したら、スクリプトを使用してテストネットワークを停止し、を使用してリソースを解放することを忘れないでください./network.sh down。このコマンドは、作成したネットワークのCA、ピア、および順序付けノードを停止します。元帳のすべてのデータが失われることに注意してください。クリーンな初期状態でチュートリアルを再開します。

この記事では、HyperledgerFabricを使用したスマートコントラクトの作成について詳しく説明しました。そのアーキテクチャ、機能、JavaScriptSDKについて説明しました。作成したものをお知らせください。ご不明な点がございましたら、必ずコメントを残してください。ハッピーコーディング!

リンク:https ://blog.logrocket.com/hyperledger-fabric-develop-blockchain-smart-contracts/

#hyperledger  #blockchain 

What is GEEK

Buddha Community

許可されたブロックチェーンスマートコントラクトを開発する
伊藤  直子

伊藤 直子

1647352920

許可されたブロックチェーンスマートコントラクトを開発する

 Hyperledgerは、分散型台帳、オープンソースのブロックチェーン実装、および分散型台帳フレームワーク、スマートコントラクトエンジン、クライアントライブラリ、グラフィカルインターフェイス、ユーティリティライブラリ、サンプルアプリケーションなどの関連ツールを提供するLinuxFoundationによる包括的なプロジェクトです。

ブロックチェーンは、スマートコントラクトやその他の支援技術のシステムと組み合わせて、コンセンサスによって作成されたトランザクションのピアツーピア分散型台帳です。これらのトランザクションは複製され、ブロックチェーン上の参加しているコンピューターシステムのネットワーク全体に分散されます。言い換えれば、ブロックチェーンは、市場、データ共有ネットワーク、マイクロ通貨、および分散型デジタルコミュニティの法的に準拠したオペレーティングシステムです。

Hyperledger Fabricは、分散型台帳テクノロジー(DLT)が必要な統合プロジェクトを主な目的とした許可されたブロックチェーンインフラストラクチャです。Node.js、JavaScript、およびGo用のSDK以外のユーザー向けサービスは提供していません。ノード間のモジュラーアーキテクチャ、スマートコントラクトの実行、構成可能なコンセンサスおよびメンバーシップサービスを提供します。

この記事では、最初の許可されたブロックチェーンアプリケーションを作成し、スマートコントラクトを調査し、HyperledgerFabricのいくつかの重要な機能について説明します。始めましょう!

HyperledgerFabricについて

Hyperledger Fabric Networkは、3つの主要コンポーネントで構成されています。

ピアノードは、チェーンコードを実行し、元帳データにアクセスし、トランザクションを承認し、アプリケーションとインターフェイスします。ピアノードは、ブロックチェーンライフサイクルの任意の時点で開始、停止、再構成、および削除できます。

注文ノードは、ブロックチェーンの一貫性を確保し、承認されたトランザクションをネットワークのピアに配信します。注文者ノードは、トランザクションの注文、注文サービスの形成、トランザクションのブロックへのパッケージ化、およびこれらのブロックをネットワーク全体のアンカーピアに配布する役割を果たします。

メンバーシップサービスプロバイダー(MSP)ノードは、通常、認証局として実装されます。認証局は、X.509証明書を管理し、メンバーのIDとロールを認証するために使用されます。MSPノードは、証明書の発行、証明書の検証、およびユーザーの認証の背後にあるすべての暗号化メカニズムとプロトコルの抽象化レイヤーです。

ピアノード、スマートコントラクト、元帳、およびブロックチェーンネットワーク間の相互接続

Hyperledger Fabricでは、さまざまなコンセンサスアルゴリズムを使用できますが、実用的なビザンチンフォールトトレランス(PBFT)が最も一般的に使用されます。

機能性

HyperledgerFabricには5つの主要な機能があります。

ID管理

許可されたネットワークの場合、メンバーシップIDサービスはユーザーIDを管理し、ブロックチェーンネットワーク上の参加者を認証します。さらに、開発者は、アクセス制御リストを使用して、追加のレイヤーを介して特定のネットワーク操作を有効にし、制限することができます。たとえば、特定のユーザーIDがチェーンコードアプリケーションの呼び出しを許可されていても、新しいチェーンコードの展開をブロックされている可能性があります。

効率的な処理

ネットワークに同時実行性と並列性を提供するために、Hyperledger Fabricには、たとえばノードオーソリティのタイプによるトランザクションの順序付けが含まれています。開発者は、同じノードで複数のトランザクションを実行し、ノードタイプごとにネットワークロールを割り当てることができます。

モジュール設計

Hyperledger Fabricは、モジュラーアーキテクチャを実装して、ネットワーク設計者に機能的な選択肢を提供します。たとえば、さまざまな暗号化アルゴリズム、アルゴリズムまたはID、暗号化、順序付け、暗号化を利用できるため、ユニバーサルデザインが可能になります。

プライバシーと守秘義務

Hyperledger Fabricを使用すると、競合する企業や、プライベートで機密性の高いトランザクションを必要とするグループを、同じ許可されたネットワーク上で共存させることができます。ネットワークメンバーの特定のサブセットに対する制限付きメッセージングパスなどの機能をサポートします。たとえば、トランザクション、メンバー、チャネル情報などのデータは、明示的にアクセスを許可されていないネットワークメンバーには表示されず、アクセスできません。

チェーンコード機能

エンコーディングロジックは、システムチェーンコード、ライフサイクルと構成システムチェーンコード、承認と検証システムチェーンコードなど、チャネル上の特定のタイプのトランザクションによって呼び出されます。

Hyperledgerファブリックアーキテクチャ

Hyperledger Fabricの機能に慣れてきたので、それを構成するコンポーネントを確認しましょう。

ノード

Hyperledger Fabricでは、ネットワーク上で通信するコンピューティングデバイスはノードと呼ばれます。

クライアント

クライアントは、エンドユーザーに代わって動作できるノードです。

ピア

Hyperledger Fabricには、ピアノードが元帳の状態とパフォーマンスの最適化を担当するピアツーピアネットワークがあります。ピアには2つのタイプがあります。1つは、承認者がトランザクションをシミュレートして承認することです。トランザクションの承認は、シミュレートされたトランザクションの結果に対する署名された応答です。一方、コミッターは、トランザクションをブロックチェーンにコミットする前に、承認を検証し、トランザクションの結果を検証します

トランザクション

HyperledgerFabricトランザクションには2つのタイプがあります。デプロイトランザクションは、パラメータをプログラムとして使用して新しいチェーンコードを作成し、ブロックチェーンにチェーンコードをインストールします。呼び出しトランザクションは、以前のチェーンコードまたはスマートコントラクトの展開のコンテキストで実行されます。

データ構造

Key-Value Store(KVS)は、ブロックチェーンの基本的なデータ構造です。多くの場合、キーは名前であり、値はblobです。KVSは2つの操作、PUTおよびをサポートしGETます。データ構造は、特定の時点での状態と見なされます。デフォルトの状態データベースであるLevelDBは、 CouchDBに置き換えることができます。

元帳

トランザクションの順序付きハッシュチェーンブロックと呼ばれるものでは、状態の変化が発生順に保存されるため、後で簡単に参照できます。ブロックチェーンは、元帳内のトランザクションを記録します。元帳には、順序付けされたトランザクション配列を含む順序付けられたブロックが含まれています。元帳は、成功したか失敗したかにかかわらず、すべての状態変更を保存します。

ファブリックデータベース

Hyperledger Fabricでは、データは状態データベースと元帳データベースの2か所に保存されます。

現在の状態データは、元帳内のすべての資産の最新の値を表します。現在の状態は、チャネル上でコミットされたすべてのトランザクションを表すため、ワールド状態と呼ばれることもあります。

元帳データベースには、各ブロックに1つ以上のトランザクションがあるシリアル化されたブロックが格納されます。各トランザクションには、1つ以上のキーと値のペアを変更する読み取り/書き込みセットが含まれています。元帳はデータの決定的なソースであり、不変です。

注文メカニズム

Hyperledger Fabricは、3つの順序付けメカニズムを提供します。

単一の順序付けノードを含むSOLO順序付けメカニズムは、HyperledgerFabricネットワークを実験している開発者によって最も一般的に使用されます。

Kafkaの注文メカニズムは、実稼働での使用をお勧めします。データは、承認されたトランザクションとRWセットで構成されます。Apache Kafkaを使用しているため、このタイプの順序付けはクラッシュフォールトトレラントです。

最後に、Simplified Byzantine Fault Toleranceの順序付けメカニズムは、クラッシュフォールトトレラントとビザンチンフォールトトレラントの両方であり、悪意のあるノードや障害のあるノードが存在する場合でも合意に達することができます。

コンセンサス

分散型台帳システムでは、コンセンサスは、元帳に追加される次の一連のトランザクションについて合意に達するプロセスです。Hyperledger Fabricは、3つの異なるステップで構成されています。

まず、トランザクション承認ステップで、承認ピアがチェーンコードを実行します。チェーンコードが成功すると、元帳の実際のトランザクションが生成されます。次に、承認ピアがトランザクションに署名し、提案者に返します。

順序付けサービスは厳密な順序付けをサポートします。つまり、トランザクションT1がすでにブロック内に書き込まれている場合B1、同じトランザクションをまたはのT1ような別のブロックに再書き込みすることはできませB2B3。最後に、検証とコミットメントには、トランザクション検証と元帳コミットメントが含まれます。

スマートコントラクト

スマートコントラクトは、グローバル状態に含まれるビジネスオブジェクトのライフサイクルを制御するトランザクションロジックを定義します。Hyperledger Fabricでは、スマートコントラクトの実行はチェーンコードと呼ばれます。Hyperledger Fabricユーザーは、スマートコントラクトとチェーンコードという用語を同じ意味で使用することがよくあります。

Hyperledger Fabricのスマートコントラクトはチェーンコードとも呼ばれ、Goで記述されています。チェーンコードはHyperledgerFabricネットワークのビジネスロジックとして機能し、スマートコントラクトは関与するノードがネットワーク内のアセットを操作する方法を指示します。

アプリケーションがネットワークとどのように相互作用するか

Hyperledger Fabricでは、スマートコントラクトとチェーンコードがネットワーク上でホストされ、名前とバージョンで識別されます。チェーンコードまたはスマートコントラクトを実行するために、アプリケーションはSDKによって実装されるSDKAPIを使用します。

Hyperledger Fabricには、開発者がアプリケーションを作成するための3つのオプション、Node.js SDK、Java SDK、およびCLIがあります。さらに、Hyperledgerは、ユーザーがHyperledgerFabricの機能を探索するためのHyperledgerFabricサンプルを提供します。

許可されたブロックチェーンアプリケーションの開発

Hyperledger Fabricアーキテクチャを理解したので、許可されたブロックチェーンアプリケーションを作成しましょう。まず、HyperledgerFabricアプリケーションを開発するときに実行する主な手順を明確にしましょう。

まず、スマートコントラクトが実行されるネットワークのインストールを含め、開発環境をセットアップする必要があります。次に、Node.jsSDKとアプリケーションの背後にあるコアプログラミングを理解する必要があります。Hyperledger Fabricは、Go、JavaScript、Javaなどの複数のSDKを提供します。このチュートリアルでは、少しのGoとたくさんのJavaScriptを使用します。

さらに、トランザクションを含むサンプルのスマートコントラクトを理解する必要があります。アプリによってシミュレートされたクエリを実行し、元帳も更新します。最後に、スマートコントラクトを使用してサンプルブロックチェーンアプリケーションを開発します。

開発環境をセットアップする

前提条件

Hyperledger Fabricを使用して開発環境をセットアップするには、次のものが必要です。

  1. cURLの最新バージョン
  2. DockerおよびDockerCompose≥v17.06.2-ce
  3. v1.12.xに移動
  4. Node.js≥v8.9または≥v10.15.3

インストール

この例では、LinuxベースのディストリビューションUbuntu20.04および18.04を使用します。まず、現在のマシンをで更新しますsudo apt-get update。次に、以下に示すように、でcURLをインストールしsudo apt instal curl、でcURLのバージョンを確認しcurl --versionます。

 curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

Docker

必要なDockerパッケージを次のようにインストールする必要があります。

sudo apt-get install apt-transport-https ca-certificates gnupg-agent software-properties-common

次に、Dockerの公式GPGキーを追加します。

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -Check OK

Dockerをセットアップするには、次のコードを実行します。

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs)  stable"

以下のコードでDockerをインストールします。

sudo apt-get install docker-ce docker-ce-cli containerd.io`

docker --version次のコードスニペットでDockerのバージョンを確認します。

logrocket:~$ docker --version
Docker version 20.10.12, build e91ed57

次に、Dockerエンジンをテスト実行します。

docker run hello-world

DockerCompose

Docker Composeの最新バージョンをダウンロードするには、次のコードを実行します。

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

権限を実行可能ファイルに変更しsudo chmod +x /usr/local/bin/docker-composeます。Docker Composeのバージョンを確認するには、次のように実行docker-compose --versionします。

logrocket:~$ docker-compose --version
docker-compose version 1.25.5, build 8a1c60f6

行け

ファイルをダウンロードしtarます。

curl -O https://storage.googleapis.com/golang/go1.12.9.linux-amd64.tar.gz

Goディレクトリを移動します。

sudo mv go1.12.9.linux-amd64.tar.gz /usr/local/

tar以下のコードでファイルを抽出します。

sudo tar -xvzpf /usr/local/go1.12.9.linux-amd64.tar.gz

tar次のコードでファイルを削除できます。

sudo rm -rf /usr/local/go1.12.9.linux-amd64.tar.gz

環境変数

でプロファイルを開き、ファイルの最後に変数をvim .profile追加します。PATH.profile

export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin

でソースプロファイルにsource ~/.profile移動し、次のコードで現在のGoバージョンを確認します。

logrocket:~$ go version
go version go1.12.9 linux/amd64

Node.js

以下のコードを実行して、Node.jsv10.xを取得します。

curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -`

以下のコマンドでNode.jsをインストールします。

sudo apt-get install -y nodejs

Node.jsの現在のバージョンを確認するには、次のコードを実行します。

nodejs --version
logrocket:~$ nodejs --version
v10.19.0

ここで、npmのバージョンを次のように確認しますnpm -v

logrocket:~$ npm -v
6.14.4

Hyperledgerファブリック

以下のコードを実行して、新しいディレクトリを作成します。

mkdir hyperledger-fabric && cd hyperledger-fabric

Docker権限を追加します:

sudo usermod -aG docker $USER

権限を確認し、ターミナルを更新します。

logrocket:~$ id -nG
tapasweni adm cdrom sudo dip plugdev lpadmin lxd sambashare
newgrp docker

Fabricv1.4.7をダウンロードします。

curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh  | bash -s -- 1.4.7 1.4.7 0.4.20


logrocket:~$ curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh  | bash -s -- 1.4.7 1.4.7 0.4.20

Clone hyperledger/fabric-samples repo

===> Cloning hyperledger/fabric-samples repo
Cloning into 'fabric-samples'...
remote: Enumerating objects: 9165, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 9165 (delta 0), reused 1 (delta 0), pack-reused 9164
Receiving objects: 100% (9165/9165), 5.21 MiB | 3.71 MiB/s, done.
Resolving deltas: 100% (4898/4898), done.
===> Checking out v1.4.7 of hyperledger/fabric-samples

Pull Hyperledger Fabric binaries

===> Downloading version 1.4.7 platform specific fabric binaries
===> Downloading:  https://github.com/hyperledger/fabric/releases/download/v1.4.7/hyperledger-fabric-linux-amd64-1.4.7.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   680  100   680    0     0   1683      0 --:--:-- --:--:-- --:--:--  1679
100 79.3M  100 79.3M    0     0  4614k      0  0:00:17  0:00:17 --:--:-- 4762k
==> Done.
===> Downloading version 1.4.7 platform specific fabric-ca-client binary
===> Downloading:  https://github.com/hyperledger/fabric-ca/releases/download/v1.4.7/hyperledger-fabric-ca-linux-amd64-1.4.7.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   683  100   683    0     0   1876      0 --:--:-- --:--:-- --:--:--  1876
100 23.6M  100 23.6M    0     0  3962k      0  0:00:06  0:00:06 --:--:-- 4904k
==> Done.

Pull Hyperledger Fabric docker images

FABRIC_IMAGES: peer orderer ccenv tools
===> Pulling fabric Images
====> hyperledger/fabric-peer:1.4.7
1.4.7: Pulling from hyperledger/fabric-peer
Digest: sha256:a395036c83125ccf3820eb1752ac9ba8017e4432768b59d658bfba91a311d154
Status: Image is up to date for hyperledger/fabric-peer:1.4.7
docker.io/hyperledger/fabric-peer:1.4.7
====> hyperledger/fabric-orderer:1.4.7
1.4.7: Pulling from hyperledger/fabric-orderer
Digest: sha256:aef31580eee468e08eb8354bb5f2ec23e0fc12f9b638bd41d207dd5e4d6c6e60
Status: Image is up to date for hyperledger/fabric-orderer:1.4.7
docker.io/hyperledger/fabric-orderer:1.4.7
====> hyperledger/fabric-ccenv:1.4.7
1.4.7: Pulling from hyperledger/fabric-ccenv
Digest: sha256:11dbbdce7f3f789d7bbc758b593005e9aeccd991ed64a3f296e824aaf67f07c6
Status: Image is up to date for hyperledger/fabric-ccenv:1.4.7
docker.io/hyperledger/fabric-ccenv:1.4.7
====> hyperledger/fabric-tools:1.4.7
1.4.7: Pulling from hyperledger/fabric-tools
Digest: sha256:59328549b3384f565cb5bd19b74c977820781e4709158666ead74fcd970c11e1
Status: Image is up to date for hyperledger/fabric-tools:1.4.7
docker.io/hyperledger/fabric-tools:1.4.7
===> Pulling fabric ca Image
====> hyperledger/fabric-ca:1.4.7
1.4.7: Pulling from hyperledger/fabric-ca
Digest: sha256:9418ea351bfbef4bf2bca34bcd77305bdb9a45d2c1aab3237c08c17da0b4d1dd
Status: Image is up to date for hyperledger/fabric-ca:1.4.7
docker.io/hyperledger/fabric-ca:1.4.7
===> List out hyperledger docker images
hyperledger/fabric-ca        1.4            743a758fae29   19 months ago   154MB
hyperledger/fabric-ca        1.4.7          743a758fae29   19 months ago   154MB
hyperledger/fabric-ca        latest         743a758fae29   19 months ago   154MB
hyperledger/fabric-tools     1.4            a026b435e575   19 months ago   1.49GB
hyperledger/fabric-tools     1.4.7          a026b435e575   19 months ago   1.49GB
hyperledger/fabric-tools     latest         a026b435e575   19 months ago   1.49GB
hyperledger/fabric-ccenv     1.4            c5fbec1827ad   19 months ago   1.36GB
hyperledger/fabric-ccenv     1.4.7          c5fbec1827ad   19 months ago   1.36GB
hyperledger/fabric-ccenv     latest         c5fbec1827ad   19 months ago   1.36GB
hyperledger/fabric-orderer   1.4            df155b01ed80   19 months ago   123MB
hyperledger/fabric-orderer   1.4.7          df155b01ed80   19 months ago   123MB
hyperledger/fabric-orderer   latest         df155b01ed80   19 months ago   123MB
hyperledger/fabric-peer      1.4            5d5fbecd1efe   19 months ago   131MB
hyperledger/fabric-peer      1.4.7          5d5fbecd1efe   19 months ago   131MB
hyperledger/fabric-peer      latest         5d5fbecd1efe   19 months ago   131MB
hyperledger/fabric-baseos    amd64-0.4.20   121a92cc3fc0   22 months ago   85MB
logrocket:~$ cURL hyperledger/fabric-samples

次に、環境変数を更新します。

vim .profile
export PATH=/home/$USER/hyperledger/fabric-samples/bin:$PATH
source ~/.profile

HyperledgerFabricを実行する

中に入るfabric-samples/first-network

HyperledgerFabricの最初のネットワークディレクトリ

ネットワークを立ち上げる./byfn.sh up

logrocket:~$ cd first-network/
logrocket:~$ ls
base               channel-artifacts     connection-org2.yaml    docker-compose-cli.yaml           docker-compose-kafka.yaml  scripts
byfn.sh            configtx.yaml         connection-org3.json    docker-compose-couch-org3.yaml    docker-compose-org3.yaml
ccp-generate.sh    connection-org1.json  connection-org3.yaml    docker-compose-couch.yaml         eyfn.sh
ccp-template.json  connection-org1.yaml  crypto-config.yaml      docker-compose-e2e-template.yaml  org3-artifacts
ccp-template.yaml  connection-org2.json  docker-compose-ca.yaml  docker-compose-etcdraft2.yaml     README.md
logrocket:~$ ./byfn.sh -m up
Starting for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds
Continue? [Y/n] 
proceeding ...
LOCAL_VERSION=1.4.7
DOCKER_IMAGE_VERSION=1.4.7
/home/tapasweni/hyperledger/fabric-samples/first-network/../bin/cryptogen

##########################################################
##### Generate certificates using cryptogen tool #########
##########################################################
+ cryptogen generate --config=./crypto-config.yaml
org1.example.com
org2.example.com
+ res=0
+ set +x

Generate CCP files for Org1 and Org2
/home/tapasweni/hyperledger/fabric-samples/first-network/../bin/configtxgen
##########################################################
#########  Generating Orderer Genesis block ##############
##########################################################
CONSENSUS_TYPE=solo
+ '[' solo == solo ']'
+ configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
2021-12-31 17:52:52.853 IST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-12-31 17:52:53.051 IST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: solo
2021-12-31 17:52:53.051 IST [common.tools.configtxgen.localconfig] Load -> INFO 003 Loaded configuration: /home/tapasweni/hyperledger/fabric-samples/first-network/configtx.yaml

Dockerを次のように確認しdocker ps -aます:

logrocket:~$ docker ps -a
CONTAINER ID   IMAGE                                                                                                  COMMAND                  CREATED              STATUS              PORTS                                           NAMES
ef86361332c7   dev-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab   "chaincode -peer.add…"   About a minute ago   Up About a minute                                                   dev-peer1.org2.example.com-mycc-1.0
c9008d040273   dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb25174305fce8f53f4e94d45ee3b6cab0ce9   "chaincode -peer.add…"   2 minutes ago        Up 2 minutes                                                        dev-peer0.org1.example.com-mycc-1.0
9ad7861a975c   dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b   "chaincode -peer.add…"   4 minutes ago        Up 4 minutes                                                        dev-peer0.org2.example.com-mycc-1.0
91ce4e6cfaf5   hyperledger/fabric-tools:latest                                                                        "/bin/bash"              5 minutes ago        Up 5 minutes                                                        cli
c4e3238a2301   hyperledger/fabric-orderer:latest                                                                      "orderer"                6 minutes ago        Up 5 minutes        0.0.0.0:7050->7050/tcp, :::7050->7050/tcp       orderer.example.com
416a0f98cb6b   hyperledger/fabric-peer:latest                                                                         "peer node start"        6 minutes ago        Up 5 minutes        0.0.0.0:10051->10051/tcp, :::10051->10051/tcp   peer1.org2.example.com
84e42d29fab9   hyperledger/fabric-peer:latest                                                                         "peer node start"        6 minutes ago        Up 5 minutes        0.0.0.0:7051->7051/tcp, :::7051->7051/tcp       peer0.org1.example.com
7ad2e6e34292   hyperledger/fabric-peer:latest                                                                         "peer node start"        6 minutes ago        Up 5 minutes        0.0.0.0:8051->8051/tcp, :::8051->8051/tcp       peer1.org1.example.com
9ff94883cacf   hyperledger/fabric-peer:latest                                                                         "peer node start"        6 minutes ago        Up 5 minutes        0.0.0.0:9051->9051/tcp, :::9051->9051/tcp       peer0.org2.example.com
logrocket:~$ 

次のコマンドでネットワークを停止し./byfn.sh downます。

logrocket:~$ ./byfn.sh -m down
Stopping for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds
Continue? [Y/n] 
proceeding ...
WARNING: The BYFN_CA1_PRIVATE_KEY variable is not set. Defaulting to a blank string.
WARNING: The BYFN_CA2_PRIVATE_KEY variable is not set. Defaulting to a blank string.
Stopping cli                    ... done
Stopping peer0.org2.example.com ... done
Stopping peer0.org1.example.com ... done
Stopping peer1.org2.example.com ... done
Stopping peer1.org1.example.com ... done
Stopping orderer.example.com    ... done
Removing cli                    ... done
Removing peer0.org2.example.com ... done
Removing peer0.org1.example.com ... done
Removing peer1.org2.example.com ... done
Removing peer1.org1.example.com ... done
Removing orderer.example.com    ... done
Removing network net_byfn
Removing volume net_orderer.example.com
Removing volume net_peer0.org1.example.com
Removing volume net_peer1.org1.example.com
Removing volume net_peer0.org2.example.com
Removing volume net_peer1.org2.example.com
Removing volume net_orderer2.example.com
WARNING: Volume net_orderer2.example.com not found.
Removing volume net_orderer3.example.com
WARNING: Volume net_orderer3.example.com not found.
Removing volume net_orderer4.example.com
WARNING: Volume net_orderer4.example.com not found.
Removing volume net_orderer5.example.com
WARNING: Volume net_orderer5.example.com not found.
Removing volume net_peer0.org3.example.com
WARNING: Volume net_peer0.org3.example.com not found.
Removing volume net_peer1.org3.example.com
WARNING: Volume net_peer1.org3.example.com not found.
1c1c3bd27578
052b542e408f
2371102e3fa1
Untagged: dev-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab:latest
Deleted: sha256:574b46ed09496b052b9963d79362fa3e15d5430d6f7e227c8edccfe37a94a54d
Deleted: sha256:89856e5feb7feafde31a15decf9d2657f7344e38ee90bc8e73f7c0e189a0422c
Deleted: sha256:570373df622999f59a978635db23a4ce6f6f3c6b1067aeafd3d2a64b4b1020b0
Deleted: sha256:31ce9090622db38830dfdc3209c4044d70f7345e863fcd54c40ac2d2a2abbf03
Untagged: dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb25174305fce8f53f4e94d45ee3b6cab0ce9:latest
Deleted: sha256:c40d025bb22f74cfa14568a70257964d94b557e23811c9bfb5d4591200f64b62
Deleted: sha256:b9e1d83750424813abf0fe6f96fbc3904680bf0ae23474b4939e60596b77f1d9
Deleted: sha256:a5dc79ea636789a36962fcac872a77a86235f95fa9f3714c8bd8da42237b51f3
Deleted: sha256:8b9a4e82ec7825be4e6f52b7192c2b76fc5ab671a871dcc9c3423f23713009da
Untagged: dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b:latest
Deleted: sha256:599b2ad18745375616a97b3a99411571aeb456b0c320f853bdd9d15d19a5c875
Deleted: sha256:65a03c40d4a982f5b6589a8fd2e6aac66b70a295d68b3c8892a8fe5bf41f3edc
Deleted: sha256:ab76526d7091a8511de05ae2c91f0279f10aa0b07ad4a62c5cc105c454d79894
Deleted: sha256:6d5781813eb41dfc57917af52d5c4e7234864d005b8d38c07f51a759fa8790f0
logrocket:~$

mychannelで名前を付けたチャネルを作成します./network.sh up createChannel

    ========= Channel successfully joined ===========

Hyperledger Fabric Node.js SDK

このチュートリアルでは、Hyperledger Node.js SDKを使用します。これを使用して、ネットワークと対話し、ネットワーク、元帳、およびAPIを介してスマートコントラクトをデプロイします。

SDK

Fabricネットワーククライアントと対話するには、FabricCAの傘下にあるFabric -CAClientを使用します。Fabric CAコンポーネントを使用すると、アプリケーションはピアとアプリケーションユーザーを登録して、ブロックチェーンネットワーク上に信頼できるIDを確立できます。また、トランザクション証明書を使用した仮名トランザクション送信のサポートも提供します。

Fabric Commonパッケージは、すべてのfabric-sdk-nodeパッケージで使用される共通コードをカプセル化し、トランザクション呼び出しを送信するためのFabricネットワークとのきめ細かい相互作用をサポートします。

ファブリックネットワークは、ファブリックブロックチェーンネットワークとの接続を確立する責任があります。このパッケージは、APIをカプセル化して、Fabricネットワークに接続し、トランザクションを送信し、FabricCommonよりも高いレベルの抽象化で元帳に対してクエリを実行します。

最後に、fabric-protosパッケージは、gRPCを介した通信に使用されるprotobuffersをカプセル化します。

APIのインストール

ネットワークAPIをインストールします。

npm install fabric-network

クライアントAPIをインストールします。

npm install fabric-ca-client

共通APIをインストールします。

npm install fabric-common

protobuffersAPIをインストールします。

npm install fabric-protos

SDKの使用を開始する

Gatewayクラスは、Hyperledger Fabricブロックチェーンネットワークと対話するために使用されるエントリポイントであり、最初に開始されます。長寿命オブジェクトは、Fabricブロックチェーンネットワーク内のピアへの再利用可能な接続を提供し、その特定のピアがメンバーになっているブロックチェーンネットワークまたはチャネルへのアクセスを可能にします。

次に、そのブロックチェーンネットワーク内で実行および展開されているスマートコントラクト/チェーンコードにアクセスします。トランザクションがトリガーされ、クエリがこのブロックチェーンネットワークに対して評価されます。

スマートコントラクトイベントリスナーを使用すると、クライアントアプリケーションは、スマートコントラクトトランザクションによって発行されたチェーンコードイベントに応答してアクションまたはビジネスプロセスを開始できます。元帳へのすべての更新は、ブロックイベントリスナーを使用して監視できます。

キーチェーンコードAPI

ChaincodeStubは、開発者が基礎となる元帳と対話してアセットを照会、更新、および削除できるようにする機能を提供します。

func (stub *ChaincodeStub) GetState(key string) ([]byte, error)

上記のコードは、指定されたキーの値を元帳から返します。キーが状態データベースに存在しない場合は、nil, nil次が返されます。

func (stub *ChaincodeStub) PutState(key string, value []byte) error 

上記のコードは、指定されたキーと値をトランザクションに入れ、データ書き込みプロポーザルとして書き込みます。PutStateトランザクションが検証されて正常にコミットされるまで、元帳には影響しません。

func (stub *ChaincodeStub) DelState(key string) error

上記のコードWriteは、トランザクション提案のセットで削除される指定されたキーを記録します。トランザクションが検証され、正常にコミットされると、キーとその値が元帳から削除されます。

fabric-contract-apiスマートコントラクトまたはチェーンコードの技術用語でビジネスロジックを記述するコントラクトインターフェイスを提供します。

このCommercialPaperContract extends Contract {...}クラスには、コマーシャルペーパー、発行、購入、および償還のトランザクション定義が含まれています。

Initチェーンコード内にとInvokeメソッドの両方を作成する必要があります。チェーンコードを呼び出す前に、ピアチェーンコードinstallinstantiateコマンドをそれぞれ使用してチェーンコードをインストールおよびインスタンス化する必要があります。

これまでのところ、Hyperledger Fabric、そのアーキテクチャ、セットアップ、機能、およびSDKについての理解はこれで完了です。記事の次のパートでは、アプリケーションをインストールし、スマートコントラクトについて詳しく説明します。

サンプルのスマートコントラクトを理解する

In Hyperledger Fabric, the core business logic and rules are defined by smart contracts or chaincode. End users interact with the blockchain network and blockchain ledger by calling a smart contract’s defined rules, invoking smart contracts or chaincode.

Let’s assume that user U has implemented smart contract SC. Anyone who wants to participate, whether an organization or group, has to validate transactions or query the blockchain ledger, which can be accomplished by installing the chaincode on their peers.

After installing or deploying the smart contract or chaincode, peers join the channel. Channel members can then deploy the chaincode to the channel and use the smart contract business logic or rules in the chaincode to create or update assets on the channel ledger.

So far, we’ve already successfully created the channel. We will not use the Peer CLI provided by Hyperledger Fabric to deploy the assets-transfer package chaincode to the channel. Instead, first, let’s package the smart contract. To be installed on any participating machine, the chaincode should be packaged in the .tar.gz file. In other words, a peer that is a participating unit on the network can interact with other machines and computing devices on the blockchain network.

Next, we install the chaincode package, which has to be installed on every peer of the participating organization to follow each others’ rules or business logic. Before participating with these organization on the blockchain network, a certain threshold of peers who are a part of the organization must approve the chaincode definition. Finally, to further invoke the business logic or rules set for interaction, each channel should have the chaincode committed.

Package smart contract

Let’s review our sample JavaScript chaincode. In fabric-samples, you’ll go to the basic Go version of the asset-transfer chaincode with cd fabric-samples/asset-transfer-basic/chaincode-javascript.

The sample uses node modules to install and deploy the chaincode. package.json describes the dependencies required to package and install our chaincode. If you’ve thoroughly understood the first part, these dependencies will be familiar to you:

$ cat package.json

"dependencies": {
        "fabric-contract-api": "^2.0.0",
        "fabric-shim": "^2.0.0"

Let’s review the fabric-contract-api of our sample smart contract:

const { Contract } = require('fabric-contract-api');

class AssetTransfer extends Contract {
    ...
}

The code above will enable basic CRUD operations on our ledger, or in other words, read and write to the blockchain ledger using different function calls:

async CreateAsset(ctx, id, color, size, owner, appraisedValue) {
        const asset = {
            ID: id,
            Color: color,
            Size: size,
            Owner: owner,
            AppraisedValue: appraisedValue,
        };

        await ctx.stub.putState(id, Buffer.from(JSON.stringify(asset)));
    }

 

Inside this directory, run npm install to install any dependencies required by our chaincode package before installing or deploying chaincode on the ledger. To create a chaincode package, go to test-network and set config paths as follows:

cd ../../test-network
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/

Run peer version to make sure you’re able to interact with the peer CLI:

logrocket:~$ peer version
peer:
 Version: 1.4.7
 Commit SHA: e0afaa741
 Go version: go1.13.9
 OS/Arch: linux/amd64
 Chaincode:
  Base Image Version: 0.4.20
  Base Docker Namespace: hyperledger
  Base Docker Label: org.hyperledger.fabric
  Docker Namespace: hyperledger

Let’s package our chaincode using the command below:

peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-javascript/ --lang node --label basic_1.0

Now, you can install the basic.tar.gz file on the network of your choice. Your chaincode or smart contract is ready to be installed, establish interactions with the ledger, and eventually become one of them by abiding by the smart contract.

Install the chaincode package

Let’s install the basic, packaged asset-transfer smart contract/chaincode on our peers. Think about our user U and smart contract SC. Let’s create two organizations, Org1 and Org2. As in our example, both organizations require endorsements from each other, so chaincode will be installed on every peer operated by both organizations:

peer0.org1.example.com
peer0.org2.example.com

Let’s install the chaincode on the Org1 peer first. Set the following environment variables to operate the peer CLI as the Org1 admin user. The CORE_PEER_ADDRESS will be set to point to the Org1 peer, peer0.org1.example.com:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

Now, install the peer lifecycle chaincode on the peer. Issue the peer lifecycle chaincode install command to install the chaincode on the peer. You will not get the chaincode package identifier. In the next step, we’ll use this package ID to approve the chaincode:

peer lifecycle chaincode install basic.tar.gz
2021-02-06 09:09:27.534 IST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nJbasic_1.0:e2db7f693d4dfwi9599953fnd00300dd0232323e9ebb88c5721cb8248c3aead8123\022\tbasic_1.0" >
2021-02-06 09:09:27.534 IST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: basic_1.0:e2db7f693d4aa6156e652741dwi487575730de9ebb88c5721cb8248c3aead8123

Next, we’ll install the chaincode package on the Org2 peer using peer lifecycle chaincode install basic.tar.gz. As we did earlier, set the required environment variables and install the chaincode package. Our Org2 peer is peer0.org2.example.com:

export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

peer lifecycle chaincode install basic.tar.gz

Approve a chaincode definition

Each participating organization has to agree on a chaincode package, which has a unique hash value and a label. Each organization may get the chaincode package from a developer; if someone tries to change something on the chaincode, that chaincode package will give a different hash value compares to others.

Next, we’ll approve the chaincode, which includes the important parameters of chaincode governance, like the name, version, and the chaincode endorsement policy for your organization.

Each organization gets an identical Package ID, which is a combination of that chaincode package’s hash value and label. Approve this identical Package ID with channelID, name, version, init-required, etc. for your organization. Run the code below:

peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: basic_1.0:63828323nvsb3283283ss283932bb6cb291df20aa39542c3ef94008615704007f3, Label: basic_1.0

Set this package ID as an environment variable and use the package ID below to approve:

export CC_PACKAGE_ID=basic_1.0:63828323nvsb3283283ss283932bb6cb291df20aa39542c3ef94008615704007f3

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

There are multiple options that can be supplied with the command as parameter. For one, the --package-id flag includes the package identifier in the chaincode definition. The --sequence flag is an integer value that keeps track of the number of times a chaincode has been defined or updated. When the chaincode package is installed for first time, the sequence number is set to 1. Lastly, the --signature-policy flag is used to specify a chaincode endorsement policy.

Now, let approve for Org1:

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

It’s recommended that all channel members approve a chaincode before committing the chaincode definition.

Committing the chaincode definition to the channel

After a sufficient number of organizations have approved a chaincode definition, one organization can commit the chaincode definition to the channel. If a majority of channel members have approved the definition, the commit transaction will be successful, and the parameters agreed to in the chaincode definition will be implemented on the channel.

Before committing, we need to check commit readiness to channel using the code below:

peer lifecycle chaincode checkcommitreadiness [flags]

Flags:
      --channel-config-policy string   The endorsement policy associated to this chaincode specified as a channel config policy reference
  -C, --channelID string               The channel on which this command should be executed
      --collections-config string      The fully qualified path to the collection JSON file including the file name
      --connectionProfile string       The fully qualified path to the connection profile that provides the necessary connection information for the network. Note: currently only supported for providing peer connection information
  -E, --endorsement-plugin string      The name of the endorsement plugin to be used for this chaincode
  -h, --help                           help for checkcommitreadiness
      --init-required                  Whether the chaincode requires invoking 'init'
  -n, --name string                    Name of the chaincode
  -O, --output string                  The output format for query results. Default is human-readable plain-text. json is currently the only supported format.
      --peerAddresses stringArray      The addresses of the peers to connect to
      --sequence int                   The sequence number of the chaincode definition for the channel (default 1)
      --signature-policy string        The endorsement policy associated to this chaincode specified as a signature policy
      --tlsRootCertFiles stringArray   If TLS is enabled, the paths to the TLS root cert files of the peers to connect to. The order and number of certs specified should match the --peerAddresses flag
  -V, --validation-plugin string       The name of the validation plugin to be used for this chaincode
  -v, --version string                 Version of the chaincode

Global Flags:
      --cafile string                       Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
      --certfile string                     Path to file containing PEM-encoded X509 public key to use for mutual TLS communication with the orderer endpoint
      --clientauth                          Use mutual TLS when communicating with the orderer endpoint
      --connTimeout duration                Timeout for client to connect (default 3s)
      --keyfile string                      Path to file containing PEM-encoded private key to use for mutual TLS communication with the orderer endpoint
  -o, --orderer string                      Ordering service endpoint
      --ordererTLSHostnameOverride string   The hostname override to use when validating the TLS connection to the orderer.
      --tls                                 Use TLS when communicating with the orderer endpoint

`
We’ll see the flags and option parameters later in this tutorial. Let’s check commit readiness:

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json

    {
            "Approvals": {
                    "Org1MSP": true,
                    "Org2MSP": true
            }
    }

When both Org1MSP and Org2MSP are set to true, it means it’s ready! Let’s commit:

peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

Using our chaincode

Now, our chaincode is installed and ready to be used by our clients. Let’s use the chaincode to create an initial set of assets on the ledger and query the chaincode:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"InitLedger","Args":[]}'

2021-02-06 10:09:27.534 IST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200

peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

[{"Key":"asset1","Record":{"ID":"asset1","color":"blue","size":5,"owner":"Tomoko","appraisedValue":300}},
{"Key":"asset2","Record":{"ID":"asset2","color":"red","size":5,"owner":"Brad","appraisedValue":400}},
{"Key":"asset3","Record":{"ID":"asset3","color":"green","size":10,"owner":"Jin Soo","appraisedValue":500}},
{"Key":"asset4","Record":{"ID":"asset4","color":"yellow","size":10,"owner":"Max","appraisedValue":600}},
{"Key":"asset5","Record":{"ID":"asset5","color":"black","size":15,"owner":"Adriana","appraisedValue":700}},
{"Key":"asset6","Record":{"ID":"asset6","color":"white","size":15,"owner":"Michel","appraisedValue":800}}]

Use the docker ps command to further see our smart contract running:

$ docker ps
CONTAINER ID        IMAGE                                                                                                                                                                    COMMAND                  CREATED             STATUS              PORTS                              NAMES
7bf2f1bf792b        dev-peer0.org1.example.com-basic_2.0-572cafd6a972a9b6aa3fa4f6a944efb6648d363c0ba4602f56bc8b3f9e66f46c-69c9e3e44ed18cafd1e58de37a70e2ec54cd49c7da0cd461fbd5e333de32879b   "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes                                           dev-peer0.org1.example.com-basic_2.0-572cafd6a972a9b6aa3fa4f6a944efb6648d363c0ba4602f56bc8b3f9e66f46c
985e0967c27a        dev-peer0.org2.example.com-basic_2.0-572cafd6a972a9b6aa3fa4f6a944efb6648d363c0ba4602f56bc8b3f9e66f46c-158e9c6a4cb51dea043461fc4d3580e7df4c74a52b41e69a25705ce85405d760   "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes                                           dev-peer0.org2.example.com-basic_2.0-572cafd6a972a9b6aa3fa4f6a944efb6648d363c0ba4602f56bc8b3f9e66f46c
31fdd19c3be7        hyperledger/fabric-peer:latest                                                                                                                                           "peer node start"        About an hour ago   Up About an hour    0.0.0.0:7051->7051/tcp             peer0.org1.example.com
1b17ff866fe0        hyperledger/fabric-peer:latest                                                                                                                                           "peer node start"        About an hour ago   Up About an hour    7051/tcp, 0.0.0.0:9051->9051/tcp   peer0.org2.example.com
4cf170c7ae9b        hyperledger/fabric-orderer:latest

Write your first application

Now, let’s install and run our sample JavaScript application, which is a simple Node.js application:

cd asset-transfer-basic/application-javascript
npm install
ls
app.js                  node_modules            package.json       package-lock.json
node app.js

Our app.js has the following main components:

  • Enrolls the admin user:
async function main() {
  try {
    // build an in memory object with the network configuration (also known as a connection profile)
    const ccp = buildCCP();

    // build an instance of the fabric ca services client based on
    // the information in the network configuration
    const caClient = buildCAClient(FabricCAServices, ccp);

    // setup the wallet to hold the credentials of the application user
    const wallet = await buildWallet(Wallets, walletPath);

    // in a real application this would be done on an administrative flow, and only once
    await enrollAdmin(caClient, wallet);
  • Registers and enrolls an application user:
// in a real application this would be done only when a new user was required to be added
// and would be part of an administrative flow
await registerAndEnrollUser(caClient, wallet, mspOrg1, org1UserId, 'org1.department1');

Successfully registered and enrolled user appUser and imported it into the wallet
  • Prepares a connection to the channel and smart contract:
// Create a new gateway instance for interacting with the fabric network.
// In a real application this would be done as the backend server session is setup for
// a user that has been verified.
const gateway = new Gateway();

try {
  // setup the gateway instance
  // The user will now be able to create connections to the fabric network and be able to
  // submit transactions and query. All transactions submitted by this gateway will be
  // signed by this user using the credentials stored in the wallet.
  await gateway.connect(ccp, {
    wallet,
    identity: userId,
    discovery: {enabled: true, asLocalhost: true} // using asLocalhost as this gateway is using a fabric network deployed locally
  });

  // Build a network instance based on the channel where the smart contract is deployed
  const network = await gateway.getNetwork(channelName);


  // Get the contract from the network.
  const contract = network.getContract(chaincodeName);
  • Initializes the ledger with some sample data:
// Initialize a set of asset data on the channel using the chaincode 'InitLedger' function.
// This type of transaction would only be run once by an application the first time it was started after it
// deployed the first time. Any updates to the chaincode deployed later would likely not need to run
// an "init" type function.
console.log('\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger');
await contract.submitTransaction('InitLedger');
console.log('*** Result: committed');

Submit Transaction: InitLedger, function creates the initial set of assets on the ledger
  • Invokes each of the chaincode functions:
// GetAllAssets returns all assets found in the world state.
 async GetAllAssets(ctx) {
     const allResults = [];
     // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace.
     const iterator = await ctx.stub.getStateByRange('', '');
     let result = await iterator.next();
     while (!result.done) {
         const strValue = Buffer.from(result.value.value.toString()).toString('utf8');
         let record;
         try {
             record = JSON.parse(strValue);
         } catch (err) {
             console.log(err);
             record = strValue;
         }
         allResults.push({ Key: result.value.key, Record: record });
         result = await iterator.next();
     }
     return JSON.stringify(allResults);
 }  Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger
  Result: [
  {
    "Key": "asset1",
    "Record": {
      "ID": "asset1",
      "Color": "blue",
      "Size": 5,
      "Owner": "Tomoko",
      "AppraisedValue": 300,
      "docType": "asset"
    }
  },
  {
    "Key": "asset2",
    "Record": {
      "ID": "asset2",
      "Color": "red",
      "Size": 5,
      "Owner": "Brad",
      "AppraisedValue": 400,
      "docType": "asset"
    }
  },
  {
    "Key": "asset3",
    "Record": {
      "ID": "asset3",
      "Color": "green",
      "Size": 10,
      "Owner": "Jin Soo",
      "AppraisedValue": 500,
      "docType": "asset"
    }
  },
  {
    "Key": "asset4",
    "Record": {
      "ID": "asset4",
      "Color": "yellow",
      "Size": 10,
      "Owner": "Max",
      "AppraisedValue": 600,
      "docType": "asset"
    }
  },
  {
    "Key": "asset5",
    "Record": {
      "ID": "asset5",
      "Color": "black",
      "Size": 15,
      "Owner": "Adriana",
      "AppraisedValue": 700,
      "docType": "asset"
    }
  },
  {
    "Key": "asset6",
    "Record": {
      "ID": "asset6",
      "Color": "white",
      "Size": 15,
      "Owner": "Michel",
      "AppraisedValue": 800,
      "docType": "asset"
    }
  }// CreateAsset issues a new asset to the world state with given details.
async CreateAsset(ctx, id, color, size, owner, appraisedValue) {
  const asset = {
      ID: id,
      Color: color,
      Size: size,
      Owner: owner,
      AppraisedValue: appraisedValue,
  };
  return ctx.stub.putState(id, Buffer.from(JSON.stringify(asset)));
}

Submit Transaction: CreateAsset, creates new asset with ID, color, owner, size, and appraisedValue arguments

Conclusion

network.shアセット転送サンプルの使用が終了したら、スクリプトを使用してテストネットワークを停止し、を使用してリソースを解放することを忘れないでください./network.sh down。このコマンドは、作成したネットワークのCA、ピア、および順序付けノードを停止します。元帳のすべてのデータが失われることに注意してください。クリーンな初期状態でチュートリアルを再開します。

この記事では、HyperledgerFabricを使用したスマートコントラクトの作成について詳しく説明しました。そのアーキテクチャ、機能、JavaScriptSDKについて説明しました。作成したものをお知らせください。ご不明な点がございましたら、必ずコメントを残してください。ハッピーコーディング!

リンク:https ://blog.logrocket.com/hyperledger-fabric-develop-blockchain-smart-contracts/

#hyperledger  #blockchain