페이지

2020년 5월 15일 금요일

Hyperledger Fabric 시작하기

Hyperledger Fabric 시작하기

Windows PC에 가상머신을 생성하고 Ubuntu를 설치한 상태에서 아래 문서를 따라하면서 실습을 하였습니다.

이 문서를 작성하면서 사용한 소프트웨어 버전을 각각의 소프트웨어 이름 옆에 표시하였습니다.

실습 환경

1. 준비 사항

Git 2.17.1

sudo apt-get install git

cURL 7.58.0

sudo apt-get install curl

Docker 19.03.8

아래 문서를 참고하여 Docker를 설치합니다.

설치 방법으로 Install using the repository을 택하여 진행하였습니다.

  • SETUP THE REPOSITORY

    1. apt가 HTTPS를 통하여 저장소를 사용할 수 있도록 패키지 추가

      $ sudo apt-get update
      
      $ sudo apt-get install \
          apt-transport-https \
          ca-certificates \
          curl \
          gnupg-agent \
          software-properties-common
      
    2. Docker의 GPG 키 추가

      $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
      
    3. stable 저장소 설정

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

      위 명령 줄에서 $(lsb_release -cs)focal을 반환합니다. 이로 인해 명령이 실패로 끝나게 되는데 이는 Docker가 아직 focal을 지원하지 않아서 발생하는 문제입니다. 이를 해결하기 위하여 $(lsb_release -cs)을 Ubuntu 18.04 LTS의 배포명인 bionic으로 대체해서 실행합니다.

      $ sudo add-apt-repository \
      	"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
      	bionic \
      	stable"
      
  • INSTALL DOCKER ENGINE

    1. Docker 엔진과 containerd 최신 버전 설치

       $ sudo apt-get update
       $ sudo apt-get install docker-ce docker-ce-cli containerd.io
      

이제 Docker 엔진을 설치하였습니다. 이에 더하여 Post-installation steps for Linux 문서가 제시하는 몇 가지 작업을 수행하면 Docker를 좀 더 편리하게 사용할 수 있습니다.

  • Manage Docker as a non-root user

    $ sudo usermod -aG docker $USER
    

    주의: 위의 명령에서 -a 없이 -G 옵션만 사용하면 사용자의 기존 그룹들은 모두 제거되고 새로 지정한 docker 그룹만 추가됩니다.

    가상머신 환경에서 그룹 멤버십을 적용하려면 가상머신을 다시 시작해야 합니다.

  • Configure Docker to start on boot

    $ sudo systemctl enable docker
    

docker-compose 1.17.1

sudo apt-get install docker-compose

Go Programming Language 1.14.2

위 문서를 참고하여 아래와 같이 Go를 설치합니다.

  1. 배포 파일 go1.14.2.linux-amd64.tar.gz 다운로드

  2. 다운로드한 파일을 /usr/local 폴더에 풀기

    sudo tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
    
  3. Go의 bin 폴더를 PATH 환경변수에 추가하기

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

Node.js 12.16.2 & NPM 6.14.4

위 문서를 참고하여 아래와 같이 Node.js를 설치합니다. NPM은 Node.js와 함께 설치됩니다.

  1. 배포 파일 node-v12.16.3-linux-x64.tar.xz 다운로드

  2. 다운로드한 파일을 /usr/local/lib/nodejs 폴더에 풀기

    sudo mkdir -p /usr/local/lib/nodejs
    sudo tar -xJvf node-v12.16.3-linux-x64.tar.xz -C /usr/local/lib/nodejs 
    
  3. Node.js의 bin 폴더를 PATH 환경변수에 추가하기

    export PATH=$PATH:/usr/local/lib/nodejs/node-v12.16.3-linux-x64/bin
    
  4. Fabric 코드 저장용 Go 작업공간을 위한 GOPATH 환경변수 추가

    export GOPATH=$HOME/go
    

Python 2.7

Fabric Node.js SDK는 npm install을 성공적으로 마치기 위하여 Python 2.7을 필요로 합니다.

