Hyperledger 1.4.1 in NCIA Education

Introducing Hyperledger Fabric 1.4.1 !!

Hyperledger is space to learn Blockchain with GO Language.

Contents

Table of Contents

NoTitleRemarks
0환경설정Hyperledger 환경셋팅
1교육과정수업게시판
2실습실습

Install

  • Public Cloud(예:AWS, Ubuntu 16.04.6 LTS)에 구축 時, 진행해야 할일

1. Curl, Docker 설치

  • apt : Ubuntu를 포함한 Debian 계열의 리눅스에서 쓰이는 패키지 관리 명령어 도구, APT(Advanced Packaging Tool)
sudo apt-get install <패키지 이름>
  • apt-get은 인덱스를 가지고 있는데 이 인덱스는 /etc/apt/sources.list 에 있으며 이곳에서 패키지의 저장소 정보를 얻게 된다.
  • curl 은 command line 용 data transfer tool 이다. download/upload 모두 가능하며 HTTP/HTTPS/FTP/LDAP/SCP/TELNET/SMTP/POP3 등 주요한 프로토콜을 지원하며 Linux/Unix 계열 및 Windows 등 주요한 OS 에서 구동
* sudo apt-get install curl     # url에서 copy 해옴, 보통 설치되어 있음
  • sudo apt install docker.io
  • sudo apt install docker-compose
  • sudo apt install software-properties-common

  • 위 docker 설치방법 취소하고, docker ce 설치

Community Edition (CE) : 개발자나 작은 팀들에게 이상적인 버전이며 무료로 사용할 수 있습니다

# 준비
$ sudo apt-get remove docker docker-engine docker.io  
$ sudo apt-get update && sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
# 패키지 저장소 추가
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
# 도커 패키지 검색
$ sudo apt-get update && sudo apt-cache search docker-ce
# 도커 CE 설치
$ sudo apt-get update && sudo apt-get install docker-ce
* sudo usermod -aG docker $USER # 현재 접속중인 사용자에게 권한주기
# 권한을 주어도 실행 오류가 발생하면, 로그아웃하고 다시 터미널 접속한다.

2. Node.js 설치

  • sudo apt-get upgrade : 설치되어 있는 패키지를 모두 새버전으로 업그레이드
sudo apt-get upgrade
  • curl -o : curl 은 remote 에서 받아온 데이타를 기본적으로는 콘솔에 출력한다. -o 옵션 뒤에 FILE 을 적어주면 해당 FILE 로 저장한다.
  • curl -s : –silent 진행 내역이나 메시지등을 출력하지 않는다. -o 옵션으로 remote data 도 /dev/null 로 보내면 결과물도 출력되지 않는다
  • curl -L : –location 서버에서 HTTP 301 이나 HTTP 302 응답이 왔을 경우 redirection URL 로 따라간다.
  • nvm : NVM은 여러 버전의 Node.js를 설치하고 관리하고 사용할 수 있게 해주는 bash 스크립트 프로그램, NVM (Node version manager)
* sudo apt-get update
* sudo apt-get install build-essential libssl-dev
* curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh -o install_nvm.sh
* bash install_nvm.sh
* source ~/.profile
* nvm install v8.11.1

3. Go 언어 설치

* curl -O https://storage.googleapis.com/golang/go1.11.2.linux-amd64.tar.gz
* tar -xvf go1.11.2.linux-amd64.tar.gz
* sudo mv go /usr/local
* sudo ln -s /usr/local/go/bin/go /usr/local/bin/go
* vi ~/.profile
* export GOPATH=$HOME/go
* export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
* source ~/.profile

4. Python, Git 설치

  • tree : 폴더의 하위 구조를 계층적으로 표시해 주는 유틸리티
* sudo apt install -y python
* sudo apt install -y git
* sudo apt install tree # tree 는 폴더의 하위 구조를 계층적으로 표시해 주는 유틸리티

5. Fabric Sample 설치, Docker Image 설치

# curl -sSL http://bit.ly/2ysbOFE | bash -s -- <fabric_version> <fabric-ca_version> <thirdparty_version>
* sudo curl -sSL http://bit.ly/2ysbOFE | bash -s -- 1.4.1 1.4.1 0.4.15  # 1.4.1 을 명시하지 않으면 가장 최신 버전을 가져옴. 안될때 sudo bash -s
* vi ~/.profile
* export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin:~/fabric-samples/bin
* source ~/.profile

Curriculum

Table of Curriculum

NoTitleEducational InstitutionLecturerDayRemarks
1하이퍼레저 개론NIPA김기형교수님Sep 2 2019fabcar
2하이퍼레저 개론 및 패브릭의 이해NIPA김재훈교수Sep 3 2019first network
3DApp개발NIPA최광훈박사Sep 4 2019basic network
4프라이빗블록체인 활용NIPA김재훈교수Sep 5 2019commpercial paper
5프라이빗 데이터의 활용과 블록체인의 미래NIPA신운섭박사Sep 6 2019Private Data

