「HyperLedger Fabric 2.3 Alliance Chain Construction」コース学習ノート

コースのプラットフォーム: 51CTO
コースの講師: Datouwa
コースの紹介: アライアンス チェーンの構築とチェーン コードの操作をゼロから説明します。アライアンスチェーンの構築とチェーンコードの展開と呼び出しプロセスを誰もが真にマスターできるようにしましょう。

1. Hyperledger Fabric Alliance チェーンの紹介

1.1 使用シナリオ

ブロックチェーンのデータは公開されていますが、銀行や医療などの一部の業界では. これらの個人データを完全に開示することはできません。または、許可メカニズムを確立して選択的に開示することもできます。デフォルトでは、ブロックチェーン内のすべてのノードが台帳を維持し、他のメンバーとのトランザクションの進行状況を確認する必要がありますが、これは非効率的で費用がかかります。ハイパーレジャーは異なり、スーパーノードを使用して会計機能を完了します。

1.2 背景の生成

公有链缺点:
1.数据完全公开
2.所有节点参与运算成本大
3.不支持私下机密交易

上記の欠点によると、Hyperledger の設計は産業用アプリケーションに焦点を当て、既存の欠点を解決し、業界の本来の機能を拡張します。
Hyperledger は、参加者のアクセス許可の管理を含む、従来のブロックチェーン モデルに革命をもたらします. つまり: Hyperledger は許可された共有台帳です. Hyperledger は、識別、監査、つまりプライバシーのための安全で健全なモデルを提供します.したがって、運用サイクルを短縮します.業界のさまざまな要求に対応します。

一个覆盖众多网络的世界
我们希望能够出现众多的区块链网络,使得每个网络账本都能执行不同的业务,基于这一期望值,而出现了Hyperledger,现在单一普遍的通用网络已经出现.
但是网络与网络之间的通信还尚未有实例.会员就是在个个网络中的通,Hyperledger,除了能够实现这种网络独立运行之外.
还有寻址系统.能够通过一个账本的交易.发现并利用另一个本中正当的交易与智能合约

ここに画像の説明を挿入

1.3 アライアンスチェーンのメリットとデメリット

メリット:
(1) 制御性
が高い パブリックチェーンに比べて一般的にノードが大きいため、一度ブロックチェーンが形成されると、ビットコインのノードが多すぎて改ざんしたいなど、ブロックデータを改ざんすることができません。ブロック データはほとんど不可能であり、コンソーシアム チェーンでは、コンソーシアム内のすべての機関の過半数がコンセンサスに達する限り、ブロック データを変更できます。
(2) 半集権化
されたコンソーシアムチェーンは、コンソーシアム内の一定のメンバーのみが所有しており、ノードの数が限られているため、合意に達しやすい。
(3) 取引速度が速い
アライアンスチェーンは、本質的にはプライベートチェーンですが、ノード数が限られているため、合意に達しやすいため、取引速度も非常に高速です。
(4) データはデフォルトで公開されない
パブリック チェーンとは異なり、アライアンス チェーンのデータはアライアンスの内部組織に限定され、そのユーザーはアクセス権限を持っています。
短所:
(1) 同盟チェーンの半中央集権的な構造のため、悪意のあるプレーヤーから簡単に攻撃されます。複数の参加者が共謀する可能性があります。
(2) 業界の統一基準がないため、解決には必然的にさまざまな障害が生じますが、現時点では、エコロジー全体はまだ同盟チェーンの統一された枠組みからはほど遠いです。
(3) アプリケーション シナリオの柔軟性が低いため、大規模な総合企業の場合。新たなアライアンスを始めるには、メンバー全員の同意が必要ですが、大企業は多くのプロセスと複雑な制約を抱えているため、多くの大企業間で一般的なネットワークを構築するには非常に時間がかかります。

1.4 アライアンスチェーンの基本構造

ここに画像の説明を挿入
Fabric システムは組織によって分割されており、各組織には異なる機能を持つ Peer ノードが含まれており、各 Peer ノードは複数の役割を果たすことができます。すべての組織は、統一された Orderer クラスターを共有します。

1.Endorser Peer(背书结点)︰每个链码在实例化的时候都会设置背书策略(Endorsement policy),指定哪些节点对交易背书才有效。
2.Leader Peer (主节点)∶主节点负责和Orderer排序服务节点通信,从排序服务节点处获取最新的区块并在组织内部同步。
3.Committer Peer(记账节点)︰负责验证从排序服务节点接收的区块里的交易,然后将块提交(写入/追加)到其通道账本的副本。
4.Anchor Peer(锚节点)︰在一个通道( channel )上可以被所有其他peer发现的peer5.Order Peer(排序节点)︰排序服务节点接收包含背书签名的交易,对未打包的交易进行排序生成区块,广播给Peer主节点。

1.5 基本要件

(1) ネットワーク権限の要求
発行局は、ネットワークの目的に応じて適切なアクセス権限を決定し、この権限は、ネットワーク上で取引を行う前に識別を要求します。Web は公的に運用されており、モバイル アプリケーションに簡単に統合できます。非公開で実行でき、権限の検証によってのみ、その状況に慣れることができます。また、必要に応じてさまざまなレベルの権限を設定できます。
(2) プライバシーと機密性の重要性
どのブロックチェーン アーキテクチャにも基本的な要件があると考えています。つまり、ネットワーク上の当事者のアイデンティティと行動パターンは、許可されていない人物が台帳を通じて状況を問い合わせることを許可していません。また、ブロックチェーン ユーザーのビジネス ロジックやその他のトランザクション パラメータの機密性を保証できるようにしたいと考えています。契約に関係する関係者以外はデータにアクセスできないようにしてください。

1.6 ハイパーレジャー用語の紹介

chainCode-chaincode
は実際にはパブリック チェーンのスマート コントラクトです. Chaincode は、台帳上で実行されるソフトウェアであり、資産をエンコードでき、その中のトランザクション命令 (またはビジネス ロジック) を使用して資産を変更することもできます.
Channel-Channel
チャネルは、Fabric ネットワーク上のプライベート ブロックチェーン上に構築されます。データの分離と機密性が実現されます。チャネルによって指定された台帳は、チャネル内のすべてのピア ノードと共有されます。トランザクション パーティは台帳と対話するために、チャネルの正しい検証に合格する必要があります。チャネルは、"構成ブロック」 .
Gengsis Block - Genesis Block
Genesis Block is a configuration block that initializes the blockchain network or channel. It is also the first block on the blockchain.
Fabric-ca certificate
Fabric-ca is the default certificate management component, which report to network members andユーザーは PKl ベースの証明書を発行します。
クライアント (アプリ)
クライアント アプリケーションは、SDK を使用して Fabric ネットワークを処理します。まず、クライアントは CA から有効な ID 証明書を取得して、ネットワーク内のアプリケーション チャネルに参加します。Hyperledger Fabric には、複数の言語の SDK が既に用意されています。これらの SDK は、基になる gRPC インターフェイスへの呼び出しをカプセル化し、Node.Js、Python、Java、Go などの複数の実装を含む、より完全なクライアントおよび開発サポートを提供できます。
Invoke - call
は chainCode の関数を呼び出すために使用されます. ChainCode invoke はトランザクション、提案であり、モジュラー プロセス (承認、合意、検証、提出) を実行します。invoke の構造は、関数とパラメーターの配列です。
Ledger -ledger
Ledger はチャネルのチェーンであり、チャネル内の各ピアによって維持されるデータベースです。

2. Go 言語の基本文法

ルーキーチュートリアルも参照できると先生が言ってました
第 2 章 02 Go コード システムの概要

//定义了包名,此文件属于哪个包,每个o程序都包含一个名为main的包
package main
// go编译器当前程序需要引用那些包(系统包,第三方包,用户自定义)
import "fmt"
//main函数,go语言的入口必须在main包
func main(){
    
    
	/*Println:面数主要用于输出内容
	2:go基于面数式编程
	*/
	fmt.Println( "Hello, world! ")
	fmt.Print("Hello,world!")
	fmt.Printf("%s d","Hello,world", 2018)
}

質問 1: エラー " go: cannot find GOROOT directory: c: \go
" がある場合、GOROOT ルート ディレクトリを構成する必要があります。構成後に再起動する必要があります。
Chapter 2 03 配列、ループ
Chapter 2 04 関数
Chapter 2 05 ポインタ
Chapter 2 06 構造体
Chapter 2 07 インターフェイス、新しい用途
Chapter 2 08 カスタムパッケージ

行く言語の概要

package mainimport(
	"fmt"
	"reflect"
)
func main(){
    
    
	fmt.Println( "main().. ........")
	// go根据赋的值判断变量类型
	var e,f = 123,"hello"
	fmt.Println("e: ", e," f:",f)
	//隐式声明(一旦赋值成功,则变量类型将确定)
	x,y := fn01()
	fmt.Print1n("x: ", x," y:", y)
	fmt.Println(fn02())
	a, b := fn03(1020)
	fmt.Println("a: ", a, "a type:", reflect.Typeof(a), " b:", b)
	fno4(123)
}

func fno1()(intint) {
    
    
	return 23
}

//定义号返回的变量(理解为函数局部变量)
func fn02()(sum int) {
    
    
	//var sum int
	//已经声明不需要重复声明
	sum = 100
	return
}


//支持返回指针类型
func fno3(×, y int)(*intint){
    
    
	sum :=x+y
	//返回变量地址,返回变量的值
	return &sum,sum
}

//可变参数
func fno4(nums ...int){
    
    
	total := 0
	//可变参数就是数组(返回元素的索引和索引对应的值)
	for _, num := range nums {
    
    
		//fmt.Println("i: ",i)
		total += num
	}
	fmt.Println(total)
}


操作結果:
ここに画像の説明を挿入

3. シェルのクイックスタート

ルーキー チュートリアルで検索: シェル チュートリアル、チュートリアルに従って少し学習する

3.1 最初のシェルスクリプト

Linux 共通ディレクトリ構造:

/bin目录存放可执行的文件, root和一般账号都可用
/boot这个目录存放开机使用的文件,例如: linux内核和系统启动文件.. ldev存放所有设备文件.包括硬盘、分区、鼠标、键盘、USB等
/etc存放系统所有配置文件,
/home:用户主目录的,当你创建一个用户时,默认的用户文件夹就在该目录下
/mnt*如果需要挂载某些设备,一般建议存放到此目录中
/root: root用户的目录
/usr:注意usr并不是user的缩写,而是Unix Software Resource的缩写,"“Unix操作系统软件资源"放在该目录,而不是用户的数据

最初のスクリプト ファイル

mkdir test
cd test
sudo vim demo01.sh
#首先在vim打开文件界面后,按一次字母“i”  vim模式转为 INSERT,处于可编辑状态
#写入文件demo01.sh的内容如下两行:其中#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell

#!/bin/bash
echo "Hello World !"
#写完之后,按“ESC”退出插入模式回到命令模式,然后按“:wq”保存退出

#给脚本文件添加执行权限
sudo chmod +x demo01.sh
#执行脚本文件
./demo01.sh 
#输出结果为:Hello World !

ファイル権限分析
ここに画像の説明を挿入

ここに画像の説明を挿入

3.2 変数とパラメータの受け渡し

注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线 _。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。

vi demo01.shスクリプト ファイルは、次の内容で編集できます

#!/bin/bash
echo "Hello World !"
url="http: // www.163.com"
echo ${
    
    url}
str="url is \n ${url}"
echo  $str
str='url is \n ${url}'
echo $str
echo 'shell传递参数案例'
echo "file name is $0"
echo"第二参数为:$1"
echo "总共传递 $# 个参数"

#执行结果说明,双引号内支持变量和转义符,而单引号不支持

ここに画像の説明を挿入

3.3 配列、ループ用

複数の値を配列に格納できます。Bash シェルは 1 次元配列のみをサポートし (多次元配列はサポートされていません)、初期化中に配列サイズを定義する必要はありません (PHP と同様)。
ほとんどのプログラミング言語と同様に、配列要素の添字は 0 から始まります。
シェル配列は括弧で表され、要素は「スペース」記号で区切られます. 構文形式は次のとおりです: array_name=(value1 value2 … valuen)

#!/bin/bash
arr=('A' 'Bug' 3.14 100)
#显示数组
echo "第1个元素为${arr[0]}"
echo "第2个元素为${arr[1]} ,长度为${#arr[1]}"
echo "数组成员为: ${arr[*]},数组的长度为${#arr[*]}"
for loop in ${
    
    arr[*]}
do
    echo "this value is ${loop}"
done

if [ $1 == $2 ]
then
  echo "a==b"
else
  echo "a!=b"
fi

ここに画像の説明を挿入

3.4 関数ファイルの内容

(1) 機能

#!/bin/bash

funWithReturn(){
    
    
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum$anotherNum !"
    #注意,加法外面是两层小括号
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"

ここに画像の説明を挿入
(2) ファイル インクルージョン
他の言語と同様に、シェルにも外部スクリプトを含めることができます。これにより、一般的なコードを別のファイルとして簡単にカプセル化できます。

Shell 文件包含的语法格式如下:

. filename   # 注意点号(.)和文件名中间有一空格
source filename

注: 含まれるファイルに実行権限は必要ありません

#文件fn.sh,这个即为被包含文件,不用为其赋予执行权限
#!/bin/bash
funcDemo(){
    
    
  echo "参数1为:$1"
  echo "参数2为:$2"
  echo "请输入一个数值:"
  read num
  return $(($1 +$2 + ${
    
    num}))
}


#文件callfn.sh
!/bin/bash
#引入同目录的sh文件
source ./fn.sh
funcDemo 1 2
echo "result: $?"


#终端执行
gan@gan-virtual-machine:~/Gantest$ vi fn.sh
gan@gan-virtual-machine:~/Gantest$ vi callfn.sh
gan@gan-virtual-machine:~/Gantest$ chmod u+x callfn.sh 
gan@gan-virtual-machine:~/Gantest$ ./callfn.sh 
参数1为:1
参数2为:2
请输入一个数值:
3
result: 6

3.5ケース

var='yes'
case $var in
"yes")
	echo 'your choose is yes'
	;;
