본문 바로가기

BlockChain Developer/Private Blockchain

[Hyperledger Fabric Tutorials v2.x] 체인코드 배포

[사전준비사항]

"하이퍼레저 패브릭 테스트 네트워크" 포스팅 내용과 동일함.

이번 튜토리얼을 통해 "Peer LifeCycle Chaincode Command"를 이용한 체인코드를 테스트네트워크에 배포하는 방법을 살펴봄.


[네트워크 시작]

#fabric-samples/test-network 경로로 이동
cd fabric-samples/test-network

#이전에 실습을 통해 진행했을 모를 도커 컨테이너와, 아티팩트를 모두 내린다.
./network.sh down

#테스트 네트워크를 시작한다.
./network.sh up createChannel

위 명령어를 실행하면, 'myChannel'이라는 디폴트 이름으로 채널이 생성되고, 두 명의 멤버를 생성한다.(Org1, Org2)

그리고, 피어를 각 Organization에 추가한다.

성공화면

 

 


[Setup Logspout (Optional)]

이번 스텝에서는 logspout 도구를 사용해 스마트 계약의 로그를 모니터링해 체인코드 문제해결을 용이하게 만드는 실습을 진행한다.

필수적 요소는 아니나, 체인코드 문제해결을 위해서 매우 유용하게 활용 됨.

#fabric network 디렉토리로 이동하자.
cd fabric-samples/test-network

#cp 명령어를 활용해 monitordocker.sh파일을 test-network 디렉토리로 복사한다.
cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh .

#monitordocker.sh파일을 실행해 로그를 출력하는 이미지를 실행하는데,
#뒤에 net_test부분에 이름을 우리가 이전 실습에서 진행해서 맞추어준 docker_test로 맞춰준다.
./monitordocker.sh net_test

결과화면

지금은 이렇게 아무런 로그도 없지만, 추후 체인코드를 디플로이 하면서 로그가 뜨게 될 것이다.

이 터미널을 열어두고 다른 터미널을 준비하자.

 


[스마트 컨트렉트 패키지]

스마트 컨트렉트를 "Peer"에 설치하기 전에, 체인코드 관련 디펜던시들을 다운로드 해야한다.

여기에서 golang, javascript, typescript등을 지원하고, 실습은 golang으로 진행한다.

#golang chaincode 패키지로 이동
cd fabric-samples/asset-transfer-basic/chaincode-go

goalng의 디팬던시는 go.mod 파일에 작성되어있으니, 한번 살펴보자.

cat go.mod

go.mod 파일을 살펴봄.

 

#스마트컨트렉트 패키지로 패브릭 계약 API를 가져오는데,
#텍스트 편집기에서 열어 한번 살펴보자.

cd chaincode-go/chaincode

ls

파일을 살펴보면, mocks, smartcontract.go, smartcontract_test.go 파일 세가지를 볼 수 있다.

이 중, smartcontract.go파일을 IDE로 열어서 살펴보자.

 

이번에는 스마트컨트렉트를 위한 디팬던시를 설치하겠다.

#asset-transfer-basic/chaincode-go 디렉토리에서 다음 명령을 수행한다.
#다음 명령어가 실행 성공했다면, vendor폴더에 고 패키지들이 설치되었을 것이다.
GO111MODULE=on go mod vendor

이로써, 체인코드 패키지 설치가 완료되었으며, 이제 test-network폴더로 돌아가서 다른 네트워크 아티팩트들과 패키지화 한 체인코드를 패키지화하자. "Peer CLI"를 활용해 체인코드 패키지를 생성할 수 있다.

#다음 명령을 통해 fabric-samples/bin 폴더에 있는 바이너리 파일들을 CLI Path로 추가하자.
export PATH=${PWD}/../bin:$PATH

#FABRIC_CFG_PATH 설정
export FABRIC_CFG_PATH=$PWD/../config/

#Peer 버전확인
#2.0 이상이면 가능하다.
peer version

#체인코드 패키지 생성하기
peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go/ --lang golang --label basic_1.0

성공화면 in test-network dir