Practice

0. Docker 사용법

docker ps -a                             # 사용중인 docker
docker rm -f $(docker ps -aq)            # 사용중인 docker 지우기   -q는 id만 가져오겠다.
docker images dev-*                      # 사용중인 docker image
docker rmi -f $(docker images dev-* -q)  # 사용중인 docker image 지우기
docker network ls                        # 사용중인 network 확인하기  3개는 기본으로 떠 있어야 한다.
docker network prune                     # 사용중인 Network 지우기

1. fabcar

1.1 Basic Network 가동

  • fabcar를 위한 basic_network 가동
$ cd ~/fabric-samples/basic_network
$ ./start.sh
$ ./stop.sh
1.1.1 Application을 통해서 fabcar 체인코드를 접근
  • basic network에 peer를 구성하고
    1. Create the channel -c mychannel
    1. Join peer0.org1.example.com to the channel
$ cd ~/fabric-samples/fabcar
$ ./startFabric.sh  

1.1.2 Node JS를 통해서 fabcar 접근

$ cd ~/fabric-samples/fabcar/javascript
  • package.json은 프로젝트에 대한 명세라고 할 수 있다. 해당 프로젝트의 이름, 버전, 사용되는 모듈 등의 스펙이 정해져 있으며, 이 package.json을 통해 모듈 의존성 모듈 관리도 진행할 수 있다.
  • 만약 어떤 오픈 소스를 다운 받을 때 이 package.json만 있다면 해당 오픈 소스가 의존하고 있는 모듈이 어떤 것인지. 그리고 그 모듈들을 npm install로 한 번에 설치할 수 있다.
# package.json 일부내용
    "dependencies": {
        "fabric-ca-client": "~1.4.0",
        "fabric-network": "~1.4.0"
    },
$ ~/fabric-samples/fabcar/javascript/npm install              # Node js 관련 파일 설치 package.json
$ ~/fabric-samples/fabcar/javascript/tree wallet
$ ~/fabric-samples/fabcar/javascript/node enrollAdmin.js      # node 라는 명령어로.. node.js 파일 실행시킴
$ ~/fabric-samples/fabcar/javascript/tree wallet
$ ~/fabric-samples/fabcar/javascript/node registerUser.js
$ ~/fabric-samples/fabcar/javascript/tree wallet
$ ~/fabric-samples/fabcar/javascript/node query.js            # 블록체인에서 쿼리로 조회해옴

1.2. Couch DB 조회

  • fabcar를 위한 Couch DB조회
  • VirtualBox에서 사용시에는 PortFowarding 작업 필요
localhost:5984/_utils

1.3. 사용중인 것 지우기

$ cd ~/fabric-samples/basic_network
$ ./teardown.sh                          # docker 까지 모두 stop

1.4. DApp Fabcar

  • npm의 경우는 Node Package Manager이기 때문에 node.js를 설치하면 같이 설치된다.
  • git clone [url] : Git 저장소를 복사하고 싶을 때 git clone 명령을 사용합니다
cd fabcar
cd javascript
git clone https://github.com/saarc/fabric-front-end.git
cd fabric-front-end
npm install
cp -R ../wallet ./    # Key 복사 필요  
node server.js

2. Commercial paper tutorial

  • Create Network
$ cd fabric-samples/basic-network
$ ./start.sh
$ docker network inspect net_basic
  • Working as MagnetoCorp
(magnetocorp admin)$ cd commercial-paper/organization/magnetocorp/configuration/cli/
(magnetocorp admin)$ ./monitordocker.sh net_basic
  • 새로운 터미널을 띄워서
(magnetocorp admin)$ cd commercial-paper/organization/magnetocorp/configuration/cli/
(magnetocorp admin)$ docker-compose -f docker-compose.yml up -d cliMagnetoCorp
  • Smart contract
(magnetocorp developer)$ cd commercial-paper/organization/magnetocorp/contract
(magnetocorp developer)$ code .
  • Install contract
(magnetocorp admin)$ docker exec cliMagnetoCorp peer chaincode install -n papercontract -v 0 -p /opt/gopath/src/github.com/contract -l node
  • Instantiate contract
(magnetocorp admin)$ docker exec cliMagnetoCorp peer chaincode instantiate -n papercontract -v 0 -l node -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' -C mychannel -P "AND ('Org1MSP.member')"
(magnetocorp admin)$ docker ps
  • Application structure
    • addToWallet.js is the program that Isabella is going to use to load her identity into her wallet.
