fabric-logo

Hyperledger Fabric Add New Org to Network- eyfn 뜯어보기

이번 포스팅에서는 네트워크 확장과 관련된 eyfn 튜토리얼에 대해서 살펴보려고한다. 이전 byfn 튜토리얼 뜯어보기 포스팅에서는 최초로 organization들이 모여서 네트워크를 구성하는 것에 대해서 살펴보았다면 eyfn에서는 이미 구성된 네트워크에 새로운 organization을 추가하기 위해서 어떻게 하는지를 알려준다. 그래서 이번 포스팅에서는 Hyperledger Fabric 네트워크에서 어떻게 새로운 organization을 추가할 수 있는지를 위주로 작성해보려고 한다.

Generate Crypto Config

eyfn.sh 를 살펴보면 up 명령어를 사용해서 시작했을 때 엔트리 포인트가 networkUp 함수인 것을 알 수 있다. networkUp 에서 하는 일은 먼저 다음과 같다:

generateCerts

First-network 튜토리얼에서는 CA를 따로 사용하지 않으므로 crypto material을 생성하기 위해서 cryptogen 을 사용한다. 다음에 CA를 이용해서 어떻게 인증서를 발급받고 그것을 이용하는지 살펴보도록 하겠다.

org3-crypto.yaml에 명시되어있는 TemplateUser 만큼 인증서를 생성한다. generateCerts 를 마치고 나면 org3-artifacts 디렉토리에 crypto-config가 생긴다.

generateChannelArtifacts

이 함수에서는 configtxgen 툴을 사용하게되는데 기본적으로 configtxgen 은 Fabric 네트워크 channel config와 관련된 파일들을 생성할 수 있게 도와준다. 그리고 configtxgen 이 작동하기 위해선 사용자가 자신이 어떻게 config를 구성할 것인지 먼저 포맷에 맞게 yaml파일을 작성해야하는데 configtxgen 은 이 yaml 파일을 환경변수 FABRIC_CFG_PATH 에서 찾는다.

eyfn에서 org3과 관련된 네트워크 config yaml 파일이 org3-artifacts 디렉토리에 config.yaml로 있기 때문에 해당 경로에 맞게 환경변수를 설정해준다.

다음으로 configtxgen -printOrg 를 이용해서 config.yaml에 Org3MSP에 해당하는 organization의 설정을 org3.json으로 쓴다. 나중에 이 org3.json 을 이용해서 기존에 존재하던 mychannel의 config를 수정하고 org3이 mychannel에 들어갈 수 있도록 할 것이다.

마지막으로 orderer의 MSP를 org3의 crypto crypto-config 로 복사를 하는데 이는 나중에 org3에서 ordering service를 이용하기 위해서이다.

Create Updated ConfigTx

이제 네트워크 밖에서 할 수 있는 사전작업은 모두 마쳤다. 다음으로 해야할 일은 mychannel의 config를 수정하고 mychannel에 속해있는 organization들에게 새로운 organization인 org3이 들어올 수 있도록 허가를 받아야한다. Hyperledger Fabric이 private chain이고 PoA이기 때문에 이와 같이 채널의 기존 그룹으로부터 허가를 받아야 들어올 수 있다.

그렇기 때문에 이제 위의 명령어처럼 도커로 직접 들어가서 작업하게된다. (여기서 조금 악랄한 부분이있다.. 좀 쉽게 만들 수 있었을 거 같은데..)

step1org3.sh에서 위와 같이 먼저 필요한 모듈들 임포트하고 jq 패키지를 설치한다.

fetchChannelConfig

먼저 mychannel 채널의 config를 수정하기 위해서 채널의 config block을 가져와서 그 중에서도 config를 담고 있는 부분만 가져온다.

채널의 configuration block을 가져오는 부분이다. 현재 우리는 cli 컨테이너에 들어와있고 네트워크에 떠있는 orderer MSP로 동작하기 위해서 setOrdererGlobals 를 사용했다. 그리고 peer channel을 통해서 mychannel의 config block을 가져온다. 그리고 tls를 사용한다면 위와 같이 orderer의 tls certification도 같이 제출해야한다.