테스트 네트워크 디렉토리에 위와 같이 basic.tar.gz 파일이 생성되었다면, 정상적으로 수행된 것이다.

 

 


[체인코드 패키지를 Peer에 설치]

체인코드 패키지는 트랜잭션을 보증할 모든 피어에 설치해야한다. Org1과 Org2 양쪽 모두 보증을 요구하기에 두 조직 모두에 설치해줘야한다.

 

<피어목록>

  • peer0.org1.example.com
  • peer0.org2.example.com

 

<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 Lifecycle Chaincode 를 설치한다

peer lifecycle chaincode install basic.tar.gz

성공화면

 

<Org2 피어에 설치>

환경변수설정

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를 설치한다.

peer lifecycle chaincode install basic.tar.gz

 

 

위 과정을 통해 Org1, Org2의 각각 피어에 체인코드를 설치가 완료되었으며, 만일 체인코드상 오류가 있다면 위 과정을 수행중에 에러가 날 것이다. 우리가 중간쯤에 옵셔널하게 설정한 로그출력 터미널에서 위 과정을 수행한 로그를 확인할 수 있다.

 

 

 

[체인코드 정의 승인]

위 과정을 통해 체인코드 패키지를 Peer에 설치까지 완료했다.

이후 조직에 대한 체인코드 정의를 승인해야하는 과정이 필요하다.

체인코드 정의에는 Name, Version, 체인코드 보증정책 등이 포함된다.

우리는 현재 채널상에 2개의 조직을 구성중이다.

따라서, Org1, Org2에서 asset-transfer 체인코드를 승인하도록해야한다.

 

만일 Organization에 chain코드를 주입하는 것이 아닌, Peer에 체인코드를 적용한다면, "package ID" 정의가 체인코드에 요구된다.

체인코드의 "pakage ID"를 정의를 살펴보기위해서는 "Peer Lifecycle Chaincode queryinstalled"명령어로 Peer를 쿼리해 찾는다.

 

peer lifecycle chaincode queryinstalled

peer의 packageID 확인하기

패키지 ID는 체인코드 레이블과, 체인코드 바이너리의 해시값이다. 모든 피어는 동일한 "package ID"를 생성해야한다.

체인코드 승인을 위해 패키지 아이디를 활용할 것이므로 환경변수로 저장한다.

#자신의 출력결과 패키지 아이디를 활용할 것.
export CC_PACKAGE_ID=basic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad

 

"Peer CLI"를 Org2 admin으로 동작하도록 환경변수 설정했기에, 체인코드 정의를 Org2로 승인이 가능하다.

관리자 역할이 있는 ID로 체인코드 정의를 승인해야하고, CORE_PEER_MSPCONFIGPATH 변수는 관리자 ID가 포함된 MSP 폴더를 향하고 있어야한다.

체인코드는 "Organization"수준에서 승인되므로, 하나의 피어만 대상으로 명령을 실행하면 된다.

 

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

 

Org1을 관리자로 작동하도록 해보자.

 

환경변수 설정

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051

이제 Org1을 통해 승인해보자.

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

 

이로써 체인코드를 승인하는 과정을 완료했다.

 

모든 채널 구성원은 체인코드를 승인한 뒤, 정의를 커밋 해야한다.

모든 조직은 "Peer"에서 체인코드를 시작하기 위해서, 체인코드 정의를 승인해야한다.

 


[채널에 체인코드 정의 커밋하기]

2/3이상의 조직에서 체인코드 정의를 승인한 뒤, 조직에서 채널에 "체인코드 정의"를 커밋할 수 있다.

대다수 채널 구성원이 체인코드 정의를 승인하면 커밋 트랜잭션이 성공한다. 그리고, 체인코드 정의를 승인한 멤버 목록을 확인할 수 있다.

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json

위 명령을 수행하면 JSON 목록으로 결과를 확인할 수 있다.

Org1, Org2의 승인결과

두 피어 모두 승인한 결과를 확인했으므로, 이제 Commit할 준비가 완료되었다.

#커밋해보자
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --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

커밋 결과화면

 

다음 명령을 통해 체인코드 정의가 채널에 커밋되었는지 확인하자.