"no")	
	echo'your choose is no'
	;;
*)
	echo 'your choose is error'
	;;
esac
#短路模式
[ -d $1 ] && rm -r $1
#动态获取当前参数数量
echo $#
#吧所有参数左移动1位
shift 1
echo $#

ここに画像の説明を挿入
ここに画像の説明を挿入

第四に、ファブリックのインストール

4.1 Ubuntu のインストール

VMWare版本:VMware® Workstation 16 Pro 16.2.3 build-19376536
Ubuntu版本:Ubuntu 22.04 LTS【好像是发行版,我就是想装最新的,哈哈哈。大头娃老师用的是20.04版本】

もちろん、最初に VMWare をインストールしてから、新しい仮想マシンを作成する必要があります==プロンプトに従って、段階的にインストールします。Ubuntu の 22.04 バージョンは適切に見え、VMtools は自動的にインストールされます。
自分で百度をダウンロードしてインストール〜

4.2 Ubuntu の基本的なコマンドと設定

1. ダウンロード元を変更する

左下隅にある 9 つのドットをクリックして検索インターフェイスに入ります -> 検索ボックスに「ソフトウェア」と入力します -> 表示される「ソフトウェアと更新」をクリックし、ダウンロード元を変更するためのインターフェイスに入ります -> 対応するボックスをクリックしますダウンロードするには -> Alibaba Cloud Source を見つけます (先生はこれは比較的安定していると言いました) -> サーバーを選択 -> パスワード認証を入力 -> 閉じる -> リロードします。

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ロードされた後、コマンドを実行して、ダウンロード ソースが正常に置き換えられたかどうかを確認できます。

cat /etc/apt/sources.list

ここに画像の説明を挿入

2. Linux の基本コマンド

创建文件 touch 文件名.文件后缀
删除文件 rm 文件名.文件后缀
创建目录 mkdir 目录名
删除目录 rmdir 目录名
删除带文件的目录 rm -r 目录名/
移动文件 mv 文件当前绝对路径  想要移动到的目录的绝对路径
		mv /home/hong/abc.txt  ../    #将abc.txt移动到上一级目录
移动文件并重命名 mv 当前文件名 目标文件名
root@ubuntu:/home# ls
abc.txt hong
root@ubuntu:/home# mv abc.txt aaa.txt
root@ubuntu:/home# ls
aaa.txt hong

#解压zip、tar压缩文件
root@ubuntu:/home/hong/Desktop# ls
fabric-2.1.1.zip fabric-2.3.0.tar.gz
root@ubuntu:/home/hong/Desktop# tar xzf fabric-2.3.0.tar.gz -C .
root@ubuntu:/home/hong/Desktop# tar xzf fabric-2.3.0.tar.gz -C ../
root@ubuntu: /home/ hong/Desktop# cd ..
root@ubuntu:/ home/hong# ls
Desktop Downloads fabric-2.3.0 Pictures  emplates Documents examples.desktop Music Public Videos
root@ubuntu :/home/hong#rm -r fabric-2.3.0/
root@ubuntu:/home/ hong# ls
Desktop Downloads Music Public Videos Documents examples.desktop Pictures Templates
root@ubuntu :/home/hong# cd Desktop/
root@ubuntu :/home/hong/Desktop# ls
fabric-2.1.1.zip fabric-2.3.0 fabric-2.3.0.tar.gz

root@ubuntu: /home/hong/Desktop# unzip fabric-2.1.1.zip -d .
#这种-d方式会覆盖原来有的文件,如果这个目录下有重名文件,解压出来直接覆盖
root@ubuntu: / home/ hong/Desktop# ls
fabric-2.1.1 fabric-2.1.1.zip fabric-2.3.0 fabric-2.3.0.tar.gz

4.3 Docker の紹介とインストール

1. docker の簡単な紹介

Fabric は直接 Linux 上にあるのではなく、Docker コンテナーに基づいて構築されています。
Docker ウェアハウス: このウェアハウスには多くのコンポーネントと環境があり、使用するファブリックのコンポーネントはその上にあります。
ルーキー チュートリアルには簡単な紹介があります。Docker を使用すると、開発者はアプリケーション依存関係軽量でポータブルなコンテナーにパッケージ化できます。これは、一般的な Linux マシンに配布したり、仮想化することもできます。コンテナーは完全にサンドボックス メカニズムを使用し、相互にインターフェイスはありません (iPhone アプリと同様)。さらに重要なのは、コンテナーのパフォーマンス オーバーヘッドが非常に低いことです。海の他のコンテンツに影響を与えることなく、クジラ内のサンドボックスで任意のテストとデバッグを実行できます。デバッグが完了したら、テストを再構成することなく、ホエール サンドボックスのコピー全体を別のオペレーティング システムに移植できます。Docker コンテナはクジラに相当します。アライアンスチェーンの異なるスーパーノードの構成は実際には同じであるため、dockerコンテナの助けを借りて行うことができます.テストは最初にdockerで完了し、他のノードをコピーして移植できます〜
ここに画像の説明を挿入

docker と VM の違い:
VM
ここに画像の説明を挿入
は docker を導入します
ここに画像の説明を挿入

综上:
docker是软件层面的虚拟化,比较轻量级,用于软件环境的复制移植和测试。
VM是操作系统层面的虚拟化,比较笨重,用于操作系统层面的测试。

2.ドッカーのインストール

(1) docker をインストールし、docker のバージョンを確認する

sudo apt install docker.io

表示する利用可能dockerなコマンド、docker インストールの成功には、サブコマンドの紹介があります。
ここに画像の説明を挿入
ドッカーのバージョンを表示

gan@gan-virtual-machine:~$ sudo docker version
Client:
 Version:           20.10.12
 API version:       1.41
 Go version:        go1.17.3
 Git commit:        20.10.12-0ubuntu4
 Built:             Mon Mar  7 17:10:06 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server:
 Engine:
  Version:          20.10.12
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.3
  Git commit:       20.10.12-0ubuntu4
  Built:            Mon Mar  7 15:57:50 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.5.9-0ubuntu3
  GitCommit:        
 runc:
  Version:          1.1.0-0ubuntu1
  GitCommit:        
 docker-init:
  Version:          0.19.0
  GitCommit:        

(2) Docker 構成
A、イメージのプルと削除のデモ - hello-world を例に取る

#拉取hello-world镜像,这样子是默认拉取最新版,如果想选特定版本就在后面加上版本号即可
sudo docker pull hello-world
#用docker images命令可以看到,我们拉取镜像成功啦,执行结果如下
sudo docker images
#REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
#hello-world   latest    feb5d9fea6a5   8 months ago   13.3kB
#删除镜像  后面跟的是镜像ID,因为同一个名字的镜像有不同版本,你可以装多个版本,所以会有多个同名的镜像,只有镜像ID才能唯一标识镜像
sudo docker rmi feb5d9fea6a5
#Untagged: hello-world:latest
#Untagged: hello-world@sha256:13e367d31ae85359f42d637adf6da428f76d75dc9afeb3c21faea0d976f5c651
#Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
#Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359
#再次查看,发现镜像删除成功啦
sudo docker images
#REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

B. Docker アクセラレータを構成する

Web ページで「 」と入力https://cr.console.aliyun.com/cn-hangzhou/instances/mirrorsし、Alipay または Taobao でスキャンして Alibaba Cloud を開き、ログインを確認します。次に、アクセラレータの Web サイトと、アクセラレータの構成ガイドがあります。
ここに画像の説明を挿入

gan@gan-virtual-machine:~$ cd /etc/docker
gan@gan-virtual-machine:/etc/docker$ ls
key.json
#发现etc/docker目录下没有daemon.json这个文件,所以我们需要新建一个

大丈夫です。Alibaba Cloud インターフェースのプロンプトに従って Ubuntu インストール コマンドに従い、その段落を直接コピーして Ubuntu コマンド ターミナルに貼り付けます。