위의 명령을 실행시키고 현재 디렉토리를 확인해보면 config_block.pb 의 이름으로 config block이 존재하는 것을 확인할 수 있다.

configtxlator는 기본적으로 json또는 protobuf 형식으로 되어있는 fabric transaction을 서로 반대의 형식으로 변환시켜준다. 또는 서로 다른 config transaction의 델타를 구하는데에도 사용된다. 이 두 번째 기능은 좀 더 나중에 사용된다.

지금은 먼저 configtxlator를 이용해서 protobuf 형태로 되어있는 config block을 JSON 형태로 바꾼다. 그리고 JSON 파싱을 도와주는 jq를 이용해서 config 값을 담고 있는 부분만 파싱해서 ${OUTPUT}에 저장한다.

위의 명령을 실행시키고 현재 디렉토리를 확인해보면 config.json 이 생성된 것을 확인할 수 있는데 vim이나 more을 통해서 확인해보면 org1, org2의 설정이 담겨있는 것을 확인할 수 있다.

Append the new organization to current configuration

이전 단계에서 현재 채널의 configuration을 가져왔으니 이제 generateChannelArtifacts 단계에서 만든 org3 configuration 파일인 org3.json 을 여기에 추가해야한다.

이 단계에서도 이전에 사용한 jq를 사용해서 JSON 파일을 수정하게된다. 위의 jq 명령어를 간단히 설명하면 우선 jq -s '<JSON_FILE_1> * <JSON_FILE_2>' 은 두 개의 JSON 파일의 합집합을 만들게 된다. 그래서 두 개의 JSON 파일을 비교해서 서로에게 없는 부분은 추가하게된다. 여기서 <JSON_FILE_1>.[0] 이 되고 <JSON_FILE_2>{"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}} 이 된다. 그리고 [0], [1] 은 각각 config.json./channel-artifacts/org3.json 으로 치환된다.

그래서 결과적으로 기존의 configuration에 channel_group.groups.Application.groups.Org3MSP 를 키로 가지고 org3.json 을 벨류로 가지는 필드를 추가하게된다.

createConfigUpdate

여기까지 우리가 생성한 파일을 정리해보면 다음과 같다.

  • config_block.pb: 현재 채널의 configuration block

  • config.json: 현재 채널의 configuration block에서 추출한 channel configuration tx

  • modified_config.json: org3 organization의 정의를 추가한 channel configuration tx

이제 createConfigUpdate 에서 하는 일은 (1) 먼저 config.jsonmodified_config.json 의 차이를 가지는 JSON 형태의 transaction을 만들고 (2) 두 번째로는 이 transaction을 ordering service에 제출하기 위해서 envelope 형태로 만들게 된다. 이 다음 단계에서 우리는 현재 mychannel에 속해있는 organization들에게 서명을 받게된다.

config.jsonmodified_config.json 의 차이를 가지는 transaction을 만들기 위해서 먼저 각각의 JSON 파일들을 protobuf 형태로 바꾼다. 그리고 각각은 original_config.pb, modified_config.pb 의 이름을 가지게된다.

위의 스크립트는 이전에 말한 과정을 풀어낸 것이다. 먼저 org3을 추가하기 이전과 추가한 후의 차이를 가지는 transaction을 configtxlator compute_update 를 통해서 구한 뒤 configtxlator proto_decode를 통해서 JSON 형식으로 바꾼다. 다음으로 transaction을 ordering service에 제출하기 위해서 envelope 형태로 바꾸고 configtxlator proto_encode 를 통해서 protobuf 형식으로 바꾼다. 위 스크립트를 실행시키면 현재 디렉토리에 결과물인 org3_update_in_envelope.pb가 생성된다.

이제 남은 과정은 org3_update_in_envelope.pb 에 mychannel에 속한 organization들에게 서명을 받은 뒤 ordering service에 제출하면 새로운 org3가 mychannel에 들어올 준비가 끝난다.

Signing to config transaction

setGlobals 를 통해서 MSP를 바꾼다. 같은 cli 컨테이너 안이지만 MSP를 바꿈으로써 다른 노드(peer, orderer)의 역할을 할 수 있다. 먼저 setGlobals 0 1 을 통해서 org1이 이전 단계에서 만든 envelope에 peer channel signconfigtx 를 통해서 서명을 한다. 그리고 setGlobals 0 2 를 통해서 org2 MSP로 바꾸고 org1이 서명한 envelope을 ordering service에 제출하게 된다. 이 때 tls를 사용한다면 위의 명령어처럼 orderer의 ca certificate도 --cafile 옵션에 넣어서 같이 제출해야한다.

유효한 envelope을 만들었다면 ordering service에 envelope을 제출했을 때 위와 같이 성공했다는 메세지가 나온다.

Join Org3’s peers to network

이제 eyfn의 핵심적인 내용은 거의 마무리되었다. 위의 과정이 엄청 복잡하지만 잘 생각해보면 결국에는 Org3의 정의를 담은 transaction을 만들고 orderer에게 제출하기 위한 envelope을 만들었다. 그래서 이제 mychannel 채널 configuration에 Org3이 등록되었기 때문에 org3이 직접 mychannel에 join 요청을 보낼 수 있다.

그래서 이제 Org3cli 컨테이너로 들어간다. Hyperledger Fabric에서 채널로 들어가기 위해서는 해당 채널의 genesis block을 이용해야하다.

그래서 위와 같이 mychannel의 genesis block을 가져오기 위해서 orderer에게 요청을 한다. 이 때도 마찬가지로 tls를 사용한다면 orderer의 ca certificate도 같이 제출하여야한다. 위의 명령어를 실행하면 현재 디렉토리에 mychannel.block 이 생성된다. 이것이 mychannel의 genesis block이다.

이제 setGlobals 로 MSP를 바꿔가면서 peer channel join 명령어를 실행시킨다. 그리고 실제로 피어들이 추가됐는지 확인하기 위해서 다음과 같은 방법을 쓸 수 있다.

위와 같이 setGlobals로 확인하고 싶은 피어의 MSP를 설정한 뒤 peer channel list 로 현재 피어가 들어가 있는 채널을 확인해볼 수 있다.

Conclusion

이번 포스팅에서는 어떻게하면 Hyperledger Fabric 네트워크에 새로운 organization을 추가할 수 있는지에 대해서 eyfn 튜토리얼을 통해서 살펴보았다. Organization을 추가하기 위한 config transaction을 만드는 부분이 조금 복잡했다. 첫 번째로 기존의 channel config transaction에서 새로운 organization의 config를 추가했다. 두 번째로는 이전 것과 새로운 것의 델타를 이용해 config envelope을 만들었다. 마지막으로는 현재 채널에 존재하고 있는 organization들에게 서명을 받은 뒤 ordering service에 제출하였다. Hyperledger Fabric은 이와같이 프라이빗 체인이고 PoA이기 때문에 기존의 네트워크에서 허가를 해주어야 새로운 노드가 참여할 수 있다.

다음 포스팅에서는 생각해둔 Hyperledger Fabric와 관련된 튜토리얼이 있는데 그것에 대해서 작성해볼 예정이다.

Hyperledger Fabric Configure Network – Network Overview

Hyperledger Fabric 네트워크 구축을 자유롭게 할 필요가 있어서 한 주간 찾으면서 공부했다. 공부해본 결과, 자료가 정말 없다. 이론적인 문서는 많은데 그것을 바탕으로 실제 네트워크를 구성하는데 레퍼런스가 될만한 것들이 정말 없었다. 그래도 고생하고 고생하며 노력한 끝에 이제 왠만큼 네트워크를 꾸릴 수 있게 되었다. 배운 것들을 정리한다는 생각으로 글을 써보기로 했다. 누군가에게 도움이 된다면 정말 더할나위 없을 것 같다.

다음과 같은 포스트를 작성할 예정이다.

  1. Network Overview
  2. byfn(Build Your First Network) 뜯어보기
  3. eyfn(Extend Your First Network) – Add New Org to Network
  4. Upgrade orderer from SOLO to Kafka
  5. No cryptogen!

Components of a Network

Hyperledger Fabric 네트워크는 다음과 같은 컴포넌트들로 구성된다.

  • Ledger (channel당 하나씩 있다. 그리고 blockchain과 state database로 구성된다.)
  • Smart Contract (chaincode)
  • Organizations, MSP
  • Peer nodes
  • Ordering services
  • Channel
  • Fabric CA

Transaction Flow

Overview

Transaction Proposal

각각의 컴포넌트들의 역할을 전체적인 흐름에서 파악하는 것이 더 이해하기 쉽다. 먼저 Client는 Application SDK에서 transaction proposal을 Endorsing Peer에게 날리게 된다. 어떤 Peer들이 endorser들이 되는지와 transaction이 valid한지 기준은 Endorsement Policy에 의해 결정된다. SmartContract의 역할을 하는 chaincode는 endorsement policy를 정의하고있다. Policy에 정의된 endorse peer들에게 Client는 무조건 transaction proposal을 보내야하며 그들의 endorse 여부를 모아야한다.

Proposal을 받은 Endorsing Peer들은 transaction을 ledger을 업데이트 시키지않고 chaincode 실제로 돌리면서 시뮬레이션해본다. 그리고 각 Endorsing Peer들은 시뮬레이션 결과를 RW Set 형태로 나오는데 이것을 endorse 할 지 reject 할 지의 응답과 함께 Application에 돌려준다. RW Set은 transaction을 시뮬레이션 하기 이전의 world state의 상태와 시뮬레이션 했을 때 그 결과 상태 두 가지 set을 말한다.

Submit to Ordering Service

만약 transaction이 endorse되었다면 ordering service에 보내게 된다. Ordering Service는 쉽게 생각하면 endorsed transaction queue라고 보면된다. 실제로는 여러 client들이 transaction 날리는데 이것을 하나로 queueing 해주는 것이다. 현재 Hyperledger Fabric에선 SOLO, Kafka 두 가지 방식을 지원한다. SOLO 방식은 production에서는 사용하지 말라고 doc에 명시하고 있다. 왜냐하면 ordering service node가 한 명이고 fault-tolerant하지 않다.

Broadcast Block

그리고 여기서 모아진 transaction들을 block으로 만들어서 anchor peer들에게 보내준다. Anchor peer들만 organization 내에서 block을 받을 수 있다. Anchor peer가 organization 내에 peer들에게 block들을 broadcast해준다. 마지막으로 block을 받은 peer들은 block validation을 거치고 나면 ledger에 저장하고 world state를 업데이트 시킨다. 그리고 transaction 성공여부를 client에게 알려준다.

Conclusion

그래서 위와 같은 전체적인 과정을 그려보면 다음과 같은 순서로 진행이 된다. Company에서 client를 이용해서 transaction을 날리면 바로 ledger에 저장하는 것이 아니라, 우선 endorse peer에게 endorse response를 수합해서 그것이 valid 하면 비로소 block으로 만들어질 수 있다. 또한 실제에서는 Company가 여러개이고, endorsed transaction들도 여러개가 날아올테니 그것을 ordering service를 이용해서 queueing하고 block으로 만들어서 전파하게된다. 다음 포스트에는 byfn 튜토리얼을 뜯어보면서 과정 하나하나가 어떤 의미인지 포스팅해보려고 한다.

Reference

  • https://medium.com/coinmonks/how-does-hyperledger-fabric-works-cdb68e6066f5
  • http://hyperledger-fabric.readthedocs.io/en/release-1.1/arch-deep-dive.html
  • https://hyperledger-fabric.readthedocs.io/en/master/network/network.html#