(magnetocorp user)$ cd commercial-paper/organization/magnetocorp/application/
(magnetocorp user)$ cd commercial-paper/organization/magnetocorp/application
 npm install
(isabella)$ node addToWallet.js
(isabella)$ tree ../identity/user/isabella/wallet/
  • Issue application
node issue.js
  • Working as DigiBank
(digibank admin)$ cd commercial-paper/organization/digibank/configuration/cli/
(digibank admin)$ docker-compose -f docker-compose.yml up -d cliDigiBank
  • Digibank applications
(balaji)$ cd commercial-paper/organization/digibank/application/
(balaji)$ code buy.js
  • Run as DigiBank
(digibank admin)$ cd commercial-paper/organization/digibank/application/
(digibank admin)$ npm install
(balaji)$ node addToWallet.js
  • Buy application
(balaji)$ node buy.js
(balaji)$ node redeem.js

3. Basic Network + Node.js + Express + Ejs

3.1 내 첫 chaincode 만들기( 프리랜서 IT 인력 마켓플레이스 )

$ cd fabric-samples/chaincode
$ cp -R sacc jobMP
$ cd jobMP
$ code .         # visudaul studio에서 mycc.go를 연다. Oracle Virtual Machine에서 가능
  • Visual Studio Code

Ctrl+~ # visual studio에서 터미널 여는 법

  • Go Third Party Package

go get 패키지명 명령 : 서드 파티 패키지를 내려 받고 설치할수 있다. go get -u 패키지명과 같이 -u 옵션을 주면 최신 버전 패키지를 내려받아서 다시 설치한다.

$fabric-samples/chaincode/jobMP/go get -u "github.com/hyperledger/fabric/core/chaincode/shim"
$fabric-samples/chaincode/jobMP/go get -u "github.com/hyperledger/fabric/protos/peer"
$fabric-samples/chaincode/jobMP/go build       # go compile 하는 법
$fabric-samples/chaincode/jobMP/go version
  • basic-network 가동
$ cd ../../basic-network/
$ ./start.sh
  • CLI 실행(CLI를 통해서 chaincode 등록 하려고 함)
* Docker compose : Docker 어플리케이션을 정의하고 멀티 컨테이너 어플리케이션을 실행시키기 위한 도구
* 여러개의 컨테이너를 1번의 명령으로 실행 시킬 수 있다. 
* docker exec : 외부에서 컨테이너에 특정 명령을 줄수 있습니다.  
` docker exec [OPTIONS] CONTAINER COMMAND [ARG...] `
$ docker-compose -f docker-compose.yml up -d cli
$ docker exec -it cli bash
  • Chaincode Install → Instantiate
# install
root@2f9f2dd49c99:/opt/gopath/src/github.com/hyperledger/fabric/peer#peer chaincode install -n jobMP -v 1 -p github.com/jobMP
root@2f9f2dd49c99:/opt/gopath/src/github.com/hyperledger/fabric/peer#peer chaincode list --installed # 등록된 chaincode 확인
# instantiate
peer chaincode instantiate -n jobMP -v 1 -C mychannel -c '{"Args":["a","100"]}' -P 'OR ("Org1MSP.member")'
peer chaincode list --instantiated -C mychannel # 어느 channel에 instantiated 되었는지 확인
# 데이터를 만들어 봄 invoke
peer chaincode invoke -n jobMP -C mychannel -c '{"Args":["set","b","200"]}'  # peer chaincode invoke 명령어 Invoke호출
# Data를 조회함
peer chaincode query -n jobMP -C mychannel -c '{"Args":["get","a"]}'         # peer chaincode query 명령어 Data 호출
  • WebServer
~/fabric-samples/fabcar$ cd javascript
~/fabric-samples/fabcar/javascript$ cp package.json *.js ../application
cd ../application/
node enrollAdmin.js
node registerUser.js
node invoke.js
node query.js
cd fabcar
cd javascript
git clone https://github.com/saarc/fabric-front-end.git
cd fabric-front-end
npm install
cp -R ../wallet ./    # Key 복사 필요  
node server.js

ubuntu@ip-172-31-28-94:~/fabric-samples$ mkdir jobMP
~/fabric-samples/fabcar$ cd javascript
cp package.json *.js ../../jobMP
cp -R ../../fabcar/javascript/wallet ./

3. Private Data

  • Private는 orderer를 사용하지 않고 private를 직접 Peer한테 전송함