gan@gan-virtual-machine:/etc/docker$ sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
    
    
  "registry-mirrors": ["https://m6juudzz.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
[sudo] password for gan: 
{
    
    
  "registry-mirrors": ["https://m6juudzz.mirror.aliyuncs.com"]
}
gan@gan-virtual-machine:/etc/docker$ ls
daemon.json  key.json
gan@gan-virtual-machine:/etc/docker$ cat daemon.json 
{
    
    
  "registry-mirrors": ["https://m6juudzz.mirror.aliyuncs.com"]
}

アクセラレータを構成したら、Docker を再起動する必要があります。その後、イメージを再度プルして、アクセラレータが正常に構成されているかどうかをテストします

#先查看docker当前状态:active (running)  运行中
gan@gan-virtual-machine:/etc/docker$ service docker status
#关闭docker
gan@gan-virtual-machine:/etc/docker$ service docker stop
#再次查看docker当前状态:inactive (dead) 关闭
gan@gan-virtual-machine:/etc/docker$ service docker status
#此时再重新启动
gan@gan-virtual-machine:/etc/docker$ service docker start
#再次查看docker状态就又变成运行中啦


#然后重新拉取hello-world镜像,如果成功,说明加速器配置应该没问题
gan@gan-virtual-machine:/etc/docker$ sudo docker pull hello-world
#Using default tag: latest
#latest: Pulling from library/hello-world
#2db29710123e: Pull complete 
#Digest: sha256:2498fce14358aa50ead0cc6c19990fc6ff866ce72aeb5546e1d59caac3d0d60f
#Status: Downloaded newer image for hello-world:latest
#docker.io/library/hello-world:latest

4.4 dockerの共通コマンド

1:查看版本: docker version
2:查看系统信息: docker info显示 Docker系统信息,包括镜像和容器数。
3: docker images //显示镜像列表
4: docker run hello-world(图文讲解)
//1∶客户端首先要连接Docker服务器。2:从Docker服务器中pull镜像。3:从lmage中创建容器,一个镜像可以创建多个容器。4: Docker守护进程将输出流式传输到Docker客户端,后者将其发送到您的终端。
5: docker rmi hello-world ===> docker images
6: docker pull nginx:1.18.0 //通过官网下载指定版本
7: docker run [-d] nginx //后台运行镜像
8: docker ps //l查看已运行镜像列表-a列表所有的容器,-f过滤,-q只列表容器的id。
9: docker run -d -p 8080:80 nginx //启动时候配置端口映射
10: docker stop containerID //只要能识别ID一位数也行-r尽量先删除容器在删除镜像2.1 docker rmi nginx:1.18.0 #删除已下载的镜像rm是删除容器(镜像运行的称为容器)
11:启动、关闭服务service docker status|start|stop

(1) イメージとコンテナ
ここに画像の説明を挿入

#拉取镜像
root@gan-virtual-machine:~# docker pull hello-world
#运行容器
root@gan-virtual-machine:~# docker run hello-world
#查看当前正在运行的容器,发现没有,因为hello-world就是下图中所示,打印几个步骤出来,执行完成后自动关闭容器。
root@gan-virtual-machine:~# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

ここに画像の説明を挿入

#删除docker镜像失败
root@gan-virtual-machine:~# docker rmi feb
Error response from daemon: conflict: unable to delete feb5d9fea6a5 (must be forced) - image is being used by stopped container 2d9ba30d106c

#查看所有镜像,包括未处于运行状态的容器
root@gan-virtual-machine:~# docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
2d9ba30d106c   hello-world   "/hello"   37 minutes ago   Exited (0) 37 minutes ago             condescending_tu
#想要删除镜像需要先删除其对应的容器,和删除类之前要删掉对应的对象一个道理。
#删除容器2d9ba30d106c。后面接的容器ID,只要能够区分就行,不用写完整的ID,如果第一位就能区分,打一个字母也是可以的
root@gan-virtual-machine:~# docker rm 2d9
#查看容器
root@gan-virtual-machine:~# docker ps -a
#CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
#容器已经删掉了,此时删除镜像
root@gan-virtual-machine:~# docker rmi feb
#查看镜像,确保删除成功
root@gan-virtual-machine:~# docker images

ここに画像の説明を挿入

(2) Nginx のデプロイ
docker ウェアハウスでバージョンを確認できます
ここに画像の説明を挿入
ここに画像の説明を挿入

#找到1.19.6版本【因为老师用的这个版本啦~】,复制镜像拉取命令
#不加版本号的话,会默认拉取最新的版本,其实装最新版也是可以哒~
docker pull nginx:1.19.6

ここに画像の説明を挿入
Nginx にアクセスできますがlocalhost:端口号、これは実際には Tomcat のサーバー インターフェイスに似ています。
ここに画像の説明を挿入

でも私のはこんな感じです:[シャオバイの崩壊は先生とは違う瞬間でした]
ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入

(3)小エピソード
Nginxのページにアクセスできなかったので、問題を検索したところ、まだアクセスできないことがわかったので、振り返ってみると、この手順だけが先生と異なっていました。
コマンドで管理者をsu切り替える
ここに画像の説明を挿入
v_v.
ここに画像の説明を挿入
それから私はバイドゥ、

ubuntu初始root密码
安装完Ubuntu后可能没有设置root密码,不知道密码自然就无法进入根用户下。
到网上搜了一下,原来是这么回事:
Ubuntu的默认root密码是随机的,即每次开机都有一个新的root密码。
解决方法:
我们可以在终端输入命令“sudo passwd”,然后输入当前用户的密码后"Enter"
终端会提示我们输入新的密码并确认,此时的密码就是root新密码。
修改成功后,输入命令 su root,再输入新的密码就ok了。

いずれにせよ、最終的には管理者の問題ではないことが判明しました。docker クライアントを再起動し、コンテナを再起動してください~
ここに画像の説明を挿入

4.5 ファブリック コンポーネントのダウンロード

1. 要約版: ファブリック コンポーネントのダウンロードおよびプル コマンド

最初に管理者に切り替えてから、次のコマンドを実行してください~

//在GitHub下载fabric2.3.0的tar.gz文件后,拖到Ubuntu中,并且解压到/opt目录下,进入解压后的目录
root@ubuntu:/home/hong/Desktop# tar xzf fabric-2.3.0.tar.gz -C /opt
root@ubuntu:/opt/fabric-2.3.0/scripts# apt install curl
//如果有报错“E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)”的话,可以不用移除/var/lib/dpkg/lock这个目录,然后重新安装apt install curl,如果没有报错,跳过下面这条语句
root@ubuntu:/opt/fabric-2.3.0/scripts# rm /var/lib/dpkg/lock
//安装,拉取下载组件,获得bin、config、test-等目录
root@ubuntu:/opt/fabric-2.3.0/scripts# ./bootstrap.sh 
//安装docker-compose
root@ubuntu/opt/fabric-2.3.0/scripts# :apt install docker-compose
//启动Fabric服务
root@ubuntu:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh up
//可以看下,现在在运行的docker容器
root@ubuntu:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# docker ps -a
//然后试一下终止网络命令——>本质就是销毁之前启动的docker容器的过程
root@ubuntu:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh down
//组件下载这部分就完成啦

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入


自動ロック画面をオフにするちょっとしたトリックを追加して、
リソースをダウンロードするときに、Ubuntu インターフェースから長時間離れているために画面がロックされないようにし、ダウンロードが中断されるのを防ぎます.これは 20.04 ですオフにする必要がある Ubuntu のバージョン。
ここに画像の説明を挿入

インストールした新しいバージョンにはこのオプションがないようです. ある場合は、設定の場所が変更されている可能性があります.
ここに画像の説明を挿入

2. ダウンロード コンポーネント プロセスのスクリーンショット [先生の手順のスクリーンショット記録、見ずにスキップできます]

先生によると、次のレッスンでは、ファブリック ソース コード パッケージのダウンロードについて説明します
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
. インストール後、ネットワークを開始して、次のことを試してください。
ここに画像の説明を挿入

このコンポーネントに対する docker の依存関係が見つかりませんでした。Docker-compose は実際には docker コマンドライン ツールです. 複数の Docker イメージが相互に呼び出して相互に依存する必要がある前に、それを完了するために docker-compose が必要です。インストールするだけです〜インストール後、最初と操作が完了した後に
ここに画像の説明を挿入
サンプルがないことがわかり、ネットワークを開始して次を確認できます。
ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入

ここに画像の説明を挿入

3. ca コンポーネントのダウンロード失敗の問題

問題 1 CA コンポーネントのダウンロードに失敗しました:「------> 1.4.9 fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----
」効果はないと思っていたので、あとでネットワークを立ち上げたときに表示されるので、もう一度確認するか、完了させたほうがいいと思いました。

===> Downloading version 1.4.9 platform specific fabric-ca-client binary
===> Downloading:  https://github.com/hyperledger/fabric-ca/releases/download/v1.4.9/hyperledger-fabric-ca-linux-amd64-1.4.9.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:21 --:--:--     0
curl: (7) Failed to connect to github.com port 443 after 21048 ms: Connection refused

gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now
==> There was an error downloading the binary file.

------> 1.4.9 fabric-ca-client binary is not available to download  (Available from 1.1.0-rc1) <----

次に、ホストにダウンロードし、ダウンロードした tar.gz ファイルをその中にコピーしました. 解凍した後、bin に 2 つのファイルがあることがわかりました.
ここに画像の説明を挿入
2 日後に追加しました. 再インストールしたところ、ネットワークが良好な場合、ダウンロードを完了できます。
ここに画像の説明を挿入

**質問 2 Docker イメージが正常にプルされませんでした: **後でサービスを開始すると、「ローカル ファブリック バイナリと Docker イメージが同期されていません。問題が発生する可能性があります。」というメッセージが表示されます。
ここに画像の説明を挿入

初回インストール時、CAコンポーネントのダウンロードに失敗したため、CAコンポーネントのダウンロードに失敗したところで停止して終了したため、dockerイメージがプルされませんでした。
ここに画像の説明を挿入
その後2回目のインストールをしたところ、うまくいき、dockerイメージができました〜
ここに画像の説明を挿入

4.6 ファブリック ダウンロード コンポーネントのプロセス分析

1. ファブリック ソース コードのダウンロード

リソース リンク
上記の GitHub Web サイトを開き、プルダウンして右側の部分に注意し“Releases 45 v2.4.3 Latest”、クリックReleasesして新しいインターフェイスに入り、 をクリックします。Tagsさまざまなバージョンが表示されます。2.3.0 が見つかり、 を選択しますtar.gzするとダウンロード成功!
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

ダウンロードしたソースコードを Ubuntu にコピーしたい 直接ドラッグできない VMtools をインストールしたのに、ソースコードファイルを Ubuntu にドラッグできないので、U ディスクでコピーする、ハハハ、私は本当に賢いです ~
[問題 ID 202206181158] 奇妙な問題に遭遇しました: ホストから 1 つのファイルを ubuntu にコピーできますが、ファイルとフォルダーを zip で Ubuntu にコピーすることはできません。エラーは次のとおりです。
ここに画像の説明を挿入

2. コンポーネントのインストール分析

教師は、カタログに従ってファブリック サービスを手動で構築しました。彼は次のように述べています。彼は、これを手動で行うことで、重要なコンポーネントとその構造をより明確に把握したいと考えていました。

//目录结构
fabric-2.3.0【项目主目录】
	|—— scripts【加载组件第一级子目录】
		|—— bootstrap.sh【启动文件,可以用这个文件拉取并下载后面几个需要的重要文件】
		|—— fabric-samples【官方实例目录】
			|—— bin【这个bin目录下有十个文件:configtxgen,cryptogen ,fabric-ca-client,idemixgen,osnadmincon,figtxlator,discover,fabric-ca-server,orderer,peer。都是很重要的组件,包括节点、证书服务端、证书客户端等】
			|—— config【配置文件目录,内含三个配置文件:configtx.yaml, core.yaml,orderer.yaml】
			|—— test-network【网络测试目录,其下有一个控制网络服务启动、关闭等相关命令的文件】
				|—— network.sh【控制网络启动、关闭的文件】
							

ここに画像の説明を挿入

五、ソースコード分析

5.1 ブートストラップ ソース コード分析

#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

# if version not passed in, default to latest released version
#设置fabric版本
VERSION=2.3.0
# if ca version not passed in, default to latest released version
#很多时候fabric有最新版,但是组件没有对应更新位相应版本,这个ca版本是1.4.9
CA_VERSION=1.4.9
ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')")
MARCH=$(uname -m)
#接下来是6个函数的定义,我们可以先跳过这些函数内容,先看后面的具体调用部分
printHelp() {
    
    #打印输出,描述性的
    echo "Usage: bootstrap.sh [version [ca_version]] [options]"
    echo
    echo "options:"
    echo "-h : this help"
    echo "-d : bypass docker image download"
    echo "-s : bypass fabric-samples repo clone"
    echo "-b : bypass download of platform-specific binaries"
    echo
    echo "e.g. bootstrap.sh 2.3.0 1.4.9 -s"
    echo "will download docker images and binaries for Fabric v2.3.0 and Fabric CA v1.4.9"
}

# dockerPull() pulls docker images from fabric and chaincode repositories
# note, if a docker image doesn't exist for a requested release, it will simply
# be skipped, since this script doesn't terminate upon errors.

dockerPull() {
    
    
    #three_digit_image_tag is passed in, e.g. "1.4.7"
    #传过来的第一个参数,FABRIC_TAG
    three_digit_image_tag=$1
    #所有参数向前移动一位,相当与FABRIC_TAG删掉啦,移动之后,第一个参数$1就变成了数组的第一个元素啦
    shift
    #two_digit_image_tag is derived, e.g. "1.4", especially useful as a local tag for two digit references to most recent baseos, ccenv, javaenv, nodeenv patch releases
    #切割版本号,把最后一位切掉
    two_digit_image_tag=$(echo "$three_digit_image_tag" | cut -d'.' -f1,2)
    #“$#”是动态获取当前参数数量,gt是“>”符号,即当前参数数量大于0
    while [[ $# -gt 0 ]]
    do
    	#获取第一个要拉取的镜像名称
        image_name="$1"
        #“$three_digit_image_tag”即版本号
        echo "====> hyperledger/fabric-$image_name:$three_digit_image_tag"
        #拉取镜像,通过镜像名称和版本号拉取
        docker pull "hyperledger/fabric-$image_name:$three_digit_image_tag"
        docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name"
        docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name:$two_digit_image_tag"
        #所有参数向前移动一位,下载完一个就往左移动一个,即当前$1变成第二个要获取的镜像名字啦
        shift
    #直到当前参数个数为0,即拉取下载完所有镜像之后,推出循环,函数执行结束
    done
}

cloneSamplesRepo() {
    
    
    # clone (if needed) hyperledger/fabric-samples and checkout corresponding
    # version to the binaries and docker images to be downloaded
    #if [ -d first-network ]用于判断当前这个目录是否存在
    if [ -d first-network ]; then #first-network在1.4好像就改了,把这个目录改成fabric-samples了,所以这条语句不重要
        # if we are in the fabric-samples repo, checkout corresponding version
        echo "==> Already in fabric-samples repo"
    elif [ -d fabric-samples ]; then #这个语句,如果fabric-samples目录存在,说明已经有东西啦,不用下载,直接进目录就行。所以这个条件下的操作为:打印“Changing directory to fabric-samples”并进入fabric-samples
        # if fabric-samples repo already cloned and in current directory,
        # cd fabric-samples
        echo "===> Changing directory to fabric-samples"
        cd fabric-samples
    else  #这时候,说明fabric-samples目录不存在,所以我们要下载。所以执行的操作为:打印“Cloning hyperledger/fabric-samples repo”,并通过git获取fabric-samples目录及其对应文件并且进入那个目录。
        echo "===> Cloning hyperledger/fabric-samples repo"
        git clone -b master https://github.com/hyperledger/fabric-samples.git && cd fabric-samples
         #这里值得多说一点,&& 与运算,两个都为真才执行,其实隐含了前一个命令执行成功才会执行后一个命令。所以在Linux里面,&&可以连接任何命令,不一定是条件表达式。这就是“短路操作”。与或非运算都有短路操作。
    	#command1 && command2 。&&左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行;换句话说,“如果这个命令执行成功&&那么执行这个命令”语法格式:commandl && command2 && command3 ...
		#1.命令之间使用&&连接,实现逻辑与的功能。2.只有在&&左边的命令返回真(命令返回值$? == 0),&&右边的命令才会被执行。3.只要有一个命令返回假(命令返回值 $?== 1),后面的命令就不会被执行。4.示例1[root@open ~]# cp anaconda-ks.cfg/data/ && rm -f anaconda-ks.cfg && echo "SUCCESS"中,cp命令首先从root的y家目录复制文件文件anaconda-ks.cfgi到 /data目录下;执行成功后,使用rm 命令删除源文件;如果删除成功则输出提示信息"SUCCESS"。
    fi
	
	#判断版本
    if GIT_DIR=.git git rev-parse v${
    
    VERSION} >/dev/null 2>&1; then
        echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
        git checkout -q v${
    
    VERSION}
    else
        echo "fabric-samples v${VERSION} does not exist, defaulting master"
        git checkout -q master
    fi
}

# This will download the .tar.gz
download() {
    
    
    local BINARY_FILE=$1
    local URL=$2
    echo "===> Downloading: " "${URL}"
    #设置重连的次数(5),每次重连延迟3秒
    #文件下载成功之后,直接调用tar解压操作
    #rc=$?表示获取函数执行的结果,即解压是否成功的结果
    curl -L --retry 5 --retry-delay 3 "${URL}" | tar xz || rc=$?
    #补充
    #|运算符:管道符号,是unix—个很强大的功能,符号为一条竖线:"|"。用法:command 1 | command 2,他的功能是把第一个命令command 1执行的结果作为command2的输入传给command 2。
    if [ -n "$rc" ]; then #rc不为空,说明解压出现问题。返回22,并打印“There was an error downloading the binary file”
        echo "==> There was an error downloading the binary file."
        return 22
    else #如果解压成功,打印"==> Done."
        echo "==> Done."
    fi
}

pullBinaries() {
    
    #通过两个下载,实现bin和config目录的生成
	#打印,并且通过传入两个参数(文件名和GitHub下载地址)调用download函数。
    echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
    download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
    if [ $? -eq 22 ]; then #获取download调用执行结果,如果为22说明download执行失败,所以打印"------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"。然后退出执行。后面下载ca也是同理的
        echo
        echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
        echo
        exit
    fi
	#同理,下载fabric-ca。打印,并且通过传入两个参数(文件名和GitHub下载地址)调用download函数。
    echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
    download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
    if [ $? -eq 22 ]; then 
        echo
        echo "------> ${CA_TAG} fabric-ca-client binary is not available to download  (Available from 1.1.0-rc1) <----"
        echo
        exit
    fi
}

pullDockerImages() {
    
    
	#command命令:无条件调用系统提供的函数。这个是为了确保即使用户自己定义了一个叫docker的函数,执行当前函数时调用的也是系统提供的docker函数。
    command -v docker >& /dev/null
    #用于接收上一条命令的执行结果,如果为0,则说明系统docker函数存在
    NODOCKER=$?
    if [ "${NODOCKER}" == 0 ]; then
    	#系统docker存在,则创建一个数组,数组里面存储待下载镜像名称
        FABRIC_IMAGES=(peer orderer ccenv tools)
        case "$VERSION" in
        #如果当前是fabric2.x版本,则组件添加baseos
        2.*)
            FABRIC_IMAGES+=(baseos)
            shift
            ;;
        esac
        echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
        echo "===> Pulling fabric Images"
        #调用函数dockerPull ,且传入两个参数:第一个参数是下载Fabric版本FABRIC_TAG,第二个是数组FABRIC_IMAGES的所有元素
        dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
        echo "===> Pulling fabric ca Image"
        #创建数组,其中只有一个元素:ca
        CA_IMAGE=(ca)
        #调用函数dockerPull ,且传入两个参数:第一个参数是下载ca版本CA_TAG,第二个是数组CA_IMAGE的所有元素
        dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
        echo "===> List out hyperledger docker images"
        #如果下载成功,则用docker images查看镜像。grep是正则表达式,也就是在所以docker images中选择和hyperledger相关的镜像打印输出。
        docker images | grep hyperledger
    else
        echo "========================================================="
        echo "Docker not installed, bypassing download of Fabric images"
        echo "========================================================="
    fi
}

#从这里开始~首先定义了三个变量,将它们都赋值为true
DOCKER=true
SAMPLES=true
BINARIES=true

# Parse commandline args pull out
# version and/or ca-version strings first
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
    VERSION=$1;shift  #一会儿下载时,读取输入的第一个参数,如果其不为“-”,则赋值给VERSION;否则前面采用默认的VERSION=2.3.0。一般是不会执行这几句的,但是加上的话逻辑更完整。
    if [ -n "$1" ]  && [ "${1:0:1}" != "-" ]; then
        CA_VERSION=$1;shift  #同理,,读取输入的第一个参数,如果不为“-”,则赋值给CA_VERSION;否则前面的采用CA_VERSION=1.4.9
        if [ -n  "$1" ] && [ "${1:0:1}" != "-" ]; then
            THIRDPARTY_IMAGE_VERSION=$1;shift #同理,读取第一个参数,如果版本号不为“-”,则赋值给THIRDPARTY_IMAGE_VERSION
        fi
    fi
fi

# prior to 1.2.0 architecture was determined by uname -m
#拼接要下载的文件下载链接,此处代码不重要
#后面打印输出的时候要用“=> Downloading version 2.3.0 platform specific fabric binaries=> Downloadinq: https://github.com/hyperledger/fabric/releases/download/v2.3.0/hyperledger-fabric-linux-amd64-2.3.0.tar.gz”以及“=> Downloading version 1.4.9 platform specific fabric-ca-client binary =>Downloading: https://github.com/hyperledger/fabric-ca/releases/download/vl.4.9/hyperledger-fabric-ca-linux-amd64-1.4.9.tar.gz”
if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
    export FABRIC_TAG=${
    
    MARCH}-${
    
    VERSION}
    export CA_TAG=${
    
    MARCH}-${
    
    CA_VERSION}
    export THIRDPARTY_TAG=${
    
    MARCH}-${
    
    THIRDPARTY_IMAGE_VERSION}
else
    # starting with 1.2.0, multi-arch images will be default
    : "${CA_TAG:="$CA_VERSION"}"
    : "${FABRIC_TAG:="$VERSION"}"
    : "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
fi

BINARY_FILE=hyperledger-fabric-${
    
    ARCH}-${
    
    VERSION}.tar.gz
CA_BINARY_FILE=hyperledger-fabric-ca-${
    
    ARCH}-${
    
    CA_VERSION}.tar.gz

#这部分才是核心逻辑,指明了其实boostrap.sh总共就完成了三件事情
#如果SAMPLES变量为True,则调用cloneSamplesRepo,下载hyperledger/fabric-samples
#如果BINARIES变量为True,则调用pullBinaries,拉取Hyperledger Fabric binaries
#如果DOCKER变量为True,则调用pullDockerImages,拉取Hyperledger Fabric docker images
# then parse opts
while getopts "h?dsb" opt; do
    case "$opt" in
        h|\?)
            printHelp
            exit 0
            ;;
        d)  DOCKER=false
            ;;
        s)  SAMPLES=false
            ;;
        b)  BINARIES=false
            ;;
    esac
