この記事では、例としてFabric 1.4.6を取り上げ、cryptogenとFabricCA証明書の相互運用性の問題を簡単に紹介します。最も効率的な方法でテストネットワークを有効にすることは、のファブリックfirst-network
で実行することです./byfn.sh up
(バージョン2.0.0は、ここで使用されている方法と同様に、test-network
置き換えられた以上のものをfirst-network
使用します。話さないでください)。ただし、スクリプトを使用する場合cryptogen
、デフォルトではツールを使用してIDが生成されますが、ツールによって生成されるアカウント(証明書)の数は固定されています。でcrypto-config.yaml
設定を変更できますが、追加ユーザーの数を1より大きい数に変更してください。ただし、この変更はネットワークが開始される前に発生します。ネットワークが開始されると、変更することはできません。したがって、ユーザーを動的に追加するメカニズムが必要です。ここで、CAが登場します。
準備するには、公式ドキュメントのInstall Samples、Binaries、およびDocker Imagesに従って、公式のオリジナルのFabric 1.4.6、Fabric Samples 1.4.6、およびFabric CA1.4.2をインストールします。
ヒント:独自のスクリプトを作成し、cryptogenの代わりにCAを使用してIDを生成し、ネットワークを起動して(fabric-samplesバージョン2.0.0以降を参照)、相互通信の問題が発生しないようにすることもできます。ただし、この記事は主に相互通信について説明するため、Fabric1.4.6バージョンを引き続き使用します。
1.テストネットワークとCAを開始します
CA発行IDを使用するには、コマンドを使用して手動で起動できるCAサーバーを起動するか、byfn.sh
スクリプトを使用してdockerコンテナを起動する必要があります。scriptメソッドを使用して作業を最小限に抑えます。
fabric-samples
次のfirst-network
ディレクトリに切り替えて、次のスクリプトを実行します。
./byfn.sh down
./byfn.sh up -a
ここ-a
でのオプションは、ネットワークの開始と同時にCAを開始することbyfn.sh
です。詳細については、スクリプトの冒頭にある概要を参照してください。
ネットワークの展開が完了すると、プロンプトが表示されます。このとき、実行中のコンテナを確認しましょう。
➜ fabric-samples git:(337f82c) ✗ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
63334fdbdd15 dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b "chaincode -peer.add…" 43 minutes ago Up 43 minutes dev-peer0.org2.example.com-mycc-1.0
7e2df103a97c dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb25174305fce8f53f4e94d45ee3b6cab0ce9 "chaincode -peer.add…" 46 minutes ago Up 46 minutes dev-peer0.org1.example.com-mycc-1.0
27c9e9e18e16 dev-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab "chaincode -peer.add…" 15 hours ago Exited (0) 55 minutes ago dev-peer1.org2.example.com-mycc-1.0
3f4f0dbc9c9e hyperledger/fabric-tools:latest "/bin/bash" 15 hours ago Up 55 minutes cli
fb080f3a877c hyperledger/fabric-ca:latest "sh -c 'fabric-ca-se…" 15 hours ago Up 55 minutes 0.0.0.0:7054->7054/tcp ca_peerOrg1
98be2c8c32b7 hyperledger/fabric-peer:latest "peer node start" 15 hours ago Up 55 minutes 0.0.0.0:7051->7051/tcp peer0.org1.example.com
3f36dbf02ed1 hyperledger/fabric-peer:latest "peer node start" 15 hours ago Up 55 minutes 0.0.0.0:8051->8051/tcp peer1.org1.example.com
789e6006049a hyperledger/fabric-orderer:latest "orderer" 15 hours ago Up 55 minutes 0.0.0.0:7050->7050/tcp orderer.example.com
1a4e27bc675f hyperledger/fabric-peer:latest "peer node start" 15 hours ago Up 55 minutes 0.0.0.0:10051->10051/tcp peer1.org2.example.com
7f4adb26061e hyperledger/fabric-ca:latest "sh -c 'fabric-ca-se…" 15 hours ago Up 55 minutes 7054/tcp, 0.0.0.0:8054->8054/tcp ca_peerOrg2
87c6b79f7292 hyperledger/fabric-peer:latest "peer node start" 15 hours ago Up 55 minutes 0.0.0.0:9051->9051/tcp peer0.org2.example.com
➜ fabric-samples git:(337f82c) ✗
NAMES
我々が見ることができる、我々はそれぞれのCAサーバコンテナ2つの団体、ポート、開始7054
、および8054
対応するORG1およびORG2を。この記事の作業は、org1のCAを使用してUser2を追加することです。
IDが生成された後、主にUser1について、対応する部分のディレクトリ構造を見てみましょう。
組織管理者AdminとユーザーUser1が生成されたことがわかります。次に、ネットワークを再起動せずにユーザーを生成しましょう。 User2。
2.ファブリックCAクライアントを確立します
便宜上、fabric-samplesディレクトリで操作します。次のコマンドを実行して、fabric-samples
ディレクトリに切り替え、作業ディレクトリを作成します。
cd ..
mkdir fabric_ca_test
cd fabric_ca_test
cp ../bin/fabric-ca-client ./
fabric-ca-client
このFabricCAクライアントツールをこのディレクトリにコピーしたことがわかります。スクリプトがCAを開始すると、TLSはデフォルトで有効になっているため、CAサーバーのTLS証明書が必要です。first-network
ディレクトリdocker-compose-ca.yaml
あなたは、証明書のパスを確認できます
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
。これは仮想ディレクトリであり、実際のディレクトリは次の場所にvolumes
マップされていることに注意してください。
volumes:
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
ここで、証明書の形式によると、CAのドメイン名はca.org1.example.comであることがわかります。
ここで注意する必要のある環境変数はに設定されてい- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/${BYFN_CA1_PRIVATE_KEY}
ます。これは、Fabric CAServerの秘密鍵をcryptogen
ツールによって生成された秘密鍵に設定します。秘密鍵が同じである場合、生成された証明書は一貫しています。これは、異なるツールによって生成された証明書の相互運用性の前提条件です。
次のコマンドを実行して、このTLS証明書をコピーします。
mkdir tls-root-cert
cp ../first-network/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem tls-root-cert/tls-ca-cert.pem
ご覧のとおり、便宜上、ファイルの名前も変更しました。
クライアントとTLS証明書を取得したので、CAサーバーにIDの発行を要求できます。
3.ユーザーをガイドするためのCAの発行
IDを発行する最初のステップは、ガイドユーザー(組織管理者ではなくCA管理者に相当)を発行することです。ガイドユーザーのアカウントパスワードは、CAサーバーdocker-compose-ca.yaml
の起動時に決定されます。次の起動コマンドを参照してください。
command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/${BYFN_CA1_PRIVATE_KEY} -b admin:adminpw -d'
特定のCAの使用法については、ここでは説明されていない公式ドキュメントを読むことができます。上記のコマンドからわかるようadmin
に、主要ユーザーのユーザー名とパスワードはadminpw
です。
先に述べたように、CAのドメイン名:ca.org1.example.com、私たちはここにはサーバー側のコンフィギュレーション・ファイルではないんので、あなたが使用することはできませんlocalhost
、あなたはまた、必要な/etc/hosts
ものを追加するため127.0.0.1
にca.org1.example.com
解像度。
次のコマンドを実行して、ガイドユーザーを発行します。
export FABRIC_CA_CLIENT_HOME=$PWD
./fabric-ca-client enroll -u https://admin:[email protected]:7054 --tls.certfiles tls-root-cert/tls-ca-cert.pem --csr.hosts localhost --mspdir admin/msp
同様の出力が得られます。
2020/08/22 12:05:43 [INFO] Created a default configuration file at /Users/likai/fabric/fabric-samples/fabric_ca_test/fabric-ca-client-config.yaml
2020/08/22 12:05:43 [INFO] TLS Enabled
2020/08/22 12:05:43 [INFO] generating key: &{
A:ecdsa S:256}
2020/08/22 12:05:43 [INFO] encoded CSR
2020/08/22 12:05:43 [INFO] Stored client certificate at /Users/likai/fabric/fabric-samples/fabric_ca_test/admin/msp/signcerts/cert.pem
2020/08/22 12:05:43 [INFO] Stored root CA certificate at /Users/likai/fabric/fabric-samples/fabric_ca_test/admin/msp/cacerts/ca-org1-example-com-7054.pem
2020/08/22 12:05:43 [INFO] Stored Issuer public key at /Users/likai/fabric/fabric-samples/fabric_ca_test/admin/msp/IssuerPublicKey
2020/08/22 12:05:43 [INFO] Stored Issuer revocation public key at /Users/likai/fabric/fabric-samples/fabric_ca_test/admin/msp/IssuerRevocationPublicKey
ガイドユーザーが正常に発行され、関連情報がadmin/msp
ディレクトリにあることを示します。
第4に、User2を登録して発行するようにユーザーをガイドするために使用します
1.登録
IDを発行する前に登録する必要があります。次のコマンドを実行して登録します。
./fabric-ca-client register --id.name User2 --id.secret User2pw --tls.certfiles tls-root-cert/tls-ca-cert.pem --mspdir admin/msp/
次のような出力があります。
2020/08/22 12:09:39 [INFO] Configuration file location: /Users/likai/fabric/fabric-samples/fabric_ca_test/fabric-ca-client-config.yaml
2020/08/22 12:09:39 [INFO] TLS Enabled
2020/08/22 12:09:39 [INFO] TLS Enabled
Password: User2pw
2.問題
登録したばかりのユーザー名とパスワードを使用して、IDを発行します。
./fabric-ca-client enroll -u https://User2:[email protected]:7054 --tls.certfiles tls-root-cert/tls-ca-cert.pem --csr.hosts localhost --mspdir users/User2/msp
次のような出力があります。
2020/08/22 12:13:13 [INFO] TLS Enabled
2020/08/22 12:13:13 [INFO] generating key: &{
A:ecdsa S:256}
2020/08/22 12:13:13 [INFO] encoded CSR
2020/08/22 12:13:13 [INFO] Stored client certificate at /Users/likai/fabric/fabric-samples/fabric_ca_test/users/User2/msp/signcerts/cert.pem
2020/08/22 12:13:13 [INFO] Stored root CA certificate at /Users/likai/fabric/fabric-samples/fabric_ca_test/users/User2/msp/cacerts/ca-org1-example-com-7054.pem
2020/08/22 12:13:13 [INFO] Stored Issuer public key at /Users/likai/fabric/fabric-samples/fabric_ca_test/users/User2/msp/IssuerPublicKey
2020/08/22 12:13:13 [INFO] Stored Issuer revocation public key at /Users/likai/fabric/fabric-samples/fabric_ca_test/users/User2/msp/IssuerRevocationPublicKey
このtree
コマンドを使用して、生成されたばかりのディレクトリ構造を表示できます。
tree users/User2/
結果の構造は次のとおりです。
users/User2/
└── msp
├── IssuerPublicKey
├── IssuerRevocationPublicKey
├── cacerts
│ └── ca-org1-example-com-7054.pem
├── keystore
│ └── 6f097b265f17e3bcab411a9ea3e328c62e851f9948ad4af7298d4e57535cb471_sk
├── signcerts
│ └── cert.pem
└── user
5 directories, 5 files
User2が生成されました。この時点で、vscodeでUser1のディレクトリ構造を比較すると、まだいくつかの違いがあることがわかります。次のステップは、新しく発行されたUser2証明書とキーをfirst-network
の対応するディレクトリ構造にコピーすることです。
5、User2をに追加しますfirst-network
次のコマンドを実行して、User1のディレクトリ構造をUser2にコピーします。
cd ../first-network/crypto-config/peerOrganizations/org1.example.com/users/
mkdir [email protected]
cd [email protected]
cp -r ../[email protected]/tls ./
cp -r ../[email protected]/msp ./
rm -f msp/keystore/*
ここでyを選択し、User1のキーを削除してから、次のコマンドを実行します。
rm -f msp/signcerts/*
また、yを選択して、User1の証明書を削除します。
User2のキーと証明書をコピーします。
cp ../../../../../../fabric_ca_test/users/User2/msp/keystore/* msp/keystore/
cp ../../../../../../fabric_ca_test/users/User2/msp/signcerts/cert.pem msp/signcerts/[email protected]
最後に、User2のCAルート証明書をコピーします(省略可能)
cp ../../../../../../fabric_ca_test/users/User2/msp/cacerts/ca-org1-example-com-7054.pem msp/cacerts/ca.org1.example.com-cert.pem
ターゲットファイルがすでに存在するため、User1からコピーされるため、ここで省略できるのはなぜですか。2つの方法がcryptogen
ありFabric CA
、同じ秘密鍵を使用するため、信頼されたルート証明書は同じである必要があります。そうでない場合、通信する方法がありません。興味のある読者は、最後にコピーされたソースファイルとターゲットファイルの内容が完全に同じであるかどうかを確認できます。一貫性がない場合は、何が問題であったかが示されます。
この時点で、新しいユーザーUser2
は正常にリリースされました。
これは、作成者が遭遇した落とし穴です。つまり、User2を登録する--id.type
ときに、指定せずに、デフォルトのままにclient
します。
6、テスト
ここでのテストはもう少し複雑で、fabric-sdk-goの適用が含まれます。ただし、参照用の記事は次のとおりです。fabric-sdk-goを使用してチェーンコードを操作します。ソースコード(構成ファイルではない)で使用さAdmin
れている場所をUser1
、User2
テストに置き換えることができます。ここで、作成者は簡単なテストファイルmain.go
を作成しましたが、go mod init
読者は自分で構成ファイルを取得する必要があります。
package main
import (
"fmt"
"log"
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
)
const (
org1CfgPath = "./config.yaml"
ChannelID = "mychannel"
peer0Org1 = "peer0.org1.example.com"
peer0Org2 = "peer0.org2.example.com"
)
func main() {
sdk, err := fabsdk.New(config.FromFile(org1CfgPath))
if err != nil {
log.Panicf("failed to create fabric sdk: %s", err)
}
ccp := sdk.ChannelContext(ChannelID, fabsdk.WithUser("User2"))
cc, err := channel.New(ccp)
if err != nil {
log.Panicf("failed to create channel client: %s", err)
}
fmt.Println("channel init over")
query(cc)
// execute(cc)
// time.Sleep(5 * time.Second)
// query(cc)
}
func query(cc *channel.Client) {
// new channel request for query
req := channel.Request{
ChaincodeID: "mycc",
Fcn: "query",
Args: packArgs([]string{
"a"}),
}
// send request and handle response
reqPeers := channel.WithTargetEndpoints(peer0Org1)
response, err := cc.Query(req, reqPeers)
if err != nil {
fmt.Printf("failed to query chaincode: %s\n", err)
}
if len(response.Payload) > 0 {
fmt.Printf("chaincode query success,the value is %s\n", string(response.Payload))
}
}
func execute(cc *channel.Client) {
args := packArgs([]string{
"a", "b", "10"})
req := channel.Request{
ChaincodeID: "mycc",
Fcn: "invoke",
Args: args,
}
peers := []string{
peer0Org1, peer0Org2}
reqPeers := channel.WithTargetEndpoints(peers...)
response, err := cc.Execute(req, reqPeers)
if err != nil {
fmt.Printf("failed to Execute chaincode: %s\n", err)
}
fmt.Printf("Execute chaincode success,txId:%s\n", response.TransactionID)
}
func packArgs(paras []string) [][]byte {
var args [][]byte
for _, k := range paras {
args = append(args, []byte(k))
}
return args
}
ccp := sdk.ChannelContext(ChannelID, fabsdk.WithUser("User2"))
途中の「User2」を「User1」または「Admin」に置き換えると動作します。
実行:
go run main.go
次のような結果が得られます
channel init over
chaincode query success,the value is 90
コメントアウトされたコードはチェーンコードを実行するために使用され、興味のある読者はコメントを外してテストすることができます。
これでテストは完了し、CAを使用して新しく生成されたユーザーは、ネットワークを変更せずに直接使用できます。
記事の問題点を指摘したり、議論のためにメッセージを残したりするために、みんなを歓迎します。