$ ~/fabric-samples/chaincode/marbles02_private/code collections_config.json
[
 {
   "name": "collectionMarbles",
   "policy": "OR('Org1MSP.member', 'Org2MSP.member')",
   "requiredPeerCount": 0,
   "maxPeerCount": 3,
   "blockToLive":1000000,  # 0 나두면 private data를 삭제 하지 않겠다.
   "memberOnlyRead": true
},
 {
   "name": "collectionMarblePrivateDetails",
   "policy": "OR('Org1MSP.member')",
   "requiredPeerCount": 0,
   "maxPeerCount": 3,       # Private는 orderer를 사용하지 않고 private를 직접 Peer한테 전송함
   "blockToLive":3,         # 몇개의 block이 생성된  삭제 가능 할수 있다. ex) 네트웍크 timeToLive
   "memberOnlyRead": true   # 멤버만 읽을수 있도록 조치함.
 }
]
  • First Network 가동
./byfn.sh up -c mychannel -s couchdb  # -s statedb에 대한 option
docker exec -it cli bash # -it keyboard를 통해서 입력을 받겠다.  환경변수 하면서..... 다른 peer도 선해

# 체인코드 설치   환경변수 하면서..... 다른 peer도 선해
root@260f8b66d769:/opt/gopath/src/github.com/hyperledger/fabric/peer#

export CORE_PEER_LOCALMSPID=Org2MSP

export PEER0_ORG2_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp

export CORE_PEER_ADDRESS=peer0.org2.example.com:9051
  • chaincode Instantiate
export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C mychannel -n marblesp -v 1.0 -c '{"Args":["init"]}' -P "OR('Org1MSP.member','Org2MSP.member')" --collections-config  $GOPATH/src/github.com/chaincode/marbles02_private/collections_config.json   # --collections-config    collections_config.json파일을 사용옵션
  • Cli org1로 연결…private data 쓰기 위해
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

export CORE_PEER_LOCALMSPID=Org1MSP

export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

export PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt



export MARBLE=$(echo -n "{\"name\":\"marble1\",\"color\":\"blue\",\"size\":35,\"owner\":\"tom\",\"price\":99}" | base64 | tr -d \\n)

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n marblesp -c '{"Args":["initMarble"]}'  --transient "{\"marble\":\"$MARBLE\"}"
  • Read marble
peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarble","marble1"]}'
  • Read org1에서만 저장 가능한 데이터
peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarblePrivateDetails","marble1"]}'
  • couchDB 접근 # docker-composer.yaml couchdb id/pw 입력 받께끔 처리 해야 함. fist-network는 이름이 다름

Click mychannel_marblesp$$pcollection$marbles
Click mychannel_marblesp$$pcollection$marble$private$details
  • Private 권한확인
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

export CORE_PEER_LOCALMSPID=Org1MSP

export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

export PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarble","marble1"]}'
peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarblePrivateDetails","marble1"]}'


# org2에서..가져올때
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051

export CORE_PEER_LOCALMSPID=Org2MSP

export PEER0_ORG2_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp



peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarble","marble1"]}'

peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarblePrivateDetails","marble1"]}'
  • 자동삭제 기능
# org1으로 새로운 block을 생성하기위해
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

export CORE_PEER_LOCALMSPID=Org1MSP

export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

export PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

  • docker를 이용해서 로그 확인
bstudent@saarc-VirtualBox$ docker logs peer0.org1.example.com 2>&1 | grep -i -a -E 'private|pvt|privdata'
  • marble 추가 생성
export MARBLE=$(echo -n "{\"name\":\"marble2\",\"color\":\"blue\",\"size\":35,\"owner\":\"tom\",\"price\":99}" | base64 | tr -d \\n)

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n marblesp -c '{"Args":["initMarble"]}' --transient "{\"marble\":\"$MARBLE\"}" 

  • owner 정보 변경(block 생성, 3번)
export MARBLE_OWNER=$(echo -n "{\"name\":\"marble2\",\"owner\":\"tom\"}" | base64 | tr -d \\n)

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n marblesp -c '{"Args":["transferMarble"]}' --transient "{\"marble_owner\":\"$MARBLE_OWNER\"}"

export MARBLE_OWNER=$(echo -n "{\"name\":\"marble2\",\"owner\":\"joe\"}" | base64 | tr -d \\n)

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n marblesp -c '{"Args":["transferMarble"]}' --transient "{\"marble_owner\":\"$MARBLE_OWNER\"}"

export MARBLE_OWNER=$(echo -n "{\"name\":\"marble2\",\"owner\":\"jerry\"}" | base64 | tr -d \\n)

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n marblesp -c '{"Args":["transferMarble"]}' --transient "{\"marble_owner\":\"$MARBLE_OWNER\"}"

  • 확인 Private Data 삭제
$ peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarblePrivateDetails","marble1"]}'
결과 : Error: endorsement failure during query. response: status:500 message:"{\"Error\":\"Marble private details does not exist: marble1\"}"
couchdb에서 삭제 가능

Reference