done

if [ "$SAMPLES" == "true" ]; then
    echo
    echo "Clone hyperledger/fabric-samples repo"
    echo
    cloneSamplesRepo
fi
if [ "$BINARIES" == "true" ]; then
    echo
    echo "Pull Hyperledger Fabric binaries"
    echo
    pullBinaries
fi
if [ "$DOCKER" == "true" ]; then
    echo
    echo "Pull Hyperledger Fabric docker images"
    echo
    pullDockerImages
fi

5.2 チャネル、組織、証明書の概念の紹介

1.チェーンコード

ファブリックでは、スマート コントラクトはチェーンコードと呼ばれ、6 つの状態があります。

. install (代码上链)
. instantate(初始化)
. invocable (调用链码)
. upgrade(由于合约有多个副本,因此每个合约都有版本号,版本升级时就是upgrade)
. Deinstantiate (合约销毁)
. Uninstall(卸载链码)

2.チャンネル

チャネル: プライベート サブネットワーク。実際には、さまざまなアプリケーションを分離するために、チャネルにはチェーンコードのバッチを含めることができます。
同じチャネル内の組織 (企業) のみが、同じブロック データを共有し、関連するチェーンコード操作を実行できます。

3. 証明書と暗号化

以前にデプロイされた CA モジュールは、公開鍵と秘密鍵をノードに配布するためのものであり、公開鍵と秘密鍵を使用して暗号化と署名を実現できます。
非対称暗号化: 公開鍵で暗号化されたメッセージは秘密鍵でのみ復号化できます。同様に、秘密鍵で署名されたメッセージは公開鍵でのみ検証できます。

数字证书:联盟链采用的非对称加密技术来事项身份验证和数据加密,本质就是SSl技术
CA(Certificate Authority):提供数字证书包括公钥(服务使用者)和私钥(服务者)
还提供一个CRL:证书吊销列表

例えば:
ここに画像の説明を挿入

Xiao Ming のメールボックス番号は 11A、Xiaohong のメールボックス番号は 11B です。これらは誰もが知っているもので、11A、11B と同様に公開鍵と呼ばれます。Xiaoming が Xiaohong に手紙を送りたい場合、彼は書いた手紙を Xiaohong のメールボックスに入れるだけで済みます。メールボックスで保護された手紙は、暗号化されたメッセージのようなものです。シャオホンだけが彼女の鍵で開けることができます。Xiaohong の鍵は彼女の秘密鍵です。
(1) これが公開鍵で、誰もが 1 組の鍵を持っています。一方は公開鍵で、もう一方は秘密鍵です
(2) A は B に情報を送信したいので、B の公開鍵で情報を暗号化し、B に送信します
(3) ) B は暗号化された情報を取得し、暗号化された情報を自分の鍵で復号化し、平文の情報を取得します。

4. コンソーシアム チェーン アーキテクチャ

fabric联盟链的开发人员主要分为三类:
底层是系统运维,负责系统的部署与维护;
其次是组织管理人员,负责证书、MSP权限管理、共识机制等;
最后是业务开发人员,他们负责编写chaincode、创建维护channel、执行transaction交易等

ここに画像の説明を挿入

5. ファブリック実行プロセス

ファブリック プロセスについては、以前の「1.4 アライアンス チェーンの基本アーキテクチャ」で説明しました。ここでは、ノードのコンセンサスと相互作用について簡単に紹介します。内容のこの部分は、短い本からのものです: In-depth analysis of fabric consensus mode

ファブリック コンセンサス モードで採用されている Endorse+Kafka+Commit モードには、次の手順が含まれます。

(1)请求背书:客户端用自己的私钥对交易进行签名后,按照指定格式将交易和签名信息进行打包,然后将打包后的数据发给背书节点请求背书。

(2)验证背书:背书节点收到背书请求后,验证交易的签名是否正确并调用智能合约验证交易内容是否合法。验证通过的话,背书节点用自己的私钥对背书结果进行签名并按照指定格式打包,然后将打包后的数据发给客户端。

(3)提交交易:客户端收到背书结果后,验证背书结果的签名是否正确。验证通过后,对交易请求和背书结果签名并打包。然后,把打包后的数据发送给orderer节点提交交易。

(4)排序广播:orderer节点收到交易后,验证数据的客户端签名[bJ1] 是否正确。验证通过后,将交易发给kafka集群对应的topic。由于orderer中的对于每个通道都在kafka上监听对应的消息,因此,kafka将消息存放到对应topic上之后,会将消息广播给通道上的所有orderer。因为各个orderer的消息都是由kafka按照相同顺序发送的,因此,这个过程也实现了消息的排序。

(5)打包出块:orderer节点接收到从kafka推送的消息(kafka节点见同步消息不需要验证),当满足出块策略[bJ2] :缓存交易个数达到区块最大交易数或者时间达到出快时间,则将交易进行打包、对数据签名,然后出块,并将区块分发给peer节点。

(6)验证记账:peer节点接收到区块后,验证交易是否有效即验证区块的交易是否满足背书策略以及区块中交易的读写集版本是否正确[bJ3] 。验证通过的话,执行此交易的内容更改状态数据库。验证失败的话,对此条交易不做任何处理。当区块中的交易全部处理完成后,将区块记录在本地数据库。

通信インタラクションのフローチャート:
ここに画像の説明を挿入

データ フロー チャート:
ここに画像の説明を挿入

5.3 テストネットワーク起動分析

chaincode:智能合约,上文已提到。每个chaincode可提供多个不同的调用命令。 transaction:交易,每条指令都是一次交易。
world state: 对同一个key的多次交易形成的最终value,就是世界状态。
endorse:背书。金融上的意义为:指持票人为将票据权利转让给他人或者将一定的票据权利授予他人行使,而在票据背面或者粘单上记载有关事项并签章的行为。通常我们引申为对某个事情负责。在我们的共识机制的投票环节里,背书意味着参与投票。
endorsement policy:背书策略。由智能合约chaincode选择哪些peer节点参与到背书环节来。 peer:存放区块链数据的结点,同时还有endorse和commit功能。
channel:私有的子网络,事实上是为了隔离不同的应用,一个channel可含有一批chaincode,
PKI: Public Key Infrastructure,一种遵循标准的利用公钥加密技术为电子商务的开展提供一套安全基础平台的技术和规范。
MSP: Membership Service Provider,联盟链成员的证书管理,它定义了哪些RCA以及ICA在链里是可信任的,包括定义了cHlannel上的合作者。
org: orginazation,管理一系列合作企业的组织。
root@gan-virtual-machine:/# cd /opt/fabric-2.3.0/scripts/fabric-samples/test-network/
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh up
#fabric采用了leveldb数据库,key-value形式,且支持海量存储。用于存储交易状态
Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb' with crypto from 'cryptogen'
LOCAL_VERSION=2.3.0
DOCKER_IMAGE_VERSION=1.4.8
Local fabric binaries and docker images are out of  sync. This may cause problems.#不知道为啥会报这个错,老师的没有报这个错诶
#这个是很重要的,用于创建证书的脚本
/opt/fabric-2.3.0/scripts/fabric-samples/test-network/../bin/cryptogen
#用上述那个文件的工具创建证书
Generating certificates using cryptogen tool
#创建组织1,其配置文件为./organizations/cryptogen/crypto-config-org1.yaml,可采用yaml验证工具验证,发现其实是json格式的内容。
#在这个配置文件中,Name: Org1 表示组织名称;Domain: org1.example.com  表示组织的域名;EnableNodeOUs: true 表示会在msp目录会生成config.yaml配置文件;另外,Users:  换行   Count: 1。修改这个Count的值,可以改变启动网络时创建的节点数,其实Count=1的话,会有一个管理员admin和一个普通用户,相当于两个节点。同理,Count=2相当于有三个节点。
Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
org1.example.com
+ res=0
+ #创建组织1
Creating Org2 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output=organizations
org2.example.com
+ res=0
+ #创建order节点
Creating Orderer Org Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output=organizations
+ res=0
Generating CCP files for Org1 and Org2
WARNING: The COMPOSE_PROJECT_NAME variable is not set. Defaulting to a blank string.
Creating network "docker_test" with the default driver
Creating volume "docker_orderer.example.com" with default driver
Creating volume "docker_peer0.org1.example.com" with default driver
Creating volume "docker_peer0.org2.example.com" with default driver
Creating peer0.org2.example.com ... done
Creating peer0.org1.example.com ... done
Creating orderer.example.com    ... done
Creating cli                    ... done
CONTAINER ID   IMAGE                               COMMAND             CREATED         STATUS                  PORTS                                                                                  NAMES
ddde72be9f06   hyperledger/fabric-tools:latest     "/bin/bash"         1 second ago    Up Less than a second                                                                                          cli
af8a3cbd19a4   hyperledger/fabric-orderer:latest   "orderer"           2 seconds ago   Up 1 second             0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:7053->7053/tcp, :::7053->7053/tcp   orderer.example.com
27cb1ca1c1b2   hyperledger/fabric-peer:latest      "peer node start"   2 seconds ago   Up Less than a second   0.0.0.0:7051->7051/tcp, :::7051->7051/tcp                                              peer0.org1.example.com
6fcc31ed3930   hyperledger/fabric-peer:latest      "peer node start"   2 seconds ago   Up 1 second             0.0.0.0:9051->9051/tcp, :::9051->9051/tcp                                              peer0.org2.example.com


