Hyperledger Fabric 튜토리얼(3) - 네트워크 시작하기
지난 포스팅에서 예고한 대로 오늘은 채널 추가 이후 네트워크 시작 방법을 알아볼 것이다. 이번 포스팅 또한 공식 사이트의 네트워크 시작하기를 참고로 작성함을 알린다.
네트워크 시작
스크립트를 활용하여 네트워크를 spin up 해 보자. docker-compose 파일은 다운해 둔 이미지를 참조할 것이며, 부트스트랩은 이전에 생성된 genesis.block
를 사용하여 orderer를 보호할 것이다.
먼저 네트워크를 시작하자.
1 | docker-compose -f docker-compose-cli.yaml up -d |
네트워크의 실시간 로그를 보고 싶다면 -d
플래그를 제외하면 된다. 로그 스트림을 보기 위해서는 터미널을 하나 더 열어야 한다.
CLI 컨테이너는 1000초 동안 유휴 상태를 유지한다. 만약 CLI가 사라졌다면 다음의 명령으로 다시 켤 수 있다.
1 | docker start cli |
환경 변수
실습이 목표인 분들은 환경 변수 파트는 진행하지 않아도 된다. 넘겨도 실습에는 아무 지장 없다.
peer0.org1.example.com
에 관한 CLI 명령이 동작하기 위해서는 아래 네 가지 환경 변수로 명령을 시작해야 한다.
1 | Environment variables for PEER0 |
변수 peer0.org1.example.com
는 CLI 컨테이너로 구워지므로(baked) 굳이 전달하지 않아도 잘 동작한다. 그러나 다른 peer나 orderer에게 값을 전달하고 싶다면 docker-compose-base.yaml
의 경로를 살펴보고 적절하게 수정해야 할 것이다.
채널 생성 및 가입
이전 포스팅인 채널 구성 트랜잭션 만들기에서 configtxgen
tool을 이용하여 트랜잭션을 생성했다. 이 프로세스를 반복하여 configtxgen
도구에 전달한 것과 동일하거나 다른 프로필을 사용하여 추가 채널 구성 트랜잭션을 생성할 수 있다. 그 다음 이 섹션에 정의된 다른 프로세스를 반복하면 된다.
일단 다음 명령으로 CLI 컨테이너에 들어가자.
1 | docker exec -it cli bash |
성공했다면 다음의 메시지가 나올 것이다.
1 | root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer# |
다음으로 생성한 채널 구성 트랜잭션 아티팩트(channel.tx
)를 채널 생성 요청의 일부로 orderer에게 전달한다.
이번엔 채널 구성 트랜잭션 생성 섹션(채널 구성 트랜잭션 생성 섹션이라고 함)에서 생성한 채널 구성 트랜잭션 아티팩트를 채널 생성 요청의 한 파트로 주문자에게 전달한다.
-c
플래그로는 채널 구성 트랜잭션의 이름을, -f
플래그로는 채널 구성 트랜잭션을 지정할 수 있다. 이 경우, channel.tx
대신 다른 이름으로 마운트 가능하다.
아래의 명령을 실행하여 CHANNEL_NAME
을 매번 전달할 필요가 없도록 CLI 컨테이너 내의 환경 변수를 설정해 보자.
1 | export CHANNEL_NAME=mychannel |
이 명령은 채널에 참여에 사용되는 초기 블록인<channel-ID.block>
을 반환한다. 채널 이름을 바꾸지 않았다면 기본 값인 mychannel.block
을 반환한다.
이제 peer0.org2.example.com
에 가입하자.
1 | 기본적으로는 'peer0.org1.example.com'에만 가입된다. |
환경 변수 섹션에서 소개한 네 가지 변수를 적절히 변경하면 필요에 따라 다른 peer가 채널에 참여하도록 만들 수 있다.
채널의 anchor peer 정의를 업데이트하는 것만으로도 모든 peer를 peer0.org2.example.com
에 가입시킬 수 있다. CLI 컨테이너에 포함된 기본 환경 변수를 제정의하는 명령은 다음과 같다.
1 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer channel join -b mychannel.block |
전체 문자열을 전달하는 대신 이러한 환경 변수를 개별적으로 설정할 수 있다. 설정 완료 후 peer channel join
명령을 다시 실행하기만 하면 CLI컨테이너가 peer0.org2.example.com
대신 동작한다.
anchor peer 업데이트
채널을 업데이트할 때에는 다음의 명령을 사용하면 된다. 해당 채널의 genesis block 상단에 정보를 추가하는 형식이다.
채널 정의를 업데이트해서 Org1의 anchor peer(peer0.org1.example.com
)를 정의하자.
1 | peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --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 |
마찬가지로, 채널 정의를 업데이트하여 Org2에 대한 앵커 피어(peer0.org2.example.com
)를 정의한다. Org2 peer에 관한 명령(peer channel join
)의 특성상, 적절한 환경 변수를 사용해야 한다.
1 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --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 |
체인 코드 설치 및 인스턴스화
Go 또는 Node.js로 작성된 샘플 체인 코드를 네 개의 피어 노드 중 하나에 설치해 보자.
Golang
1 | this installs the Go chaincode |
Node.js
1 | this installs the Node.js chaincode |
그 다음 채널에서 체인 코드를 인스턴스화한다. 그러면 채널의 체인 코드가 초기화되고, 체인 코드 승인 정책이 실행되며, 대상 peer에 대한 체인 노드 컨테이너가 실행된다.
Golang
1 | be sure to replace the $CHANNEL_NAME environment variable if you have not exported it |
Node.js
1 | be sure to replace the $CHANNEL_NAME environment variable if you have not exported it |
Query
chaincode가 제대로 설치되고 상태 DB가 채워지는지 확인하기 위해 a
의 값을 쿼리로 불러 보자.
1 | be sure to set the -C and -n flags appropriately |
Invoke
이제 10
을 a
에서 b
로 이동시키자. 이 트랜잭션은 새 블록을 자르고 상태 DB를 업데이트한다.
1 | be sure to set the -C and -n flags appropriately |
Query
이전 호출이 제대로 실행되었는지 확인하자. 값이 100인 키 A를 초기화하고 이전 호출을 통해 10을 옮겼다. 따라서 아래 쿼리의 실행 결과는 90이 나와야 한다.
1 | be sure to set the -C and -n flags appropriately |
결과는 다음과 같다
1 | Query Result: 90 |
트랜잭션은 어떻게 볼 수 있나요?
CLI 도커 컨테이너의 로그를 확인하면 된다.
1 | docker logs -f cli |
다음과 비슷한 로그가 출력될 것이다.
1 | 2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP |
체인 코드 로그는 어떻게 확인하나요?
개별 체인 컨테이너를 검사하여 각 컨테이너에 대해 실행된 별도의 트랜잭션을 확인한다.
1 | docker logs dev-peer0.org2.example.com-mycc-1.0 |