peer lifecycle chaincode querycommitted --channelID mychannel --name basic --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

체인코드가 정상정으로 commit되었다면 위와 같이 나옴

 

 


[체인코드 호출 (Invoke the ChainCode)]

체인코드를 승인하고 커밋하는 과정까지 완료했으며 호출하는 과정을 실습해보자.

우리가 커밋한 체인코드는 이제 클라이언트 애플리케이션에서 호출할 준비가 완료되었다.

다음 명령을 통해 "Ledger(원장)"에 초기 자산을 셋팅하자.

status 200 이 나온다면 성공이다.

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --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":"InitLedger","Args":[]}'

 

이제 다음 명령을 통해 query해 체인코드에서 생성한 car 목록을 살펴보자.

peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

출력결과

 

**invoke를 통해 ledger를 write할 수 있었으며, query를 통해 read할 수 있다.

 

 

[스마트 컨트렉트 업그레이드]

체인코드의 시퀀스 버전을 1 -> 2 로 업그레이드 하거나, 체인코드 정책을 변경하거나,

만약 1버전은 Golang으로 배포가 진행되었으나, Javascript로 새로운 시퀀스 버전을 배포한다면 이라는 시나리오다.

#test-network 디렉토리라면 다음 명령어를 통해 javascript 체인코드 패키지를 설치한다.

cd ../asset-transfer-basic/chaincode-javascript
npm install
cd ../../test-network

 

Org1 Admin 을 만들고 체인코드를 설치해보자.

 

환경변수설정

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

새로운 javascript 체인코드를'basic_2.tar.gz'이름으로 설치하자.

peer lifecycle chaincode package basic_2.tar.gz --path ../asset-transfer-basic/chaincode-javascript/ --lang node --label basic_2.0

ls명령어로 확인하면 basic_2.tar.gz 파일이 생성된 것을 확인 할 수 있을 것이다.

 

Org1 Peer에 체인코드를 설치하고, 패키지 아이디를 확인해보자.

#basic_2.tar.gz를 활용한 체인코드 패키지를 인스톨
peer lifecycle chaincode install basic_2.tar.gz

#basic_2.tar.gz 패키지id 확인
peer lifecycle chaincode queryinstalled

 

Basic_2.0 package Id를 환경변수로 설정한다.

#자신의 패키지아이디를 확인하고 설정할 것.
export NEW_CC_PACKAGE_ID=basic_2.0:5756b51eeafd6dbb96a9cea71bbba2aa1bd421c2b293c91594c4b6676c944c69

 

Org1 Peer로 방금 생성한 새로운 체인코드를 승인하자

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 2.0 --package-id $NEW_CC_PACKAGE_ID --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

 

이제 체인코드 업그레이드를 위해 Org2 관리자로 접근해 새 체인코드 정의를 승인해야한다.

#환경변수설정

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_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 Org2에 체인코드 설치
peer lifecycle chaincode install basic_2.tar.gz

#Peer Org2에서 승인
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 2.0 --package-id $NEW_CC_PACKAGE_ID --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

 

체인코드 정의를 Org1, 2에서 정상적으로 승인되었는지 확인한다.

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 2.0 --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json

 

Org2는 다음 명령을 통해 체인코드를 업그레이드한다. 새 체인코드가 정의되면 새 체인코드가 즉시 시작된다.

peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name basic --version 2.0 --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --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

 

docker를 통해 새 체인코드가 정상적으로 배포되었는지 확인해보자.

docker ps

basic2.0으로 되었는지 확인

 

이제 새 원장에다가, 정보를 추가하고, 목록을 출력해보자.

#invoke로 새 원장에 데이터를 추가함.

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --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":"CreateAsset","Args":["asset8","blue","16","Kelley","750"]}'


#query 명령어를 통해 모든 자동차목록을 출력한다.

peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

결과화면 invoke & query

 


[실습종료]

Logspout 도구 제거

docker stop logspout
docker rm logspout

test-network 디렉토리에서 다음 명령으로 테스트 네트워크 종료.

./network.sh down