補足 --- yamlファイル検証ツール: から証明書情報http://www.bejson.com/validators/yaml_editor
ここに画像の説明を挿入
を閲覧できます。教師が を に変更しました。ネットワーク構築すると、組織 1 にさらに 2 人のユーザーがいることがわかります。“vim connection-org1.yaml”
ここに画像の説明を挿入
connection-org1.yamlCount=1Count=3./network.sh up
ここに画像の説明を挿入

5.4 チャネルの作成とチェーンコードのデプロイ

创建通道
	创建区块信息
	组织	加入通道
部署链码
	部署deploycc
	查看各种版本链码
	部署go版本链码
	apt、wget、curl对比
	Linux程序存储结构介绍
	wget下载的配置Go
	配置GOProxy代理

1.チャンネルを作成する

//通过别名定义命令,这是“临时性”的,下一次打开Ubuntu就需要重新定义了
root@gan-virtual-machine:~#  alias ss='cd /opt/fabric-2.3.0/scripts/fabric-samples/test-network/'
root@gan-virtual-machine:~#  ss
//进入目录,启动网络
root@gan-virtual-machine :/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh up
//创建通道,可以后接-C指定通道别名,不指定通道名字的话,默认通道名为“mychannel”
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh createChannel
//创建通道时在终端显示的日志信息:主要包括两大部分内容——**创建区块信息和****组织加入通道**

2.チェーンコードをデプロイする

(1) チェーンコード展開コマンドの解析

./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
1.-ccn 代表要部署目录简称
2.-ccp代表部署的路径
3.-ccl代表链码语言版本

(2) さまざまなバージョン チェーン コードを表示する
ここに画像の説明を挿入

(3) go版のチェーンコードをデプロイする

./network.sh deployCC-ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
执行链码部署命令之后,会有报错提示
#通过executable file not found in $PATH异常可以发现缺少go命令,但是如果通过apt安装默认go的版本比较低,而Fabric2.3需要配套的go版本为>go1.15,因此我们直接采用wget或者官网下载新版本

(4) apt、wget、curlの比較

1. apt用于Debian系列(社区组织维护的发行版本)的linux系统,代表是Ubuntu,之前低版本是apt-get,下载与安装一气呵成!
2. wget:(World Wide Web get): 通过FTP或HTTP协议抓取的文件,默认下载到当前目录,可以通过**wget -O savePath** 要下载文件的url路径,来指定保存路径
3. curl:对应 TP, FTPS,HTTP, HTTPS, GOPHER,TELNET等协议的lib

(5) Linux のプログラム格納構造の紹介

1./usr:系统级的目录,可以理解为C:/Windowsl。/usr/lib理解为c:/Windows/System32。
2./usr/local:用户级的程序目录,可以理解为C:/Progrem Filesl。用户自己编译的软件默认会安装到这个目录下。
3. /opt:用户级的程序目录,可以理解为D:.Software,opt有可选的意思,这里可以用于放置第三方大型软件(或游戏),当你不需要时,直接rm -rf掉即可。
源码放哪里
1./usr/src:系统级的源码目录。
2./usr/local/src:用户级的源码目录

(6) go のインストール
go バージョンのデモを実行したいので、go 言語環境をインストールする必要があります。
方法 1

#可以用apt,但是不推荐。因为如果部署新版本fabric的时候,很有可能阿里云源这边没有更新对应的go语言高版本
#但其实我试了一下,因为今年已经2022年啦~所以apt安装的已经是1.18版本了,够用于fabric2.3.0的了。但是我还是用了老师说的另一种方法
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# apt install golang-go
#如果go版本太低,部署链码会报错“go: unknown subcommand "mod"
#要卸载掉低版本的go,apt方式安装之后的卸载命令
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# apt remove golang-go

方法 2

#下载go源码。我看现在go版本已经到1.18.3了,所以我把连接替换了https://studygolang.com/dl/golang/go1.18.3.linux-amd64.tar.gz
# 如果前面那个连接不上的话,用这个网址 https://golang.google.cn/dl/go1.18.3.linux-amd64.tar.gz
wget https://studygolang.com/dl/golang/go1.15.4.linux-amd64.tar.gz
#解压文件到/usr/local中
tar xfz go1.15.4.linux-amd64.tar.gz -C /usr/local
#修改~/.bashrc
vim ~/.bashrc
#配置GOROOT,添加Gopath路径。如果不配GOROOT的话之后运行go version时会提示warning warning: GOPATH set to GOROOT (/usr/local/go) has no effectgo version go1.13.4 linux / amd64

export GOROOT=/usr/local/go
export GOPATH=/home/go
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH


#激活配置bachrc相当于当前用户环境变量配置  root@gan-virtual-machine:~# source ~/.bashrc  注意所在目录
source ~/.bashrc
go version #验证go是否安装成功,go version go1.18.3 linux/amd64

(7) GOProxy プロキシの設定
上記で指定したバージョンの GO がダウンロードされ、GOPATH と GOROOT 環境変数が設定されている場合、検索プロセスに従ってチェーンコード関連の依存パッケージを github からダウンロードできますが、最後の例外はそれでもthrow. 、異常情報からgithub.comへのアクセスがタイムアウトしたことがわかります.このとき、Githubのリソースをダウンロードするようにエージェントを設定する必要があります.

#可以直接利用命令添加
go env -w GOPROXY=https://goproxy.cn/
#也可以像之前配置GOROOT那样去/.barshrc文件中添加
export GOPROXY=https://goproxy.cn/

(8) go版のチェーンコードを再デプロイする

root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

5.5 補足説明

1. ファブリック コンソーシアム チェーン エコシステムの紹介

Fabric プロジェクトの目標は、一般的なパーミッション ブロックチェーン (パーミッション チェーン) の基礎となる基本フレームワークを実現することです. さまざまな状況に適したものにするために、モジュラー アーキテクチャを使用して、コンセンサス アルゴリズム、暗号化セキュリティなど、切り替え可能でスケーラブルなコンポーネントを提供します。 、資産、スマート コントラクト、識別などのデジタル サービス。
ここに画像の説明を挿入