sudo apt-get install python

2. 샘플 파일, 실행 파일, 도커 이미지 설치

1. 작업 폴더 생성

파일을 다운로드하여 저장할 폴더를 만듭니다. 폴더 이름을 아래 예시와 다르게 지어도 됩니다.

mkdir Hyperledger
cd Hyperledger

2. 스크립트 실행

아래 명령으로 스크립트 파일을 다운로드하고 실행합니다.

curl -sSL https://bit.ly/2ysbOFE | bash -s

위 명령은 아래의 작업들을 수행합니다.

  1. If needed, clone the hyperledger/fabric-samples repository
  2. Checkout the appropriate version tag
  3. Install the Hyperledger Fabric platform-specific binaries and config files for the version specified into the /bin and /config directories of fabric-samples
  4. Download the Hyperledger Fabric docker images for the version specified

실행 명령들을 실행 경로에서 찾을 수 있도록 아래 환경 변수를 설정합니다.

export PATH=$PATH:$HOME/Hyperledger/fabric-samples/bin

3. Using the Fabric test network

1. 테스트 네트워크 실행

cd $HOME/Hyperledger/fabric-samples/test-network
./network.sh up

위 명령이 정상적으로 실행되면 아래와 같은 메시지가 출력됩니다.

Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb' 

LOCAL_VERSION=2.1.0
DOCKER_IMAGE_VERSION=2.1.0
Creating network "net_test" with the default driver
Creating volume "net_peer0.org1.example.com" with default driver
Creating volume "net_peer0.org2.example.com" with default driver
Creating volume "net_orderer.example.com" with default driver
Creating peer0.org1.example.com ... 
Creating orderer.example.com ... 
Creating peer0.org2.example.com ... 
Creating peer0.org1.example.com
Creating orderer.example.com
Creating orderer.example.com ... done
CONTAINER ID        IMAGE                               COMMAND             CREATED             STATUS                  PORTS                              NAMES
41aa446a5e54        hyperledger/fabric-peer:latest      "peer node start"   6 seconds ago       Up 1 second             7051/tcp, 0.0.0.0:9051->9051/tcp   peer0.org2.example.com
3822795b91e4        hyperledger/fabric-orderer:latest   "orderer"           6 seconds ago       Up Less than a second   0.0.0.0:7050->7050/tcp             orderer.example.com
979efa6ddbc5        hyperledger/fabric-peer:latest      "peer node start"   6 seconds ago       Up 1 second             0.0.0.0:7051->7051/tcp             peer0.org1.example.com

2. 채널 생성

./network.sh createChannel

위 명령을 수행하면 이름이 mychannel인 채널을 생성합니다. 출력 메시지는 아래와 같습니다.

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 

### Generating channel configuration transaction 'mychannel.tx' ###
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
2020-05-05 21:46:11.150 KST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-05 21:46:11.222 KST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /home/trvoid/Hyperledger/fabric-samples/test-network/configtx/configtx.yaml
2020-05-05 21:46:11.222 KST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2020-05-05 21:46:11.225 KST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx
+ res=0
+ set +x

### Generating channel configuration transaction 'mychannel.tx' ###
#######    Generating anchor peer update for Org1MSP  ##########
+ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
2020-05-05 21:46:11.285 KST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-05 21:46:11.354 KST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /home/trvoid/Hyperledger/fabric-samples/test-network/configtx/configtx.yaml
2020-05-05 21:46:11.355 KST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 003 Generating anchor peer update
2020-05-05 21:46:11.356 KST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 004 Writing anchor peer update
+ res=0
+ set +x

#######    Generating anchor peer update for Org2MSP  ##########
+ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
2020-05-05 21:46:11.419 KST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-05-05 21:46:11.494 KST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /home/trvoid/Hyperledger/fabric-samples/test-network/configtx/configtx.yaml
2020-05-05 21:46:11.494 KST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 003 Generating anchor peer update
2020-05-05 21:46:11.497 KST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 004 Writing anchor peer update
+ res=0
+ set +x

