[주의사항]
* 도커는 기본적으로 root 권한이 필요합니다. 사용자 계정으로 sudo 없이 사용하려면 해당 사용자를 docker 그룹에 추가해야 합니다.
* 설치도중 또는 설치 후 fabric 샘플 소스를 실행할 때 root 권한이 맞는지 잘 확인해주세요.
* 특정 사용자 계정으로 진행할 경우 아래 모든 명령어들은 사용자 계정 및 root 계정 모두 지정된 버전으로 실행되어야 합니다.
[특정 사용자를 docker 그룹에 추가 (추천)]
sudo usermod -aG docker 사용자계정
[CentOS 7 - 환경 구축]
# 2018.04.24
# DNS 8.8.8.8
# KT DNS 주소로 진행했더니
# 도커 이미지를 제대로 못받는 경우가 발생함 (정확하지는 않음)
######################################
# 선행 조건 - fabric 공식 문서(Prerequisite 항목)에서 확인
# 각 오픈소스별 버전 매우 중요
# Python(2.7 버전만, 3.x는 안 됨)
# Docker(17.06-ce 이상, Ubuntu (docker.io 설치 시) 는 1.13 이상)
# Docker compose(1.14 이상)
# Go(1.9 이상)
# Node.js(8.9 이상 9.0 미만 - 8.11 추천)
# NPM(5.6.0 이상)
# repository 및 epel 업데이트
sudo yum -y update
sudo yum -y install epel-release
# 설치가 안되어 있다면 설치할 것.
# curl, git, wget, python2.7
#sudo yum -y install curl git
sudo yum -y install wget
# docker (17.06-ce 이상) 설치
sudo yum -y install yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum makecache fast
sudo yum -y install docker-ce
# docker-compose (1.14 이상) 설치
sudo yum -y install python-pip
sudo pip install docker-compose
# docker-compose 설치 다른방법 (root 로그인 후 실행)
curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# docker 서버 실행 및 자동실행 설정 추가
systemctl start docker
systemctl enable docker
# n (최신), nodejs (8.9 이상 9.0 미만 - 8.11 추천), npm (5.6.0 이상) 설치
sudo yum -y install npm nodejs
sudo npm install -g n
sudo n 8.11.1
sudo ln -sf /usr/local/n/versions/node/8.11.1/bin/node /usr/bin/node
sudo npm install -g npm
sudo npm install --global grpc --unsafe
# go 1.95 버전 다운로드
cd ~
wget https://dl.google.com/go/go1.9.5.linux-amd64.tar.gz
sudo tar -zxvf go1.9.5.linux-amd64.tar.gz -C /usr/local/
(이후 아래 환경변수 설정 후에 go 명령어 사용 가능합니다.)
###################################################
[도커 이미지 다운로드]
# HyperLedger Fabric 도커 이미지 및 바이너리 다운로드
cd ~
mkdir -p go/src/github.com/hyperledger
cd go/src/github.com/hyperledger
sudo curl -sSL https://goo.gl/6wtTN5 | sudo bash -s 1.1.0
(* docker 그룹에 사용자계정을 추가했을 경우 sudo 를 안써도 된다.)
curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0
* 도커 필수 이미지를 받는 스크립트의 경우 사용자 계정을 docker 그룹에 추가하지 않으면
sudo 를 통해 실행해야 docker 명령어가 정상적으로 수행됩니다. 그러나 sudo 를 사용하면 다운받는 fabric-samples 폴더 소유자가 root 가 되어
소유 및 권한을 다시 사용자계정으로 변경해 주거나 이후 샘플 폴더 안에서 실행할 작업들을 모두 sudo 로 진행해야 합니다.
* 사용자 계정을 docker 그룹에 추가 (sudo usermod -aG docker 사용자계정) 한 후 위 스크립트를 진행한다면 sudo 명령어를 빼고 실행해도 되며
(curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0) 이럴 경우 fabric-sample 폴더는 사용자계정 소유로 진행되고 추후 작업들도 sudo 없이 진행 가능합니다.
[환경변수 설정]
# go 환경변수
sudo vi /etc/profile
# 프로필 맨 아래 추가
# GOPATH 는 golang 의 workspace 와 비슷하므로 원하는 곳으로 설정해도 괜찮습니다.
export GOPATH=/home/사용자계정/go
export PATH=/usr/local/go/bin:$PATH
# 나중에 소스코드 실행 시 또는 Chaincode 수정시 peer, configtxgen, cryptogen 등 관련 명령어를 못찾는 오류가 생길 경우
export PATH=$HOME/go/src/github.com/hyperledger/fabric-samples/bin:$PATH
source /etc/profile
# fabcar 예제
cd fabcar
sudo npm install --unsafe-perm
sudo ./startFabric.sh
[결과]
1. startFabric.sh 실행
[user@localhost fabcar]$ sudo ./startFabric.sh
# don't rewrite paths for Windows Git Bash users
export MSYS_NO_PATHCONV=1
docker-compose -f docker-compose.yml down
Removing cli ... done
Removing peer0.org1.example.com ... done
Removing orderer.example.com ... done
Removing ca.example.com ... done
Removing couchdb ... done
Removing network net_basic
docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb
Creating network "net_basic" with the default driver
Creating orderer.example.com ... done
Creating couchdb ... done
Creating ca.example.com ... done
Creating peer0.org1.example.com ... done
# wait for Hyperledger Fabric to start
# incase of errors when running later commands, issue export FABRIC_START_TIMEOUT=<larger number>
export FABRIC_START_TIMEOUT=10
#echo ${FABRIC_START_TIMEOUT}
sleep ${FABRIC_START_TIMEOUT}
# Create the channel
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel create -o orderer.example.com:7050 -c mychannel -f /etc/hyperledger/configtx/channel.tx
2018-04-24 08:02:04.449 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2018-04-24 08:02:04.482 UTC [channelCmd] InitCmdFactory -> INFO 002 Endorser and orderer connections initialized
2018-04-24 08:02:04.685 UTC [main] main -> INFO 003 Exiting.....
# Join peer0.org1.example.com to the channel.
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel join -b mychannel.block
2018-04-24 08:02:04.862 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2018-04-24 08:02:04.962 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
2018-04-24 08:02:04.962 UTC [main] main -> INFO 003 Exiting.....
Creating cli ... done
2018-04-24 08:02:05.666 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP
2018-04-24 08:02:05.666 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity
2018-04-24 08:02:05.666 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2018-04-24 08:02:05.666 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2018-04-24 08:02:05.666 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled
2018-04-24 08:02:05.693 UTC [golang-platform] getCodeFromFS -> DEBU 006 getCodeFromFS github.com/fabcar/go
2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 007 Discarding GOROOT package bytes
2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 008 Discarding GOROOT package encoding/json
2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 009 Discarding GOROOT package fmt
2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 00a Discarding provided package github.com/hyperledger/fabric/core/chaincode/shim
2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 00b Discarding provided package github.com/hyperledger/fabric/protos/peer
2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 00c Discarding GOROOT package strconv
2018-04-24 08:02:05.783 UTC [golang-platform] GetDeploymentPayload -> DEBU 00d done
2018-04-24 08:02:05.783 UTC [container] WriteFileToPackage -> DEBU 00e Writing file to tarball: src/github.com/fabcar/go/fabcar.go
2018-04-24 08:02:05.787 UTC [msp/identity] Sign -> DEBU 00f Sign: plaintext: ---
2018-04-24 08:02:05.787 UTC [msp/identity] Sign -> DEBU 010 Sign: digest: ---
2018-04-24 08:02:05.817 UTC [chaincodeCmd] install -> DEBU 011 Installed remotely response:<status:200 payload:"OK" >
2018-04-24 08:02:05.817 UTC [main] main -> INFO 012 Exiting.....
2018-04-24 08:02:05.983 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP
2018-04-24 08:02:05.983 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity
2018-04-24 08:02:05.984 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2018-04-24 08:02:05.984 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2018-04-24 08:02:06.018 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled
2018-04-24 08:02:06.019 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: ---
2018-04-24 08:02:06.019 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: ---
2018-04-24 08:02:06.293 UTC [msp/identity] Sign -> DEBU 008 Sign: plaintext: ---
2018-04-24 08:02:06.293 UTC [msp/identity] Sign -> DEBU 009 Sign: digest: ---
2018-04-24 08:02:06.294 UTC [main] main -> INFO 00a Exiting.....
2018-04-24 08:02:16.467 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP
2018-04-24 08:02:16.467 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity
2018-04-24 08:02:16.468 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2018-04-24 08:02:16.468 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2018-04-24 08:02:16.468 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled
2018-04-24 08:02:16.469 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: ---
2018-04-24 08:02:16.469 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: ---
2018-04-24 08:02:16.476 UTC [msp/identity] Sign -> DEBU 008 Sign: plaintext: ---
2018-04-24 08:02:16.476 UTC [msp/identity] Sign -> DEBU 009 Sign: digest: ---
2018-04-24 08:02:16.477 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> DEBU 00a ESCC invoke result: version:1 response:<status:200 message:"OK" > payload:"\n L\373h\037A><&3\371c0\261\243d\245\3207\240\254\225 \201\201.\240vDH?\205\260\022\267\006\n\240\006\022\205\006\n\006fabcar\022\372\005\032J\n\004CAR0\032B{\"make\":\"Toyota\",\"model\":\"Prius\",\"colour\":\"blue\",\"owner\":\"Tomoko\"}\032G\n\004CAR1\032?{\"make\":\"Ford\",\"model\":\"Mustang\",\"colour\":\"red\",\"owner\":\"Brad\"}\032N\n\004CAR2\032F{\"make\":\"Hyundai\",\"model\":\"Tucson\",\"colour\":\"green\",\"owner\":\"Jin Soo\"}\032N\n\004CAR3\032F{\"make\":\"Volkswagen\",\"model\":\"Passat\",\"colour\":\"yellow\",\"owner\":\"Max\"}\032G\n\004CAR4\032?{\"make\":\"Tesla\",\"model\":\"S\",\"colour\":\"black\",\"owner\":\"Adriana\"}\032K\n\004CAR5\032C{\"make\":\"Peugeot\",\"model\":\"205\",\"colour\":\"purple\",\"owner\":\"Michel\"}\032H\n\004CAR6\032@{\"make\":\"Chery\",\"model\":\"S22L\",\"colour\":\"white\",\"owner\":\"Aarav\"}\032H\n\004CAR7\032@{\"make\":\"Fiat\",\"model\":\"Punto\",\"colour\":\"violet\",\"owner\":\"Pari\"}\032J\n\004CAR8\032B{\"make\":\"Tata\",\"model\":\"Nano\",\"colour\":\"indigo\",\"owner\":\"Valeria\"}\032M\n\004CAR9\032E{\"make\":\"Holden\",\"model\":\"Barina\",\"colour\":\"brown\",\"owner\":\"Shotaro\"}\022\026\n\004lscc\022\016\n\014\n\006fabcar\022\002\010\001\032\003\010\310\001\"\r\022\006fabcar\032\0031.0" endorsement:<endorser:"\-----BEGIN CERTIFICATE-----\---\n-----END CERTIFICATE-----\n" signature:"---" >
2018-04-24 08:02:16.478 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 00b Chaincode invoke successful. result: status:200
2018-04-24 08:02:16.478 UTC [main] main -> INFO 00c Exiting.....
Total setup execution time : 25 secs ...
Start by installing required packages run 'npm install'
Then run 'node enrollAdmin.js', then 'node registerUser'
The 'node invoke.js' will fail until it has been updated with valid arguments
The 'node query.js' may be run at anytime once the user has been registered
[user@localhost fabcar]$
2. enrollAdmin.js 실행
- admin 등록
[user@localhost fabcar]$ sudo node enrollAdmin.js
Store path:$HOME/go/src/github.com/hyperledger/fabric-samples/fabcar/hfc-key-store
Successfully enrolled admin user "admin"
Assigned the admin user to the fabric client ::{"name":"admin","mspid":"Org1MSP","roles":null,"affiliation":"","enrollmentSecret":"","enrollment":{"signingIdentity":"*******************","identity":{"certificate":"-----BEGIN CERTIFICATE-----\n********************\n-----END CERTIFICATE-----\n"}}}
[user@localhost fabcar]$
3. registerUser.js 실행
- 일반 유저 등록
[user@localhost fabcar]$ sudo node registerUser.js
Store path:$HOME/go/src/github.com/hyperledger/fabric-samples/fabcar/hfc-key-store
Successfully loaded admin from persistence
Successfully registered user1 - secret:******
Successfully enrolled member user "user1"
User1 was successfully registered and enrolled and is ready to intreact with the fabric network
[user@localhost fabcar]$
4. query.js 실행
- 자동차 데이터 확인
[user@localhost fabcar]$ sudo node query.js
Store path:$HOME/go/src/github.com/hyperledger/fabric-samples/fabcar/hfc-key-store
Successfully loaded user1 from persistence
Query has completed, checking results
Response is [{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},{"Key":"CAR1", "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"205","owner":"Michel"}},{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]
[user@localhost fabcar]$
* 특정 문자열은 임의로 가렸습니다.
[참고]
- HyperLedger Fabric
http://hyperledger-fabric.readthedocs.io/en/release-1.1/
https://github.com/hyperledger/fabric-samples
---