1.Fabric CALIPER:性能测试组件
2.Fabric Explorer:查看区块链信息组件
3. Fabric Composer:包含了开发构架,和工具的开源项目
4.Fabric Cello:支持定制(例如,大小,一致〉区块链请求、在裸机,虚拟云(例如,虚拟机,云数据云),容器集群方便部署自己联盟链

2.重要な注文の見直し

  1. cryptogen: 組織構造と ID ファイル (証明書) を生成します
  2. configtxgen: 構成ブロックと構成トランザクションを生成します
  3. configtxlator: 構成情報を読み取る
    ここに画像の説明を挿入
    ここに画像の説明を挿入

3.補足:チャネルプロンプトログを作成する

チャンネル作成時に端末に表示されるログ情報は、主にブロック情報の作成と、チャンネルの参加の整理とノード情報の同期の3つの主要な部分で構成されます。

另外补充Fabric命令手册:http://cw.hubwiz.com/card/c/fabric-command-manual/1/1/10/
Protobuf详细说明: https://www.jianshu.com/p/a24c88c0526a
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh createChannel Creating channel 'mychannel'.

If network is not up, starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb'
#创建了一个区块mychannel.block,存储目录为“./channel-artifacts/mychannel.block ”
Generating channel genesis block 'mychannel.block'
/opt/fabric-2.3.0/scripts/fabric-samples/test-network/../bin/configtxgen
#以“+”开头的语句是fabric命令,可以到Fabric命令手册网址去看对应命令的含义
+ configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/mychannel.block -channelID mychannel
2022-06-19 10:44:45.834 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2022-06-19 10:44:45.844 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
2022-06-19 10:44:45.844 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 Orderer.EtcdRaft.Options unset, setting to tick_interval:"500ms" election_tick:10 heartbeat_tick:1 max_inflight_blocks:5 snapshot_interval_size:16777216 
2022-06-19 10:44:45.845 CST [common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /opt/fabric-2.3.0/scripts/fabric-samples/test-network/configtx/configtx.yaml
2022-06-19 10:44:45.847 CST [common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
2022-06-19 10:44:45.847 CST [common.tools.configtxgen] doOutputBlock -> INFO 006 Creating application channel genesis block
2022-06-19 10:44:45.848 CST [common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block
+ res=0
Creating channel mychannel
#区块创建完成之后,就调用组织,将组织1和组织2添加到通道中去。联盟链中,不通的通道是隔离开的,不通的组织必须在同一个通道里面才能相互访问并执行通道中的链码。
#下面是其加入的一些信息,包括组织的基本信息、验证、状态等。
Using organization 1
+ osnadmin channel join --channel-id mychannel --config-block ./channel-artifacts/mychannel.block -o localhost:7053 --ca-file /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --client-cert /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt --client-key /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
+ res=0
#20开头的状态表示成功
Status: 201
{
    
    
	"name": "mychannel",
	"url": "/participation/v1/channels/mychannel",
	"consensusRelation": "consenter",
	"status": "active",
	"height": 1
}

Channel 'mychannel' created
#将组织1加入通道
Joining org1 peer to the channel...
Using organization 1
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2022-06-19 10:44:52.033 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-06-19 10:44:52.071 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
#将组织2加入通道
Joining org2 peer to the channel...
Using organization 2
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2022-06-19 10:44:55.142 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-06-19 10:44:55.180 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
#添加锚节点到通道,通过锚节点可以实现节点同步
Setting anchor peer for org1...
Using organization 1
Fetching channel config for channel mychannel
Using organization 1
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2022-06-19 02:44:55.425 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-06-19 02:44:55.429 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2022-06-19 02:44:55.430 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2022-06-19 02:44:55.433 UTC [cli.common] readBlock -> INFO 004 Received block: 0
Decoding config block to JSON and isolating config to Org1MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
+ jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' Org1MSPconfig.json
Generating anchor peer update transaction for Org1 on channel mychannel
+ configtxlator proto_encode --input Org1MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org1MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
+ jq .
++ cat config_update.json
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org1.example.com",' '"port":' 7051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2022-06-19 02:44:55.758 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-06-19 02:44:55.781 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org1MSP' on channel 'mychannel'

Setting anchor peer for org2...
Using organization 2
Fetching channel config for channel mychannel
Using organization 2
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2022-06-19 02:44:56.166 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-06-19 02:44:56.172 UTC [cli.common] readBlock -> INFO 002 Received block: 1
2022-06-19 02:44:56.173 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 1
2022-06-19 02:44:56.175 UTC [cli.common] readBlock -> INFO 004 Received block: 1
Decoding config block to JSON and isolating config to Org2MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
Generating anchor peer update transaction for Org2 on channel mychannel
+ jq '.channel_group.groups.Application.groups.Org2MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org2.example.com","port": 9051}]},"version": "0"}}' Org2MSPconfig.json
#configtxlator命令用来将fabric的数据结构在protobuf和JSON 之间进行转换,也可以用来创建配置更新。该命令可以启动一个REST 服务来通过HTTP暴露服务接口,也可以直接在命令行使用。
+ configtxlator proto_encode --input Org2MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org2MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
+ jq .
++ cat config_update.json
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org2.example.com",' '"port":' 9051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2022-06-19 02:44:56.504 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-06-19 02:44:56.531 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org2MSP' on channel 'mychannel'
#提示:通道'mychannel'创建成功
Channel 'mychannel' joined

4. 補足: チェーンコード プロンプト ログのデプロイ

チェーンコードの展開時に端末に表示されるログ情報: 主に、チェーンコードのダウンロード、チェーンコード解凍、チェーンコードのチャネルへ展開とインストール、承認ノードへのチェーンコードの送信、注文への送信が含まれます。承認が成功した後にのみノード

root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
deploying chaincode on channel 'mychannel'
executing with the following
- CHANNEL_NAME: mychannel
- CC_NAME: basic
- CC_SRC_PATH: ../asset-transfer-basic/chaincode-go
- CC_SRC_LANGUAGE: go
- CC_VERSION: 1.0
- CC_SEQUENCE: 1
- CC_END_POLICY: NA
- CC_COLL_CONFIG: NA
- CC_INIT_FCN: NA
- DELAY: 3
- MAX_RETRY: 5
- VERBOSE: false
Vendoring Go dependencies at ../asset-transfer-basic/chaincode-go
/opt/fabric-2.3.0/scripts/fabric-samples/asset-transfer-basic/chaincode-go /opt/fabric-2.3.0/scripts/fabric-samples/test-network
go: downloading github.com/hyperledger/fabric-contract-api-go v1.1.0
go: downloading github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212
go: downloading github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e
go: downloading github.com/stretchr/testify v1.5.1
go: downloading github.com/golang/protobuf v1.3.2
go: downloading google.golang.org/grpc v1.23.0
go: downloading github.com/xeipuuv/gojsonschema v1.2.0
go: downloading github.com/go-openapi/spec v0.19.4
go: downloading github.com/gobuffalo/packr v1.30.1
go: downloading github.com/davecgh/go-spew v1.1.1
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading gopkg.in/yaml.v2 v2.2.8
go: downloading google.golang.org/genproto v0.0.0-20180831171423-11092d34479b
go: downloading golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
go: downloading github.com/go-openapi/jsonpointer v0.19.3
go: downloading github.com/go-openapi/jsonreference v0.19.2
go: downloading github.com/go-openapi/swag v0.19.5
go: downloading github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415
go: downloading github.com/gobuffalo/envy v1.7.0
go: downloading github.com/gobuffalo/packd v0.3.0
go: downloading golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542
go: downloading github.com/PuerkitoBio/purell v1.1.1
go: downloading github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e
go: downloading github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f
go: downloading github.com/joho/godotenv v1.3.0
go: downloading github.com/rogpeppe/go-internal v1.3.0
go: downloading github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578
go: downloading golang.org/x/text v0.3.2
/opt/fabric-2.3.0/scripts/fabric-samples/test-network
#链码下载已完成
Finished vendoring Go dependencies
#打包链码并生成打包文件
+ peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go --lang golang --label basic_1.0
+ res=0
Chaincode is packaged
#给组织1,2安装链码
Installing chaincode on peer0.org1...
Using organization 1
#在指定peer节点上安装链码
+ peer lifecycle chaincode install basic.tar.gz
+ res=0
2022-06-19 13:57:09.511 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nJbasic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad\022\tbasic_1.0" > 
2022-06-19 13:57:09.511 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: basic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad
Chaincode is installed on peer0.org1

Install chaincode on peer0.org2...
Using organization 2
+ peer lifecycle chaincode install basic.tar.gz
+ res=0
2022-06-19 13:57:24.197 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nJbasic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad\022\tbasic_1.0" > 
2022-06-19 13:57:24.197 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: basic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad
Chaincode is installed on peer0.org2


Using organization 1
#查询指定peer节点上已经安装的链码
+ peer lifecycle chaincode queryinstalled
+ res=0
Installed chaincodes on peer:
Package ID: basic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad, Label: basic_1.0
Query installed successful on peer0.org1 on channel
Using organization 1
#机构审批链码,即提交链码到背书节点,背书机构进行审批。其中“--tls --cafile”参数后面跟着证书,指明审批机构要具有相应资质,即指明证书文件。
+ peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name basic --version 1.0 --package-id basic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad --sequence 1
+ res=0
2022-06-19 13:57:26.409 CST [chaincodeCmd] ClientWait -> INFO 001 txid [790e1b59b00f895df8b49474d836a5636ddfe1138aff24923b5509869bd8eb26] committed with status (VALID) at localhost:7051
#提示:链码在组织1节点1审批通过
Chaincode definition approved on peer0.org1 on channel 'mychannel'
Using organization 1
Checking the commit readiness of the chaincode definition on peer0.org1 on channel 'mychannel'...
Attempting to check the commit readiness of the chaincode definition on peer0.org1, Retry after 3 seconds.
#检查指定的链码是否可以向通道提交。
+ peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json
+ res=0
{
    
    
	"approvals": {
    
    
		"Org1MSP": true,#表示链码审批在组织1通过
		"Org2MSP": false#表示链码审批在组织2还没通过
	}
}
Checking the commit readiness of the chaincode definition successful on peer0.org1 on channel 'mychannel'
Using organization 2
Checking the commit readiness of the chaincode definition on peer0.org2 on channel 'mychannel'...
Attempting to check the commit readiness of the chaincode definition on peer0.org2, Retry after 3 seconds.
#检查指定的链码是否可以向通道提交。
+ peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json
+ res=0
{
    
    
	"approvals": {
    
    #这时候组织2还没执行审批操作,所以和签名的结果一样,组织1通过链码审批,而组织2还没有
		"Org1MSP": true,
		"Org2MSP": false
	}
}
Checking the commit readiness of the chaincode definition successful on peer0.org2 on channel 'mychannel'
Using organization 2
#向组织2提交链码的审核操作,和向组织1提交的步骤是类似的
+ peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name basic --version 1.0 --package-id basic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad --sequence 1
+ res=0
2022-06-19 13:57:34.732 CST [chaincodeCmd] ClientWait -> INFO 001 txid [a3959f8b65cdf8dff719c9e5c12a0a713d116ddb4f4d5f56d295af2b62478fb2] committed with status (VALID) at localhost:9051
#链码在组织2审批通过
Chaincode definition approved on peer0.org2 on channel 'mychannel'
Using organization 1
Checking the commit readiness of the chaincode definition on peer0.org1 on channel 'mychannel'...
Attempting to check the commit readiness of the chaincode definition on peer0.org1, Retry after 3 seconds.
#这时候再检查一下指定的链码是否可以向通道提交。
+ peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json
+ res=0
{
    
    
	"approvals": {
    
    #这时候组织1和组织2都通过了链码审批
		"Org1MSP": true,
		"Org2MSP": true
	}
}
Checking the commit readiness of the chaincode definition successful on peer0.org1 on channel 'mychannel'
Using organization 2
Checking the commit readiness of the chaincode definition on peer0.org2 on channel 'mychannel'...
Attempting to check the commit readiness of the chaincode definition on peer0.org2, Retry after 3 seconds.
#同样,在组织2也再检查一下指定的链码是否可以向通道提交。
+ peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json
+ res=0
{
    
    
	"approvals": {
    
    #结果也是:组织1和组织2都通过了链码审批
		"Org1MSP": true,
		"Org2MSP": true
	}
}
Checking the commit readiness of the chaincode definition successful on peer0.org2 on channel 'mychannel'

#在上面,组织1和2都完成了对链码的审批操作并且通过之后

Using organization 1
Using organization 2
# 向指定通道提交链码,提交给order(排序节点)
+ peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name basic --peerAddresses localhost:7051 --tlsRootCertFiles /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1.0 --sequence 1
+ res=0
2022-06-19 13:57:43.304 CST [chaincodeCmd] ClientWait -> INFO 001 txid [8f5eafd1b019ffc861a890af9944f5ce74b6ac13795301f5d531a610fdc21c13] committed with status (VALID) at localhost:9051
2022-06-19 13:57:43.330 CST [chaincodeCmd] ClientWait -> INFO 002 txid [8f5eafd1b019ffc861a890af9944f5ce74b6ac13795301f5d531a610fdc21c13] committed with status (VALID) at localhost:7051
#这时候提示,提交到排序节点的操作已经成功啦
Chaincode definition committed on channel 'mychannel'



Using organization 1
Querying chaincode definition on peer0.org1 on channel 'mychannel'...
Attempting to Query committed status on peer0.org1, Retry after 3 seconds.
#在组织1这边查询指定通道上已经提交的链码
+ peer lifecycle chaincode querycommitted --channelID mychannel --name basic
+ res=0
Committed chaincode definition for chaincode 'basic' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
#查询结果是,链码已经在组织1上定义成功
Query chaincode definition successful on peer0.org1 on channel 'mychannel'
Using organization 2
Querying chaincode definition on peer0.org2 on channel 'mychannel'...
Attempting to Query committed status on peer0.org2, Retry after 3 seconds.
#同理,在组织2这边查询指定通道上已经提交的链码
+ peer lifecycle chaincode querycommitted --channelID mychannel --name basic
+ res=0
Committed chaincode definition for chaincode 'basic' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
#查询结果是,链码已经在组织2上也定义成功
Query chaincode definition successful on peer0.org2 on channel 'mychannel'
Chaincode initialization is not required

5. ピア環境を手動で構築する

コマンド ラインでピア コマンドを直接実行すると、例外がスローされます。これは、すべての操作で、どの組織ノードがどのチャネルで使用されているかを指定する必要があること、およびこれらのノードに正当な権限が必要であることを理解しやすいためです。
ここに画像の説明を挿入

ここに画像の説明を挿入
//まず、test-network ディレクトリにいることを確認し、次の環境変数を構成します (今回は、一時変数の構成を容易にするためです)
。 //一時変数の構成: この方法で構成された環境変数は一時的なものです。次回起動時に消えます。今回は、学生が構成プロセスを理解できるようにするためのものです。

PWD='/opt/fabric-2.3.0/scripts/fabric-samples/test-network'
export PATH=${
    
    PWD}/../bin:$PATH    #这时候,在终端输入peer,已经有用法提示了,但是现在还不能正常使用,继续配置。还有配置组织、证书等相关信息配置文件
export FABRIC_CFG_PATH=${
    
    PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
#启用对服务端的TLS身份验证
export CORE_PEER_LOCALMSPID="Org1MSP"
#两行指明了org1的加密所用的信息
export CORE_PEER_TLS_ROOTCERT_FILE=${
    
    PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
 open /opt/fabric-2.3.0/scripts/fabric-samples/config/tls/ca.crt: no such file or directory

export CORE_PEER_MSPCONFIGPATH=${
    
    PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
#当前组织节点IP与端口
export CORE_PEER_ADDRESS=localhost:7051
#注意:这里的端口配置也要区分节点的哟——排序节点7050,第一个组织节点7051,第二个组织节点9051

#补充————fabric环境变量手册:http://cw.hubwiz.com/card/c/fabric-env-manual/1/6/1/


PWD='/opt/fabric-2.3.0/scripts/fabric-samples/test-network'
export PATH=${
    
    PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${
    
    PWD}/../config/
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

組織 1 ノードの環境変数は上記で構成されています。次に、組織 1 ノードの ID を使用して、ピア コマンドの検証を実行できます。

peer channel list
peer lifecycle chaincode queryinstalled
peer channel getinfo -c mychannel

ここに画像の説明を挿入
ここに画像の説明を挿入

6.fabcar公式ケース展開実装

6.1 fabcar プロジェクトの取得とインストール

fabcar チェーン コードの取得とインストールの契約 Fabcar プロジェクトの構造分析
fabcar は、車 (車) トランザクション用の分散型チェーン コードです. プロジェクトは、単一の車のクエリ、追加、クエリの追加、更新の追加、削除、およびその他の操作をサポートします。一般的なチェーン コードの追加、削除、チェック、および変更の機能を実現します。

ここに画像の説明を挿入
go.mod 依存関係分析
ここに画像の説明を挿入
ここに画像の説明を挿入

(1) fabcar 依存パッケージを入手する

実行が完了すると、スマート コントラクトの依存関係が配置されるフォルダーである現在のフォルダーに、さらに多くのベンダーが存在します。

#配置go代理。然后已经配置可以跳过
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# go env -w GOPROXY=https://goproxy.cn
#刚开始执行的时候,遇到报错“missing go.sum entry; to add it:”。通过执行命令:“go mod tidy”后再执行“go mod vendor”
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# go mod vendor

(2) ホストレコードの追加

/etc/hosts、ホスト名および ip 構成ファイル、ビューロー都市ネットワークまたはインターネット上で、各ホストには P アドレスがあり、各ホストを区別し、通信のために ip を拒否できます。しかし、彼女の世界で 1 億を覚えておくのは不便で、すべてドメイン名を持っています。ローカル エリア ネットワークでは、各カメラにはホスト名があり、ホストを区別して相互アクセスを容易にするために使用されます。

#我们当前配置都是在本地的,如果以后大项目部署之后,不同的节点对应不同的ip地址,道理都是一样的,在/etc/hosts中配置其映射关系即可。
#这个项目,我们就把下面三条语句加入/etc/hosts文件中即可
127.0.0.1 orderer.example.com
127.0.0.1 peer0.org1.example.com
127.0.0.1 peer0.org2.example.com

root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# vim /etc/hosts

ここに画像の説明を挿入

ORG1 チェーン コードのレビューと提出の操作

(3) 環境変数と組織認証情報の設定

これは、セクション 5.5: ピア環境で構成された環境変数を手動で構築するのポイント 5 です。内容は同じですよ~

#后续很多地方会用到test-network目录,因此把它赋值到PwD变量中
PWD='/opt/fabric-2.3.0/scripts/fabric-samples/test-network'
#把${PwD}/ ../bin临时注册到环境变量中, peer命令可以执行
export PATH=${
    
    PWD}/../bin:$PATH
#还需要设置FABRIc_CF6_PATH路径指向fabric-samples中的core.yaml文件路径
export FABRIC_CFG_PATH=${
    
    PWD}/../config/
#下载是配置组织的证书和相关信息
# http:/ / cw.hgbwiz.com/card/c/fabric-env-manual/1/3/12/
#启用对服务端的TLs身份验证(TLS 由ssL发展而来)是一种身份验证机制
export CORE_PEER_TLS_ENABLED=true
#组织1的MSP的标识ID
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
#获取访问账户的msp证书
export CORE_PEER_MSPCONFIGPATH=${
    
    PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
#同一机构中其他Peer节点要连接此节点需指定的P2P连接地址
export CORE_PEER_ADDRESS=localhost:7051
#注意:这里的端口配置也要区分节点的哟——排序节点7050,第一个组织节点7051,第二个组织节点9051


#下面是方便复制粘贴到终端命令行直接执行的版本
PWD='/opt/fabric-2.3.0/scripts/fabric-samples/test-network'
export PATH=${
    
    PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${
    
    PWD}/../config/
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

(4) パッケージチェーンコード契約

#前提:fabric网络启动且通道创建完成  可以只使用一个命令./network.sh up createChannel
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh up
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# ./network.sh createChannel

root@ubuntu:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# 
#参数介绍:
#(1)package outputfile #打包输出文件名
#(2)path string #链码源代码路径
#(3)lang string # 链码开发语言,默认:golang
#(4)label string #链码标识,相当于链码的名字


root@ubuntu:/opt/fabric-2.3. /scripts /fabric-samples /fabcar/go# peer lifecycle chaincode package fabcar.tar.gz --path /opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go --label fabcar_1
#1s查看当前目录,发现有了一个fabcar.tar.gz文件
root@ubuntu:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# ls
#上一条语句执行结果:fabcar.go fabcar.tar.gz go.mod go.sum runfabcar.sh vendor


(5) チェーンコードをインストールする

#安装智能合约(时间会比较久,耐心稍等)
peer lifecycle chaincode install fabcar.tar.gz
#2022-06-19 18:44:00.603 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b\022\010fabcar_1" > 
#2022-06-19 18:44:00.603 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b
#这个hash值很重要,下面的步骤要用===》   fabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b

ここに画像の説明を挿入
この時点で、インストールされたチェーン コードを照会できます。組織 1 はチェーン コードのインストール操作を完了しており (組織 2 はまだ完了していません)、インストールの完了後にこのチェーン コードを識別するための一意のハッシュ値が生成されます。この時点で、次のコマンドを使用して、現在のノードにインストールされているチェーンコード ファイルを表示することもできます。

root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: fabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b, Label: fabcar_1
#peer lifecycle chaincode queryinstalled:如果出现两个链码名字,其中第一个basic_1.0是上一章节官方自动安装的deployCC案例,而fabcar_1是本章节手动安装的案例。我把上一章节自动安装的删掉了,所以我查询结果只有一个~

以前にインストールされたチェーンコードが削除されていない場合basic、クエリの結果は次のようになります。
ここに画像の説明を挿入

(6) ORG1チェーンのコードレビューと提出業務

チェーンコード パッケージがピア ノードにインストールされると、エンドース ノードはチェーンコード定義を承認できます. すべてのエンドースメント ノードまたはほとんどのエンドースメント ノード (異なるエンドースメント ポリシーにはパス数の要件があります) を通過した後にのみ、その後の承認が行われます。チェーンコードをインスタンス化して呼び出すことができます。

root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name fabcar --version 1.0 --package-id fabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b --sequence 1

#1.-o localhost:7050#排序节点地址
#2.--tls #排序节点启动时是否启动tls
#3. --ordererTLSHostnameOverride orderer.example.com #验证TLS连接时使用的排序节点主机名
#4. --cafile PEM编码的CA证书文件路径
#5.--channellD mychannel# 通道ID
#6. --name fabcar#链码名称
#7. --version 1.0#链码版本
#8.--package-id fabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b  #链码安装包标识ID
#9. --sequence 1#通道链码定义序列号,默认值:1


#运行结果
#2022-06-19 19:08:44.426 CST [chaincodeCmd] ClientWait -> INFO 001 txid [5a9ae2ad8e9dcc9d03201df1cad3dd11664eb2ec3eb041b19b98fcb78ba6148c] committed with status (VALID) at localhost:7051
#解释:链码审核的过程本身也是一次交易


#如果已经安装上basic链码demo,再装这个fabcar的话,记得修改链码ID为“fabcar_1:1146b4b491871bf18b23dd67dd8cc058655b36cc0e2274f165ed06b796a8f276 ”。反正注意--package-id 后面跟的内容要替换成自己安装成功之后日志显示中出现的hash~
#peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name fabcar --version 1.0 --package-id fabcar_1:1146b4b491871bf18b23dd67dd8cc058655b36cc0e2274f165ed06b796a8f276  --sequence 1

ORG1 クエリを実行してチェーン コードのレビュー ステータスを確認し、チェーン コードをチャンネルに送信してみてください
[この手順は必要ありません。教師は正常に送信するためにすべての組織の同意が必要です。今送信しようとしても、私たちをより良いものにするためです。正常に送信されました。]
組織 2 はまだ fabcar 監査に合格していないため、組織 1 の提出は失敗し、後で終了します. 次のコマンドを使用して、チェーン コードが監査された組織を表示することもできます.

 root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1.0 --sequence 1 --output json

#1. --channellID通道ID
#2.--name链码名称
#3. --version链码版本
#4. --output结果输出格式

#执行结果:组织1已经对链码审核且通过。组织2这边还没通过。
{
    
    
	"approvals": {
    
    
		"Org1MSP": true,
		"Org2MSP": false
	}
}

組織 2 が承認したチェーン コードはありません。試しに提出してみましょう

peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name fabcar --peerAddresses localhost:7051 --tlsRootCertFiles /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1.0 --sequence 1

ここに画像の説明を挿入
ここに画像の説明を挿入
組織 2 の証明書の場所と組織 1 の証明書の場所を間違って貼り付けていたため、後で理由がわかりました。

ORG2 チェーン コードのレビューと提出の操作

以前は、ORG1 の構成情報は、シェルの残りのコマンド ラインで一時的に構成され、コマンド ラインを終了すると消えていました. したがって、ORG2 の情報は ~/.bashrc ファイルで構成できます.このファイルは自動的に読み込まれます.現在のユーザーがコマンドラインを開始するたびに. .
実際、組織 2 側の操作は、構成情報が異なることを除いて、組織 1 のコマンドと同じです。

(7) ORG2組織情報の設定

vim ~/.bashrc で編集モードに入り、ORG2 の情報を末尾に追加して保存し、コマンドラインを閉じて再起動し、変数が認識できれば設定成功です。

PWD='/opt/fabric-2.3.0/scripts/fabric-samples/test-network'
#把$(PMD}/ ../bin临时注册到环境变量中, peer命令可以执行
export PATH=${
    
    PWD}/../bin:$PATH
#还需要设置FABRIc_CF6_PATH路径指向fabric-samples中的core.yaml文件路径
export FABRIC_CFG_PATH=${
    
    PWD}/../config/
#下载是配置组织的证书和相关信息
# http://cw.hubwiz.com/card/c/fabric-env-manual/1/3/12/
#启用对服务端的TLS身份验证(TLS 由 ssL发展而来)是一种身份验证机制
export CORE_PEER_TLS_ENABLED=true
#组织1的NSP的标识ID
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 
#同一机构中其他Peer节点要连接此节点需指定的P2P连接地址
export CORE_PEER_ADDRESS=localhost:9051


#下面是方便复制粘贴到终端命令行直接执行的版本
PWD='/opt/fabric-2.3.0/scripts/fabric-samples/test-network'
export PATH=${
    
    PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${
    
    PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
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

(8) ORG2 インストール チェーン コード

#进入........fabcar/go,发现有了一个fabcar.tar.gz文件,表明链码已经打包好了
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# ls
fabcar.go  fabcar.tar.gz  go.mod  go.sum  runfabcar.sh  vendor
#安装链码,结果中链码名字及其hash值与组织1安装之后的结果一样。
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# peer lifecycle chaincode install fabcar.tar.gz
#运行结果
#2022-06-19 21:07:18.548 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b\022\010fabcar_1" > 
#2022-06-19 21:07:18.548 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b

(9) チェーンコードの見直し

チェーンコード パッケージがピア ノードにインストールされると、エンドース ノードはチェーンコード定義を承認できます。すべてのエンドースメント ノードまたは異なるエンドースメント ポリシーを持つほとんどのエンドースメント ノードを通過した後でのみ、レビュー. チェーン コードはインスタンス化して呼び出すことができます. チェーン コード宣言コアは順序付けノードの関連情報を構成するため, このコードは ORG1 とまったく同じです.

root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name fabcar --version 1.0 --package-id fabcar_1:4e7996bf4058869807f239b859a97dc609ed19e2fcfd10f1bf86540f6dd3cf5b,Label: fabcar_1 --sequence 1

#运行结果
#2022-06-19 21:09:43.517 CST [chaincodeCmd] ClientWait -> INFO 001 txid [39a98e0f41600cb2dce82fc05b70e50ea3aa28025c2d134860d725864865eacb] committed with status (VALID) at localhost:9051

(10)チェーンコード審査状況の閲覧とチェーンコードの提出

ORG2 は、チェーンコードのレビュー ステータスを確認し、チェーンコードを送信します。今回、ORG1とORG2が同時に審査を通過し、今回ようやくチェーンコードを提出できるようになりました

#查看链码审核状态
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/fabcar/go# peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1.0 --sequence 1 --output json
#运行结果
{
    
    
	"approvals": {
    
    
		"Org1MSP": true,
		"Org2MSP": true
	}
}


チェーン コードは最終的に組織ノードに送信されます
.コードは ORG1 と同じですが、ORG2 は以前にレビューを通過できなかったため、チェーン コードの最初の送信に失敗しました。

peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name fabcar --peerAddresses localhost:7051 --tlsRootCertFiles /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /opt/fabric-2.3.0/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1.0 --sequence 1


#返回的结果如下,如图可以看出链码已经提交成功,由于已经同时通过了ORG1,ORG2的审核,因此链码可以提交给排序节点
# 2022-06-19 21:57:01.524 CST [chaincodeCmd] ClientWait -> INFO 001 txid [26be9ccdddf6de2c5994406ac2411a5e478112d6f8d005a17be293939be11c89] committed with status (VALID) at localhost:7051
#2022-06-19 21:57:01.527 CST [chaincodeCmd] ClientWait -> INFO 002 txid [26be9ccdddf6de2c5994406ac2411a5e478112d6f8d005a17be293939be11c89] committed with status (VALID) at localhost:9051

ここに画像の説明を挿入

#这样子是没起来的,要这些容器的状态都变成Up才行~
#可以看到后面的invoke我就执行不了,本质原因就是链码容器没启起来~
root@gan-virtual-machine:/opt/fabric-2.3.0/scripts/fabric-samples/test-network# docker ps -a
CONTAINER ID   IMAGE                                                                                                                                                                    COMMAND                  CREATED         STATUS         PORTS                                                                                  NAMES
7af1a01a5b75   dev-peer0.org2.example.com-basic_1.0-4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad-6c0d5b0755cb92ed5555bd2e8a8765a6f425d1ed5ed9a90e625e01939e2113be   "chaincode -peer.add…"   6 minutes ago   Created                                                                                               dev-peer0.org2.example.com-basic_1.0-4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad
dc3cc5f8e9ad   dev-peer0.org1.example.com-basic_1.0-4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad-42f57faac8360472e47cbbbf3940e81bba83439702d085878d148089a1b213ca   "chaincode -peer.add…"   6 minutes ago   Created                                                                                               dev-peer0.org1.example.com-basic_1.0-4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad
9d7a9f992eae   hyperledger/fabric-tools:latest                                                                                                                                          "/bin/bash"              9 minutes ago   Up 9 minutes                                                                                          cli
b474ffa6a73e   hyperledger/fabric-peer:latest                                                                                                                                           "peer node start"        9 minutes ago   Up 9 minutes   7051/tcp, 0.0.0.0:9051->9051/tcp, :::9051->9051/tcp                                    peer0.org2.example.com
e6a08f02b506   hyperledger/fabric-peer:latest                                                                                                                                           "peer node start"        9 minutes ago   Up 9 minutes   0.0.0.0:7051->7051/tcp, :::7051->7051/tcp                                              peer0.org1.example.com
8adfb840488c   hyperledger/fabric-orderer:latest                                                                                                                                        "orderer"                9 minutes ago   Up 9 minutes   0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:7053->7053/tcp, :::7053->7053/tcp   orderer.example.com

チェーンコードの追加、削除、変更

前提条件: 前の章の提出を成功させるための手順がまだ残っているか、前の章の内容を再インストールしてもう一度やり直すことができます ~ 環境変数と組織認証情報、パッケージ チェーン コードを構成し、ノード監査チェーン コードを編成します。すべての組織ノードが監査に合格 チェーン コードを提出した後、チェーン コードは正常に承認されます。
次に、追加、削除、変更、チェックなどのメソッドを呼び出します。
(11) 初期化

#采用invoke,调用链码的InitLedger方法初始化数据
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $cafile -C mychannel -n fabcar --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles $org1_CertFiles --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles $org2_CertFiles -c '{"Args":["InitLedger"]}'
#参数解释
#-o 排序服务器节点
#--cafile排序节点的PEM证书文件路径
#-C通道名称
#-n链码名称
#-peerAddresses锚节点的地址
#--tlsRootCertFiles前面peerAddresses的TLS证书路径
#-c链码的方法和调用方法的参数


#备注,其中
$cafile = /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
$org1_CertFiles=/opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
$org2_CertFiles=/opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt


エラーを報告しました ~ すべての文字を確認したように感じます。問題ないはずです! しかし、エラーが報告されるのはなぜですか?
ここに画像の説明を挿入
確認したところ、チャンネルが存在します.
ここに画像の説明を挿入
この解決策は機能せず、問題は解決しません~

#搜到一个解决方案,试一下不知道能不能成功
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
docker rmi -f $(docker image|grep "dev-" |awk '{print $3}')
然后重新执行一下

[質問 ID: 202206202151] docker ps -a「 」で照会したコンテナのステータスは ですCreatedその後、私の友人は、2.2.5 バージョンを使用してチェーンコード コンテナーを使用することを提案しましたが、Up原因はまだわかりません ~
ここに画像の説明を挿入

(12) クエリ

#采用query调用链码中的QueryCar方法查询单部汽车
peer chaincode query -C mychannel -n fabcar -c '{"Args":["QueryCar","CAR0"]}'
#果然,上一步初始化没有成功是查询不了的,但如果上一步成功是可以查询的

(13) 新規

#采用invoke调用链码的CreateCar新增一辆汽车
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $cafile -C mychannel -n fabcar --peerAddresses peer0O.org1.example.com:7051 --tlsRootCertFiles $org1_CertFiles --peerAddresses peer0.org2.example.com:9051--tlsRootCertFiles $org2_CertFiles -c '{"Args":["CreateCar","CAR10","GEELY","Borui","Blue","Yujialing"]}'

(14) 新しいクエリ

#采用query调用链码中的QueryCar方法查询新增的汽车
peer chaincode query -C mychannel -n fabcar -c '{
    
    " Args":["QueryCar" , "CAR10"]}

(15) 改造

#采用invoke调用链码的ChangeCarOwner 更新汽车所有者
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $cafile -C mychannel
-n fabcar --peerAddresses
peer0.org1.example.com:7051 --tlsRootCertFiles $org1_CertFiles --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles $org2_CertFiles -c '{
    
    "Args":["ChangeCarOwner","CAR10","小岳岳"]}

6.2 独自のチェーンコードを書く

#编写链码,存为atcc


package main

import (
"encoding/json"
"fmt"
"log"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)

//SmartContract provides functions for managing an Asset
type SmartContract struct {
    
    
	contractapi.Contract
}


type Asset struct {
    
    
	ID string `json: "ID"`
	Owner string `json : "owner"`
	Value int`json : "Value"`
}


func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
    
    
	assets := []Asset{
    
    
		{
    
    ID: "asset1", Owner: "ZhangSan", Value: 300},
		{
    
    ID: "asset2",Owner: "Lisi", Value: 400},
		{
    
    ID: "asset3",Owner: "Klay", Value: 500},
	}

	for _, asset := range assets {
    
    
		assetjSON, err := json.Marshal(asset)
		if err != nil {
    
    
			return err
		}

		err = ctx.GetStub().PutState(asset.ID,assetjSON)
		if err != nil {
    
    
			return fmt.Errorf( "failed to put to world state. %v"  , err)
		}
	}
	return nil
}


func(s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error){
    
    
	assetJSON, err := ctx.GetStub().GetState(id)
	if err != nil {
    
    
		return nil, fmt.Errorf("failed to read from world state: %v" , err)
	}
	if assetJSON == nil {
    
    
		return nil, fmt.Errorf( "the asset %s does not exist", id)
	}

	var asset Asset
	err = json. Unmarshal(assetJSON, &asset)
	if err != nil {
    
    
		return nil, err
	}
	return &asset, nil
}


func(s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]*Asset, error){
    
    
// range query with empty string for startKey and endKey does an
// open-ended query of all assets in the chaincode namespace
	resultsIterator,err := ctx.GetStub().GetStateByRange("", "")
	if err != nil {
    
    
		return nil,err
	}
	defer resultsIterator.Close()
	
	var assets []*Asset
	for resultsIterator.HasNext() {
    
    
		queryResponse, err := resultsIterator.Next()
		if err != nil {
    
    
			return nil, err
		}
		var asset Asset
		err = json.Unmarshal(queryResponse.Value, &asset)
		if err != nil {
    
     
			return nil, err
		}
		assets = append(assets, &asset)
	}
	return assets, nil
}


func main() {
    
    
	assetChaincode, err := contractapi.NewChaincode(&SmartContract{
    
    })
	if err != nil {
    
    
		log.Panicf("Error creating asset-transfer-basic chaincode: %v" , err)
	}
	if err := assetChaincode.Start(); err != nil {
    
    
		log. Panicf("Error starting asset-transfer-basic chaincode:%v" , err)
	}
}

この部分は、バージョン 2.2.5 で fabcar のテストに成功した後に学んだので、基本的な fabcar チェーンコード デモの以前の展開に基づいて直接実行しました。したがって、hosts ファイルの変更と情報環境の構成を整理する手順は省略されています。

//在配置了组织1信息的终端上执行:
//创建链码文件存放目录atcc,并新建atcc.go,写入上述的go语言链码代码段
//我选择在chaincode目录下创建的,这个创建在哪里没关系,自己喜欢就好~【在配置了组织1信息的终端上执行或者配置了组织1信息的终端上执行都可以】
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode# mkdir atcc
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode# cd atcc
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# vim atcc.go
//获取链码依赖
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# go mod init atcc.go 
//go: creating new go.mod: module atcc.go
//go: to add module requirements and sums:
//	go mod tidy             这里它提示我要用go mod tidy,如果执行之后是正常发现了可拉取的依赖包的话,没有这个提醒可以不用执行这句命令          
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# go mod tidy
//go: finding module for package github.com/hyperledger/fabric-contract-api-go/contractapi
//go: found github.com/hyperledger/fabric-contract-api-go/contractapi in github.com/hyperledger/fabric-contract-api-go v1.1.1
//拉取依赖并下载到vendor目录下存储
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# go mod vendor
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# ls
//atcc.go  go.mod  go.sum  vendor   这时候可以看到,依赖下载成功啦
//通过组织1打包链码
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer lifecycle chaincode package atcc.tar.gz --path /opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc --label atcc_1
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# ls
//atcc.go  atcc.tar.gz  go.mod  go.sum  vendor   可以看到打包完成后,目录下增加了atcc.tar.gz文件
//然后我们将链码包atcc.tar.gz安装到组织1节点上,下面所示:安装成功后,返回status 200且会输出链码包标识ID——“atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48”
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer lifecycle chaincode install atcc.tar.gz
//2022-06-21 19:38:06.193 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nGatcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48\022\006atcc_1" > 
//2022-06-21 19:38:06.193 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48
//然后组织1节点要审核链码,通过审核后会输出交易ID——“txid [117c564ffca5a75299a84a613a4c33380c6ed1e6744f2ca85f20efa9823252fd]”
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name atcc --version 1.0 --package-id atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48 --sequence 1
//2022-06-21 19:39:19.540 CST [chaincodeCmd] ClientWait -> INFO 001 txid [117c564ffca5a75299a84a613a4c33380c6ed1e6744f2ca85f20efa9823252fd] committed with status (VALID) at localhost:7051
//可以通过命令查看当前链码的审核状态,因为只有所有组织节点都审核通过之后,才能提交链码。但这个时候只有Org1MSP通过了审核,组织2还没有通过审核
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name atcc --version 1.0 --sequence 1 --output json
{
    
    
	"approvals": {
    
    
		"Org1MSP": true,
		"Org2MSP": false
	}
}
//也可以通过命令查看当前节点上安装的链码
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer lifecycle chaincode queryinstalled
//Installed chaincodes on peer:
//Package ID: basic_1.0:3cfcf67978d6b3f7c5e0375660c995b21db19c4330946079afc3925ad7306881, Label: basic_1.0
//Package ID: fabcar_1:1146b4b491871bf18b23dd67dd8cc058655b36cc0e2274f165ed06b796a8f276, Label: fabcar_1
//Package ID: atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48, Label: atcc_1


//在配置了组织2信息的终端上执行:
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# ls
atcc.go  atcc.tar.gz  go.mod  go.sum  vendor
//同之前一样,将链码包atcc.tar.gz安装到组织2节点上,安装成功后也会返回status 200且会输出链码包标识ID——“atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48”
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer lifecycle chaincode install atcc.tar.gz
//2022-06-21 19:41:36.634 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nGatcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48\022\006atcc_1" > 
//2022-06-21 19:41:36.634 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48
//然后组织2节点也要审核链码,通过审核后也会输出交易ID——“txid [117c564ffca5a75299a84a613a4c33380c6ed1e6744f2ca85f20efa9823252fd]”
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name atcc --version 1.0 --package-id atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48 --sequence 1
//2022-06-21 19:41:53.240 CST [chaincodeCmd] ClientWait -> INFO 001 txid [50999fd3617bd19d9dc26d9826abdfac3a468628872550574cdd5887184250c8] committed with status (VALID) at localhost:9051
//可以通过命令查看当前链码的审核状态,这时候组织1和组织2都审核通过啦,可以提交链码了
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name atcc --version 1.0 --sequence 1 --output json
{
    
    
	"approvals": {
    
    
		"Org1MSP": true,
		"Org2MSP": true
	}
}
//通过组织2提交链码【通过组织1提交也是可以的,提交一次就行啦~都是同步的。】
//提交成功后会输出两条日志信息,说明提交的交易来自两个节点【真实情况下是多个,有多少个节点审核并通过了链码,这里就会有多少条日志信息,且都是对应于同一条交易ID】
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc#  peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name atcc --peerAddresses localhost:7051 --tlsRootCertFiles /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1.0 --sequence 1
//2022-06-21 19:49:24.598 CST [chaincodeCmd] ClientWait -> INFO 001 txid [b01da77332d3b3525f03a854b5ba4a442010626491a70637aeffd65b622738e0] committed with status (VALID) at localhost:9051
//2022-06-21 19:49:24.624 CST [chaincodeCmd] ClientWait -> INFO 002 txid [b01da77332d3b3525f03a854b5ba4a442010626491a70637aeffd65b622738e0] committed with status (VALID) at localhost:7051
//提交成功输出上面的日志之后,可以用docker ps -a 命令看到docker容器中又多了三个节点对应的atcc链码容器,且均处于Up状态。这时候可以进行链码调用啦~
//首先进行链码初始化,如果成功会返回status200,否则会提示错误原因
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n atcc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{
    
    "Args":["InitLedger"]}'
//2022-06-21 19:55:41.739 CST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 
//初始化成功之后可以采用query调用链码中的ReadAsset方法查询某条asset记录。-c后面接的是链码中的方法及其所需要的参数,这些方法是自己定义的,如InitLedger、ReadAsset、GetAllAssets,自己编写这个链码中只有这三个方法~
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer chaincode query -C mychannel -n atcc -c '{
    
    "Args":["ReadAsset","asset1"]}'
//{"ID":"asset1","Owner":"ZhangSan","Value":300}
//也可以采用query调用链码的GetAllAssets查询所有asset记录
root@gan-virtual-machine:/opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc# peer chaincode query -C mychannel -n atcc -c '{
    
    "Args":["GetAllAssets"]}'
//[{"ID":"asset1","Owner":"ZhangSan","Value":300},{"ID":"asset2","Owner":"Lisi","Value":400},{"ID":"asset3","Owner":"Klay","Value":500}]
//补充第14步:Java调用链码扩展: https://www.cnblogs.com/aarond/p/12173797.html   感兴趣的话可以自己下去看~

以下は純粋なコマンドです。端末ディレクトリのプロンプトはありません。コピーして貼り付ける方が便利です〜

//组织1执行
PWD='/opt/fabric-2.2.5/scripts/fabric-samples/test-network'
export PATH=${
    
    PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${
    
    PWD}/../config/
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

peer lifecycle chaincode package atcc.tar.gz --path /opt/fabric-2.2.5/scripts/fabric-samples/chaincode/atcc --label atcc_1
peer lifecycle chaincode install atcc.tar.gz 
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name atcc --version 1.0 --package-id atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48 --sequence 1
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name atcc --version 1.0 --sequence 1 --output json



//组织2执行
PWD='/opt/fabric-2.2.5/scripts/fabric-samples/test-network'
export PATH=${
    
    PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${
    
    PWD}/../config/
export CORE_PEER_TLS_ENABLED=true
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 atcc.tar.gz 
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name atcc --version 1.0 --package-id atcc_1:a682cc7b1295ef65592650b9bcd0936ebc7812fb842eee436b8e1ca9dbc1da48 --sequence 1
 peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name atcc --peerAddresses localhost:7051 --tlsRootCertFiles /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1.0 --sequence 1
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n atcc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/fabric-2.2.5/scripts/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{
    
    "Args":["InitLedger"]}'
peer chaincode query -C mychannel -n atcc -c '{
    
    "Args":["ReadAsset","asset1"]}'
peer chaincode query -C mychannel -n atcc -c '{
    
    "Args":["GetAllAssets"]}'




小さな質問を追加してください ~ 無視できます

序文:
ここに画像の説明を挿入

パッケージ化された 2 つのチェーンコード ファイルは異なります。これは重要ではありません。スキップしてください

fabcar.tar.gz は chaincode ディレクトリにパッケージ化されており、追加、削除、変更、および確認が可能
です. fabcar_.tar.gz は fabcar ディレクトリにパッケージ化されています. 前の章で取得したもので、追加、削除、変更することはできませんとチェックしました。

ここに画像の説明を挿入
先生の一人は3.M以上、もう一人は2.M以上。普通に追加、削除、修正、チェックできて、違いは無いと思いますが、ディレクトリ構造を見てみると、chaincodeディレクトリにパッケージ化された7.55Mディレクトリがfabcarディレクトリ2つ分に相当します。内容は同じはずです、多すぎて、ファイルの内容を1つずつ比較することはできません〜
ここに画像の説明を挿入

学習概要

このコースの内容はまだ非常に基本的なものですが、深く学ばなければならないことがたくさんあります。しかし、このコースを通じて、後でコードを読むのに役立つ簡単な shell と go の構文を学びました。さらに、ブロックチェーン関連の知識は、実際のケースを通じて確認されます。これは、ブロックチェーンを理解するのに役立ち、後で必要になる可能性があります。
だとうわ先生、どうもありがとうございました~ とても良いお話でした!非常に有益です。
道は遠いので、上り下りして探します。ファイト〜

おすすめ

転載: blog.csdn.net/weixin_49422491/article/details/125309519