Creating channel mychannel
Using organization 1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls true --cafile /home/trvoid/Hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
+ set +x
2020-05-05 21:46:14.834 KST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-05 21:46:14.895 KST [cli.common] readBlock -> INFO 002 Expect block, but got status: &{NOT_FOUND}
2020-05-05 21:46:14.898 KST [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2020-05-05 21:46:15.101 KST [cli.common] readBlock -> INFO 004 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2020-05-05 21:46:15.110 KST [channelCmd] InitCmdFactory -> INFO 005 Endorser and orderer connections initialized
2020-05-05 21:46:15.311 KST [cli.common] readBlock -> INFO 006 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2020-05-05 21:46:15.315 KST [channelCmd] InitCmdFactory -> INFO 007 Endorser and orderer connections initialized
2020-05-05 21:46:15.519 KST [cli.common] readBlock -> INFO 008 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2020-05-05 21:46:15.537 KST [channelCmd] InitCmdFactory -> INFO 009 Endorser and orderer connections initialized
2020-05-05 21:46:15.740 KST [cli.common] readBlock -> INFO 00a Expect block, but got status: &{SERVICE_UNAVAILABLE}
2020-05-05 21:46:15.758 KST [channelCmd] InitCmdFactory -> INFO 00b Endorser and orderer connections initialized
2020-05-05 21:46:15.987 KST [cli.common] readBlock -> INFO 00c Received block: 0

===================== Channel 'mychannel' created ===================== 

Join Org1 peers to the channel...
Using organization 1
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
+ set +x
2020-05-05 21:46:19.407 KST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-05 21:46:19.478 KST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

Join Org2 peers to the channel...
Using organization 2
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
+ set +x
2020-05-05 21:46:22.752 KST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-05 21:46:22.834 KST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

Updating anchor peers for org1...
Using organization 1
+ peer channel update -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx --tls true --cafile /home/trvoid/Hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
+ set +x
2020-05-05 21:46:25.969 KST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-05 21:46:25.990 KST [channelCmd] update -> INFO 002 Successfully submitted channel update
===================== Anchor peers updated for org 'Org1MSP' on channel 'mychannel' ===================== 

Updating anchor peers for org2...
Using organization 2
+ peer channel update -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx --tls true --cafile /home/trvoid/Hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
+ set +x
2020-05-05 21:46:32.147 KST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-05-05 21:46:32.185 KST [channelCmd] update -> INFO 002 Successfully submitted channel update
===================== Anchor peers updated for org 'Org2MSP' on channel 'mychannel' ===================== 


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

3. 체인코드 배포

./network.sh deployCC

위 명령은 fabcar 체인코드를 peer0.org1.example.compeer0.org2.example.com에 설치하고 mychannel 채널에 배포합니다. 출력 메시지는 아래와 같습니다.

deploying chaincode on channel 'mychannel'

Vendoring Go dependencies ...
~/Hyperledger/fabric-samples/chaincode/fabcar/go ~/Hyperledger/fabric-samples/test-network
go: downloading github.com/hyperledger/fabric-contract-api-go v1.0.0
go: downloading github.com/xeipuuv/gojsonschema v1.2.0
go: downloading github.com/hyperledger/fabric-chaincode-go v0.0.0-20200128192331-2d899240a7ed
go: downloading github.com/gobuffalo/packr v1.30.1
go: downloading github.com/go-openapi/spec v0.19.4
go: downloading github.com/hyperledger/fabric-protos-go v0.0.0-20200124220212-e9cfc186ba7b
go: downloading github.com/gobuffalo/envy v1.7.0
go: downloading github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415
go: downloading github.com/go-openapi/jsonreference v0.19.2
go: downloading github.com/rogpeppe/go-internal v1.3.0
go: downloading github.com/gobuffalo/packd v0.3.0
go: downloading github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f
go: downloading github.com/go-openapi/swag v0.19.5
go: downloading github.com/PuerkitoBio/purell v1.1.1
go: downloading github.com/joho/godotenv v1.3.0
go: downloading github.com/go-openapi/jsonpointer v0.19.3
go: downloading golang.org/x/text v0.3.2
go: downloading github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e
go: downloading gopkg.in/yaml.v2 v2.2.2
go: downloading github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578
go: downloading github.com/golang/protobuf v1.3.2
go: downloading google.golang.org/grpc v1.23.0
go: downloading golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
go: downloading google.golang.org/genproto v0.0.0-20180831171423-11092d34479b
go: downloading golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542
~/Hyperledger/fabric-samples/test-network
Finished vendoring Go dependencies
Using organization 1
++ peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label fabcar_1
++ res=0
++ set +x
===================== Chaincode is packaged on peer0.org1 ===================== 

Installing chaincode on peer0.org1...
Using organization 1
++ peer lifecycle chaincode install fabcar.tar.gz
++ res=0
++ set +x
2020-05-05 21:49:02.614 KST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:65710fa851d5c73690faa4709ef40b798c085e7210c46d44f8b1e2d5a062c9b0\022\010fabcar_1" > 
2020-05-05 21:49:02.614 KST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:65710fa851d5c73690faa4709ef40b798c085e7210c46d44f8b1e2d5a062c9b0
===================== Chaincode is installed on peer0.org1 ===================== 

Install chaincode on peer0.org2...
Using organization 2
++ peer lifecycle chaincode install fabcar.tar.gz
++ res=0
++ set +x
2020-05-05 21:49:36.021 KST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:65710fa851d5c73690faa4709ef40b798c085e7210c46d44f8b1e2d5a062c9b0\022\010fabcar_1" > 
2020-05-05 21:49:36.021 KST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:65710fa851d5c73690faa4709ef40b798c085e7210c46d44f8b1e2d5a062c9b0
===================== Chaincode is installed on peer0.org2 ===================== 

Using organization 1
++ peer lifecycle chaincode queryinstalled
++ res=0
++ set +x
Installed chaincodes on peer:
Package ID: fabcar_1:65710fa851d5c73690faa4709ef40b798c085e7210c46d44f8b1e2d5a062c9b0, Label: fabcar_1
PackageID is fabcar_1:65710fa851d5c73690faa4709ef40b798c085e7210c46d44f8b1e2d5a062c9b0
===================== Query installed successful on peer0.org1 on channel ===================== 

Using organization 1
++ peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --cafile /home/trvoid/Hyperledger/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 --init-required --package-id fabcar_1:65710fa851d5c73690faa4709ef40b798c085e7210c46d44f8b1e2d5a062c9b0 --sequence 1
++ set +x
2020-05-05 21:49:38.331 KST [chaincodeCmd] ClientWait -> INFO 001 txid [a122868923412b668458f936bc571db608cbd31e057fbb1556404ee63f175726] committed with status (VALID) at 
===================== 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 secs
++ peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1 --sequence 1 --output json --init-required
++ res=0
++ set +x
{
	"approvals": {
		"Org1MSP": true,
		"Org2MSP": false
	}
}
===================== 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 secs
++ peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1 --sequence 1 --output json --init-required
++ res=0
++ set +x
{
	"approvals": {
		"Org1MSP": true,
		"Org2MSP": false
	}
}
===================== Checking the commit readiness of the chaincode definition successful on peer0.org2 on channel 'mychannel' ===================== 
Using organization 2
++ peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --cafile /home/trvoid/Hyperledger/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 --init-required --package-id fabcar_1:65710fa851d5c73690faa4709ef40b798c085e7210c46d44f8b1e2d5a062c9b0 --sequence 1
++ set +x
2020-05-05 21:49:47.033 KST [chaincodeCmd] ClientWait -> INFO 001 txid [f5433e77e5894194a92abb51809562e09a75480fd43e02c12e83aececd0ec2af] committed with status (VALID) at 
===================== 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 secs
++ peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1 --sequence 1 --output json --init-required
++ res=0
++ set +x
{
	"approvals": {
		"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 secs
++ peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1 --sequence 1 --output json --init-required
++ res=0
++ set +x
{
	"approvals": {
		"Org1MSP": true,
		"Org2MSP": true
	}
}
===================== Checking the commit readiness of the chaincode definition successful on peer0.org2 on channel 'mychannel' ===================== 
Using organization 1
Using organization 2
++ peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --cafile /home/trvoid/Hyperledger/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 /home/trvoid/Hyperledger/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /home/trvoid/Hyperledger/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 1 --init-required
++ res=0
++ set +x
2020-05-05 21:49:57.343 KST [chaincodeCmd] ClientWait -> INFO 001 txid [dad109dc9f24d8bd22d05ffdfb830a35573cc1775d2021f8ffc898c7bb32705b] committed with status (VALID) at localhost:9051
2020-05-05 21:49:57.346 KST [chaincodeCmd] ClientWait -> INFO 002 txid [dad109dc9f24d8bd22d05ffdfb830a35573cc1775d2021f8ffc898c7bb32705b] 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.
++ peer lifecycle chaincode querycommitted --channelID mychannel --name fabcar
++ res=0
++ set +x

Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
===================== 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.
++ peer lifecycle chaincode querycommitted --channelID mychannel --name fabcar
++ res=0
++ set +x

Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
===================== Query chaincode definition successful on peer0.org2 on channel 'mychannel' ===================== 

Using organization 1
Using organization 2
++ peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --cafile /home/trvoid/Hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabcar --peerAddresses localhost:7051 --tlsRootCertFiles /home/trvoid/Hyperledger/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles /home/trvoid/Hyperledger/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --isInit -c '{"function":"initLedger","Args":[]}'
++ res=0
++ set +x
2020-05-05 21:50:03.941 KST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 
===================== Invoke transaction successful on peer0.org1 peer0.org2 on channel 'mychannel' ===================== 

Querying chaincode on peer0.org1...
Using organization 1
===================== Querying on peer0.org1 on channel 'mychannel'... ===================== 
Attempting to Query peer0.org1 ...1588683016 secs
++ peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
++ res=0
++ set +x

[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
===================== Query successful on peer0.org1 on channel 'mychannel' =====================

4. 체인코드 호출

peer 명령을 사용하여 아래 작업들을 수행할 수 있습니다.

  • invoke deployed smart contracts
  • update channels
  • install and deploy new smart contracts

peer 명령을 실행 경로에서 찾을 수 있도록 아래 환경 변수를 설정합니다.

export PATH=${PWD}/../bin:${PWD}:$PATH

core.yaml 파일을 찾을 수 있도록 아래 환경 변수를 설정합니다.

export FABRIC_CFG_PATH=$PWD/../config/

peer CLI를 Org1으로 동작시키기 위하여 아래 환경 변수들을 설정합니다.

# Environment variables for Org1

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 chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'

자동차 소유자를 변경하기 위하여 아래 명령을 실행합니다.

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

peer CLI를 Org2로 동작시키고자 한다면 아래 환경 변수들을 설정합니다.

# Environment variables for Org2

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

5. 테스트 네트워크 종료

아래 명령으로 테스트 네트워크를 내릴 수 있습니다.

./network.sh down

위 명령은 아래 항목들을 제거합니다.

  • the node and chaincode containers
  • the organization crypto material
  • the chaincode images from your Docker Registry
  • the channel artifacts and docker volumes

6. 다음 단계

  • Bring up the network with Certificate Authorities
  • What’s happening behind the scenes?
  • Troubleshooting

Written with StackEdit.

댓글 없음:

댓글 쓰기

JWT 토큰 생성과 유효성 확인 과정

JWT 토큰 생성과 유효성 확인 과정 API 서비스를 개발하고 이에 대한 접근 권한을 제어하기 위하여 JSON Web Token(JWT)을 활용할 수 있습니다. 이 문서에서는 JWT 토큰의 생성과 유효성 확인 과정...