Upgrading Your Network Components(네트워크 구성 요소 업그레이드)

[Note]
이 문서에서 "업그레이드"라는 용어를 사용할 때는 주로 구성 요소의 버전을 변경하는 것을 말합니다 (예 : v1.0.x 바이너리에서 v1.1 바이너리로 변경). 반면에 "업데이트"라는 용어는 버전이 아니라 채널 구성 또는 배포 스크립트 업데이트와 같은 구성 변경을 의미합니다.

Overview

첫 번째 네트워크 빌드 (BYFN) 자습서는 기본적으로 "최신"바이너리로 기본 설정되어 있기 때문에 v1.1 릴리스 이후에 실행 한 경우 시스템에 v1.1 바이너리와 도구가 설치되어 사용자가 그들을 업그레이 드하십시오.

결과적으로이 튜토리얼에서는 Hyperledger Fabric v1.0.6 바이너리와 업그레이드 할 v1.1 바이너리를 기반으로 한 네트워크를 제공합니다. 또한 기능 요구 사항을 파악하기 위해 채널 구성을 업데이트하는 방법을 보여줍니다.

그러나 BYFN은 다음 구성 요소를 지원하지 않으므로 BYFN 업그레이드 스크립트에서 해당 구성 요소를 다루지 않습니다.

  • Fabric-CA
  • Kafka
  • SDK

이러한 구성 요소를 업그레이드하는 프로세스는 자습서 다음 섹션에서 다룹니다.

높은 수준에서 업그레이드 가이드는 다음 단계를 수행합니다.

  1. 원장과 MSP를 백업하십시오.
  2. Orderer 바이너리를 Fabric v1.1로 업그레이드하십시오.
  3. 피어 바이너리를 Fabric v1.1로 업그레이드하십시오.
  4. v1.1 채널 기능 요구 사항을 사용합니다.
[Note]
프로덕션 환경에서는 orderer 및 peer를 동시에 업그레이드 할 수 있습니다. 즉, peer를 업그레이드하기 전에 orderer를 업그레이드 할 필요가 없습니다. 주의를 기울여야하는 곳은 능력을 발휘하는 것입니다. 모든 orderer 및 peer 는 해당 단계 전에 업그레이드해야합니다 (일부 orderer 가 기능이 활성화되었을 때 업그레이드 된 경우 치명적인 State 포크를 만들 수 있음).

이 자습서에서는 CLI 명령을 사용하여 각 단계를 개별적으로 수행하는 방법을 보여줍니다.

prerequisites(전제 조건)

아직 수행하지 않은 경우, 전제 조건에서 설명한대로 시스템에 모든 종속성이 있는지 확인하십시오.

Launch a v1.0.6 Network(v1.0.6 네트워크 시작)

먼저, Fabric v1.0.6 이미지를 실행하는 기본 네트워크를 프로비저닝합니다. 이 네트워크는 2 개의 피어 노드를 유지 관리하는 두 개의 조직과 "솔로" Ordering Service로 구성됩니다.

로컬 fabric-samples.의 first-network 하위 디렉토리에서 작업 할 것입니다. 지금 해당 디렉토리로 변경하십시오. 또한 사용하기 쉽도록 몇 개의 여분의 터미널을 열고 싶을 것입니다.

Clean up

우리는 알려진 State에서 작업하기를 원하므로  byfn.sh 스크립트를 사용하여 처음에는 정리를합니다. 이 명령은 활성 또는 비활성 도커 컨테이너를 제거하고 이전에 생성 된 아티팩트를 제거합니다. 다음 명령을 실행하십시오.

./byfn.sh -m down

Generate the Crypto and Bring Up the Network(암호화 생성 및 네트워크 활성화)

새로운 환경에서 다음 네 가지 명령을 사용하여 v1.0.6 BYFN 네트워크를 시작하십시오.

git fetch origin

git checkout v1.0.6

./byfn.sh -m generate

./byfn.sh -m up -t 3000 -i 1.0.6

BYFN이 제대로 시작되면 다음과 같이 표시됩니다.

===================== All GOOD, BYFN execution completed =====================

이제 네트워크를 Hyperledger Fabric v1.1로 업그레이드 할 준비가되었습니다.

Get the newest samples(최신 샘플 가져오기)

[Note]
아래 지침은 1.1.0-rc1부터 시작하여 v1.1.x의 가장 최근에 게시 된 버전과 관련이 있습니다. '1.1.x'는 테스트중인 게시 된 릴리스의 버전 식별자로 대체하십시오. 'v1.1.x'를 'v1.1.0'으로 바꾸십시오.

나머지 튜토리얼을 끝내기 전에 v1.1.x 버전의 샘플을 얻는 것이 중요합니다. 다음과 같이 하면 됩니다.

git fetch origin

git checkout v1.1.x

Want to upgrade now?(지금 업그레이드 하시겠습니까?)

BYFN의 모든 구성 요소를 업그레이드하고 기능을 활성화하는 스크립트가 있습니다. 그런 다음 스크립트의 단계를 수행하고 업그레이드 프로세스에서 각 코드가 수행하는 작업을 설명합니다.

스크립트를 실행하려면 다음 명령을 실행하십시오.

# Note, replace '1.1.x' with a specific version, for example '1.1.0'.
# Don't pass the image flag '-i 1.1.x' if you prefer to default to 'latest' images.
# '1.1.x'를 특정 버전으로 바꾸십시오 (예 : '1.1.0').
# 이미지 플래그 '-i 1.1.x'를 지나치지 마십시오. 'latest'이미지를 기본값으로 사용하는 것이 좋습니다.

./byfn.sh upgrade -i 1.1.x

업그레이드가 성공하면 다음이 표시됩니다.

===================== All GOOD, End-2-End UPGRADE Scenario execution completed =====================

네트워크를 수동으로 업그레이드하려면  ./byfn.sh -m down을 다시 실행하고 – ./byfn.sh upgrade -i 1.1.x까지의 단계를 수행하십시오. 그런 다음 다음 섹션으로 진행하십시오.

[Note]
이 섹션에서 실행하는 명령 중 많은 부분이 출력되지 않습니다. 일반적으로 출력이 좋은 출력이 없다고 가정합니다.

Upgrade the Orderer Containers(Orderer 컨테이너 업그레이드)

[Note]
귀하의 Orderer 업그레이드에 관심을 기울이십시오. 그들이 정확하게 완료되지 않은 경우 - 특히 일부 Orderer 만 업그레이드하고 다른 사용자는 업그레이드하지 않은 경우 - 주 fork 가 만들어 질 수 있습니다 (즉, 원장이 더 이상 일관성이 없음). 이것은 반드시 피해야합니다.

Orderer  컨테이너는 롤링 방식으로 업그레이드해야 합니다 (한 번에 하나씩). 높은 수준에서 Orderer 업그레이드 프로세스는 다음과 같이 진행됩니다.

1. Orderer를 중지 시키십시오.

2. Orderer의 원장과 MSP를 백업하십시오.

3. 최신 이미지로 Orderer를 다시 시작하십시오.

4. 업그레이드가 완료되었는지 확인하십시오.

BYFN을 활용 한 결과, 우리는 솔로 Orderer 설정을 가지므로,이 과정은 한 번만 수행 할 것입니다. 그러나 Kafka 설정에서이 프로세스는 각 Orderer에 대해 수행되어야합니다.

[Note]
이 튜토리얼에서는 docker 배포를 사용합니다. 원시 배치(native deployments)의 경우, 파일 순서대로 파일을 릴리스 아티팩트의 파일로 대체하십시오. orderer.yaml을 i 업하고 릴리스 아티팩트의 orderer.yaml 파일로 YY십시오. 그런 다음 수정 된 변수를 백업 된 orderer.yaml에서 새 변수로 이식합니다. diff와 같은 유틸리티를 사용하면 도움이 될 수 있습니다. 혼란을 줄이기 위해 General.TLS.ClientAuthRequired 변수가 General.TLS.ClientAuthEnabled로 변경되었습니다 (피어 구성에서 지정한 것처럼). 이 변수의 이전 이름이 여전히 orderer.yaml 파일에 존재하면, 새  orderer 2 진이 시작되지 않습니다.

Orderer 아래로 내림으로써 업그레이드 프로세스를 시작합시다.

docker stop orderer.example.com

export LEDGERS_BACKUP=./ledgers-backup

# Note, replace '1.1.x' with a specific version, for example '1.1.0'.
# Set IMAGE_TAG to 'latest' if you prefer to default to the images tagged 'latest' on your system.
# '1.1.x'를 특정 버전으로 바꾸십시오 (예 : '1.1.0').
# 시스템에서 '최신'태그가 붙은 이미지를 기본값으로 사용하려면 IMAGE_TAG를 'latest'로 설정하십시오.

export IMAGE_TAG=`uname -m`-1.1.x

파일 백업을 넣을 디렉토리 변수를 만들었으며 이동하려는  IMAGE_TAG을 내 보냈습니다.

orderer 가 내려 가면 원장과 MSP를 백업 할 수 있습니다.

mkdir -p $LEDGERS_BACKUP

docker cp orderer.example.com:/var/hyperledger/production/orderer/ ./$LEDGERS_BACKUP/orderer.example.com

생산 네트워크( production network)에서 이 프로세스는 각 Kafka 기반의 Orderer에 대해 롤링 방식으로 반복됩니다.

이제 우리의 새로운 패브릭 이미지로 orderer 를 다운로드하고 다시 시작하십시오.

docker-compose -f docker-compose-cli.yaml up -d --no-deps orderer.example.com

이 샘플에서는 "solo" Ordering Service를 사용하기 때문에 네트워크에 다시 Order한 Orderer가 동기화해야하는 다른 Orderer가 없습니다. 그러나 Kafka를 활용 한 프로덕션 네트워크에서는 다른 Orderer를 따라 잡았는지 확인하기 위해 Orderer를 다시 시작한 후  peer channel fetch <blocknumber>를 실행하는 것이 좋습니다.

Upgrade the Peer Containers(피어 컨테이너 업그레이드)

다음으로, 피어 컨테이너를 Fabric v1.1로 업그레이드하는 방법을 살펴 보겠습니다. 피어 컨테이너는 orderer처럼 롤링 방식으로 업그레이드 해야 합니다 (한 번에 하나씩). orderer 업그레이드 중에 언급 한 바와 같이 orderer 및 피어는 동시에 업그레이드 할 수 있지만이 자습서에서는 프로세스를 분리했습니다. 높은 수준에서 다음 단계를 수행합니다.

  1. 피어를 중지하십시오.
  2. 피어의 원장과 MSP를 백업하십시오.
  3. 체인 코드 컨테이너 및 이미지를 제거하십시오.
  4. 최신 이미지로 피어를 다시 시작하십시오.
  5. 업그레이드가 완료되었는지 확인하십시오.

우리는 우리 네트워크에서 4 명의 동료를 운영합니다. 각 피어에 대해이 프로세스를 한 번 수행하여 총 4 개의 업그레이드를 수행합니다.

[Note]
다시 말하면,이 튜토리얼은 도커 배치를 사용합니다. 원시 배치(native deployments)의 경우, 파일 피어를 릴리스 아티팩트의 파일 피어로 바꾸십시오. core.yaml을 백업하고 릴리스 아티팩트의 파일로 바꾸십시오. 백업 된 core.yaml에서 수정 된 변수를 새 포트로 이식합니다. diff와 같은 유틸리티를 사용하면 도움이 될 수 있습니다.

다음 명령을 사용하여 첫 번째 피어 를 가져와 봅시다.

export PEER=peer0.org1.example.com

docker stop $PEER

그런 다음 피어의 원장과 MSP 를 백업 할 수 있습니다 .

mkdir -p $LEDGERS_BACKUP

docker cp $PEER:/var/hyperledger/production ./$LEDGERS_BACKUP/$PEER

피어가 중지되고 원장이 백업 된 State에서 피어 체인 코드 컨테이너를 제거합니다.

CC_CONTAINERS=$(docker ps | grep dev-$PEER | awk '{print $1}')
if [ -n "$CC_CONTAINERS" ] ; then docker rm -f $CC_CONTAINERS ; fi

그리고 피어 체인 코드 이미지 :

CC_IMAGES=$(docker images | grep dev-$PEER | awk '{print $1}')
if [ -n "$CC_IMAGES" ] ; then docker rmi -f $CC_IMAGES ; fi

이제 v1.1 이미지 태그를 사용하여 피어를 다시 시작합니다.

docker-compose -f docker-compose-cli.yaml up -d --no-deps $PEER

튜토리얼 후에 CouchDB를 업데이트하는 방법에 대해 더 자세하게 이야기 할 것입니다.

Verify Upgrade Completion(업그레이드 완료 확인)

우리는 첫 번째 피어의 업그레이드를 완료했지만 계속하기 전에 체인 코드 호출로 업그레이드가 제대로 완료되었는지 확인합니다. 다음 명령을 사용하여  a에서b 로  10을 이동합시다.

docker-compose -f docker-compose-cli.yaml up -d --no-deps cli

docker exec -it cli bash

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 mycc -c '{"Args":["invoke","a","b","10"]}'

우리의 쿼리는 초기에  a가  90이라는 값을 가지고 있고 우리는 호출을 사용하여  10을 제거했습니다. 따라서 a에 대한 질의는  80을 나타내야합니다.

peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'

우리는 다음을보아야합니다.

Query Result: 80

피어가 올바르게 업그레이드되었는지 확인한 후 피어를 계속 업그레이드하기 전에 이탈을 실행하여 컨테이너에서 나가십시오. 다른 피어 이름을 내 보낸 위의 프로세스를 반복하면이 작업을 수행 할 수 있습니다.

export PEER=peer1.org1.example.com
export PEER=peer0.org2.example.com
export PEER=peer1.org2.example.com

Enable Capabilities for the Channels(채널 기능 활성화)

v1.0.x 패브릭 바이너리는 채널 기능의 개념을 이해할 수 없으므로 처음에는 채널에 기능을 사용할 때 특별히 주의해야합니다.

패브릭 바이너리는 롤링 방식으로 업그레이드 할 수 있고 업그레이드 해야 하지만 ordering admin 는 모든 order 바이너리가 v1.1.x 이상이 될 때까지 v1.1 기능을 사용하지 않도록하는 것이 중요합니다. 어떤 orderer 가 v1.0.x 코드를 실행 중이고 채널에 대한 기능을 사용할 수있는 경우 v1.0.x orderer가 변경을 무효화하고 v1.1.x + orderer가 이를 승인하면 블록 체인이 포크를합니다. 이것은 v1.0에서 v1.1 로의 업그레이드에 대한 예외입니다. v1.1에서 v1.2와 같은 향후 업그레이드의 경우 orderer 네트워크가 업그레이드를보다 정상적으로 처리하고 State 포크를 방지합니다.

포크 가능성을 최소화하기 위해 orderer v1.1 기능을 사용하기 전에 응용 프로그램 또는 채널 v1.1 기능을 사용하려는 시도가 거부됩니다. orderer가 v1.1 기능을 사용할 수있게하는 것은 ordering admin 만 가능하기 때문에 다른 기능의 필수 조건으로 설정하면 ordering admin가 지원할 준비가 되기 전에 응용 프로그램 관리자가 실수로 기능을 사용하는 것을 방지 할 수 있습니다.

[Note]
기능을 사용하도록 설정 한 후에는 기능을 사용하지 않도록 설정하거나 권장하지 않습니다.

기능을 사용하도록 설정하면 해당 채널의 영구 기록의 일부가됩니다. 즉, 기능을 사용하지 않도록 설정 한 후에도 오래된 바이너리는 채널을 사용할 수없는 블록으로 이동할 수있는 블록을 처리 할 수 없으므로 채널에 참여할 수 없습니다.

이러한 이유로 채널 기능을 아무런 수익이 없는 지점으로 사용할 수 있다고 생각하십시오. 테스트 환경에서 새로운 기능을 시험하고 프로덕션 환경에서 사용할 수있게하기 전에 자신감을 가져보십시오.

v1.0.0 피어가 결합 된 채널에서 기능 요구 사항을 활성화하면 피어가 충돌하게됩니다. 이 충돌하는 동작은 의도하지 않은 잘못된 구성 State를 나타내므로 의도적 인 동작입니다.

실패한 v1.0.x 피어에서 표시되는 오류 메시지는 다음과 같습니다.

Cannot commit block to the ledger due to Error validating config which passed
initial validity checks: ConfigEnvelope LastUpdate did not produce the supplied
config result

초기 유효성 검사를 통과 한 구성의 유효성을 검사하는 구성 오류로 인해 원장에게 블록을 적용 할 수 없음 : ConfigEnvelope LastUpdate가 제공된 구성 결과를 생성하지 않았습니다.

우리는 다음 순서대로 기능을 활성화 할 것입니다.

  1. Orderer System Channel
    1. Orderer Group
    2. Channel Group
  2. Individual Channels
    1. Orderer Group
    2. Channel Group
    3. Application Group
[Note]
포크 (fork)의 가능성을 최소화하기 위해서는 먼저 orderer system  기능을 활성화 한 다음 개별 채널 기능을 활성화하는 것이 가장 좋습니다.

각 그룹에 대해 다음 순서로 기능을 활성화합니다.

  1. 최신 채널 설정 가져 오기
  2. 수정 된 채널 구성 만들기
  3. 구성 업데이트 트랜잭션 만들기
[Note]
이 프로세스는 일련의 구성 업데이트 트랜잭션 (각 채널 그룹당 하나씩)을 통해 수행됩니다. 실제 제작 네트워크에서 이러한 채널 구성 업데이트는 각 채널의 관리자가 처리합니다. BYFN은 모두 단일 시스템에 있기 때문에 이러한 각 채널을 업데이트 할 수 있습니다.

채널 구성을 업데이트하는 방법에 대한 자세한 내용은 채널에 조직 추가 또는 채널 구성 업데이트의 문서를 클릭하십시오.

docker exec -it cli bash를 다시 발행하여  cli컨테이너로 돌아가십시오.

이제 다음과 같이 설정된 환경 변수를 확인해 봅시다.

env|grep PEER

또한 jq를 설치해야합니다.

apt-get update

apt-get install -y jq

Orderer System Channel Capabilities(Orderer 시스템 채널 기능)

orderer  시스템 채널에 대한 환경 변수를 설정합시다. 다음 명령을 각각 발행하십시오.

CORE_PEER_LOCALMSPID="OrdererMSP"

CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

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

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

채널 이름을 testchainid다음 과 같이 설정해 보겠습니다 .

CH_NAME=testchainid

Orderer Group(Orderer 그룹)

채널 구성을 업데이트하는 첫 번째 단계는 최신 구성 블록을 얻는 것입니다.

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME  --tls --cafile $ORDERER_CA

config를 쉽게 편집 할 수 있도록 configtxlator를 사용하여 config 블록을 JSON으로 변환 해 봅시다.

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json

이 명령은 jq 를 사용하여 config에서 헤더, 메타 데이터 및 시그니처를 제거합니다.

jq .data.data[0].payload.data.config config_block.json > config.json

그런 다음 orderer group에 기능을 추가하십시오. 다음 명령은 구성 파일의 복사본을 만들고 여기에 새로운 기능을 추가합니다.

jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1]}}}}}' config.json ./scripts/capabilities.json > modified_config.json

우리가 여기에서 변화하고있는 것에 주목하십시오.  Capabilities은 channel_group아래의  orderer 그룹의  value로 추가되고 있습니다. 우리가 작업하고있는 특정 채널은이 명령에 명시되어 있지 않지만, 그것이 Orderer 시스템 채널 testchainid라는 것을 기억하십시오. 새 채널을 만들 때 기본적으로 복사 될이 채널의 구성이기 때문에 먼저 업데이트해야합니다.

이제 config 업데이트를 만들 수 있습니다.

configtxlator proto_encode --input config.json --type common.Config --output config.pb

configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb

구성 업데이트를 트랜잭션으로 패키지화하십시오.

configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json

echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json

configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb

구성 업데이트 트랜잭션 제출 :

[Note]
이 다음 단계에서는 아래의 명령은 트랜잭션을 서명하고 ordering service에 제출합니다.

우리의 구성 업데이트 트랜잭션은 원래 구성과 수정 된 구성 간의 차이를 나타내지 만, Orderer는 이것을 전체 채널 구성으로 변환합니다.

Channel Group(채널 그룹)

이제 orderer system 수준에서 채널 그룹에 대한 기능을 활성화하는 단계로 넘어 갑니 다.

이전과 마찬가지로 첫 번째 단계는 최신 채널 구성을 얻는 것입니다.

[Note]
이 다음 단계에서는 이 명령 세트는 orderer 그룹의 단계와 완전히 동일합니다.

다음으로 수정 된 채널 구성을 만듭니다.

jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1]}}}' config.json ./scripts/capabilities.json > modified_config.json

우리가 여기서 바뀌고있는 것에 주목하십시오 : Capabilities은 최상위 channel_group 의 value 으로 추가됩니다 (이전처럼 testchainid  채널에서).

구성 업데이트 트랜잭션을 만듭니다.

[Note]
이 명령 세트는 orderer 그룹의 세 번째 단계와 완전히 동일합니다.

구성 업데이트를 트랜잭션으로 패키지화하십시오.

configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json

echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json

configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb

구성 업데이트 트랜잭션 제출 :

peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA

Enabling Capabilities on Existing Channels(기존 채널에서 기능 활성화)

채널 이름을 mychannel다음으로 설정하십시오 .

CH_NAME=mychannel

Orderer Group(Orderer 그룹)

채널 설정 가져 오기 :

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME  --tls --cafile $ORDERER_CA

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json

jq .data.data[0].payload.data.config config_block.json > config.json

Orderer 그룹에 기능을 추가해 보겠습니다. 다음 명령은 구성 파일의 복사본을 만들고 여기에 새로운 기능을 추가합니다.

jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1]}}}}}' config.json ./scripts/capabilities.json > modified_config.json

우리가 여기에서 변화하고있는 것에 주목하십시오.  Capabilities은  channel_group 아래의  orderer 그룹의  value로 추가되고 있습니다. 이것은 정확히 우리가 이전에 변경 한 것인데, 지금은  testchainid 대신 채널  mychannel에 config를 사용하고 있습니다.

구성 업데이트 만들기 :

configtxlator proto_encode --input config.json --type common.Config --output config.pb

configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb

구성 업데이트를 트랜잭션으로 패키지화하십시오.

configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json

echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json

configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb

구성 업데이트 트랜잭션 제출 :

peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA

Channel Group(채널 그룹)

[Note]
이 명령 세트는 orderer 반복되는 것처럼 보일 수 있지만, 우리는 다른 그룹에서 동일한 프로세스를 수행하고 있음을 기억하십시오. 앞에서 말했듯이 프로덕션 네트워크에서 이 프로세스는 여러 채널 관리자간에 분열 될 수 있습니다. 세 번째 단계와 완전히 동일합니다.

설정 가져 오기, 디코딩 및 범위 지정 :

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME --tls --cafile $ORDERER_CA

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json

jq .data.data[0].payload.data.config config_block.json > config.json

수정 된 구성 만들기 :

jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1]}}}' config.json ./scripts/capabilities.json > modified_config.json

우리가 여기서 바뀌고 있는 것에 주목하십시오.  Capabilities은 최상위 channel_group  (이전처럼  mychannel에서)의  value으로 추가됩니다.

구성 업데이트 만들기 :

configtxlator proto_encode --input config.json --type common.Config --output config.pb

configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb

구성 업데이트를 트랜잭션으로 패키지화하십시오.

configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json

echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json

configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb

channel그룹 의 구성을 업데이트하기 때문에 관련 조직 (Org1, Org2 및 OrdererOrg)이 서명해야합니다. 이 작업은 일반적으로 개별 조직 관리자가 수행하지만, BYFN에서는 앞서 말했듯이 이 작업이 우리에게 위임됩니다.

먼저 Org1로 전환하고 업데이트에 서명하십시오.

CORE_PEER_LOCALMSPID="Org1MSP"

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

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

CORE_PEER_ADDRESS=peer0.org1.example.com:7051

peer channel signconfigtx -f config_update_in_envelope.pb

그리고 Org2와 동일하게하십시오 :

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

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.org1.example.com:7051

peer channel signconfigtx -f config_update_in_envelope.pb

그리고 OrdererOrg :

CORE_PEER_LOCALMSPID="OrdererMSP"

CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

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

peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA

Application Group(응용 프로그램 그룹)

응용 프로그램 그룹의 경우 환경 변수를 하나의 조직으로 재설정해야합니다.

CORE_PEER_LOCALMSPID="Org1MSP"

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

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

CORE_PEER_ADDRESS=peer0.org1.example.com:7051

이제 최신 채널 구성을 가져 오십시오 (이 프로세스는 지금까지 매우 친숙해야합니다).

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME --tls --cafile $ORDERER_CA

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json

jq .data.data[0].payload.data.config config_block.json > config.json

수정 된 채널 구성 만들기 :

jq -s '.[0] * {"channel_group":{"groups":{"Application": {"values": {"Capabilities": .[1]}}}}}' config.json ./scripts/capabilities.json > modified_config.json

우리가 여기서 바뀌고 있는 것에 주목하십시오.  Capabilities은 최상위 channel_group  (이전처럼  mychannel에서)의  value으로 추가됩니다.

구성 업데이트 트랜잭션 만들기 :

configtxlator proto_encode --input config.json --type common.Config --output config.pb

configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb

구성 업데이트를 트랜잭션으로 패키지화하십시오.

configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json

echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json

configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb

Org1이 트랜잭션을 서명합니다.

peer channel signconfigtx -f config_update_in_envelope.pb

환경 변수를 Org2로 설정하십시오.

export CORE_PEER_LOCALMSPID="Org2MSP"

export 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

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:7051

Org2는 설정 업데이트 트랜잭션을 서명과 함께 제출합니다.

peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA

축하! 이제 모든 채널에서 기능을 사용할 수 있습니다.

Verify that Capabilities are Enabled(기능이 활성화되어 있는지 확인)

그러나 이전과 같이  10을  a에서  b로 이동하여 테스트 해 봅시다.

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 mycc -c '{"Args":["invoke","a","b","10"]}'

그런 다음  a의 값을 조회하면  70이라는 값이 나타납니다.

peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'

우리는 다음을보아야합니다.

어떤 경우 우리는 모든 채널에 기능을 성공적으로 추가했습니다.

Upgrading Components BYFN Does Not Support(BYFN이 지원하지 않는 구성 요소 업그레이드)

이것이 업데이트 자습서의 끝 부분이지만 BYFN 샘플에서 지원하지 않는 프로덕션 네트워크에있는 다른 구성 요소가 있습니다. 이 섹션에서는 업데이트 프로세스에 대해 설명하겠습니다.

Fabric CA Container(패브릭 CA 컨테이너)

Fabric CA 서버를 업그레이드하는 방법을 배우려면 CA 문서 를 클릭하십시오 .

Upgrade Node SDK Clients(Node SDK 클라이언트 업그레이드)

[Note]
노드 SDK 클라이언트를 업그레이드하기 전에 패브릭 CA를 업그레이드하십시오.

NPM을 사용하여 응용 프로그램의 루트 디렉토리에서 다음 명령을 실행하여  Node.js클라이언트를 업그레이드하십시오.

이 명령은 Fabric 클라이언트와 Fabric-CA 클라이언트의 새 버전을 설치하고 새 버전을 작성합니다 package.json.

Upgrading the Kafka Cluster(카프카 클러스터 업그레이드)

반드시 필요한 것은 아니지만 Kafka 클러스터를 나머지 Fabric과 함께 업그레이드하고 최신 State로 유지하는 것이 좋습니다. Kafka의 최신 버전은 이전 버전의 프로토콜을 지원하므로 나머지 Fabric 이전 또는 이후에 Kafka를 업그레이드 할 수 있습니다.

Kafka 클러스터가 Kafka v0.11.0보다 오래된 경우 충돌 복구를보다 잘 처리하기 위해 복제를 강화하므로이 업그레이드가 특히 권장됩니다.

Kafka 클러스터 브로커를 업그레이드하기 위해 이전 버전에서 Kafka를 업그레이드하는 공식 Apache Kafka 문서를 참조하십시오.

Orderer가 Kafka 브로커 버전보다 오래된 Kafka 프로토콜 버전을 사용하도록 구성된 경우 Kafka 클러스터가 성능에 부정적인 영향을 줄 수 있습니다. Kafka 프로토콜 버전은orderer.yaml 파일의  Kafka.Version 키 또는 Docker 배포의 ORDERER_KAFKA_VERSION 환경 변수를 사용하여 설정됩니다. Fabric v1.0은 카프카 버전 0.9.0.1이 포함 된 샘플 카프카 도커 이미지를 제공했습니다. Fabric v1.1은 Kafka 버전 v1.0.0이 포함 된 샘플 Kafka 도커 이미지를 제공합니다.

[Note] 이전에 설정하지 않은 경우에도 Kafka 클러스터 버전과 일치하도록 Orderer가 사용하는 Kafka 프로토콜 버전을 구성해야합니다. 예를 들어 Fabric v1.0.x와 함께 제공되는 샘플 Kafka 이미지를 사용하는 경우 ORDERER_KAFKA_VERSION 환경 변수를 설정하거나 orderer.yaml의 Kafka.Version 키를 0.9.0.1로 설정하십시오. Kafka 클러스터 버전에 대해 잘 모르는 경우 최대 호환을 위해 Orderer의 Kafka 프로토콜 버전을 0.9.0.1로 구성하고 이후 Kafka 클러스터 버전을 결정한 후 설정을 업데이트 할 수 있습니다.

Upgrading Zookeeper(Zookeeper 업그레이드)

Apache Kafka 클러스터에는 Apache Zookeeper 클러스터가 필요합니다. Zookeeper API는 오래 동안 안정되어 있었으며, 거의 모든 Zookeeper 버전이 Kafka에서 용인되었습니다. Zookeeper의 특정 버전으로 업그레이드하는 특정 요구 사항이있는 경우 Apache Kafka 업그레이드 설명서를 참조하십시오. Zookeeper 클러스터를 업그레이드하려면 Zookeeper 클러스터 업그레이드에 대한 정보를 Zookeeper FAQ에서 찾으실 수 있습니다.

Upgrading CouchDB(CouchDB 업그레이드)

CouchDB를 State 데이터베이스로 사용하는 경우, 피어가 업그레이드되는 것과 동시에 피어의 CouchDB를 업그레이드하십시오. CouchDB를 업그레이드하려면 다음을 수행하십시오.

  1. CouchDB를 중지하십시오.
  2. CouchDB 데이터 디렉토리를 백업하십시오.
  3. CouchDB 데이터 디렉토리를 삭제하십시오.
  4. CouchDB v2.1.1 바이너리를 설치하거나 배치 스크립트를 업데이트하여 새로운 Docker 이미지를 사용하십시오 (CouchDB v2.1.1 사전 구성된 Docker 이미지는 Fabric v1.1과 함께 제공됨).
  5. CouchDB를 다시 시작하십시오.

CouchDB 데이터 디렉토리를 삭제하는 이유는 시작시 v1.1 피어가 블록 체인 트랜잭션에서 CouchDB State 데이터베이스를 재구성하기 때문입니다. v1.1부터는 각 channel_chaincode 조합에 대한 내부 CouchDB 데이터베이스가 있습니다 (피어가 조인 한 각 채널에서 인스턴스화 된 각 체인 코드 용).

Upgrade Chaincodes With Vendored Shim(벤더 된 심으로 체인 코드 업그레이드)

벤더에 체인 코드 심을 제공 할 수있는 여러 가지 타사 도구가 있습니다. 이 도구 중 하나를 사용한 경우 동일한 도구를 사용하여 벤더링을 업데이트하고 체인 코드를 다시 패키징하십시오.

체인 코드가 shim을 공급하는 경우 shim 버전을 업데이트 한 후에는 이미 체인 코드가있는 모든 피어에 설치해야합니다. 같은 이름이지만 새로운 버전으로 설치하십시오. 그런 다음이 체인 코드가 배포 된 각 채널에서 새 버전으로 이동하기 위해 체인 코드 업그레이드를 실행해야합니다.

체인 코드를 판매하지 않은 경우이 단계를 완전히 건너 뛸 수 있습니다.


출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/upgrading_your_network_tutorial.html

Adding an Org to a Channel(채널에 조직 추가하기)

[Note]
이 설명서의 버전과 일치하는 하이퍼레저 패브릭 샘플 및 사전 요구 사항 (왼쪽의 목차 맨 아래에 있음)에 설명 된대로 적절한 이미지와 바이너리를 다운로드했는지 확인하십시오. 특히, fabric-samples 폴더의 버전에는 eyfn.sh ( "첫 번째 네트워크 확장") 스크립트와 관련 스크립트가 포함되어야합니다.

이 튜토리얼은 BYFN (Building Your First Network) 튜토리얼의 확장 기능으로 BYFN에서 자동 생성 한 애플리케이션 채널 (mychannel) 에 새로운 조직 – Org3 –을 추가하는 방법을 보여줍니다. 앞서 언급 한 유틸리티의 사용법 및 기능을 포함하여 BYFN에 대한 강력한 이해를 전제로 합니다.

여기서 새로운 조직의 통합에만 초점을 맞추지만 다른 채널 구성 업데이트 (예 : 수정 정책 업데이트 또는 배치 크기 변경)를 수행 할 때 동일한 접근 방식을 채택 할 수 있습니다. 일반적으로 채널 구성 업데이트의 프로세스와 가능성에 대한 자세한 내용은 채널 구성 업데이트를 참조하십시오. 여기에 설명 된 것과 같은 채널 구성 업데이트는 일반적으로 체인 코드 또는 응용 프로그램 개발자가 아닌 조직 관리자의 책임입니다.

[Note]
계속하기 전에 자동화 된 byfn.sh 스크립트가 시스템에서 오류없이 실행되는지 확인하십시오. 바이너리 및 관련 도구 (cryptogen, configtxgen 등)를 PATH 변수로 내 보낸 경우 정규화 된 경로를 통과하지 않고 그에 따라 명령을 수정할 수 있습니다.

Setup the Environment(환경 설정)

로컬fabric-samples의  first-network 하위 디렉토리의 루트에서 작동 할 것입니다. 지금 해당 디렉토리로 변경하십시오. 또한 사용하기 쉽도록 몇 개의 여분의 터미널을 열고 싶을 것입니다.

먼저,  byfn.sh 스크립트를 사용하여 정리하십시오. 이 명령은 활성 또는 비활성 docker 컨테이너를 제거하고 이전에 생성 된 아티팩트를 제거합니다. 채널 구성 업데이트 작업을 수행하기 위해 패브릭 네트워크를 중단 할 필요는 없습니다. 그러나이 자습서에서는 알려진 초기 State에서 작동하려고합니다. 따라서 다음 명령을 실행하여 이전 환경을 정리하십시오.

./byfn.sh -m down

이제 기본 BYFN 아티팩트를 생성하십시오.

./byfn.sh -m generate

CLI 컨테이너 내에서 스크립트 실행을 사용하여 네트워크를 시작하십시오.

./byfn.sh -m up

BYFN의 깨끗한 버전이 컴퓨터에서 실행되었으므로 두 가지 다른 경로를 사용할 수 있습니다. 첫째, Org3을 네트워크로 가져 오기 위해 config 트랜잭션 업데이트를 수행하는 주석 처리 된 스크립트를 제공합니다.

또한 동일한 프로세스의 "수동"버전을 보여 주며 각 단계를 보여주고 그 결과를 설명합니다 (이 수동 프로세스 전에 네트워크를 중단시키는 방법을 보여주기 때문에 스크립트를 실행 한 다음 각 프로세스를 볼 수도 있습니다 단계).

Bring Org3 into the Channel with the Script(스크립트로 Org3을 채널에 가져오기)

당신은  first-network에 있어야합니다. 스크립트를 사용하려면 다음을 실행하십시오.

./eyfn.sh up

여기에 나오는 결과는 읽을 가치가 있습니다. Org3 암호 자료가 추가되고, 구성 갱신이 작성되고 서명 된 다음 체인 코드가 설치되어 Org3가 원장 조회를 실행할 수 있습니다.

모든 것이 잘 진행되면 다음 메시지가 표시됩니다.

========= All GOOD, EYFN test execution completed ===========

eyfn.sh 는  ./byfn.sh -m -up 대신 다음을 실행하여 동일한 Node.js 체인 코드 및  byfn.sh와 같은 데이터베이스 옵션과 함께 사용할 수 있습니다.

./byfn.sh up -c testchannel -s couchdb -l node

그리고:

./eyfn.sh up -c testchannel -s couchdb -l node

이 프로세스를 면밀히 살펴보고자하는 사람들에게 나머지 문서는 채널 업데이트를위한 각 명령과 그 기능을 보여줍니다.

Bring Org3 into the Channel Manually(Org3을 채널에 수동으로 가져오기)

[Note]
아래에 설명 된 수동 단계에서는 cli 및 Org3cli 컨테이너의 CORE_LOGGING_LEVEL이 DEBUG로 설정되어 있다고 가정합니다.
cli 컨테이너의 경우 first-network 디렉토리의 docker-compose-cli.yaml 파일을 수정하여이를 설정할 수 있습니다. 예 :

cli:
  container_name: cli
  image: hyperledger/fabric-tools:$IMAGE_TAG
  tty: true
  stdin_open: true
  environment:
    - GOPATH=/opt/gopath
    - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
    #- CORE_LOGGING_LEVEL=INFO
    - CORE_LOGGING_LEVEL=DEBUG

Org3cli 컨테이너의 경우 first-network 디렉토리의 docker-compose-org3.yaml 파일을 수정하여 이를 설정할 수 있습니다. 예 :

Org3cli:
  container_name: Org3cli
  image: hyperledger/fabric-tools:$IMAGE_TAG
  tty: true
  stdin_open: true
  environment:
    - GOPATH=/opt/gopath
    - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
    #- CORE_LOGGING_LEVEL=INFO
    - CORE_LOGGING_LEVEL=DEBUG

eyfn.sh스크립트를 사용 했다면 네트워크를 중단시켜야합니다. 이것은 다음을 발행하여 수행 할 수 있습니다.

./eyfn.sh down

이렇게하면 네트워크가 중단되고 모든 컨테이너가 삭제되며 Org3을 추가하기 위해 수행 한 작업이 취소됩니다.

네트워크가 다운되었을 때 다시 켭니다.

./byfn.sh -m generate

그리고나서,

./byfn.sh -m up

이렇게하면 네트워크를 eyfn.sh스크립트 를 실행하기 전과 동일한 State로 되돌릴 수 있습니다.

이제 Org3을 수동으로 추가 할 준비가되었습니다. 첫 번째 단계에서는 Org3의 암호 자료를 생성해야합니다.

Generate the Org3 Crypto Material(Org3 Crypto Material 생성)

다른 터미널에서,  first-network의  org3-artifacts 서브 디렉토리로 변경하십시오.

cd org3-artifacts

여기서 관심있는 두 개의 yaml 파일이 있습니다 org3-crypto.yaml및  configtx.yaml 먼저 Org3 용 암호 자료를 생성하십시오.

../../bin/cryptogen generate --config=./org3-crypto.yaml

이 명령은 새로운 암호화  yaml 파일 (– org3-crypto.yaml –)을 읽고  cryptogen을 활용하여 Org3 CA 및이 Org에 바인딩 된 두 명의 피어에 대한 키와 인증서를 생성합니다. BYFN 구현과 마찬가지로이 암호 자료는 현재 작업 디렉토리 (이 경우에는  org3-artifacts) 내에 새로 생성 된 crypto-config  폴더에 저장됩니다.

이제 configtxgen 유틸리티를 사용하여 JSON에서 Org3 특정 구성 자료를 인쇄하십시오. 도구에서 현재 디렉토리에서 가져올 configtx.yaml  파일을 찾도록 명령하여 명령을 시작합니다.

export FABRIC_CFG_PATH=$PWD && ../../bin/configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json

위의 명령은 JSON 파일 (– org3.json –)을 만들고 이를  first-network의 루트에있는  channel-artifacts 하위 디렉토리로 출력합니다. 이 파일에는 Org3에 대한 정책 정의와 기본 64 형식으로 제공되는 세 가지 중요한 인증서 인 관리 사용자 인증서 (나중에 Org3의 관리자로 작동해야 함), CA 루트 인증서 및 TLS 루트가 포함되어 있습니다 증명. 다음 단계에서는이 JSON 파일을 채널 구성에 추가합니다.

하우스 키핑의 마지막 부분은 Orderer Org의 MSP 자료를 Org3 crypto-config 디렉토리로 이식하는 것입니다. 특히, 우리는 Ord3 엔티티와 네트워크의 Ordering Node 사이의 보안 통신을 허용하는 Orderer의 TLS 루트 인증서와 관련이 있습니다.

cd ../ && cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/

이제 채널 구성을 업데이트 할 준비가되었습니다 ...

Prepare the CLI Environment(CLI 환경 준비)

업데이트 프로세스는 구성 변환기 도구 - configtxlator를 사용합니다. 이 도구는 SDK와 독립적 인 State 비 저장 REST API를 제공합니다. 또한 Fabric 네트워크의 구성 작업을 단순화하기 위해 CLI를 제공합니다. 이 도구를 사용하면 서로 다른 데이터 표현 / 형식 (이 경우 protobufs와 JSON)을 손쉽게 변환 할 수 있습니다. 또한이 도구는 두 채널 구성 간의 차이점을 기반으로 구성 업데이트 트랜잭션을 계산할 수 있습니다.

먼저 CLI 컨테이너에 exec하십시오. 이 컨테이너는 BYFN crypto-config  라이브러리로 마운트되어 두 개의 원래 피어 조직과 Orderer Org의 MSP 자료에 액세스 할 수 있습니다. 부트 스트랩 된 ID는 Org1 관리자 사용자입니다. 즉, Org2 역할을 수행하려는 모든 단계에서 MSP 관련 환경 변수를 내 보내야합니다.

docker exec -it cli bash

이제  jq도구를 컨테이너에 설치하십시오. 이 도구는  configtxlator도구가 반환 한 JSON 파일과 스크립트 상호 작용을 허용합니다.

apt update && apt install -y jq

변수 ORDERER_CA및 CHANNEL_NAME변수 내보내기 :

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  && export CHANNEL_NAME=mychannel

변수가 올바르게 설정되었는지 확인하십시오.

echo $ORDERER_CA && echo $CHANNEL_NAME

Fetch the Configuration(구성 가져오기)

이제 CLI 컨테이너에는  ORDERER_CACHANNEL_NAME 이라는 두 가지 주요 환경 변수가 있습니다. 채널 ( mychannel)에 대한 가장 최근의 config 블록을 가져 오십시오.

config의 최신 버전을 가져와야하는 이유는 채널 구성 요소의 버전이 지정 되었기 때문입니다. 버전 관리는 여러 가지 이유로 중요합니다. 구성 변경이 반복되거나 재생되는 것을 방지합니다 (예 : 이전 CRL이있는 채널 구성으로 되돌릴 경우 보안 위험이 있음). 또한 동시성을 확보하는 데 도움이됩니다 (예를 들어, 새로운 Org가 추가 된 후 채널에서 Org를 제거하려는 경우, 버전 관리는 제거하려는 Org가 아닌 두 Org를 모두 제거하지 못하게합니다).

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

이 명령은 바이너리 protobuf 채널 구성 블록을  config_block.pb에 저장합니다. 이름과 파일 확장명의 선택은 임의적입니다. 그러나 표현되는 객체의 유형과 인코딩 (protobuf 또는 JSON)을 모두 식별하는 규칙을 따르는 것이 좋습니다.

peer channel fetch 명령을 실행하면 터미널에 상당한 양의 출력이 발생합니다. 로그의 마지막 행이 중요합니다.

2017-11-07 17:17:57.383 UTC [channelCmd] readBlock -> DEBU 011 Received block: 2

이것은  mychannel에 대한 가장 최근의 구성 블록이 실제로는 genesis 블록이 아니라 블록 2라는 것을 알려줍니다. 기본적으로  peer channel fetch config 명령은 대상 채널 (이 경우 세 번째 블록)에 대한 가장 최근의 구성 블록을 반환합니다. 이것은 BYFN 스크립트가  Org1및  Org2의 두 조직에 대한 앵커 피어를 두 개의 개별 채널 업데이트 트랜잭션에 정의했기 때문입니다.

결과적으로 다음과 같은 구성 순서가 있습니다.

  • 블록 0 : genesis block
  • 블록 1 : Org1 앵커 피어 업데이트
  • 블록 2 : Org2 앵커 피어 업데이트

Convert the Configuration to JSON and Trim It Down

이제  configtxlator도구를 사용하여이 채널 구성 블록을 JSON 형식 (사람이 읽고 수정할 수 있음)으로 디코딩 할 것입니다. 우리가 만들고자하는 변경과 관련이없는 모든 헤더, 메타 데이터, 작성자 서명 등을 제거해야합니다. 우리는 jq 도구를 사용하여이를 수행합니다.

configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json

이로 인해 first-network  내부의  fabric-samples폴더에 있는 JSON 객체 ( config.json)가 축소되어 구성 설정 업데이트의 기준이 됩니다.

잠시 시간을 내어 선택한 텍스트 편집기 (또는 브라우저)에서이 파일을 여십시오. 이 튜토리얼을 끝내고 나면 기본 구성 구조와 다른 종류의 채널 업데이트를 확인할 수 있으므로이 튜토리얼을 공부하는 것이 좋습니다. 채널 구성 업데이트에서 자세히 설명합니다.

Add the Org3 Crypto Material(Org3 Crypto Material 추가)

[Note]
이 시점까지 수행 한 단계는 구성 업데이트의 종류에 관계없이 거의 동일합니다. 시도 할 수있는 가장 복잡한 채널 구성 업데이트 중 하나이기 때문에이 자습서에 조직을 추가하기로 결정했습니다.

jq 도구를 다시 사용하여 Org3 구성 정의 ( org3.json)를 채널의 응용 프로그램 그룹 필드에 추가하고 출력 이름을 지정합니다.  modified_config.json

jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json

이제 CLI 컨테이너 내에 두 개의 JSON 파일 ( config.json 와 modified_config.json)이 있습니다. 초기 파일에는 Org1 및 Org2 자료 만 들어 있고, 수정 된 파일에는 세 개의 Org가 모두 들어 있습니다. 이 시점에서이 두 JSON 파일을 다시 인코딩하고 델타를 계산하기 만하면됩니다.

먼저 , config.json을  config.pb라는 protobuf로 다시 변환하십시오.

configtxlator proto_encode --input config.json --type common.Config --output config.pb

그런 다음  modified_config.json을 modified_config.pb로 인코딩합니다.

configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output org3_update.pb

이 새로운 proto – org3_update.pb – Org1 및 Org2 자료에 대한 Org3 정의 및 상위 레벨 포인터를 포함합니다. Org1 및 Org2에 대한 광범위한 MSP 자료 및 수정 정책 정보는 해당 채널의 기원 블록에 이미 있기 때문에 무시할 수 있습니다. 따라서 두 구성 사이에 델타 만 있으면됩니다.

채널 업데이트를 제출하기 전에 몇 가지 마지막 단계를 수행해야합니다. 먼저이 객체를 편집 가능한 JSON 형식으로 디코딩하고  org3_update.json이라고 부릅니다.

configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json

이제 우리는 엔코딩 된 업데이트 파일 ( – org3_update.json –)을 봉투 메시지(an envelope message)로 포장해야합니다. 이 단계는 이전에 제거한 헤더 필드를 되돌려줍니다. 이 파일의 이름은  org3_update_in_envelope.json입니다.

echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json

제대로 구성된 JSON org3_update_in_envelope.json 을 사용하여 마지막으로 configtxlator  도구를 활용하고 Fabric이 필요로하는 본격적인 protobuf 형식으로 변환합니다. 마지막 업데이트 개체 이름을  org3_update_in_envelope.pb로 지정합니다.

configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb

Sign and Submit the Config Update(구성 업데이트 서명 및 제출)

이제 CLI 컨테이너 내에 protobuf 바이너리 (– org3_update_in_envelope.pb –)가 있습니다. 그러나 구성을 원장에 기록하려면 필요한 관리 사용자의 서명이 필요합니다. 채널 응용 프로그램 그룹의 수정 정책 (mod_policy)은 기본값 인 "MAJORITY"로 설정됩니다. 즉, 기존 org 관리자의 대다수가 서명해야합니다. Org1과 Org2라는 두 개의 조직 만 있고 두 개의 대다수가 두 개이므로 두 가지 모두 서명해야합니다. 두 서명이 없으면 Ordering Service는 정책을 이행하지 못하여 트랜잭션을 거부합니다.

먼저이 업데이트를 Org1 Admin으로 서명하십시오. CLI 컨테이너는 Org1 MSP 자료로 부트 스트랩되므로 peer channel signconfigtx 명령을 실행하기 만하면됩니다.

peer channel signconfigtx -f org3_update_in_envelope.pb

마지막 단계는 Org2 Admin 사용자를 반영하도록 CLI 컨테이너의 ID를 전환하는 것입니다. Org2 MSP와 관련된 네 가지 환경 변수를 내보내서이 작업을 수행합니다.

[Note]
조직간에 설정 트랜잭션을 서명하거나 다른 작업을 수행하는 것은 실제 패브릭 작업을 반영하지 않습니다. 단일 컨테이너는 전체 네트워크의 암호 자료로 마운트되지 않습니다. 오히려 구성 업데이트는 Org2 Admin에 검사 및 승인을 위해 대역 외로 안전하게 전달되어야합니다.

Org2 환경 변수를 내 보냅니다.

# you can issue all of these commands at once

export CORE_PEER_LOCALMSPID="Org2MSP"

export 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

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:7051

마지막으로 peer channel update  명령을 실행합니다. Org2 Admin 서명이이 호출에 첨부되어 수동으로 protobuf에 다시 서명 할 필요가 없습니다.

[Note] ordering service 에 대한 다가오는 업데이트 호출은 일련의 체계적인 서명 및 정책 검사를 거치게됩니다. 따라서 Order 노드의 로그를 스트리밍하고 검사하는 것이 유용 할 수 있습니다. 다른 쉘에서 docker logs -f orderer.example.com 명령을 실행하여 표시하십시오.

업데이트 호출 보내기 (Send the update call):

peer channel update -f org3_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA

업데이트가 성공적으로 제출 된 경우 다음과 비슷한 메시지 요약 표시가 나타납니다.

2018-02-24 18:56:33.499 UTC [msp/identity] Sign -> DEBU 00f Sign: digest: 3207B24E40DE2FAB87A2E42BC004FEAA1E6FDCA42977CB78C64F05A88E556ABA

구성 트랜잭션의 제출도 보실 수 있습니다 :

2018-02-24 18:56:33.499 UTC [channelCmd] update -> INFO 010 Successfully submitted channel update

성공적인 채널 업데이트 호출은 채널의 모든 피어 (peer)에게 새로운 블록 (블록 5)을 반환합니다. 기억한다면 블록 0-2는 초기 채널 구성이고 블록 3과 4는 mycc 체인 코드의 인스턴스 생성과 호출입니다. 이와 같이, 블록 5는 현재 채널 상에 정의 된 Org3을 갖는 가장 최근의 채널 구성으로서 기능한다.

peer0.org1.example.com에 대한 로그를 검사하십시오.

docker logs -f peer0.org1.example.com

새 구성 블록을 가져오고 내용을 검사하려면 데모 프로세스를 수행하십시오.

Configuring Leader Election(리더 선출 구성)

[Note]
이 섹션은 초기 채널 구성이 완료된 후 조직을 네트워크에 추가 할 때 리더 선택 설정을 이해하기 위한 일반적인 참조로 포함됩니다. 이 샘플의 기본값은 peer-base.yaml 의 네트워크에있는 모든 피어에 대해 설정된 동적 리더 선거 입니다.

새로 가입 한 피어는 채널 구성 업데이트에 추가되는 조직에 대한 정보가 포함되지 않은 창 블록으로 부트 스트랩됩니다. 따라서 새로운 동료는 소셜을 조직에 추가 한 구성 트랜잭션을 얻을 때까지 소속 조직의 다른 동료가 전달한 블록을 확인할 수 없기 때문에 가십을 활용할 수 없습니다. 따라서 새로 추가 된 피어는 Ordering Service에서 블록을 수신 할 수 있도록 다음 구성 중 하나를 가져야합니다.

1. 정적 리더 모드를 사용하려면 피어를 조직 리더로 구성합니다.

CORE_PEER_GOSSIP_USELEADERELECTION=false
CORE_PEER_GOSSIP_ORGLEADER=true

2. 역동적 인 리더 선거를 사용하려면 리더 선거를 사용하도록 피어를 구성합니다.

CORE_PEER_GOSSIP_USELEADERELECTION = true 
CORE_PEER_GOSSIP_ORGLEADER = false

Join Org3 to the Channel(채널에 Org3 가입)

이 시점에서 채널 구성이 새로운 조직 인 – Org3 –을 포함하도록 업데이트되었습니다. 조직에 연결된 피어가 이제  mychannel에 참여할 수 있습니다.

먼저, Org3 피어 및 Org3 관련 CLI 컨테이너를 시작하십시오.

새 터미널을 열고 Org3 도커 컴포즈  first-network에서 시작 :

docker-compose -f docker-compose-org3.yaml up -d

이 새로운 작성 파일은 초기 네트워크에서 연결되도록 구성되었으므로 두 피어 및 CLI 컨테이너는 기존 피어 및 Order 노드로 해결할 수 있습니다. 이제 세 개의 새 컨테이너가 실행되면서 Org3 관련 CLI 컨테이너로 exec하십시오.

docker exec -it Org3cli bash

초기 CLI 컨테이너에서했던 것처럼 ORDERER_CA 와  CHANNEL_NAME의 두 가지 주요 환경 변수를 내 보냅니다.

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 && export CHANNEL_NAME=mychannel

변수가 올바르게 설정되었는지 확인하십시오.

echo $ORDERER_CA && echo $CHANNEL_NAME

이제  mychannel의 제네시스 블록을 요청하는 ordering service로 보냅니다. ordering service는 성공적인 채널 업데이트 결과로이 통화에 첨부 된 Org3 서명을 확인할 수 있습니다. Org3이 채널 구성에 성공적으로 추가되지 않은 경우 Ordering Service는이 요청을 거부해야합니다.

[Note]
다시 말하지만, ordering node의 로그를 스트리밍하여 서명 / 검증 논리 및 정책 점검을 표시하는 것이 유용 할 수 있습니다.

이 블록을 검색 하려면 다음 peer channel fetch 명령을 사용하십시오.

peer channel fetch 0 mychannel.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

채널의 원장 (즉, genesis block)의 첫 번째 블록을 원한다는 것을 나타 내기 위해 0을 전달합니다.  peer channel fetch config 명령을 단순히 전달하면 블록 5를 수신하게됩니다. Org3이 정의 된 업데이트 된 구성입니다. 그러나 우리는 다운 스트림 블록으로 원장을 시작할 수 없습니다 - 블록 0부터 시작해야합니다.

peer channel join 명령을 실행하고 genesis 블록– mychannel.block을 전달합니다.

peer channel join -b mychannel.block

Org3에 대해 두 번째 피어에 가입하려면  TLS 및  ADDRESS 변수를 내보내고  peer channel join command 명령을 다시 실행하십시오.

export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/tls/ca.crt && export CORE_PEER_ADDRESS=peer1.org3.example.com:7051

peer channel join -b mychannel.block

Upgrade and Invoke Chaincode(체인코드 업그레이드)

퍼즐의 마지막 부분은 체인 코드 버전을 증가시키고 Org3을 포함하도록 Endorsement Policy를 업데이트하는 것입니다. 업그레이드가 다가오고 있음을 알고 있으므로 체인 코드의 버전 1을 설치할 필요가 없습니다. 우리는 Org3이 Endorsement Policy의 일부가 될 새 버전에만 관심이 있으므로 체인 코드의 버전 2로 바로 넘어갈 것입니다.

Org3 CLI에서 :

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

Org3의 두 번째 피어에 체인 코드를 설치하려면 환경 변수를 수정하고 명령을 다시 실행하십시오. 두 번째 설치는 endorsors 역할을하거나 다른 방식으로 원장과 인터페이스 할 동료 (예 : query )에만 체인 코드를 설치하기 만하면되므로 두 번째 설치는 필수 사항이 아닙니다. 피어는 여전히 유효성 검증 논리를 실행하고 체인 코드 컨테이너를 실행하지 않고 커미터로 작동합니다.

이제 원래 CLI 컨테이너로 돌아가서 Org1 및 Org2 피어에 새 버전을 설치하십시오. Org2 관리자 ID로 채널 업데이트 호출을 제출 했으므로 컨테이너는 여전히  peer0.org2를 대신하여 작동합니다.

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

peer0.org1 ID로 전환 :

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 CORE_PEER_ADDRESS=peer0.org1.example.com:7051

그리고 다시 설치하십시오 :

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

이제 체인 코드를 업그레이드 할 준비가되었습니다. 기본 소스 코드를 수정하지 않았으므로 단순히 mychannel 에 – mycc – 라는 체인 코드에 대한 Endorsement Policy에 Org3을 추가하는 것입니다.

[Note]
체인 코드의 인스턴스화 정책을 만족하는 모든 ID는 업그레이드 호출을 발행 할 수 있습니다. 기본적으로 이러한 ID는 채널 관리자입니다.

위의 명령에서  v플래그를 사용하여 새 버전을 지정하고 있음을 알 수 있습니다. 정책에 Org3을 추가하여 승인 정책이 -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')" 로 수정되었음을 알 수 있습니다. 마지막 관심 영역은 생성자 요청 ( c 플래그로 지정)입니다.

인스턴스화 호출과 마찬가지로 체인 코드를 업그레이드하려면  init 메소드를 사용해야합니다. chaincode가 인수를  init 메소드에 전달해야한다면 여기에서해야합니다.

업그레이드 호출은 채널의 원장에 새로운 블록 (블록 6)을 추가하고 Endorsement 단계에서 Org3 피어가 트랜잭션을 실행할 수있게합니다. Org3 CLI 컨테이너로 다시 돌아가서  a의 값에 대한 쿼리를 실행하십시오. 대상 피어에 대해 체인 코드 이미지를 작성해야하고 컨테이너를 시작해야하기 때문에 시간이 조금 걸릴 것입니다.

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

Query Result: 90의 응답을 확인해야합니다.

이제  10을  a에서  b로 이동하기위한 호출을 실행하십시오.

peer chaincode invoke -o orderer.example.com:7050  --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

마지막으로 한 번 쿼리 :

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

이 chaincode’s world state 업데이트를 정확하게 반영하여  Query Result: 80의 응답을 확인해야합니다.

Conclusion(결론)

채널 구성 업데이트 프로세스는 실제로 상당히 복잡하지만 다양한 단계에 대한 논리적 인 방법이 있습니다. 최종 게임은 protobuf 바이너리 형식으로 표현 된 델타 트랜잭션 객체를 형성 한 다음 채널 구성 업데이트 트랜잭션이 채널의 수정 정책을 충족하도록 필요한 수의 관리자 서명을 획득하는 것입니다.

configtxlator 및  jq 도구는 계속 증가하는  peer channel  명령과 함께이 작업을 수행하는 기능을 제공합니다.


http://hyperledger-fabric.readthedocs.io/en/release-1.1/channel_update_tutorial.html

Writing Your First Application(첫번째 애플리케이션 작성)

[Note]
패브릭 네트워크의 기본 아키텍처에 익숙하지 않은 경우 계속하기 전에 먼저 소개 및 기본 네트워크 구성 설명서를 참조하십시오.

이 섹션에서는 Fabric 앱의 작동 방식을 보여주는 몇 가지 샘플 프로그램을 살펴 보겠습니다.  fabcar 라고 하는 이러한 앱 (그리고 그들이 사용하는 스마트 계약(smart contract ))은 Fabric 기능에 대한 폭 넓은 시연을 제공합니다. 특히 우리는 인증 기관과 상호 작용하고 등록 인증서를 생성하는 프로세스를 보여줄 것이며 그 후에 이러한 ID를 활용하여 장부를 쿼리하고 업데이트 할 것입니다.

우리는 세 가지 주요 단계를 거칩니다.



  1. 개발 환경 설정. 우리의 응용 프로그램은 상호 작용할 네트워크가 필요하기 때문에 신청(registration)/등록(enrollment), 쿼리(queries) 및 업데이트(updates)에 필요한 구성 요소 만 다운로드합니다.
  2. 앱에서 사용할 샘플 스마트 계약(Smart contract)의 매개 변수를 학습합니다. 우리의 현명한 계약에는 다양한 방법으로 원장과 상호 작용할 수있는 다양한 기능이 포함되어 있습니다. 우리는 응용 프로그램이 사용할 기능에 대해 배우기 위해 스마트 계약서(Smart contract)를 조사 할 것입니다.
  3. 원장에서 자산을 쿼리하고 업데이트 할 수 있는 응용 프로그램 개발. 앱 코드 자체 (자바 스크립트로 작성된 앱)에 들어가서 변수를 수동으로 조작하여 다양한 종류의 쿼리와 업데이트를 실행합니다.

이 튜토리얼을 완료 한 후에는 Fabric 네트워크에서 장부 (예 : 피어)와 상호 작용할 수있는 스마트 계약서와 함께 애플리케이션을 프로그래밍하는 방법에 대한 기본적인 이해가 필요합니다.

Setting up your Dev Environment(개발자 환경 설정하기)

첫 번째 네트워크 구축을 통해 이미 실행 한 적이 있다면 dev 환경을 설정하고 함께 제공된 패브릭 샘플과 함께 아티팩트를 다운로드해야합니다. 이 자습서를 실행하려면 현재 수행중인 기존 네트워크를 모두 제거해야합니다. 다음을 실행하여 수행 할 수 있습니다.

./byfn.sh -m down

네트워크 및 응용 프로그램에 대한 개발 환경 및 관련 아티팩트가 없는 경우 전제 조건 페이지를 방문 하여 시스템에 필요한 종속성을 설치했는지 확인하십시오.

다음으로, Hyperledger Fabric Samples 페이지를 방문 하여 제공된 지시 사항을 따르십시오. fabric-samples저장소를 복제 한 후에 이 튜토리얼로 돌아가서 최신의 안정된 Fabric 이미지와 사용 가능한 유틸리티를 다운로드하십시오.

이 시점에서 모든 것이 설치되어야합니다. 저장소 fabcar내의 하위 디렉토리로 이동하여 fabric-samples내부 내용을 살펴보십시오.

cd fabric-samples/fabcar  && ls

다음이 보입니다.

enrollAdmin.js     invoke.js       package.json    query.js        registerUser.js startFabric.sh

시작하기 전에 우리는 또한 약간의 정리 작업이 필요합니다.  오래되거나 활성되어 있는 컨테이너를 강제 종료하려면 다음 명령을 실행하십시오.

docker rm -f $(docker ps -aq)

캐시 된 네트워크를 지우십시오.

# Press 'y' when prompted by the command

docker network prune

마지막으로이 튜토리얼을 이미 실행 한 경우 fabcar스마트 계약 의 기본 체인 코드 이미지를 삭제할 수도 있습니다 . 이 콘텐츠를 처음으로 사용하는 사용자는 시스템에 이 체인 코드 이미지가 없습니다.

docker rmi dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba

Install the clients & launch the network( 클라이언트 설치 및 네트워크 시작)

[Note]
다음 지침에서는 fabric-samples repo의 로컬 복제본 내의 fabcar 하위 디렉토리에 있어야합니다. 이 튜토리얼의 나머지 부분에 대해서는이 서브 디렉토리의 루트에 남아 있어야한다.

다음 명령을 실행하여 응용 프로그램에 대한 Fabric 종속성을 설치하십시오. 우리는 우리의 앱 (들)이 CA 서버와 통신하고 신원 자료(identity material)를 검색 할 수있게 해주는 fabric-ca-client에 관심을 가지고 있으며 신원 자료를 로드하고 피어 및 ordering service 와 대화할 수 있는  fabric-client를 사용합니다.

npm install

startFabric.sh  쉘 스크립트를 사용하여 네트워크를 시작하십시오. 이 명령은 다양한 Fabric 엔티티를 회전시키고 Golang으로 작성된 체인 코드 용 스마트 계약 컨테이너를 시작합니다.

./startFabric.sh

또한 Node.js로 작성된 체인 코드에 대해이 자습서를 실행할 수 있습니다 . 이 경로를 찾으려면 다음 명령을 대신 실행하십시오.

./startFabric.sh node

How Applications Interact with the Network(응용 프로그램이 네트워크와 상호 작용하는 방법)

fabcar네트워크의 구성 요소(및 배포 방법)와 응용 프로그램이 세부적인 수준에서 구성 요소와 상호 작용하는 방법에 대한 자세한 내용은 Fabcar 네트워크 이해를 참조하십시오.

응용 프로그램을 보는 데 더 관심이있는 개발자는 물론 응용 프로그램이 어떻게 구성되어 있는지보기 위해 코드 자체를 살펴 보는 등의 작업을 계속해야합니다. 현재 가장 중요한 점은 응용 프로그램이 소프트웨어 개발 키트 (SDK)를 사용하여 원장에 대한 쿼리 및 업데이트를 허용하는 API에 액세스한다는 것입니다.

Enrolling the Admin User(관리 사용자 등록)

[Note]
다음 두 섹션에는 인증 기관과의 통신이 포함됩니다. 다가오는 프로그램을 실행할 때 CA 로그를 스트리밍하는 것이 유용 할 수 있습니다.

CA 로그를 스트리밍하려면 터미널을 분할하거나 새 쉘을 열고 다음을 실행하십시오.

docker logs -f ca.example.com

이제 fabcar콘텐츠로 터미널로 돌아 가세요 ...

네트워크를 시작했을 때 관리자 인 admin이 우리의 인증 기관에 등록되었습니다. 이제 CA 서버에 등록 호출을 보내고 이 사용자의 등록 인증서 (eCert)를 검색해야합니다. 등록 세부 정보는 여기에서 다루지 않겠지만 SDK 및 확장 프로그램에서 관리자 용 사용자 개체를 구성하기 위해이 인증서가 필요하다고 말하는 것으로 충분합니다. 그런 다음이 admin 객체를 사용하여 새 사용자를 등록하고 등록합니다. 관리자 등록 호출을 CA 서버로 보냅니다.

node enrollAdmin.js

이 프로그램은 인증서 서명 요청 (CSR)을 호출하고 궁극적으로 eCert 및 주요 자료를이 프로젝트의 루트에 새로 생성 된 폴더  – hfc-key-store –로 출력합니다. 그러면 Google Apps는 다양한 사용자를 위해 ID 개체를 만들거나 로드해야 할 때이 위치를 찾습니다.

Register and Enroll user1 (user1 의 신청과 등록)

새로 생성 된  admineCert를 사용하여 이제 CA 서버와 통신하여 새 사용자를 등록하고 등록합니다. 이 사용자 – user1 –는 원장을 쿼리하고 업데이트 할 때 사용하는 ID입니다. 새로운 사용자 (즉,이 사용자는 등록 기관의 역할을 맡고 있음)에 대한 등록 및 등록 요청을 발행하는 것이 관리자 ID임을 유의해야합니다. 등록자를 보내고  user1 에 대한 호출을 등록하십시오.

node registerUser.js

관리자 등록과 마찬가지로이 프로그램은 CSR을 호출하고 키와 eCert를 hfc-key-store 하위 디렉토리로 출력합니다. 이제– admin & user1이라는 두 명의 개별 사용자에 대한 신원 자료가 생겼습니다. 장부와 상호 작용할 시간입니다.

Querying the Ledger(원장 조회)

쿼리는 원장에서 데이터를 읽는 방법입니다. 이 데이터는 일련의 키 - 값 쌍으로 저장되며 단일 키, 여러 키의 값을 쿼리 할 수 ​​있습니다. 또는 - 원장이 JSON과 같은 풍부한 데이터 저장 형식으로 작성된 경우 복잡한 키를 검색 할 수 있습니다 ( 예를 들어 특정 키워드가 포함 된 모든 자산을 찾습니다. )

이는 쿼리가 작동하는 방식을 나타냅니다.



먼저  query.js프로그램을 실행하여 원장에있는 모든 자동차의 목록을 반환합시다. 두 번째 ID 인 – user1 –을이 애플리케이션의 서명 엔티티로 사용합니다. 우리 프로그램의 다음 행은  user1을 서명자로 지정합니다.

fabric_client.getUserContext('user1', true);

user1 등록 자료는  hfc-key-store하위 디렉토리에 이미 배치되어 있으므로 응용 프로그램에 해당 ID를 부여하기 만하면됩니다. 정의 된 사용자 객체를 사용하여 이제 장부에서 읽는 작업을 진행할 수 있습니다. 모든 자동차  queryAllCars 를 쿼리하는 함수는 앱에 미리 로드되어 있으므로 간단히 프로그램을 실행할 수 있습니다.

node query.js

다음과 같이 반환되어야 합니다.

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"}}]

이들은 10 대입니다. Adriana 소유의 검은 색 Tesla Model S, Brad 소유의 빨간색 포드 머스탱, Pari 소유의 보라색 Fiat Punto 등등. 원장은 키 - 값을 기반으로하며 구현시 키는  CAR0-  CAR9입니다. 이것은 특히 중요하게 될 것입니다.

이 프로그램을 자세히 살펴 보겠습니다. 편집기 (예 : atom 또는 visual studio)를 사용하고 query.js 를 엽니 다.

응용 프로그램의 초기 섹션에서는 채널 이름, 인증서 저장소 위치 및 네트워크 끝점과 같은 특정 변수를 정의합니다. 우리의 샘플 앱에서는 이러한 변수가 구워졌지만 실제 앱에서는 이러한 변수가 앱 개발자에 의해 지정되어야합니다.

var channel = fabric_client.newChannel('mychannel');
var peer = fabric_client.newPeer('grpc://localhost:7051');
channel.addPeer(peer);

var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store');
console.log('Store path:'+store_path);
var tx_id = null;

이것은 쿼리를 구성하는 청크입니다.

// queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
// queryAllCars chaincode function - requires no arguments , ex: args: [''],
const request = {
  //targets : --- letting this default to the peers assigned to the channel
  chaincodeId: 'fabcar',
  fcn: 'queryAllCars',
  args: ['']
};

응용 프로그램이 실행되면 피어에서  fabcar chaincode를 호출하고 그 안에  queryAllCars함수를 실행 한 다음 인수를 전달하지 않았습니다.

스마트 계약에서 사용 가능한 기능을 살펴 보려면 fabric-samples 의 루트에서 chaincode/fabcar/go  하위 디렉토리로 이동 한 다음 편집기에서 fabcar.go를여십시오.

[Note]
이러한 동일한 기능은 Node.js 버전의 fabcarchaincode 에서 정의됩니다.

initLedgerqueryCarqueryAllCarscreateCar,   changeCarOwner와 같이 호출 할 수 있는 함수가 있음을 알 수 있습니다.

queryAllCars함수가 장부와 어떻게 상호 작용하는지 확인하기 위해 함수를 자세히 살펴 보겠습니다.

func (s *SmartContract) queryAllCars(APIstub shim.ChaincodeStubInterface) sc.Response {

      startKey := "CAR0"
      endKey := "CAR999"

      resultsIterator, err := APIstub.GetStateByRange(startKey, endKey)

queryAllCars의 범위를 정의합니다. CAR0와 CAR999 사이의 모든 자동차 (모든 키가 올바르게 태그되었다고 가정 할 때 1,000 대)가 쿼리에 의해 반환됩니다.

다음은 앱이 chaincode에서 다른 기능을 호출하는 방법을 나타낸 것입니다. 각 함수는 chaincode shim 인터페이스에서 사용 가능한 API에 대해 코딩되어야하며 스마트 계약 컨테이너가 피어 원장과 적절하게 인터페이스 할 수 있습니다.



queryAllCars 함수와  createCar 함수를 볼 수 있습니다. 그러면 createCar 함수를 통해 원장을 업데이트하고 궁극적으로 새로운 블록을 체인에 추가 할 수 있습니다.

하지만 먼저  query.js 프로그램으로 돌아가서 생성자 요청을 편집하여  CAR4를 쿼리합니다.  query.js의 함수를  queryAllCars에서  queryCar로 변경하고  CAR4를 특정 키로 전달하여이를 수행합니다.

query.js 프로그램은 이제 다음과 같이 보입니다.

const request = {
  //targets : --- letting this default to the peers assigned to the channel
  chaincodeId: 'fabcar',
  fcn: 'queryCar',
  args: ['CAR4']
};

프로그램을 저장하고 fabcar디렉토리로 다시 이동하십시오 . 이제 프로그램을 다시 실행하십시오.

node query.js

다음을 보아야합니다.

{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}

돌아가서 전에 모든 차량을 질의 한 결과를 보면 CAR4 가 Adriana의 검정색 Tesla 모델 S임을 알 수 있습니다.이 모델은 여기에 반환 된 결과입니다.

queryCar 함수를 사용하여 모든 키 (예 : CAR0)에 대해 쿼리하고 해당 자동차와 관련된 모든 제조사, 모델, 색상 및 소유자를 가져올 수 있습니다.

좋습니다. 이 시점에서 스마트 컨트렉트의 기본 쿼리 기능과 쿼리 프로그램의 소수의 매개 변수에 익숙해야합니다.

Updating the Ledger(원장 업데이트)

이제는 원장 쿼리를 수행하고 약간의 코드를 추가 했으므로 원장을 업데이트 할 준비가되었습니다. 우리가 할 수있는 많은 잠재적인 업데이트가 있지만 자동차를 만드는 것으로 시작합시다.

아래에서 우리는 이 과정이 어떻게 작동하는지 볼 수 있습니다. 업데이트가 제안되고 승인된 다음 응용 프로그램으로 돌아가서 응용 프로그램에 보내지고 모든 피어의 원장에게 작성되고 순서가 정해집니다.

원장에 대한 우리의 첫 번째 업데이트는 새 차를 만드는 것입니다. 우리는 invoke.js업데이트를 위해 사용할 별도의 자바 스크립트 프로그램을 가지고 있습니다. 쿼리와 마찬가지로 편집기를 사용하여 프로그램을 열고 호출을 구성하는 코드 블록으로 이동합니다.

// createCar chaincode function - requires 5 args, ex: args: ['CAR12', 'Honda', 'Accord', 'Black', 'Tom'],
// changeCarOwner chaincode function - requires 2 args , ex: args: ['CAR10', 'Barry'],
// must send the proposal to endorsing peers
var request = {
  //targets: let default to the peer assigned to the client
  chaincodeId: 'fabcar',
  fcn: '',
  args: [''],
  chainId: 'mychannel',
  txId: tx_id
};

createCar또는changeCarOwner의 두 함수 중 하나를 호출 할 수 있습니다. 먼저 빨간색 Chevy Volt를 만들어 Nick이라는 소유자에게 주자. 우리는 원장 위에서  CAR9 를 사용하기 때문에 여기서 CAR10을 식별 키로 사용합니다. 이 코드 블록을 다음과 같이 편집하십시오.

var request = {
  //targets: let default to the peer assigned to the client
  chaincodeId: 'fabcar',
  fcn: 'createCar',
  args: ['CAR10', 'Chevy', 'Volt', 'Red', 'Nick'],
  chainId: 'mychannel',
  txId: tx_id
};

저장하고 프로그램을 실행하십시오.

node invoke.js

ProposalResponse및 약속과 관련하여 터미널에 약간의 출력이 있을 것입니다. 그러나 우리가 염려하는 것은이 메시지입니다.

The transaction has been committed on peer localhost:7053

이 트랜잭션이 기록되었는지 확인하려면 query.js로 돌아가서 인수를  CAR4에서  CAR10으로 변경하십시오.

즉, 다음과 같이 변경하십시오.

const request = {
  //targets : --- letting this default to the peers assigned to the channel
  chaincodeId: 'fabcar',
  fcn: 'queryCar',
  args: ['CAR4']
};

다시 저장하고 다음 쿼리를 수행하십시오.

node query.js

어떤 결과가 나옵니까?

Response is  {"colour":"Red","make":"Chevy","model":"Volt","owner":"Nick"}

축하. 당신은 차를 만들었습니다!

이제 우리는 그렇게 해 Nick 이 기분이 좋고 데이브 (Dave)라는 누군가에게 시보레 볼트 (Chevy Volt)를 주고 싶다고 합시다.

이를 수행하려면 invoke.js  로 돌아가서 함수를  createCar에서  changeCarOwner로 변경하고 다음과 같은 인수를 입력하십시오.

var request = {
  //targets: let default to the peer assigned to the client
  chaincodeId: 'fabcar',
  fcn: 'changeCarOwner',
  args: ['CAR10', 'Dave'],
  chainId: 'mychannel',
  txId: tx_id
};

첫번째 논쟁 – CAR10 –는 소유자를 바꿀 차를 반영합니다. 두 번째 인수 인 – Dave –는 자동차의 새 소유자를 정의합니다.

저장하고 프로그램을 다시 실행하십시오.

node invoke.js

이제 장부에 다시 ​​쿼리하여 Dave가 이제 CAR10키 와 연결되었는지 확인하십시오 .

node query.js

이 결과를 반환해야합니다.

Response is  {"colour":"Red","make":"Chevy","model":"Volt","owner":"Dave"}

CAR10의 소유권이 Nick에서 Dave로 변경되었습니다.

[Note]
실제 응용 프로그램에서 chaincode에는 액세스 제어 논리가 있을 수 있습니다. 예를 들어 특정 승인 된 사용자만 새 자동차를 만들 수 있으며 자동차 소유자만 자동차를 다른 사람에게 양도 할 수 있습니다.

Summary(요약)

이제는 몇 가지 쿼리와 업데이트를 수행 했으므로 응용 프로그램이 네트워크와 상호 작용하는 방식을 이해해야합니다. 스마트 계약, API 및 SDK가 쿼리 및 업데이트에서 수행하는 역할의 기본 사항을 확인했으며 다른 비즈니스 작업 및 작업을 수행하는 데 사용할 수있는 다양한 종류의 응용 프로그램에 대한 느낌을 알고 있어야합니다.

후속 문서에서는 스마트 계약을 실제로 작성하는 방법과 이러한 낮은 수준의 응용 프로그램 기능 중 일부를 활용할 수있는 방법 (특히 신원 및 멤버십 서비스 관련)을 배우게됩니다.

Additional Resources(추가 자료)

Hyperledger Fabric Node SDK Repo는 더 자세한 문서 및 샘플 코드를 위한 훌륭한 리소스입니다. 패브릭 커뮤니티 및 Hyperledger Rocket Chat의 구성 전문가에게 문의 할 수도 있습니다.


출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/write_first_app.html

Building Your First Network(첫 번째 네트워크 구축)

[Note]
이 지침은 제공된 tar 파일 내의 최신 안정된 Docker 이미지와 사전 컴파일된 설치 유틸리티에 대해 작동하는 것으로 확인되었습니다. 현재 마스터 브랜치의 이미지나 도구로 이 명령을 실행하면 구성 및 패닉에러(panic errors) 가 표시될 수 있습니다.

첫 번째 네트워크 (BYFN) 시나리오를 구축하면 2개의 피어 노드(peer nodes)를 유지 관리하는 두 개의 조직과 "solo" ordering service로 구성된 샘플 Hyperbelger 패브릭 네트워크가 프로비저닝됩니다.

Install prerequisites(필수 구성요소 설치)

시작하기 전에 아직 수행하지 않은 경우, 블록 체인 응용 프로그램을 개발하거나 Hyperledger Fabric을 운영 할 플랫폼에 모든 필수 구성 요소가 설치되어 있는지 확인하십시오.

또한 Hyperledger Fabric Samples를 다운로드하여 설치해야합니다.  fabric-samples 레파지토리에는 많은 샘플이 포함되어 있습니다.  first-network 샘플을 사용할 것입니다. 이제 그 하위 디렉토리를 열어 봅시다.

cd fabric-samples/first-network

Want to run it now?

우리는 2개의 다른 조직(organizations)을 대표하는 4명의 peer와 orderer node로 구성된 Hyperledger Fabric network 를 신속하게 bootstrap하기 위해 이러한 Docker 이미지를 활용하는 완전히 주석한 스크립트 (byfn.sh)를 제공합니다. 또한 피어를 채널에 참여시키고 체인코드(chaincode)를 배포 및 인스턴스화(instantiate)하며 배포된 체인 코드(the deployed chaincode)에 대한 트랜잭션하는 스크립트를 실행할 수 있는 컨테이너를 시작합니다.

byfn.sh  스크립트의 도움말 텍스트는 다음과 같습니다.

./byfn.sh --help
Usage:
byfn.sh up|down|restart|generate [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>]
byfn.sh -h|--help (print this message)
# docker compose의 모드를 선택합니다.
  -m <mode> - one of 'up', 'down', 'restart' or 'generate'
    - 'up' - bring up the network with docker-compose up
    - 'down' - clear the network with docker-compose down
    - 'restart' - restart the network
    - 'generate' - generate required certificates and genesis block
# 채널이름을 사용합니다
  -c <channel name> - channel name to use (defaults to "mychannel")
# cli의 타임아웃 시간을 설정합니다. 
  -t <timeout> - CLI timeout duration in seconds (defaults to 10)
# delay 시간을 설정합니다.
  -d <delay> - delay duration in seconds (defaults to 3)
# 특정 docker compose file을 사용합니다.
  -f <docker-compose-file> - specify which docker-compose file use (defaults to docker-compose-cli.yaml)
# 데이터베이스 백앤드를 사용합니다. goleveldb(디폴트) 또는 couchdb
  -s <dbtype> - the database backend to use: goleveldb (기본) or couchdb
# 체인코드 언어를 선택합니다. golang(기본) 또는 node 
  -l <language> - the chaincode language: golang (default) or node
# 진행전에 확인을 하지 않는 옵션
  -a - don't ask for confirmation before proceeding

  Typically, one would first generate the required certificates and
  genesis block, then bring up the network. e.g.:
# 일반적으로, 먼저 필요한 인증서와 생성 블록을 생성 한 다음 네트워크를 시작합니다. 예 :

      byfn.sh -m generate -c mychannel
      byfn.sh -m up -c mychannel -s couchdb

채널 이름을 제공하지 않기로 선택하면 스크립트는 기본 이름인 mychannel을 사용합니다. CLI 시간 초과 매개 변수 (-t 플래그로 지정)는 선택적 값입니다. 설정하지 않으려는 경우 CLI는 기본 설정 인 10초 후에 수행된 쿼리 요청을 하지않습니다.

Generate Network Artifacts(네트워크 아키팩트 생성)

준비사항이 끝났으면 다음 명령을 실행하십시오.

./byfn.sh -m generate

yes/no 커맨드 라인(command line) 프롬프트와 함께 일어날 일에 대한 간단한 설명을 볼 수 있습니다. 설명된 사항을 실행하려면 y로 응답하거나 리턴 키(return key)를 누르십시오.

# 채널 'mychannel'및 CLI 시간 초과 '10'을 사용하여 certs 및 genesis block 생성 계속 하시겠습니까? [Y / n] y
Generating certs and genesis block for with channel 'mychannel' and CLI timeout of '10'
Continue? [Y/n] y
proceeding ...
/Users/xxx/dev/fabric-samples/bin/cryptogen

##########################################################
##### Generate certificates using cryptogen tool #########
##########################################################
org1.example.com
2017-06-12 21:01:37.334 EDT [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP.
...

/Users/xxx/dev/fabric-samples/bin/configtxgen
##########################################################
#########  Generating Orderer Genesis block ##############
##########################################################
2017-06-12 21:01:37.558 EDT [common/configtx/tool] main -> INFO 001 Loading configuration
2017-06-12 21:01:37.562 EDT [msp] getMspConfig -> INFO 002 intermediate certs folder not found at [/Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts]. Skipping.: [stat /Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts: no such file or directory]
...
2017-06-12 21:01:37.588 EDT [common/configtx/tool] doOutputBlock -> INFO 00b Generating genesis block
2017-06-12 21:01:37.590 EDT [common/configtx/tool] doOutputBlock -> INFO 00c Writing genesis block

#################################################################
### Generating channel configuration transaction 'channel.tx' ###
#################################################################
2017-06-12 21:01:37.634 EDT [common/configtx/tool] main -> INFO 001 Loading configuration
2017-06-12 21:01:37.644 EDT [common/configtx/tool] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx
2017-06-12 21:01:37.645 EDT [common/configtx/tool] doOutputChannelCreateTx -> INFO 003 Writing new channel tx

#################################################################
#######    Generating anchor peer update for Org1MSP   ##########
#################################################################
2017-06-12 21:01:37.674 EDT [common/configtx/tool] main -> INFO 001 Loading configuration
2017-06-12 21:01:37.678 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update
2017-06-12 21:01:37.679 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update

#################################################################
#######    Generating anchor peer update for Org2MSP   ##########
#################################################################
2017-06-12 21:01:37.700 EDT [common/configtx/tool] main -> INFO 001 Loading configuration
2017-06-12 21:01:37.704 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update
2017-06-12 21:01:37.704 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update

이 첫 번째 단계는 다양한 네트워크 엔티티에 대한 모든 인증서와 키, 오더링 서비스(the ordering service)를 부트스트랩 하는 데 사용되는  genesis block 및 채널을 구성하는 데 필요한 구성 트랜잭션 모음을 생성합니다.

Bring Up the Network(네트워크 가동)

다음 명령어를 수행시켜 네트워크를 가동합니다.

./byfn.sh -m up

위의 명령은 Golang 체인 코드 이미지를 컴파일하고 해당 컨테이너를 실행시킵니다. Go는 기본 체인 코드 언어이지만 Node.js 체인 코드도 지원됩니다. 노드 체인 코드를 사용하여이 자습서를 실행하려면 다음 명령을 대신 전달하십시오.

# 우리는 chaincode 언어를 지정하기 위해 -l 플래그를 사용합니다.
# -l 플래그를 지정하면 Golang이 기본값이 됩니다.

./byfn.sh -m up -l node

다시 한 번, 계속하거나 중단 할 것인지 묻는 메시지가 나타납니다. y로 응답하거나 return 키를 누르십시오.

Starting with channel 'mychannel' and CLI timeout of '10'
Continue? [Y/n]
proceeding ...
Creating network "net_byfn" with the default driver
Creating peer0.org1.example.com
Creating peer1.org1.example.com
Creating peer0.org2.example.com
Creating orderer.example.com
Creating peer1.org2.example.com
Creating cli


 ____    _____      _      ____    _____
/ ___|  |_   _|    / \    |  _ \  |_   _|
\___ \    | |     / _ \   | |_) |   | |
 ___) |   | |    / ___ \  |  _ <    | |
|____/    |_|   /_/   \_\ |_| \_\   |_|

Channel name : mychannel
Creating channel...

여기에서 로그가 계속됩니다. 이렇게 하면 모든 컨테이너가 시작되고 완전한 종단 간 응용 프로그램(end-to-end application) 시나리오가 시작됩니다. 성공적으로 완료되면 터미널 창에서 다음을 보고해야 합니다.

Query Result: 90
2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting.....
===================== Query on peer1.org2 on channel 'mychannel' is successful =====================

===================== All GOOD, BYFN execution completed =====================


 _____   _   _   ____
| ____| | \ | | |  _ \
|  _|   |  \| | | | | |
| |___  | |\  | | |_| |
|_____| |_| \_| |____/

이러한 로그를 스크롤하여 다양한 트랜잭션을 볼 수 있습니다. 이 결과를 얻지 못하면 문제 해결 섹션으로 넘어가 무엇이 잘못되었는지 발견 할 수 있는지 알아 보겠습니다.

Bring Down the Network(가동중인 네트워크 중단)

마지막으로 한 번에 명령어로 설정되어 있던 네트워크를 중단할 수 있습니다. 다음은 컨테이너를 죽이고( kill your containers), 암호 자료( crypto material)와 4가지 아티팩트(artifacts)를 제거하고, Docker 레지스트리에서 chaincode 이미지를 삭제합니다.

./byfn.sh -m down

다시 한 번 계속하기를 원하면 y로 응답하거나 return 키를 누르십시오.

Stopping with channel 'mychannel' and CLI timeout of '10'
Continue? [Y/n] y
proceeding ...
WARNING: The CHANNEL_NAME variable is not set. Defaulting to a blank string.
WARNING: The TIMEOUT variable is not set. Defaulting to a blank string.
Removing network net_byfn
468aaa6201ed
...
Untagged: dev-peer1.org2.example.com-mycc-1.0:latest
Deleted: sha256:ed3230614e64e1c83e510c0c282e982d2b06d148b1c498bbdcc429e2b2531e91
...

기본 툴링 및 부트 스트랩 메커니즘에 대해 더 자세히 알고 싶으면 계속 읽으십시오. 다음 섹션에서는 완전한 기능의 Hyperledger 패브릭 네트워크를 구축하기위한 다양한 단계와 요구 사항을 살펴 보겠습니다.

[Note]
아래에 설명된 수동 단계에서는 cli 컨테이너의 CORE_LOGGING_LEVEL이 DEBUG로 설정되어 있다고 가정합니다. 첫 번째 네트워크 디렉토리의 docker-compose-cli.yaml 파일을 수정하여 이를 설정할 수 있습니다. 예 :

cli:
  container_name: cli
  image: hyperledger/fabric-tools:$IMAGE_TAG
  tty: true
  stdin_open: true
  environment:
    - GOPATH=/opt/gopath
    - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
    - CORE_LOGGING_LEVEL=DEBUG
    #- CORE_LOGGING_LEVEL=INFO

Crypto Generator(암호 생성기)

cryptogen 도구를 사용하여 다양한 네트워크 엔터티에 대한 암호 자료 (x509[1] 인증서 및 서명 키)를 생성합니다. 이 인증서는 신원을 나타내며 당사 엔티티가 통신하고 트랜잭션 할 때 서명/확인(sign/verify ) 인증을 수행할 수 있습니다.

How does it work?(어떻게 작동합니까?)

Cryptogen은 네트워크 토폴로지를 포함하고 있는 - crypto-config.yaml - 파일을 사용하며 조직(Organizations)과 해당 조직(Organizations)에 속한 구성 요소 모두에 대한 인증서 및 키 세트를 생성 할 수 있습니다. 각 조직(Organizations)에는 특정 구성 요소(peers and orderers)를 해당 조직에 바인딩하는 고유 루트 인증서(ca-cert)가 제공됩니다. 각 조직에 고유 한 CA 인증서를 할당하여 참여하는 회원(Memeber)이 자체 인증 기관을 사용하는 일반적인 네트워크를 모방합니다. Hyperledger Fabric 내의 트랜잭션 및 통신은 엔티티의 개인 키 (keystore)에 의해 서명 된 다음 공개 키(signcerts)를 통해 검증됩니다.

이 파일 내에  count변수가 있음을 알 수 있습니다. 우리는 이를 사용하여 조직 당 피어의 수를 지정합니다. 우리의 경우 Org 당 2명의 피어(peers)가 있습니다. 우리는 지금 x.509 인증서 및 공개 키 인프라의 세부 사항을 조사하지 않을 것입니다. 관심이 있다면, 다음 링크를 읽어보세요.

이 도구를 실행하기 전에crypto-config.yaml의 스니펫(snippet)을 간단히 살펴 보겠습니다. OrdererOrgs 헤더 아래의 "Name", "Domain"및 "Specs"매개 변수에 특히 주의하십시오.

OrdererOrgs:
#---------------------------------------------------------
# Orderer
# --------------------------------------------------------
- Name: Orderer
  Domain: example.com
  CA:
      Country: US
      Province: California
      Locality: San Francisco
  #   OrganizationalUnit: Hyperledger Fabric
  #   StreetAddress: address for org # default nil
  #   PostalCode: postalCode for org # default nil
  # ------------------------------------------------------
  # "Specs" - See PeerOrgs below for complete description
# -----------------------------------------------------
  Specs:
    - Hostname: orderer
# -------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
 # ------------------------------------------------------
PeerOrgs:
# -----------------------------------------------------
# Org1
# ----------------------------------------------------
- Name: Org1
  Domain: org1.example.com
  EnableNodeOUs: true

네트워크 엔터티의 명명 규칙은 "{{.Hostname}}.{{.Domain}}" 입니다. 따라서  ordering node를 참조점으로 사용하여  Orderer의 MSP ID에 연결된  orderer.example.com 이라는 ordering node가 남습니다. 이 파일에는 정의 및 구문에 대한 광범위한 설명서가 들어 있습니다. MSP에 관한보다 자세한 정보는  Membership Service Providers (MSP) 문서를 참조하십시오.  cryptogen도구를 실행하면 생성 된 인증서와 키가  crypto-config 라는 폴더에 저장됩니다.

Configuration Transaction Generator(트랜잭션 생성기 구성)

configtxgen tool는 4가지 구성 아티팩트(Artifact)[2]를 만드는 데 사용됩니다.

  • orderer genesis block,
  • channel configuration transaction,
  • and two anchor peer transactions - one for each Peer Org.

이 도구의 기능에 대한 자세한 내용은 configtxgen 을 참조하십시오.

Orderer 블록은 ordering service를 위한 Genesis Block이며 채널 구성 트랜잭션 파일은 채널(Channel) 생성시 orderer에게 브로드캐스트(broadcast)됩니다. 앵커 피어(The anchor peer) 트랜잭션은 이름에서 알 수 있듯이 이 채널에서 각 조직의 앵커 피어(anchor peer)를 지정합니다.

How does it work?(어떻게 작동합니까?)

Configtxgen은 샘플 네트워크의 정의가 들어있는 파일 ( - configtx.yaml -)을 사용합니다. 각 피어 노드를 관리하고 유지 관리하는 Orderer Org (OrdererOrg) 와 Peer Org (Org1 & Org2)의 세 멤버가 있습니다. 이 파일은 또한 2개의 Peer Orgs로 구성된 컨소시엄  - SampleConsortium -을 지정합니다. 이 파일 맨 위에있는 "프로필"섹션에 특히 주의하십시오. 2개의 고유한 헤더가 있음을 알 수 있습니다. 고유한 2개의 헤더는 orderer genesis block 인 - TwoOrgsOrdererGenesis -과 채널의  - TwoOrgsChannel - 입니다.

이러한 헤더는 중요합니다. 우리가 아티팩트를 생성 할 때 인수로 전달합니다.

[Note]
SampleConsortium은 시스템 레벨 프로필에 정의된 다음 채널 레벨 프로필에서 참조됩니다. 컨소시엄의 범위 내에 채널이 존재하며, 모든 컨소시엄은 네트워크 범위 전체에 정의되어야합니다.

이 파일에는 주목할 가치가 있는 두 가지 추가 사양이 포함되어 있습니다.

첫 번째, 각 피어 조직 (peer0.org1.example.com & peer0.org2.example.com)에 대한 앵커 피어(the anchor peers)를 지정합니다.

두 번째, 우리는 각 구성원에 대한 MSP 디렉토리의 위치를 가리키며 차례로 Orderer genesis block에 각 Org에 대한 루트 인증서를 저장할 수 있습니다. 이것은 중요한 개념입니다.

이제 Ordering service와 통신하는 모든 네트워크 엔터티는 디지털 서명을 확인할 수 있습니다.

Run the tools(툴즈 실행)

configtxgen 및  cryptogen 명령을 사용하여 인증서/키(certificates/keys) 및 다양한 구성 아티팩트를 수동으로 생성 할 수 있습니다. 또는, 목표를 달성하기 위해 byfn.sh 스크립트를 적용 할 수도 있습니다.

Manually generate the artifacts(수동으로 아티팩트 생성하기)

byfn.sh 스크립트의  generateCerts 함수를 참조하여  crypto-config.yaml파일에 정의 된대로 네트워크 구성에 사용될 인증서를 생성하는 데 필요한 명령을 참조 할 수 있습니다. 그러나 편의를 위해 여기서도 참조 할 것입니다.

우선 cryptogen 도구를 실행 해 봅시다. 우리의 바이너리는  bin 디렉토리에 있으므로 도구(tool)가 있는 상대 경로를 제공해야합니다.

../bin/cryptogen generate --config=./crypto-config.yaml

터미널에서 다음을 보아야합니다.

org1.example.com
org2.example.com

인증서 및 키 (즉, MSP 자료)는  first-network 디렉토리의 루트에 있는- crypto-config -디렉토리로 출력됩니다.

다음으로, configtxgen 도구를 사용하기 위해 configtx.yaml 파일의 위치를 알려줄 필요가 있습니다. 우리는 현재의 작업 디렉토리를 살펴볼 것입니다 :

export FABRIC_CFG_PATH=$PWD

그런 다음  configtxgen 도구를 호출하여 orderer genesis block 을 만듭니다.

../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

터미널에서 다음과 비슷한 출력이 표시되어야합니다.

2017-10-26 19:21:56.301 EDT [common/tools/configtxgen] main -> INFO 001 Loading configuration
2017-10-26 19:21:56.309 EDT [common/tools/configtxgen] doOutputBlock -> INFO 002 Generating genesis block
2017-10-26 19:21:56.309 EDT [common/tools/configtxgen] doOutputBlock -> INFO 003 Writing genesis block

Create a Channel Configuration Transaction(채널 구성 트랜잭션 생성하기)

다음에는 채널 트랜잭션 아티팩트( the channel transaction artifact)를 생성해야 합니다. 다음에 따라 사용할 수있는 환경 변수로 $CHANNEL_NAME을 (를) 바꾸거나 CHANNEL_NAME을 (를) 설정( set CHANNEL_NAME)하십시오.

# The channel.tx artifact contains the definitions for our sample channel
# channel.tx artifact에는 샘플 채널에 대한 정의가 포함되어 있습니다.

export CHANNEL_NAME=mychannel  && ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

터미널에서 다음과 유사한 출력을 볼 수 있습니다.

2017-10-26 19:24:05.324 EDT [common/tools/configtxgen] main -> INFO 001 Loading configuration
2017-10-26 19:24:05.329 EDT [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx
2017-10-26 19:24:05.329 EDT [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 003 Writing new channel tx

다음으로 우리가 구성 할 채널에서 Org1의 앵커 피어를 정의합니다. 다시 말하지만  $CHANNEL_NAME을 바꾸거나 다음 명령에 대한 환경 변수를 설정하십시오. 터미널 출력은 채널 트랜잭션 아티팩트의 출력을 모방합니다.

../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP

이제 Org2에 대한 앵커 피어를 동일한 채널에서 정의합니다.

../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP

Start the network(네트워크 시작하기)

script를 활용하여 네트워크를 시작할 것입니다. docker-compose 파일은 이전에 다운로드 한 이미지를 참조하고 이전에 생성 된 genesis.block으로 orderer를 부트스트랩(bootstraps)합니다.

우리는 각 호출을 통해 사용구문과 기능을 보이기 위해 명령을 수동으로 수행하려고 합니다.

먼저 네트워크를 시작하십시오.

docker-compose -f docker-compose-cli.yaml up -d

네트워크의 실시간 로그를 보려면  -d플래그를 제공하지 마십시오. 로그 스트림을 보내려면 CLI 호출을 실행하기 위해 두 번째 터미널을 열어야 합니다.

CLI 컨테이너는 1000 초 동안 유휴 State를 유지합니다. 필요가 있을 때 사라졌다면 간단한 명령으로 다시 시작할 수 있습니다:

docker start cli

Environment variables(환경 변수)

peer0.org1.example.com에 대한 다음 CLI 명령이 작동하려면 아래에 제시된 4개의 환경 변수를 사용하여 명령을 시작해야합니다.  peer0.org1.example.com에 대한 이러한 변수는 CLI 컨테이너에 저장되므로 그것을 전달하지 않고 운영할 수 있습니다. 그러나 다른 peer 또는 Orderer에게 보내려면 해당 값을 적절하게 제공해야합니다. docker-compose-base.yaml 에서 특정 경로를 검사합니다.

# Environment variables for PEER0

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID="Org1MSP"
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

Create & Join Channel(채널 생성 및 조인)

위의 <채널 구성 트랜잭션 만들기> 절의 configtxgen 도구를 사용하여 채널 구성 트랜잭션을 만들었습니다. 이 프로세스를 반복하여 configtxgen 도구에 전달한configtx.yaml 의 동일하거나 다른 프로필을 사용하여 추가 채널 구성 트랜잭션을 만들 수 있습니다. 그런 다음이 섹션에서 정의한 프로세스를 반복하여 네트워크에 다른 채널을 설정할 수 있습니다.

docker exec 명령을 사용하여 CLI 컨테이너에 들어갑니다.

docker exec -it cli bash

성공하면 다음이 표시됩니다.

root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#

다음으로 생성 된 채널 구성 트랜잭션 아티팩트를 전달합니다. 채널 생성 요청의 일환으로 Orderer에게 채널 구성 트랜잭션 생성 섹션 ( channel.tx라고 함)에서 생성 한 내용을 확인하십시오.

채널 이름을 -c 플래그로 지정하고 채널 구성 트랜잭션을  -f 플래그로 지정합니다. 이 경우에는  channel.tx이지만 다른 이름으로 구성 트랜잭션을 마운트 할 수 있습니다. 이 인수를 명시적으로 전달할 필요가 없도록 CLI 컨테이너 내에 CHANNEL_NAME환경 변수를 설정합니다.

export CHANNEL_NAME=mychannel

# the channel.tx file is mounted in the channel-artifacts directory within your CLI container
# as a result, we pass the full path for the file
# we also pass the path for the orderer ca-cert in order to verify the TLS handshake
# be sure to export or replace the $CHANNEL_NAME variable appropriately

peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.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

이 명령은 채널에 참여하는 데 사용하는  genesis block - <channel-ID.block> - 을 반환합니다. channel.tx에 지정된 구성 정보가 들어 있습니다. 기본 채널 이름을 수정하지 않은 경우 mychannel.block이라는 제목의 프로토 타입이 반환됩니다.

[Note]
이러한 나머지 수동 명령은 CLI 컨테이너에 남아 있습니다. peer0.org1.example.com 이외의 다른 피어를 대상으로 할 때는 모든 명령 앞에 해당 환경 변수를 사용하는 것을 기억해야합니다.

이제  peer0.org1.example.com을 채널에 가입시켜 보겠습니다.

# 디폴트로, 이것은``peer0.org1.example.com``에만 합류합니다
# 이전 명령에서 <channel-ID.block>을 반환했습니다.
# 채널 이름을 수정하지 않으면 mychannel.block과 함께 참여하게됩니다.
# 다른 채널 이름을 만든 경우 적절하게 명명된 블록을 전달하십시오.

peer channel join -b mychannel.block

위의 환경 변수 섹션에서 사용한 4가지 환경 변수를 적절히 변경하여 다른 피어가 필요에 따라 채널에 참여하도록 만들 수 있습니다.

모든 피어에 가입하는 대신 peer0.org2.example.com 에 간단히 가입하여 채널의 앵커 피어 정의를 올바르게 업데이트 할 수 있습니다. CLI 컨테이너에 구워진 기본 환경 변수를 무시하므로이 전체 명령은 다음과 같습니다.

Update the anchor peers(앵커 피어 업데이트)

다음 명령은 채널 업데이트이며 채널의 정의로 전파됩니다. 본질적으로 채널의 기원 블록(the channel’s genesis block) 상단에 추가 구성 정보를 추가합니다.genesis block을 수정하는 것이 아니라 단순히 앵커 피어를 정의하는 체인에 델타(deltas)를 추가하는 것입니다.

channel 정의를 업데이트하여 Org1의 앵커 피어를  peer0.org1.example.com 으로 정의합니다.

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 피어의 피어 채널 조인 명령과 동일하게 이 호출을 적절한 환경 변수로 시작해야 합니다.

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

Install & Instantiate Chaincode(체인코드 설치 & 인스턴스화)

[Note]
우리는 단순한 기존 chaincode를 활용할 것입니다. 독자적인 체인 코드를 작성하는 방법을 배우려면, 개발자 용 Chaincode 자습서(http://hyperledger-fabric.readthedocs.io/en/release-1.1/chaincode4ade.html)를 참조하십시오.

응용 프로그램은  chaincode를 통해 블록 체인 원장과 상호 작용합니다. 따라서 트랜잭션을 실행하고 Endorse할 모든 피어에 체인 코드를 설치 한 다음 채널에서 체인 코드를 인스턴스화해야합니다.

먼저 샘플 Go 또는 Node.js 체인 코드를 4개의 피어 노드 중 하나에 설치하십시오. 이 명령은 지정된 소스 코드를 피어의 파일 시스템에 배치합니다.

[Note]
체인 코드 이름 및 버전 당 한 버전의 소스 코드 만 설치할 수 있습니다. 소스 코드는 체인 코드 이름과 버전의 컨텍스트에서 피어의 파일 시스템에 존재합니다. 그것은 언어에 상관없습니다. 마찬가지로 인스턴스화 된 chaincode 컨테이너는 피어에 설치된 언어를 반영합니다.

Golang

# this installs the Go chaincode
peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/

Node.js

# this installs the Node.js chaincode
# make note of the -l flag; we use this to specify the language
peer chaincode install -n mycc -v 1.0 -l node -p /opt/gopath/src/github.com/chaincode/chaincode_example02/node/

그런 다음 채널에서 체인 코드를 인스턴스화합니다. 그러면 채널의 체인 코드가 초기화되고 체인 코드에 대한 Endorsement Policy가 설정되며 대상 피어에 대해 체인 코드 컨테이너가 시작됩니다. -P 인수에 유의하십시오 . 이것은 우리의 정책으로,이 체인 코드에 대한 트랜잭션의 유효성을 검증하는 데 필요한 Endorsement Level을 지정합니다.

아래 명령에서 정책을 -P "OR ('Org0MSP.peer','Org1MSP.peer')" 로 지정한다는 것을 알 수 있습니다. 즉, Org1 OR Org2에 속한 피어 (즉, 단 하나의 Endorsement)로부터 "Endorsement"해야합니다. 구문을  AND 로 변경하면 2가지 Endorsement가 필요합니다.

Golang

# $CHANNEL_NAME 환경 변수를 내보내지 않은 경우 이를 바꿔야 합니다.
# mycc라는 이름의 체인 코드를 설치하지 않았다면 그 인수도 수정하십시오.

peer chaincode instantiate -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 $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')"

Node.js

[Note]
Node.js 체인 코드의 인스턴스 생성은 대략 1분 정도 소요됩니다. 이 명령은 걸려 있지 않습니다. 이미지가 편집 될 때  fabric-shim을 설치하고 있습니다.
The instantiation of the Node.js chaincode will take roughly a minute. The command is not hanging; rather it is installing the fabric-shim layer as the image is being compiled.

정책 구현에 대한 자세한 내용은 Endorsement Policy 문서를 참조하십시오.

추가 피어가 원장과 상호 작용하게 하려면 해당 피어를 원장과 연결해야 하며 체인 코드 소스의 이름, 버전 및 언어를 해당 피어의 파일 시스템에 설치해야합니다. 체인 코드 컨테이너는 특정 체인 코드와 상호 작용하는 즉시 각 피어에 대해 실행됩니다. 다시 말하지만, Node.js 이미지가 더 느리게 컴파일된다는 사실을 인식하십시오.

체인 코드가 채널에서 인스턴스화되면  l 플래그를 무시할 수 있습니다. 채널 식별자와 체인 코드 이름 만 전달하면됩니다.

Query(쿼리)

체인 코드가 올바르게 인스턴스화되고 State DB가 채워 졌는지 확인하기 위해  a 의 값을 쿼리(query)합니다. 쿼리(query)의 구문은 다음과 같습니다.

# -C와 -n 플래그를 적절하게 설정해야한다.
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

Invoke(호출, 업데이트)

이제  10을  a에서 b로 이동합시다. 이 트랜잭션은 새 블록을 잘라내어 State DB를 업데이트합니다. 호출(invoke) 구문은 다음과 같습니다.

# -C와 -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 $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

Query(쿼리)

우리의 이전 호출(invocation )이 제대로 실행되었는지 확인합시다. 키 a를  100으로 초기화하고 이전 호출을 사용하여  10 을 제거했습니다. 따라서 a에 대한 쿼리는  90 을 나타내야합니다. 쿼리 구문은 다음과 같습니다.

# -C와 -n 플래그를 적절하게 설정해야한다.
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

결과는 다음과 같습니다.

Query Result: 90

처음부터 다시 시작하여 키 값 쌍 및 후속 호출을 수정하여 실습해보세요.

What’s happening behind the scenes?(그 뒤에서 무슨 일이 일어나나요?)

[Note]
이 단계에서는 script.sh가 './byfn.sh up'에 의해 실행되는 시나리오를 설명합니다. ./byfn.sh를 사용하여 네트워크를 정리하고 이 명령이 활성 State인지 확인하십시오. 그런 다음 동일한 도커 작성 프롬프트를 사용하여 네트워크를 다시 시작하십시오.
  • 스크립트 - script.sh - 는 CLI 컨테이너에서 실행됩니다. 스크립트는 제공된 채널 이름에 대해  createChannel명령을 실행하고 채널 구성에 channel.tx 파일을 사용합니다.
  • createChannel의 출력은 피어들의 파일 시스템에 저장되고 channel.tx에서 지정된 채널 구성을 포함하는 genesis block 인  - <your_channel_name>.block - 입니다.
  • joinChannel 명령은 이전에 생성된 genesis block을 입력으로 사용하는 4개의 모든 피어에 대해 실행됩니다. 이 명령은 피어가 <your_channel_name> 에 가입하고  <your_channel_name>.block으로 시작하는 체인을 만들도록 지시합니다.
  • 이제 우리에게는 4 명의 피어와 2 개의 조직으로 구성된 채널이 있습니다. 이것은 TwoOrgsChannel 프로필입니다.
  • peer0.org1.example.com  및 peer1.org1.example.com 은 Org1에 속합니다.  peer0.org2.example.com 및  peer1.org2.example.com은 Org2에 속합니다.
  • 이러한 관계는  crypto-config.yaml을 통해 정의되며 MSP 경로는 docker compose에서 지정됩니다.
  • Org1MSP  (peer0.org1.example.com) 및 Org2MSP (peer0.org2.example.com)의 앵커 피어(anchor peers)가 업데이트됩니다.  Org1MSPanchors.txOrg2MSPanchors.tx 아티팩트를 채널 이름과 함께 Ordering service에 전달하여 이 작업을 수행합니다.
  • 체인코드- chaincode_example02 -는 peer0.org1.example.com  및 peer0.org2.example.com에 설치됩니다.
  • 그런 다음 chaincode는  peer0.org2.example.com 에서 "인스턴스화(instantiated)"됩니다. 인스턴스화(Instantiation )는 채널에 체인 코드를 추가하고 대상 피어에 대한 컨테이너를 시작하며 체인 코드와 연관된 키 값 쌍을 초기화합니다( initializes the key value pairs associated with the chaincode). 이 예제의 초기 값은 [ "a", "100" "b", "200"]입니다. 이 "인스턴스화"는 dev-peer0.org2.example.com-mycc-1.0 이라는 이름으로 컨테이너를 시작합니다.
  • 이 인스턴스화는 Endorsement Policy에 대한 인수도 전달합니다. 이 정책은  -P "OR    ('Org1MSP.peer','Org2MSP.peer')" 로 정의됩니다. 이는 모든 트랜잭션이 Org1 또는 Org2에 연결된 피어에 의해 Endorse되어야 함을 의미합니다.
  • peer0.org1.example.com에 "a"값에 대한 쿼리가 발행됩니다. chaincode는 이전에  peer0.org1.example.com 에 설치되었으므로 Org1 peer0의 컨테이너가  dev-peer0.org1.example.com-mycc-1.0이라는 이름으로 시작됩니다. 쿼리의 결과도 반환됩니다. 쓰기 작업이 발생하지 않으므로 "a"에 대한 쿼리는 여전히 "100"값을 반환합니다.
  • "a"에서 "b"로 "10"을 이동하기 위해 호출이 peer0.org1.example.com 으로 전송됩니다.
  • chaincode는  peer1.org2.example.com에 설치됩니다.
  • "a"값에 대한 쿼리가  peer1.org2.example.com 으로 전송됩니다. 그러면  dev-peer1.org2.example.com-mycc-1.0이라는 이름으로 세 번째 chaincode 컨테이너가 시작됩니다. 키 "a"의 값이 10으로 수정 된 이전 트랜잭션을 정확하게 반영하여 값 90이 리턴됩니다.

What does this demonstrate?(이것은 무엇을 보여줍니까?)

원장(ledger)에 대한 읽기/쓰기 작업을 성공적으로 수행하려면 피어에 체인 코드를 설치해야 합니다. 또한 체인 코드 컨테이너는 해당 체인 코드 (예 : "a"값에 대한 쿼리)에 대해 초기화 또는 기존 트랜잭션 (읽기/쓰기)이 수행 될 때까지 피어에 대해 시작되지 않습니다. 트랜잭션은 컨테이너를 시작하게 합니다. 또한 채널의 모든 피어는 불변의 시퀀스 된 레코드를 블록으로 저장하는 블록 체인과 현재 State의 스냅 샷을 유지 관리하는 State 데이터베이스를 포함하는 원장의 정확한 사본을 유지 관리합니다. 여기에는 위의 예에서 peer1.org1.example.com 과 같이 chaincode가 설치되지 않은 피어가 포함됩니다. 마지막으로 체인 코드는 이미 인스턴스화되었으므로 위의 예에서 peer1.org2.example.com과 같이 설치 한 후에 액세스 할 수 있습니다.

How do I see these transactions?(트랜잭션은 어떻게 볼 수 있습니까?)

CLI Docker 컨테이너의 로그를 확인하십시오.

docker logs -f cli

다음과 같은 결과가 나옵니다.

2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP
2017-05-16 17:08:01.366 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining default signing identity
2017-05-16 17:08:01.366 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AB1070A6708031A0C08F1E3ECC80510...6D7963631A0A0A0571756572790A0161
2017-05-16 17:08:01.367 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: E61DB37F4E8B0D32C9FE10E3936BA9B8CD278FAA1F3320B08712164248285C54
Query Result: 90
2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting.....
===================== Query on peer1.org2 on channel 'mychannel' is successful =====================

===================== All GOOD, BYFN execution completed =====================


 _____   _   _   ____
| ____| | \ | | |  _ \
|  _|   |  \| | | | | |
| |___  | |\  | | |_| |
|_____| |_| \_| |____/

How can I see the chaincode logs?(체인 코드 로그는 어떻게 볼 수 있습니까?)

개별 체인 코드 컨테이너를 검사하여 각 컨테이너에 대해 실행 된 개별 트랜잭션을 확인합니다. 다음은 각 컨테이너에서 결합 된 출력입니다.

$ docker logs dev-peer0.org2.example.com-mycc-1.0
04:30:45.947 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
ex02 Init
Aval = 100, Bval = 200

$ docker logs dev-peer0.org1.example.com-mycc-1.0
04:31:10.569 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
ex02 Invoke
Query Response:{"Name":"a","Amount":"100"}
ex02 Invoke
Aval = 90, Bval = 210

$ docker logs dev-peer1.org2.example.com-mycc-1.0
04:31:30.420 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
ex02 Invoke
Query Response:{"Name":"a","Amount":"90"}

Understanding the Docker Compose topology(Docker Compose 토폴로지 이해)

BYFN 샘플은  docker-compose-base.yamlbase폴더에 있음)에서 확장 된 두 가지 Docker Compose 파일을 제공합니다. 첫 번째는, docker-compose-cli.yaml 은 CLI 컨테이너와 함께 4 명의 피어와 함께 orderer 를 제공합니다. 이 파일은 이 페이지의 지침 전체에 사용됩니다.

[Note]
이 절의 나머지 부분에서는 SDK 용으로 설계된 도커 작성 파일에 대해 설명합니다. 이러한 테스트 실행에 대한 자세한 내용은 노드 SDK 레포를 참조하십시오.

두 번째인 docker-compose-e2e.yaml  은 Node.js SDK를 사용하여 end-to-end 테스트를 실행하도록 구성됩니다. SDK의 기능 외에도 fabric-ca 서버를 위한 컨테이너가 있다는 것이 주요 차이점입니다. 결과적으로 사용자 등록 및 등록을 위해 REST 호출을 조직 CA에 보낼 수 있습니다.

byfn.sh 스크립트를 먼저 실행하지 않고  docker-compose-e2e.yaml을 사용하려면 4 단계를 약간 수정해야 합니다. 조직의 CA의 개인 키를 가리켜야 합니다. crypto-config 폴더에서 이 값을 찾을 수 있습니다. 예를 들어, Org1의 개인 키를 찾으려면이 경로 (crypto-config/peerOrganizations/org1.example.com/ca/)를 따라야합니다. 개인 키는_sk뒤에 오는 긴 해시 값입니다. Org2의 경로는 - crypto-config/peerOrganizations/org2.example.com/ca/ 입니다.

docker-compose-e2e.yaml에서 ca0 및 ca1에 대한 FABRIC_CA_SERVER_TLS_KEYFILE 변수를 업데이트하십시오. 또한 ca 서버를 시작하기 위해 명령에 제공된 경로를 편집해야합니다. 각 CA 컨테이너에 동일한 개인 키를 2번 제공합니다.

Using CouchDB(CouchDB 사용)

State 데이터베이스는 기본값 (goleveldb)에서 CouchDB로 전환 할 수 있습니다. 동일한 체인 코드 기능을 CouchDB에서 사용할 수 있지만 체인 코드 데이터를 JSON으로 모델링 할 때 State 데이터베이스 데이터 내용에 대해 풍부하고 복잡한 쿼리를 수행 할 수있는 추가 기능이 있습니다.

기본 데이터베이스 (goleveldb) 대신 CouchDB를 사용하려면 네트워크 시작 docker-compose-couch.yaml  을 제외하고 아티팩트 생성을 위해 앞에서 설명한 것과 동일한 절차를 따르십시오.

docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d

chaincode_example02 는 이제 CouchDB를 사용하여 작동합니다.

[Note]
fabric-couchdb 컨테이너 포트를 호스트 포트에 매핑하는 방법을 선택하는 경우 보안 관련 사항을 알고 있는지 확인하십시오. 개발 환경에서 포트를 매핑하면 CouchDB REST API를 사용할 수 있으며 CouchDB 웹 인터페이스 (Fauxton)를 통해 데이터베이스를 시각화 할 수 있습니다. 프로덕션 환경에서는 CouchDB 컨테이너에 대한 외부 액세스를 제한하기 위해 포트 매핑을 구현하지 않을 가능성이 높습니다.

위에서 설명한 단계를 사용하여 CouchDB State 데이터베이스에 chaincode_example02 chaincode를 사용할 수 있지만 CouchDB 쿼리 기능을 사용하려면 JSON으로 모델링 된 데이터가있는 체인 코드 (예 : marbles02)를 사용해야합니다. marbles02 chaincode는  fabric/examples/chaincode/go 디렉토리에서 찾을 수 있습니다.

위의 Create & Join 채널 섹션에서 설명한대로 동일한 프로세스를 따라 채널을 만들고 가입하십시오. 피어(들)를 채널에 가입시킨 후 다음 단계를 사용하여 marbles02 체인 코드와 상호 작용하십시오.

  • peer0.org1.example.com 에 체인 코드를 설치하고 인스턴스화하십시오.
# 인스턴스화 명령에 따라 $CHANNEL_NAME 변수를 수정해야합니다.

peer chaincode install -n marbles -v 1.0 -p github.com/chaincode/marbles02/go
peer chaincode instantiate -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 $CHANNEL_NAME -n marbles -v 1.0 -c '{"Args":["init"]}' -P "OR ('Org0MSP.peer','Org1MSP.peer')"
  • 몇개의 구슬을 만들어 이동시켜 보세요.
# $CHANNEL_NAME 변수를 적절히 수정해야합니다.

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 $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
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 $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}'
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 $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
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 $CHANNEL_NAME -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}'
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 $CHANNEL_NAME -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}'
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 $CHANNEL_NAME -n marbles -c '{"Args":["delete","marble1"]}'
  • docker-compose에서 CouchDB 포트를 매핑하도록 선택한 경우 브라우저를 열고 다음 URL로 이동하여 CouchDB 웹 인터페이스 (Fauxton)를 통해 State 데이터베이스를 볼 수 있습니다.

http://localhost:5984/_utils

mychannel(또는 고유한 채널 이름)이라는 데이터베이스와 그 안에있는 문서를 볼 수 있습니다.

[Note]
아래 명령에 대해서는 $CHANNEL_NAME 변수를 적절하게 업데이트해야합니다.

CLI에서 정기적으로 쿼리를 실행할 수 있습니다. (예 : marble2)

peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["readMarble","marble2"]}'

결과물에는  marble2의 세부 정보가 표시되어야합니다.

Query Result: {"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}

특정 구술의 기록을 검색 할 수 있습니다 (예 :  marble1)

peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}'

결과물은  marble1에 트랜잭션을 표시해야합니다.

Query Result: [{"TxId":"1c3d3caf124c89f91a4c0f353723ac736c58155325f02890adebaa15e16e6464", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"tom"}},{"TxId":"755d55c281889eaeebf405586f9e25d71d36eb3d35420af833a20a2f53a3eefd", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"jerry"}},{"TxId":"819451032d813dde6247f85e56a89262555e04f14788ee33e28b232eef36d98f", "Value":}]

소유자  jerry 에 의한 marble 필드 쿼리와 같은 데이터 컨텐츠에 대한 풍부한 쿼리를 수행 할 수도 있습니다. :

peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}'

결과물에는 jerry 소유의 두 marbles구술이 표시되어야합니다.

Query Result: [{"Key":"marble2", "Record":{"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}},{"Key":"marble3", "Record":{"color":"blue","docType":"marble","name":"marble3","owner":"jerry","size":70}}]

Why CouchDB(왜 CouchDB인가?)

CouchDB는 일종의 NoSQL 솔루션이다. 문서 필드가 키-값 맵으로 저장되는 문서 지향 데이터베이스입니다. 필드는 간단한 키-값 쌍, 목록 또는 맵이 될 수 있습니다. LevelDB에서 지원하는 키/복합 키/키 범위 쿼리 외에도 CouchDB는 전체 블록 체인 데이터에 대한 키가 아닌 쿼리와 같은 전체 데이터 리치 쿼리 기능을 지원합니다. 데이터 내용은 JSON 형식으로 저장되므로 완전히 쿼리 가능합니다. 따라서 CouchDB는 Levelcode에서 지원하지 않는 많은 유스 케이스에 대한 체인 코드, 감사,보고 요구 사항을 충족시킬 수 있습니다.

또한 CouchDB는 블록 체인에서 준수 및 데이터 보호를 위한 보안을 향상시킬 수 있습니다. 트랜잭션 내에서 개별 속성의 필터링 및 마스킹을 통해 필드 수준의 보안을 구현할 수 있으므로 필요에 따라 읽기 전용 권한 만 인증합니다.

또한 CouchDB는 CAP 정리의 AP 유형 (가용성 및 파티션 허용 오차)에 해당합니다.  Eventual Consistency을 갖춘 master-master 복제 모델을 사용합니다. 더 많은 정보는 CouchDB 문서의 최종 일관성 페이지에서 찾을 수 있습니다. 그러나 각 패브릭 피어마다 데이터베이스 복제본이 없으며 데이터베이스에 대한 쓰기가 일관되고 내구성이 보장됩니다 ( Eventual Consistency이 아님).

CouchDB는 Fabric을위한 최초의 외부 플러그 가능 State 데이터베이스이며, 다른 외부 데이터베이스 옵션이있을 수 있고 있어야합니다. 예를 들어, IBM은 블록 체인에 관계형 데이터베이스를 사용 가능하게 합니다. 또한 응용 프로그램 수준의 Endorsement없이 데이터 일관성을 유지할 수 있도록 CP 유형 (일관성 및 파티션 허용 오차) 데이터베이스가 필요할 수 있습니다.

A Note on Data Persistence(데이터 지속성에 대한 참고사항)

피어 컨테이너 또는 CouchDB 컨테이너에서 데이터 지속성이 필요한 경우, 한 가지 옵션은 docker-host의 디렉토리를 컨테이너의 관련 디렉토리에 마운트하는 것입니다. 예를 들어, docker-compose-base.yaml파일의 피어 컨테이너 스펙에 다음 두 행을 추가 할 수 있습니다.

volumes:
 - /var/hyperledger/peer0:/var/hyperledger/production

CouchDB 컨테이너의 경우 CouchDB 컨테이너 사양에 다음 두 줄을 추가 할 수있다.

volumes:
 - /var/hyperledger/couchdb0:/opt/couchdb/data

Troubleshooting(문제해결)

항상 네트워크를 새로 시작하십시오. 아티팩트, 암호, 컨테이너 및 체인 코드 이미지를 제거하려면 다음 명령을 사용하십시오.

./byfn.sh -m down
  • Docker 오류가 표시되면 먼저 도커 버전 (선행 조건)을 확인한 다음 Docker 프로세스를 다시 시작하십시오. Docker의 문제점은 종종 즉시 인식되지 않습니다. 예를 들어, 컨테이너에 마운트된 암호 자료에 액세스 할 수 없으므로 오류가 발생할 수 있습니다. 그들이 지속되면 이미지를 제거하고 처음부터 시작하십시오.
docker rm -f $(docker ps -aq)
docker rmi -f $(docker images -q)
  • 작성, 인스턴스 작성, 호출 또는 조회 명령에 오류가 있는 경우, 채널 이름 및 체인 코드 이름을 올바르게 갱신했는지 확인하십시오. 제공된 샘플 명령에는 자리 표시 자 값이 있습니다.
  • 아래 오류가 표시되면 :
Error: Error endorsing chaincode: rpc error: code = 2 desc = Error installing chaincode code mycc:1.0(chaincode /var/hyperledger/production/chaincodes/mycc.1.0 exits)

이전 실행에서 체인 코드 이미지 (예 :  dev-peer1.org2.example.com-mycc-1.0 또는 dev-peer0.org1.example.com-mycc-1.0)가 있을 가능성이 큽니다. 그들을 제거하고 다시 시도하십시오.

docker rmi -f $(docker images | grep peer[0-9]-peer[0-9] | awk '{print $3}')
  • 다음과 유사한 내용이 표시되는 경우
Error connecting: rpc error: code = 14 desc = grpc: RPC failed fast due to transport failure
Error: rpc error: code = 14 desc = grpc: RPC failed fast due to transport failure

"latest"으로 태그가 다시 지정된 "1.0.0"이미지에 대해 네트워크를 실행하고 있는지 확인하십시오.

  • 아래 오류가 표시되면 :
[configtx/tool/localconfig] Load -> CRIT 002 Error reading configuration: Unsupported Config Type ""
panic: Error reading configuration: Unsupported Config Type ""
# [configtx / tool / localconfig]로드 -> CRIT 002 구성 읽기 오류 : 지원되지 않는 구성 유형 "" 패닉 : 구성 읽기 오류 : 지원되지 않는 구성 유형 ""

그런 다음  FABRIC_CFG_PATH 환경 변수를 올바르게 설정하지 않았습니다. configtxgen 도구는 configtx.yaml을 찾으려면 이 변수가 필요합니다. 돌아가서 export FABRIC_CFG_PATH=$PWD를 실행 한 다음 채널 아티팩트를 다시 만드십시오.

  • 네트워크를 정리하려면 다음 down옵션을 사용하십시오.
./byfn.sh -m down
  • "active endpoints"가 있음을 나타내는 오류가 표시되면 Docker 네트워크를 정리하십시오. 이렇게 하면 이전 네트워크를 지우고 새로운 환경에서 시작할 수 있습니다.
docker network prune

다음 메시지가 표시가 되면 y 를 선택하세요.

WARNING! This will remove all networks not used by at least one container.
Are you sure you want to continue? [y/N]
# 경고! 이렇게하면 하나 이상의 컨테이너에서 사용하지 않는 모든 네트워크가 제거됩니다. 정말 계속하고 싶습니까? [y/N]

  1. X.509는 암호학에서 공개키 인증서와 인증알고리즘의 표준 가운데에서 공개 키 기반(PKI)의 ITU-T 표준이다.
  2. 아티팩트의 의미는 운영체제나 애플리케이션을 사용하면서 생성되는 흔적을 말한다. 보통 시스템에 생성되는 증거를 다음과 같이 2가지로 분류하는데 생성 증거에 해당하는 것이 아티팩트다. 생성 증거 : 시스템이나 애플리케이션이 자동으로 생성한 데이터 보관 증거 : 사람의 사상이나 감정을 표현하기 위해 작성한 데이터 예를 들어, 윈도우 시스템의 생성 증거(아티팩트)로는 레지스트리, 프리/슈퍼패치, 이벤트 로그 등이 있다. 보관 증거로는 직접 작성한 메일 내용, 블로그 및 소셜 네트워크 작성 내용, 직접 작성한 문서 등이 있다.


출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/build_network.html

 Identity란 무엇인가요?

블록체인 네트워크에는 피어, Orderer, 클라이언트 어플리케이션, 관리자와 같은 다양한 액터가 있습니다.

이러한 각각의 액터들은 X.509 Digital Certificate을 따르는 Identity를 가지고 있습니다.

이러한 Identity는 블록체인 네트워크 안에 액터들이 리소스에 대한 허가를 결정한다는 점에서 정말 중요합니다.

Hyperledger Fabric은 액터 안에 특성을 사용해서 허가 여부를 결정합니다. 그리고 Principal이라고 불리는 특별한 이름을 부여합니다.

Principal은 User Id나 Group Id와 같은 종류의 Identity입니다. 그러나 액터의 특성을 더 넓은 범위에서 포함하고 있다는 점에서

조금 더 유연합니다. 우리가 Principal에 대해서 말할 때 우리는 시스템 내부의 액터를 생각합니다.

특히 허가 여부를 결정하는 특성들을 고려합니다.

이러한 특성들은 전형적으로 액터의 조직, 조직 단위, 역할 또는 심지어는 액터의 특별한 Identity를 의미합니다.

가장 중요한 것은 Identity는 증명 가능성을 가지고 있어야 합니다.(다른 말로는 실제 Identity를 의미합니다.)

그리고 이러한 이유 때문에 이 Identity가 시스템 내부의 권한자로부터 나와야합니다.

Membership service provider(MSP)는 Hyperledger Fabric에서 Identity를 얻는 방법입니다.

더욱 특별하게도, MSP는 조직의 회원 규칙을 대표하고 조직 회원의 유효한 Identity를 운영하는 규칙을 정의 하는 것과 같은 하나의 요소입니다.

Fabric에서 기본적인 MSP를 구현할 때 전통적인 Public Key Infrastructure(PKI) Hierarchical model을 적용한 X.509 인증을 사용합니다.

Identity를 사용하는 단순한 시나리오

슈퍼 마켓에 식료품 구매를 위해서 방문했을 때를 생각해보세요. 계산대 앞에서 여러분은 Visa, Mastercard. AMEX 카드와 같은 것들만 결제가 가능하다는 것을 보실겁니다.

예를 들어 ImagineCard와 같은 다른 카드를 사용하려고 하면 계좌에 돈이 많고, 실제 트랜잭션 가능 카드 이더라도 받아들여지지 않을 것입니다.


유효한 신용카드를 가지는 것으로는 충분하지 않습니다. 무조건 슈퍼 마켓에서 받아 들여져야만 합니다. PKI와 MSP는 이런 방식으로 작동합니다.

그리고 MSP는 이 중 어떤 것이 네트워크 내부에 주어진 조직인지 확인합니다.

PKI 인증 권한자와 MSP는 비슷한 기능성을 제공합니다. PKI는 카드 제조사와 비슷합니다. PKI는 인증 가능한 많은 다른 종류의 Identity를 나누어줍니다.

한편 MSP는 매장에서 받을 수 있는 카드사 목록들과 같습니다. 매장에서 허가된 어떤 카드인지 결정합니다.

MSP는 인증 가능한 Identity를 블록 체인 내부의 사용자로 바꾸어줍니다.

PKI는 무엇인가요?

Public Key Infrastructure(PKI)는 네트워크의 보안 커뮤니케이션을 제공하는 인터넷 기술의 집합체입니다.

HTTPS의 S는 PKI에서 제공하는 것입니다. 만약 당신이 지금 이것을 웹브라우져에서 읽고 계신다면, 당신은 인증된 소스에서 나온 PKI를 사용하고 계십니다.


위의 사진은 PKI의 구성 요소입니다. PKI는 Certificate Authorities로 구성되어 있습니다.

Certificate Authorities는 서비스의 유저나 서비스 프로바이더같은 단체에 디지털 인증을 부여합니다.

그리고 사용자가 사용자 환경과 메시지 교환을 하면 그것을 증명 하게 됩니다.

A CA의 Certificate Revolution List(CRL)은 더 이상 유효하지 않은 인증의 기준을 구성합니다.

인증의 폐지는 많은 이유로 발생합니다. 예를 들자면 암호화된 Private 요소가 노출이 되는 경우에 인증이 폐지될 수 있습니다.

비록 블록체인 네트워크가 커뮤니케이션 네트워크보다 더욱 많지만, 다양한 네트워크 참여자 간의 보안 커뮤니케이션과

블록체인 내부에서 전송되는 메시지가 적절한 인증을 가지고 있는가를 확실하게 하기 위해서 블록체인 네트워크는 PKI에 의존합니다.

그러므로 PKI의 기본 개념과 왜 MSP가 중요한가를 이해하는 것은 매우 중요합니다.

PKI에는 4가지의 핵심 요소가 있습니다.

  • 디지털 인증
  • Public과 Private 키
  • 인증 권한자
  • 인증 폐지 리스트

PKI의 기본에 대해서 설명하겠습니다. 그리고 더 자세한 설명을 위해서 Wikipedia는 좋은 시작점일 수 있습니다.

디지털 인증

디지털 인증은 어떤 단체와 관련된 특성들의 집합체를 가지고 있는 일종의 문서입니다.

가장 일반적인 인증 타입은 X.509 기준을 따르는 하나의 인증입니다.

X.509 기준은 기준 내부 구조 안에서 단체 인증 세부사항을 암호화하도록 합니다.

예를 들자면, 디트로이트 미셸 자동차 생산부서의 Mary Morris라는 사람은 subject 특성 안에 이와 같은 정보를 가지게 됩니다.

C=US, ST=Michigan, L=Detroit, O=Mitchell Cars, OU=Manufacturing, CN=Mary Morris/UID=123456

Mary의 인증은 정부 주민등록번호와 유사합니다.

이 인증은 그녀가 증명할 수 있는 키로서 사용하기 위한 정보를 제공합니다.

X.509 인증의 많은 다양한 특성들이 있지만 지금은 이것들에 집중해봅시다.

위와 같이 디지털 인증은 Mary Morris를 Mary Morris라고 불리는 단체로 묘사하고 있습니다.

Mary는 인증의 하나의 Subject 입니다.

그리고 강조되어 있는 Subject 텍스트는 Mary에 대한 핵심 사실들을 전달하고 있습니다.

인증은 또한 많은 다른 종류의 정보를 보유하고 있습니다.

가장 중요하게도, Mary의 Public Key는 그녀의 Private signing Key가 배포되어 있지 않은 것과 반대로 그녀의 인증과 함께 배포되어 있습니다.

이 사인은 Private임이 유지되어야합니다.

가장 중요한 것은 Mary의 인증이 다른 조작에 의해서 인증이 유효화 되지 못하도록 암호화(비밀 쓰기)라는 수학적 기술을 활용해서 입력될 수 있습니다.

이 암호화는 Mary로 하여금 Certificate Autority(인증 권한자; CA)로 알려진 인증 배부자를 다른 단체에서 신용받는 한 그녀의 Identity를 다른 누군가에게 증명할 수 있는 인증으로 존재하게 해줍니다.

CA가 그녀의 확실한 암호화 비밀 정보(Private signing Key)를 유지해주는 한, 누구든 인증에서 알려주는 Mary에 대한 정보가 조작되지 않았다는 것에 대해서 확신할 수 있을 것입니다.

항상 Mary Morris에 대한 특별한 정보를 가지고 있을 것이기 때문에 Mary의 X.509 인증은 디지털 Identity 키로 조작이 불가능합니다.

Authentication & Public keys and Private keys

인증과 메시지 통합은 보안 커뮤니케이션의 중요한 컨셉입니다.

인증은 메시지를 교환하는 단체가 특정한 메시지를 만드는 Identity를 확신할 수 있다는 것을 요구합니다.

통합성은 메시지가 전송 간에 조작되지 않았다는 것을 요구합니다.

예를 들면, 여러분은 실제 Mary Morris와 소통하는 것이 그와 비슷한 대상과 소통하는 것보다 더욱 확실시 하고 싶으실 겁니다.

또는 Mary가 여러분께 메시지를 보냈더라도 그녀가 보낸 메시지가 교환 중에 어느 누구에게도 조작되지 않았다는 사실을 확실시하고 싶으실 겁니다.

전통적인 인증 메커니즘은 전자 서명 메커니즘을 따릅니다.

그 이름 그대로, 단체가 전자적으로 그들의 메시지를 서명할 수 있습니다.

전자 서명은 서명된 메시지의 통합성을 보장합니다.

기술적으로 말하자면, 전자 서명 메커니즘은 두 개의 암호학적으로 연결된 키를 요구합니다.

하나는 퍼블릭 키로 널리 사용되고 있고, 인증의 기점으로 작용합니다.

둘째는 프라이빗 키로 메시지의 전자 서명을 만들기 위해서 사용됩니다.

전자적으로 서명된 메시지를 받는 사람은 받은 메시지의 출처와 통합성을 보냈을 것으로 예상된 사람의 퍼블릭 키로 메시지에 포함된 서명의 유효성을 확인함으로서 인증할 수 있습니다.

프라이빗 키와 각각의 퍼블릭 키의 특별한 관계는 보안 커뮤니케이션을 가능하게 하는 암호학적 마술입니다.

각각의 키들의 특별한 수학적 관계는 프라이빗 키가 해당되는 퍼블릭 키가 맞아 떨어지고,

오직 같은 메시지에만 해당되는 메시지의 서명을 생성하기 위해서 사용될 수 있습니다.



위의 예시에서, Mary의 메시지를 인증하기 위해서 메시지에 프라이빗 키를 사용해서 메시지의 서명을 만들었습니다.

그 메시지는 그 이후 Mary가 메시지에 다시 첨부합니다.

서명은 어느 누구에게나 서명된 Mary의 퍼블릭 키를 이용해서 인증될 수 있습니다.

인증 권한자

여러분이 보신데로, 노드나 액터는 시스템에서 신뢰받는 권한자에 의해서 디지털 Identity를 발급받는 방법을 통해서

블록체인 네트워크에 참여할 수 있습니다. 가장 일반적인 케이스에선, 디지털 Identity(또는 단순화 Identity)

는 X.509 기준을 따르는 암호학적으로 유효한 디지털 서명의 형태를 가지고 있습니다.

그리고 Certificate Authority(CA)로부터 발급 받습니다.

CA는 인터넷 보안 프로토콜의 일반적인 부분입니다. 그리고 여러분은 조금 유명한 것에 대해선 들어보셨을 것 입니다.

Symantec, GeoTrust,DigiCert,GoDaddy 마지막으로 Comodo가 있습니다.


Certificate Authority는 다른 액터들에게 인증을 나누어줍니다.

이러한 인증은 CA에 의해서 서명을 받았고(CA의 프라이빗 키를 이용해서), 그리고 액터의 퍼블릭 키와 실제 액터를 묶습니다.

그리고 선택적으로 종합적인 특성들의 리스트도 묶기도 합니다.

명료하게, 만약 한사람이 CA를 믿는다면(퍼블릭 키를 알고 있기도 하면서), 특정한 액터가 인증 안에서 퍼블릭키와 묶여있고,

그리고 포함된 특성들을 가지고 있다는 것을 믿을 수 있습니다.(CA의 서명을 이용해서 액터의 인증을 유효화하면)

인증이 액터나 실제 CA의 프라이빗 키를 포함하지 않아도, 중요하게도 인증은 널리 전파될 수 있습니다.

이것은 주어진 CA로부터 발급받은 Identity의 소비자로 하여금 인증이 오직 해당하는 프라이빗 키의 보유자로부터

생설 될 수 있다는 것을 확인함으로서 Identity를 유효화 하도록 허가합니다.

블록체인 세팅에서, 네트워크와 상호작용하길 원하는 모든 액터는 identity가 필요합니다.

이 세팅에서, 여러분은 하나나 하나 이상의 CA가 디지털 관점에서 오직의 멤버를 정의하기 위해서 사용된다고 말하게 될 것입니다.

인증가능한 디지털 Identity를 위해서 조직의 액터를 위한 기본을 제공하는 것을 CA라고 합니다.

루트 CA, 중간 CA들과 신뢰 사슬

CA는 두 가지 종류가 있습니다.

하나는 루트 CA 그리고 둘째는 중간 CA라고 합니다.

왜냐하면 루트 CA는 인터넷 유져에게 수백만의 인증을 안전하게 분배해야하기 때문입니다.

그래서 중간 CA라는 부르는 것이 이 프로세스의 개념을 넓히는 것에 있어 합리적입니다.

이러한 중간 CA는 루트 CA나 다른 중간 권한자로부터 받은 그들만의 인증을 가지고 있습니다.

동시에 블록체인 안 어느 CA에서 발급받은 어떤 인증이던 간에 신뢰 사슬(Chain of Trust)을 설립을 허가하도록 합니다.

루트 CA로 추적해 나갈 수 있는 능력은 단지 CA가 여전히 보안성을 제공하는 동안 그 기능 확인을 허가하는 것뿐만 아니라(중간 CA에 신뢰를 가지고 조직에서 인증을 소모하는 것을 허가하는 것)

루트 CA의 노출을 제한하는 효과도 있습니다.이 루트 CA는 만약 밝혀진다면, 모든 신뢰 사슬을 위협할 수 있습니다.

만약 중간 CA가 밝혀진다면 노출이 조금 더 작은 부분에서 이루어 질 것입니다.

신뢰 사슬은 루트 CA와 중간 CA의 집합 중간에서 형성되며 CA가 형성되는 동안 어떤 중간 CA도 루트 CA가 되기도 하거나 루트 CA를 향한 신뢰 사슬이 되기도 합니다.

중간 CA는 다양한 조직에 인증을 발행하는 것에 관해서 큰 유연성을 제공해주고, 블록체인 시스템을 허가 관리하는 것에 매우 도움이 됩니다.

예를 들자면, 각각 다른 루트 CA를 사용하거나 같은 루트 CA를 가졌지만 다른 중간 CA를 가진 다양한 조직을 가정할 수 있습니다. 그리고 이것은 네트워크에 요구사항에 의존하게 됩니다.

Fabric CA

Fabric에서 이미 빌트인된 CA 요소들을 사용자가 만든 블록체인 내트워크에 새로운 CA를 만드는 것을 허가하기 때문에 CA는 매우 중요합니다.

이 요소는 Fabric-ca라고 알려져 있으며, X.509 인증 형태를 가진 Fabric 사용자의 디지털 identity를 관리하는 것이 가능한 프라이빗 루트 CA입니다.

왜냐하면 Fabric-CA는 Fabric의 필요한 루트 CA를 목표로 만들어진 커스텀 CA이기 때문입니다.

또한 브라우저에서 일반적이거나 자동생성형 SSL 인증을 제공하는 것이 내제적으로 불가능합니다.

그러나 몇몇 CA는 Identity를 관리하는 것에 사용해야만 하기 때문에(테스트 환경에서도), Fabric-CA는 인증을 관리/배포하는 것에도 사용할 수 있습니다.

또한 상황이 적절하다면, 퍼블릭/상업용 루트 또는 중간 CA를 Identification을 제공하기 위해서 사용하는 것 역시 가능합니다.

더 많은 정보를 위해선 CA Documentation Section을 확인해보세요.

인증 폐지 리스트

인증 폐지 리스트(Certification Revocation List; CRL)은 이해하기 쉽습니다.

단지 몇가지 사유로 폐지된 인증들의 리스트입니다.

만약 아까의 매장 시나리오를 돌려보자면, CRL은 분실 신용카드와 같은 것로 볼 수 있습니다.

제삼자가 다른 파티의 Identity를 증명하려하면, 우선적으로 발급된 CA의 CRL을 통해서 인증의 폐기 여부를 확인합니다.

인증자는 CRL을 확인하지 않아도 되고, 그러나 만약 확인하지 않는다면, 발각된(compromised) Identity를 사용할 수 있는 위험성을 안고 있어야합니다.


CRL을 사용해서 인증을 확인하는 것은 여전히 유효합니다. 만약 가짜 유저가 발각된 디지털 인증을 활용해서 파티를 증명하려하면,

우선, CA CRL을 확인해서 더 이상 유효하지 않아서 리스트에 존재하지 않는다는 것을 확인하게 될 것 입니다.

주의해야할 점은 인증의 폐지는 인증의 만료와는 다르다는 것입니다.

폐지된 인증은 만료되지 않았습니다. 이러한 인증들은 다른 측면에선 여전히 유효한 인증입니다.

이는 만료된 운전면허증과 폐지된 운전면허증과 같습니다.

더 많은 정보를 원하신다면 here을 클릭해주세요.

이제 PKI가 어떻게 인증가능한 Identity를 신뢰 사슬에 배포하는지 배우셨고, 다음 단계는 블록체인 네트워크의 사용자가 어떻게 그들의 Identity를

신뢰받는 사용자로서 인증받는지에 대해서 배울 예정입니다.

이는 MSP가 작용하는 부분이고, MSP는 블록체인 내 사용자의 Identity를 주어진 조직 중 어느 조직에 속해있는지를 구분해 줍니다.

membership에 대해서 더 배우기 위해선 MSPs에 대한 개념적 문서를 확인하세요.


출처 : https://hyperledger-fabric.readthedocs.io/en/release-1.1/tutorials.html


Hyperledger Fabric 모델

 

이 장에서는 포괄적이지만 customizing 가능한 enterprise blockchain solution, Hyperledger Fabric에 포함 된 주요 설계 기능에 대해 간략히 설명합니다.

  1. 자산(asset) : 자산 설정(asset definition)를 통해 전체 식품에서 골동품 자동차, 통화 선물에 이르기까지 네트워크를 통해 거의 모든 가치를 교환 할 수 있습니다..
  2. Chaincode: Chaincode 실행은 트랜잭션 합의, 노드 타임에 대한 신뢰와 검증의 요구 수준 제한, 그리고 네트워크의 확장성과 성능을 최적화 하는 것을 분리해줍니다.
  3. 원장 특성: 영속성을 가진 공유 원장은 각기 채널과 SQL(효율적인 감사와 분쟁 해결을 위한 쿼리 능력)을 내포하고 있습니다.
  4. 채널 간의 프라이버시: 채널은 경쟁관계의 비즈니스와 규제가 많은 산업이 일반적인 네트워크에서 자산을 교환할 수 있을 만큼 높은 수준의 프라이버시와 신뢰성을 다양한 측면에서의 트랜잭션을 가능하게 합니다.
  5. 보안성과 사용자 서비스: 허가받은 사용자는 모든 트랜잭션이 공인된 규제자와 감사자가 확인하고 추적할 가능할만큼 신뢰도 있는 블록체인 네트워크를 제공합니다.
  6. 합의: 합의에 대한 특별한 접근은 기업 환경에 필요한 유연성과 확장성을 가능하게 합니다.



자산

자산은 부동산과 하드웨어 같은 유형의 자산에서 계약이나 지적 재산권같은 무형의 자산까지 범위를 포함하고 있습니다.

Hyperledger Fabric은 Chaincode 트랜잭션을 사용해서 자산을 수정할 수 있는 기능을 제공합니다.

자산은 키-밸류 쌍으로서 Hyperledger Fabric 내부에 존재하게 되고 채널 원장에 트랜잭션으로 State 변화를 기록하게 됩니다.

자산은 바이너리 값이나 JSON의 형태로 표현됩니다.




Chaincode

Chaincode는 자산과 자산 변동을 하기 위한 트랜잭션 지시를 정의하는 소프트웨어입니다.

다시 말해서, 비즈니스 로직입니다. Chaincode는 다른 데이터베이스 State 정보나 key-value 쌍을 읽거나 바꾸도록 시행합니다.

Chaincode 기능은 원장의 현재 데이터베이스 State에 대해서 작동하고 트랜잭션 제안을 통해서 시작됩니다.

Chaincode 실행은 새로운 key-value를 만들어내고 네트워크로 전송되어 모든 피어의 원장에 적용될 수 있습니다.




원장 특성

원장은 순서가 있고, Fabric안의 모든 State 변동에 대한 간섭 저항성 기록입니다.

State 변동은 트랜잭션이라는 Chaincode 호출을 하고 참여한 조직에 제출되게 되는 결과를 가집니다.

각각의 트랜잭션은 key-value 쌍 자산의 집합을 낳는 결과를 가지게 되고. 이 key-value 쌍은 원장에 만들어지거나, 업데이트 또는 삭제 됩니다.

원장은 불변하고 순서가 있는 블록 안의 기록을 위한 블록체인과 현재의 Fabric State를 유지하기 위한 데이터베이스 State로 구성되어 있습니다.

채널당 하나의 원장을 가지고 있습니다. 각각의 피어는 그들이 속해 있는 모든 채널에 원장 복사본을 관리하게 됩니다.

  • 키 기반의 색인, 범위 쿼리, 복합 키 쿼리를 사용한 원장에 쿼리와 업데이트
  • 풍부한 쿼리 언어(CouchDB를 데이터베이스 State로 사용한다면)를 사용한 읽기 전용 쿼리
  • 데이터의 출처 시나리오를 가능하게 하는 키를 위한 원장 히스토리 쿼리와 같은 읽기 전용 쿼리
  • Chaincode안에서 읽혀질 수 있는 Key/Value의 버전과 Chaincode에 씌여진 Key/Value로 이루어진 트랜잭션
  • 트랜잭션은 동의하는 피어의 서명을 포함하고 순서 시스템에 제출됩니다.
  • 트랜잭션은 블록으로 순서가 매겨지고 순서 시스템에 의해서 채널 내부의 피어에게 "배송"됩니다.
  • 피어는 Endorsement Policy와 집행 정책에 대한 트랜잭션을 검증합니다.
  • 블록을 읽기 이전에, Chaincode가 실행되는 동안 자산의 State 변동을 확실시 하는 버젼 체크를 수행합니다.
  • 트랜잭션이 한 번 검증되거나 커밋되면 불변성을 가지게 됩니다.
  • 채널 원장은 정책, 접근 권한 리스트, 그리고 다른 관련 정보를 규정하는 설정 블록을 포함.
  • 채널이 포함하고 있는 MSP(Membership Service Provider)는 다른 자격 권한자로 부터 유래한 암호화 요소를 허가.

Ledger 토픽을 확인하면 데이터베이스, 저장 구조, 그리고 쿼리 능력에 대한 더욱 심도있는 학습을 하실 수 있습니다.




채널 간의 프라이버시

Hyperledger Fabric은 현재 State의 자산의 State를 조정하고 조절할 수 있는 Chaincode 뿐만 아니고 단위 채널 기반 불변의 원장을 이용합니다.

원장은 채널의 범위에서 존재합니다. 이는 전체 네트워크 내에서 공유되는 채널 일 수 있습니다.(모든 사용자가 1개 채널에서 작동되고 있다는 전제하에)

또는 특정한 모임의 사용자만을 위한 사유화 채널일 수도 있습니다.

후자의 시나리오에선, 이러한 사용자들이 분리된 채널을 만들고 그렇게 함으로서 그들의 트랜잭션과 원장을 분리/격리 조치 할 수 있습니다.

모든 프라이버시와 투명성 사이의 갭을 연결하고 싶은 시나리오를 해결하기 위해서, Chaincode가 오직 자산 State에만 접근하여 읽고 쓰는 것을 필요로 하는 피어에게만 설치 할 수 있습니다.

(다시 말해서, 피어에게 Chaincode가 설치되지 않았다면, 적절하게 원장에 인터페이싱 할 수 없다는 것을 의미한다)

더욱 데이터를 애매하게 만들기 위해서, Chaincode 안의 Value값은 순서 시스템에 트랜잭션으로 보내지기 이전이나 원장에 씌여지기 이전에 AES와 같은 일반적인 암호호 알고리즘을 이용하여 부분적이거나 전체적으로 암호화 될 수 있습니다. 한번 암호화된 데이터가 원장에 씌여지면, 오직 암호키를 생성하기 위한 관계키를 보유한 유저에 의해서만 복호화 할 수 있습니다.

Chaincode 암호화에 대해서 더욱 궁금하시면, Chaincode for Developer 토픽을 확인해보세요.

 

보안성과 사용자 서비스

Hyperledger Fabric은 사용자가 각자의 신원을 알 수 있는 트랜잭션적인 네트워크를 지원합니다.

퍼블릭 키 인프라는 조직, 네트워크 요소, 그리고 엔드 유져나 클라이언트 어플리케이션과 관련된 암호 인증을 생성하는 것에 사용됩니다.

결과적으로, 데이터 접근 관리를 이용해서 더 넓은 네트워크와 채널 단위를 관리하고 조절할 수 있습니다.

채널의 실존성과 가능성의 묶음인 Hyperledger Fabric에서 Permissioned라는 개념은 프라이버시와 기밀성이 중요한 관련 정보인 시나리오가 어드레싱되게 합니다.

Member Service Provider(MSP) 토픽을 확인하시면 암호 구현물을 더 잘 이해할 수 있을 것입니다. 그리고 Hyperledger Fabric의 서명, 검증, 인증도 또한 이해할 수 있습니다.




합의

분산 원장 기술에서, 합의는 최근 하나의 Function 안의 특정한 알고리즘이 되었습니다. 그러나, 합의는 트랜잭션의 순서를 동의하는 것이나 차별점은 제안, Endorsement부터 순서, 인증, 커밋까지 전체적인 트랜잭션 흐름에서 기본적인 역할을 Hyperledger Fabric에서 강조하고 있다. 한 마디로, 합의는 트랜잭션 구성 블락에 대한 집합의 정확성 인증을 전부 확인하는 것으로 정의 될 수 있습니다.

합의는 궁극적으로 트랜잭션이 명시적 규정 범위 확인에 대한 오더와 결과를 얻어집니다. 이러한 확인과 균형은 트랜잭션의 수명 주기동안 발생하며 사용자로 하여금 트랜잭션 클래스를 Endorsement하도록 서술되어 있는 것과 이러한 Endorsement Policy가 시행되고 유지되기 위한 시스템의 Chaincode를 서술 하기 위해서 Endorsement Policy를 사용하는 것을 포함하고 있습니다. 커밋이 되기 이전에, 충분한 Endorsement가 존재하도록 하는 시스템 Chaincode를 피어가 이용할 것입니다. 그리고 이러한 Endorsement은 적절한 실체로부터 얻어졌을 것입니다. 더욱이, 트랜잭션이 포함되어 있는 블록이 원장에 씌여지기 이전에 현재 State의 원장이 동의를 얻는 시점에 버전 확인이 될 것 입니다.

최종적인 확인 과정은 오퍼레이션이 중복 시행되거나 데이터 통합성을 위협할만한 점으로부터 지켜주고, function을 non-static 변수로 실행되도록 허가합니다.

합의, 타당성과 버전 확인의 다중 발생 이외에도, 모든 트랜잭션 흐름 동안 신원확인을 진행합니다. 접근 제어 리스트는 네트워크의 상하 단계(순서 서비스부터 채널까지)에서 구현되고, 보내지는 데이터가 각자 다른 구조 요소에서 트랜젝션 제안으로서 서명되고, 타당성을 인증받고, 확인됩니다. 결론 짓자면, 합의는 트랜잭션 집단 순서 동의를 제한하는 것이 아니고, 오히려 트랜잭션이 발생하여 등록되는 동안의 계속되는 인증의 부산물로서 얻어지는 것입니다.

Transaction Flow 다이어그램을 확인하여 합의의 시각적 표현을 확인하십니오.


 

출처 : https://hyperledger-fabric.readthedocs.io/en/release-1.1/fabric_model.html


Hyperledger Fabric 모든 기능

Hyperbelger Fabric은 엔터프라이즈급 네트워크 보안, 확장성, 기밀성 및 성능을 제공하는 모듈형 블록체인 아키텍처 기반의 DLT (distributed ledger technology)의 구현체입니다
Hyperledger Fabric은 아래의 블록체인 네트워크 기능들을 제공합니다.




유저 식별 관리

허가형 네트워크 사용을 위해, Hyperledger Fabric는 네트워크 상의 모든 참여자들의 User ID와 인증을 관리하기 위해 Membership Identity Service를 제공합니다.

특정 네트워크 운영의 인가(authorization)을 통해 Access Control List는 허가 계층을 추가하여 사용할 수 있다.

(원문 : Access control lists can be used to provide additional layers of permission through authorization of specific network operations.)

예를 들면, 특정한 User  ID는 Chaincode 어플리케이션 구동할 수 이지만,  신규 Chaincode 설치도록 제한 할 수 있습니다.




프라이버시와 기밀성


Hyperbelger Fabric은 비즈니스 이해관계에 따라 경쟁하고,사적이고 기밀성을 요하는 트랜잭션을 요구하는 모든 그룹이 하나의 허가형 네트워크에 공존 할 수 있게합니다.

비공개(Privacy) channels은 제한된 메시지 송수신 경로(path)로서, 네트워크 멤버의 특정 하위집단(subset)을 위한 transaction의 프라이버시와 기밀성 제공하는데 사용될 수 있습니다.
Transaction, Member 및 Channel 정보를 포함한 모든 데이터는, 해당 Channel에 대해 명시적으로 액세스 권한이 부여되지 않으면 네트워크의 어떤한 Member도 볼수없고, 접근할 수 없습니다.




효율적인 프로세싱

Hyperledger Fabric은 노드 유형별로 네트워크 역할을 할당합니다 

네트워크에 동시성과 병렬성을 제공하기 위해 Transaction 실행이 Transaction 순서정렬 및 commitment 작업과 분리되어 있습니다.

ordering(순서화) 수행전 트랜잭션을 실행하면 각 피어 노드가 여러 트랜잭션을 동시에 처리 할 수 있습니다.

이 동시 실행(concurrent execution)은 각 피어의 처리 효율성을 증가시키고, ordering service에 트랜잭션 전달을 가속화합니다. 

 

네트워크에 동시성과 병렬성을 제공하기 위해서, 트랜잭션 실행이 트랜잭션 순서와 커밋으로부터 분리되도록 합니다.

트랜잭션을 실행하는 것이 동시에 다양한 트랜잭션을 각각의 피어 노드에서 순서를 만드는 것을 가능하도록 하는 것보다 선행됩니다.

이 동시성은 각각의 피어에서 프로세싱 효율성을 높혀주고, 순서를 매기는 서비스로의 전송을 가속합니다.

병렬 처리를 가능하게하는 것 외에도,업무 분장은 Transaction 실행과 Ledger 유지보수 요청으로 부터 ordering noded의 부담을 줄어들며, Peer Node도 ordering(consensus) 로부터 자유로워진다.

역할이 분기는 인증 및 인가에 필요한 처리를 제한합니다.
모든 피어 노드는 모든 ordering node를 신뢰 할 필요가 없으며, 그 반대의 경우도 동일하다.
그래서 노드의 프로세스는 다른 노드의 검증과 독립적으로 실행할 수 있습니다



 

Chaincode의 모든 기능

Chaincode 어플리케이션은 채널내 Transaction의 유형에 따라 실행될수 있는 로직을 포함하고 있습니다.

예를 들어 자산 소유권 이전을 위한 매개변수를 정의한 ChainCode는, 소유권을 이전하는 모든 Transaction이 동일한 rule 및 요구 사항을 준수하도록 보장합니다.

System Chaincode는 전체 Channel을 위한 operaing 매개변수를 정의하는 Chaincoded와 구별됩니다

life cycle 및 구성 System Channel는 channel에 대한 규칙을 정의하고, Endorsement 및 Validation System Chaincode는 Transaction의 보증(Endorsing) 과 검증에 대한 요구를 정의합니다.

 




모듈러한 디자인

Hyperledger Fabric은 네트워크 설계자 들이 기능 선택을 지원하기 위해 모듈러한 아키텍처로 구현되었습니다.

이것으로 나온 결과물이 어떤 산업이나 퍼블릭 도메인에 적용할 수 있는 전체 블록체인 아키텍쳐입니다.

이를 통해 그 네트워크가 마켓간 상호운영이나 규제, 지리적인 범위 안에서 상호 작동 가능성을 보장하게 됩니다.


출처 : https://hyperledger-fabric.readthedocs.io/en/release-1.1/functionalities.html

 

 

 

[포스팅개정]

2018.06.08 2차 번역 까칠한마녀

Hyperledger Fabric CA는 Hyperledger Fabric용 CA(Certificate Authority)입니다.

이는 다음과 같은 기능을 제공합니다:

  • ID 등록 또는 LDAP에 사용자 레지스트리 연결
  • 등록 인증서 발급(ECERT)
  • 인증서 갱신 및 취소

Hyperledger Fabric CA는 이 문서의 뒷부분에서 설명할 서버와 클라이언트 구성 요소입니다.

Hyperledger Fabric CA에 참여하고 싶은 개발자는 Fabric CA 저장소에서 자세한 내용을 확인하십니오.

개요

아래의 다이어그램은 Hyperledger Fabric CA 서버가 전체 Hyperledger Fabric 아키텍쳐에 적용되는 방식을 보여줍니다.


Hyperledger Fabric CA 서버와 상호 작용하는 방법으론 다음의 두 가지 방식이 있습니다: Hyperledger Fabric CA 클라이언트를 사용하는 방법과 Fabric SDK중 하나를 사용하는 방법입니다.

Hyperledger Fabric CA 서버에 대한 모든 통신은 REST API를 통해서 이루어집니다.

이 REST API에 대한 자세한 내용은 fabric-ca/swagger/swagger-fabric-ca.json을 참조하십시오.

이 설명서는 http://editor2.swagger.io 온라인 에디터를 통해서 볼 수 있습니다.

Hyperledger Fabric CA 클라이언트 또는 SDK는 Hyperledger Fabric CA 서버 클러스터에 연결 할 수 있습니다.

이는 위의 다이어그램 오른쪽 상단에 설명되어 있습니다. 클라이언트는 HA 프록시 End Point로 라우팅하여, Fabric-ca-server 클러스터 구성원 중 하나에 트래픽을 로드 밸런싱 합니다.

클러스터의 모든 Hyperledger Fabric CA 서버는 ID 및 인증서를 추적하기 위해 동일한 데이터베이스를 공유합니다. LDAP이 구성된 경우 ID 정보는 DB가 아닌 LDAP에 보관됩니다.

서버는 여러 CA를 포함할 수 있습니다. 각각의 중간 CA는 루트 CA나 다른 중간 CA를 부모 CA(Parent CA)를 가집니다.

시작하기

선행 사항

  • Go언어 1.9버전 이상 설치
  • Gopath 환경 변수의 올바른 설정
  • libtool 및 libtdhl-dev 패키지 설치

다음의 명령어로 우분투에 libtool 의존성을 설치합니다.

sudo apt install libtool ibltdl-dev

다음의 명령어는 OSX에 libtool 의존성을 설치합니다.

brew install libtool
노트. Homebrew를 통해 libtool을 설치하면 libtldl-dev가 MacOSX에서 필요하지 않습니다.

libtool에 대한 자세한 내용은 https://www.gnu.org/software/libtool을 참조하십시오 .

libltdl-dev에 대한 자세한 내용은 https://www.gnu.org/software/libtool/manual/html_node/Using-libltdl.html을 참조하십시오.

설치

다음으로 $GOPATH/bin에 fabric-ca-server 및 fabric-ca-client 바이너리를 모두 설치합니다.

go get -u github.com/hyperledger/fabric-ca/cmd/...

참고: fabric-ca 저장소를 이미 복제한 경우 위의 'go get' 명령을 실행하기 이전에 master 브랜치에 있는지 확인하십시오. 그렇지 않으면 다음의 오류가 표시 될 수 있습니다.

<gopath>/src/github.com/hyperledger/fabric-ca; git pull --ff-only
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=<remote>/<branch> tlsdoc

package github.com/hyperledger/fabric-ca/cmd/fabric-ca-client: exit status 1

기본 서버 실행

다음의 명령어로 fabric-ca-server를 시작합니다.

fabric-ca-server start -b admin:adminpw

-b 옵션은 부트 스트랩 관리자에 등록 ID와 패스워드를 제공합니다.

LDAP이 "ldap.enabled" 설정으로 활성화되지 않은 경우에 이 작업을 필요로 합니다.

fabric-ca-server-config.yaml이라는 기본 설정 파일은 사용자가 정의 할 수 있는 로컬 디렉토리에 작성됩니다.

Docker를 활용해 서버 시작

Docker 허브

URL: https://hub.docker.com/r/hyperledger/fabric-ca/tags/

보유하고 있는 fabric-ca의 아키텍쳐 및 버전이 일치하는 태그를 찾습니다.

$GOPATH/src/github.com/hyperledger/fabric-ca/docker/server로 이동하여 에디터로 docker-compose.yml을 열도록 합니다.

이전에 찾은 태그를 반영할 수 있도록 image 항목을 변경하십니오. 베타 버전의 x86 아키텍쳐에서는 아래와 같이 보일 수 있습니다.

fabric-ca-server:
  image: hyperledger/fabric-ca:x86_64-1.0.0-beta
  container_name: fabric-ca-server
  ports:
    - "7054:7054"
  environment:
    - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
  volumes:
    - "./fabric-ca-server:/etc/hyperledger/fabric-ca-server"
  command: sh -c 'fabric-ca-server start -b admin:adminpw'

docker-compose.yml 파일과 같은 디렉토리에 있는 터미널을 열어 다음을 실행합니다.

# docker-compose up -d

compose 파일에 지정된 fabric-ca 이미지가 없는 경우 해당 이미지가 삽입되고 fabric-ca 서버 인스턴스가 시작됩니다.

나만의 도커 이미지 만들기

다음의 명령을 입력하면 docker-comsose로 서버를 만들고 시작할 수 있습니다.

cd $GOPATH/src/github.com/hyperledger/fabric-ca
make docker
cd docker/server
docker-compose up -d

The hyperledger/fabric-ca docker 이미지는 fabric-ca-server와 fabric-ca-client 모두 포함하고 있습니다.

# cd $GOPATH/src/github.com/hyperledger/fabric-ca
# FABRIC_CA_DYNAMIC_LINK=true make docker
# cd docker/server
# docker-compose up -d

Fabric CA CLI 살펴보기

이 섹션에서는 편의상 Fabric CA 서버 및 클라이언트를 사용할 수 있는 기본 명령어를 제공합니다.

추가 명령어 정보는 다음 절에서 제공됩니다.

다음 링크는 서버 커맨드 라인과 클라이언트 커맨드 라인을 표시합니다.

문자열 슬라이스(목록)인 커맨드 라인 옵션은 쉼표로 구분된 목록 요소로 옵션을 지정하거나 목록을 구성하는 문자열 값이 있는 옵션을 여러번 지정할 수 있습니다. 예를 들어, host1과 host2를 csr.hosts 옵션에 지정하기 위해선, --csr.hosts 'host1,host2' 또는  --csr.hosts host1,  --csr.hosts host2를 입력하여야 합니다. 이전의 형식을 사용할 땐, 쉼표 앞 뒤에 공간이 없는지 확인하십시오.

구성 설정

Fabirc CA는 Fabric CA 서버와 클라이언트 설정을 구성하기 위한 3가지 방법을 제시합니다.

해당 방법에 대한 우선 순위는 아래와 같습니다.

  1. CLI 플래그
  2. 환경 변수
  3. 설정 파일

이 문서의 나머지 부분에선 설정 파일을 수정하는 방법에 대해서 설명합니다.

그러나, 설정 파일 변경 사항은 환경 변수나 CLI 플래그를 통해 덮어쓰기가 될 수 있습니다.

예를 들어 클라이언트 설정 파일에 아래와 같은 내용이 있는 경우:

tls:
  # Enable TLS (default: false)
  enabled: false

  # TLS for the client's listenting port (default: false)
  certfiles:
  client:
    certfile: cert.pem
    keyfile:

다음의 환경 변수를 cert.pem의 설정 파일 설정을 덮어쓰기 할 수 있습니다.

export FABRIC_CA_CLIENT_TLS_CLIENT_CERTFILE=cert2.pem

만약 환경 변수와 설정 파일 모두 덮어쓰고 싶다면, 아래의 커맨드 라인에서 다음의 플래그를 사용할 수 있습니다.

fabric-ca-client enroll --tls.client.certfile cert3.pem

동일한 방식을 활용하여, FABRIC_CA_CLIENT에서도 해당 변수를 환경 변수에 접두어로 사용되는 것을 제외하고는 FABRIC_CA_SERVER의 사례와 동일합니다.

파일 경로에 대한 단어

파일 이름을 지정하는 Fabric CA 서버 및 클라이언트 설정 파일의 모든 등록 정보는 상대 경로와 절대 경로를 모두 지원합니다. 상대 경로는 설정 파일이 위치한 config 디렉토리와 상대적인 경로입니다.

예를 들자면, ~/config가 config 디렉토리 이고,만약 tls 섹션이 아래와 같다면, Fabric CA server나 client는 ~/config 디렉토리에 있는 root.pem, ~/config/certs 디렉토리의 cert.pem, /abs/path 디렉토리의 key.pem 파일들을 찾을 것 입니다.

tls:
  enabled: true
  certfiles:
    - root.pem
  client:
    certfile: certs/cert.pem
    keyfile: /abs/path/key.pem

Fabric CA 서버

이 섹션에선 Fabric CA 서버에 대해서 설명합니다.

Fabric 서버를 시작하기 이전에 초기화를 이미 하셨을 것 입니다.

이렇게하면 서버를 시작하기 전에 검토하고 사용자 정의 할 수있는 기본 설정 파일을 생성 할 수 있습니다.

  • -home 커맨드 라인 옵션이 설정된 경우, 해당 값을 사용합니다.
  • 그렇지 않으면 FABRIC_CA_SERVER_HOME환경 변수가 설정되면 해당 값을 사용합니다.
  • 그렇지 않으면 FABRIC_CA_HOME환경 변수가 설정되면 해당 값을 사용합니다.
  • 그렇지 않으면 CA_CFG_PATH환경 변수가 설정되면 해당 값을 사용합니다.
  • 그렇지 않으면 현재 작업 디렉토리를 사용합니다.

이 이후로는, FABRIC_CA_HOME 환경 설정이 $HOME/fabric-ca/server에 설정되어 있다고 가정하고 설명하겠습니다.

아래의 지시 사항부터는 서버 설정 파일이 서버의 홈 디렉토리에 있다고 가정합니다.

서버 초기화

다음 명령어를 활용해서 Fabric CA 서버를 초기화 하십시오.

fabric-ca-server init -b admin:adminpw

LDAP이 disabled 되어 있을 경우엔 -b(부트 스트랩 ID)옵션이 초기화를 위해서 필요합니다.

Fabric CA 서버를 시작하려면 하나 이상의 부트 스트랩 ID가 필요합니다. 위에의 ID는 서버 관리자입니다.

서버 설정 파일에는 구성 할 수있는 CSR (Certificate Signing Request) 섹션이 들어 있습니다. 다음은 CSR 샘플입니다.

cn: fabric-ca-server
names:
   - C: US
     ST: "North Carolina"
     L:
     O: Hyperledger
     OU: Fabric
hosts:
  - host1.example.com
  - localhost
ca:
   expiry: 131400h
   pathlength: 1

위의 모든 필드는 X.509 서명 키 및 fabric-ca-server init으로부터 생성된 인증과 관련이 있습니다.

이는 서버 설정 파일에 있는 ca.certfile과 ca.keyfile에 해당됩니다. 필드는 다음과 같습니다:

  • cn 은 일반 이름(Common name)입니다.
  • O 는 조직 이름(Organization name)입니다.
  • OU 는 조직 단위(Organization Unit)입니다.
  • L 은 위치(Location) 또는 도시(city)입니다.
  • ST 는 State입니다.
  • C 가 나라(Country)입니다.

CSR에 대한 사용자 정의 값이 필요하다면 ca.certfile과 ca.keyfile을 삭제하고 설정 파일을 정의한 뒤 다음의 커맨드를 다시 실행함으로서 해결할 수 있습니다.

fabric-ca-server init -b admin:adminpw

이 커맨드는 -u <parent-fabric-ca-server-URL> 옵션이 지정되지 않는다면 자체 서명된 CA 인증서를 생성합니다.

만약 -u 옵션이 지정된다면, 서버의 CA 인증서가 Fabric 부모(parent) CA 서버에 의해서 서명됩니다.

부모 CA 서버를 인증하기 위해선, URL은 반드시 <scheme>://<enrollmentID>:<secret>@<host>:<port>과 같은 구조여야 하고,

여기서 <enrollmentID> 및 <secret>은 값이 'true'인 'hf.IntermediateCA'속성이있는 ID에 해당합니다.

fabric-ca-server init 명령은 또한 fabric-ca-server-config.yaml이라는 기본 설정 파일을 서버의 홈 디렉토리에 생성합니다.

만약 가지고 있는 CA 서명 인증서 및 Key 파일을 사용해서 Fabric CA 서버를 실행하려는 경우 ca.certfile과 ca.keyfile에 각각의 참조 경로를 배치해야 합니다.

두 파일 모두 PEM으로 인코딩 해야하며, 암호화되어 있어서는 안됩니다.

더욱 구체적으로 설명하자면, CA 인증서 파일의 내용은 -----BEGIN CERTIFICATE-----으로 시작해야하고, Key 파일의 내용은 -----BEGIN PRIVATE KEY-----으로 시작해야 합니다.

-----BEGIN ENCRYPTED PRIVATE KEY-----으로 실행하면 실행에 실패하게 됩니다.

알고리즘 및 키 크기

CSR은 ECDSA(타원 곡선)의 지원을 받는 X.509 인증서와 키를 생성하도록 사용자 정의 할 수 있습니다.

다음의 설정은 곡선 prime256v1과 ecdsa-with-SHA256 서명 알고리즘을 활용하여 ECDSA(Elliptic Curve Digital Signature Algorithm)를 구현하는 예시입니다.

key:
   algo: ecdsa
   size: 256

알고리즘 및 키 크기의 선택은 보안 요구 사항을 기반으로합니다.

ECDSA(Elliptic Curve Digital Signature Algorithm)는 다음과 같은 주요 크기 옵션을 제공합니다.

크기 ASN1 OID 서명 알고리즘
256 prime256v1 ecdsa-with-SHA256
384 secp384r1 ecdsa-with-SHA384
521 secp521r1 ecdsa-with-SHA512

서버 시작

다음과 같이 Fabric CA 서버를 시작합니다.

fabric-ca-server start -b <admin>:<adminpw>

서버가 이전에 초기화되지 않은 경우 처음 시작할 때 서버가 초기화됩니다. 

이 초기화 중에 서버는 ca-cert.pem 및 ca-key.pem 파일이 아직 없으면 생성하고 기본 설정 파일도 생성합니다. 

참고 항목 초기화에게 Fabric CA 서버섹션을 참조하십시오.

Fabric CA 서버가 LDAP를 사용하도록 구성되어 있지 않으면 다른 ID를 등록하고 등록 할 수 있도록 미리 등록 된 하나 이상의 부트 스트랩 ID로 구성해야합니다. 

-b 옵션은 부트 스트랩 ID의 이름과 암호를 지정합니다.

Fabric CA 서버가 http 대신 https에 수신 하도록 하려면, tls.enabled 값을 true로 설정하십시오.

동일한 암호를 사용하여 등록하는 횟수를 제한하려면, 설정 파일의 registry.maxenrollments 값을 적절한 값으로 설정하십시오.

이 값을 1로 설정하면 Fabric CA 서버는 특정 등록 ID에 대해 암호를 한 번만 사용할 수 있습니다.

이 값을 -1로 설정하면 Fabric CA 서버는 등록을 위해 비밀을 재사용 할 수있는 횟수에 제한을 두지 않습니다.

기본값은 -1입니다.

값을 0으로 설정하면 Fabric CA 서버가 모든 ID에 대한 등록을 비활성화하고 ID 등록을 허용하지 않습니다.

이제 Fabric CA 서버가 7054포트에서 수신 대기 State일 것 입니다.

Fabric CA 서버가 클러스터에서 실행되도록 구성하거나 LDAP를 사용하지 않으려면 Fabric CA 클라이언트 섹션으로 건너 뛸 수 있습니다 .

Database 구성

이 절에서는 PostgreSQL 또는 MySQL 데이터베이스에 연결하도록 Fabric CA 서버를 구성하는 방법에 대해 설명합니다.

기본 데이터베이스는 SQLite이고 기본 데이터베이스 파일은 Fabric CA 서버 홈 디렉토리의 fabric-ca-server.db에 있습니다.

클러스터에서 Fabric CA 서버 실행에 신경 쓰지 않으면이 절을 건너 뛸 수 있습니다.

그렇지 않으면 아래의 버전 사양으로 PostgreSQL 또는 MySQL을 구성해야합니다.

Fabric CA는 클러스터 설정에서 다음 데이터베이스 버전을 지원합니다.

  • PostgreSQL : 9.5.5 이상
  • MySQL : 5.7 이상

PostgreSQL

다음 샘플은 PostgreSQL 데이터베이스에 연결하기 위해 서버의 설정 파일에 추가 될 수 있습니다. 다양한 값을 적절하게 사용자 정의해야합니다.

데이터베이스 이름에는 어떤 문자가 허용되는지에 대한 제한 사항이 있습니다.

자세한 내용은 다음 Postgres 문서를 참조하십시오.

https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS

db:
  type: postgres
  datasource: host=localhost port=5432 user=Username password=Password dbname=fabric_ca sslmode=verify-full

sslmode를 지정 하면 SSL 인증 유형이 구성됩니다. sslmode의 유효한 값은 다음과 같습니다.

모드 설명
disable SSL 없음
require 항상 SSL (확인 건너 뛰기)
verify-ca 항상 SSL (서버가 제공 한 인증서가 신뢰할 수있는 CA에 의해 서명되었는지 확인)
verify-full verify-ca와 동일하며 서버가 제공 한 인증서가 신뢰할 수있는 CA에 의해 서명되었고 서버 호스트 이름이 인증서의 인증서와 일치하는지 확인합니다.

TLS를 사용하려면, Fabric CA 서버의 db.tls 섹션이 지정되어야만 합니다.

PostgreSQL 서버에서 SSL 클라이언트 인증을 사용하는 경우 db.tls.client 섹션에 클라이언트 인증서와 키 파일도 지정해야합니다.

다음은 db.tls 섹션 의 예입니다.

db:
  ...
  tls:
      enabled: true
      certfiles:
        - db-server-cert.pem
      client:
            certfile: db-client-cert.pem
            keyfile: db-client-key.pem

certfiles - PEM으로 인코딩 된 신뢰할 수있는 루트 인증서 파일 목록

certfile 및 keyfile - PostgreSQL 서버와 안전하게 통신하기 위해 Fabric CA 서버에서 사용하는 PEM 인코딩 인증서 및 키 파일

PostgreSQL SSL 설정

PostgreSQL 서버에서 SSL을 구성하기위한 기본 지침 :

  1. postgresql.conf에서 SSL의 주석 처리를 제거하고 "on"(SSL = on)으로 설정하십시오.
  2. 인증서와 키 파일을 PostgreSQL 데이터 디렉토리에 저장하십시오.

다음에 대한 자체 서명 인증서 생성 지침 :https://www.postgresql.org/docs/9.5/static/ssl-tcp.html

참고 : 자체 서명 인증서는 테스트 용이므로 프로덕션 환경에서 사용하면 안됩니다.

PostgreSQL 서버 - 클라이언트 인증서 필요

  1. 신뢰할 수있는 인증 기관 (CA)의 인증서를 PostgreSQL 데이터 디렉토리의 root.crt 파일에 배치합니다.
  2. postgresql.conf에서 클라이언트의 루트 인증서 (CA cert)를 가리 키도록 "ssl_ca_file"을 설정합니다.
  3. pg_hba.conf의 해당 hostssl 행에서 clientcert 매개 변수를 1로 설정하십시오.

PostgreSQL 서버에서 SSL을 구성하는 방법에 대한 자세한 내용은 다음 PostgreSQL 설명서를 참조하십시오.https://www.postgresql.org/docs/9.4/static/libpq-ssl.html

MySQL

다음 샘플은 Fabric CA 서버 설정 파일에 추가되어 MySQL 데이터베이스에 연결될 수 있습니다. 다양한 값을 적절하게 사용자 정의해야합니다. 데이터베이스 이름에는 어떤 문자가 허용되는지에 대한 제한 사항이 있습니다. 자세한 내용은 다음 MySQL 설명서를 참조하십시오. https://dev.mysql.com/doc/refman/5.7/en/identifiers.html

MySQL 5.7.X에서 특정 모드는 서버가 '0000-00-00'을 유효한 날짜로 허용하는지 여부에 영향을 미칩니다. MySQL 서버가 사용하는 모드를 완화해야 할 수도 있습니다. 우리는 서버가 0의 날짜 값을 받아 들일 수있게하려고합니다.

my.cnf에서 sql_mode 구성 옵션을 찾아 NO_ZERO_DATE를 제거하십시오 . 이 변경 후 MySQL 서버를 다시 시작하십시오.

사용 가능한 다른 모드에 대한 다음 MySQL 설명서를 참조하고 사용중인 특정 버전의 MySQL에 대한 적절한 설정을 선택하십시오.

https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

db:
  type: mysql
  datasource: root:rootpw@tcp(localhost:3306)/fabric_ca?parseTime=true&tls=custom

TLS를 통해 MySQL 서버에 연결하는 경우, db.tls.client 섹션은 위의 PostgreSQL 섹션에서 설명한 것과 같은 것이 필요합니다.

MySQL SSL 설정

MySQL 서버에서 SSL을 구성하기위한 기본 지침 :

  1. 서버용 my.cnf 파일을 열거 나 작성하십시오. [mysqld] 섹션에서 아래 줄을 추가하거나 주석을 제거하십시오. 이것들은 서버의 키와 인증서 및 루트 CA 인증서를 가리켜 야합니다. 서버 및 클라이언트 측 인증서 생성에 대한 지침 :http://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html [mysqld] ssl-ca = ca-cert.pem ssl-cert = server-cert.pem ssl-key = server-key.pem 다음 쿼리를 실행하여 SSL이 활성화되었는지 확인할 수 있습니다. mysql> SHOW GLOBAL VARIABLES LIKE ‘have_%ssl’; 쿼리 실행 결과: {| class="wikitable" !변수 이름 !값 |- |have_openssl |예 |- |have_ssl |예 |}
  2. 서버 측 SSL 설정이 완료되면 다음 단계는 SSL을 통해 MySQL 서버에 액세스 할 수있는 권한을 가진 사용자를 생성하는 것입니다. 이를 위해 MySQL 서버에 로그인하고 다음을 입력하십시오.

mysql> GRANT ALL PRIVILEGES ON . TO ‘ssluser’@’%’ IDENTIFIED BY ‘password’ REQUIRE SSL; mysql> FLUSH PRIVILEGES;

  1. 사용자가 서버에 액세스 할 특정 IP 주소를 지정하려면 '%'를 특정 IP 주소로 변경하십시오.

MySQL 서버 - 클라이언트 인증서 필요

보안 연결 옵션은 서버 측에서 사용되는 옵션과 유사합니다.

ssl-ca는 CA (Certificate Authority) 인증서를 식별합니다. 이 옵션을 사용하면 서버에서 사용하는 것과 동일한 인증서를 지정해야합니다.

ssl-cert는 MySQL 서버 인증서를 식별합니다.

ssl-key는 MySQL 서버의 개인 키를 식별합니다.

특별한 암호화 요구 사항이 없거나 REQUIRE SSL 옵션이 포함 된 GRANT 문을 사용하여 생성 된 계정을 사용하여 연결하려고한다고 가정합니다.

보안 연결 옵션의 권장 세트로서 최소한 -ssl-cert 및 -ssl-key 옵션을 사용하여 MySQL 서버를 시작하십시오.

그런 다음 서버 설정 파일에 db.tls.certfiles 정보를 설정하고, Fabric CA 서버를 시작합니다.

클라이언트 인증서도 지정되도록 요구하려면 REQUIRE X509 옵션을 사용하여 계정을 만드십시오.

그런 다음 클라이언트는 적절한 클라이언트 키와 인증서 파일을 지정해야합니다.

그렇지 않으면 MySQL 서버가 연결을 거부합니다.

Fabric CA 서버에 대한 클라이언트 키 및 인증서 파일을 지정하려면 db.tls.client.certfile과 db.tls.client.keyfile 구성 등록 정보를 설정합니다.

LDAP 설정

Fabric CA 서버는 LDAP 서버에서 읽을 수 있도록 구성 할 수 있습니다.

특히 Fabric CA 서버는 LDAP 서버에 연결하여 다음 작업을 수행 할 수 있습니다.

등록하기 전에 ID를 인증한다.

권한 부여에 사용되는 ID의 속성 값을 검색합니다.

Fabric CA 서버 구성 파일의 LDAP 섹션을 수정하여 서버가 LDAP 서버에 연결되도록 구성하십시오.

ldap:
   # Enables or disables the LDAP client (default: false)
   enabled: false
   # The URL of the LDAP server
   url: <scheme>://<adminDN>:<adminPassword>@<host>:<port>/<base>
   userfilter: <filter>
   attribute:
      # 'names' is an array of strings that identify the specific attributes
      # which are requested from the LDAP server.
      names: <LDAPAttrs>
      # The 'converters' section is used to convert LDAP attribute values
      # to fabric CA attribute values.
      #
      # For example, the following converts an LDAP 'uid' attribute
      # whose value begins with 'revoker' to a fabric CA attribute
      # named "hf.Revoker" with a value of "true" (because the expression
      # evaluates to true).
      #    converters:
      #       - name: hf.Revoker
      #         value: attr("uid") =~ "revoker*"
      #
      # As another example, assume a user has an LDAP attribute named
      # 'member' which has multiple values of "dn1", "dn2", and "dn3".
      # Further assume the following configuration.
      #    converters:
      #       - name: myAttr
      #         value: map(attr("member"),"groups")
      #    maps:
      #       groups:
      #          - name: dn1
      #            value: orderer
      #          - name: dn2
      #            value: peer
      # The value of the user's 'myAttr' attribute is then computed to be
      # "orderer,peer,dn3".  This is because the value of 'attr("member")' is
      # "dn1,dn2,dn3", and the call to 'map' with a 2nd argument of
      # "group" replaces "dn1" with "orderer" and "dn2" with "peer".
      converters:
        - name: <fcaAttrName>
          value: <fcaExpr>
      maps:
        <mapName>:
            - name: <from>
              value: <to>

용어 설명:

  • scheme: ldap 또는 ldaps 중 하나입니다 .
  • adminDN: 관리자 사용자의 고유 이름입니다.
  • pass: 관리자 사용자의 암호입니다.
  • host: LDAP 서버의 호스트 이름 또는 IP 주소입니다.
  • port: 옵션 포트 번호는입니다에 대한 기본 389 LDAP 및 636 LDAPS ;
  • base: 검색에 사용할 LDAP 트리의 선택적 루트입니다.
  • filter: 로그인 사용자 이름을 고유 이름으로 변환하기 위해 검색 할 때 사용하는 필터입니다. 예를 들어 값이 로그인 사용자 이름 인 속성 (uid=%s)값이있는 LDAP 항목 을 검색 하는 값입니다 uid. 마찬가지로 (email=%s)이메일 주소로 로그인하는 데 사용할 수 있습니다.
  • LDAPAttrs: 사용자를 대신하여 LDAP 서버에 요청할 LDAP 속성 이름의 배열입니다.
  • attribute.converters 섹션은 LDAP 속성을 fabric CA 속성으로 변환하는 데 사용됩니다. 여기서 * fcaAttrName는 fabric CA 속성의 이름입니다. * fcaExpr는 계산 된 값이 fabric CA 속성에 지정된 표현식입니다. 예를 들어 <LDAPAttrs>가 [ "uid"]이고 <fcaAttrName>이 'hf.Revoker'이고 <fcaExpr>이 'attr ( "uid") = ~ "revoker *"'라고 가정합니다. 즉, "uid"라는 이름의 속성이 사용자를 대신하여 LDAP 서버에 요청됩니다. 사용자의 'uid'LDAP 속성 값이 'revoker'로 시작하면 'hf.Revoker'속성에 'true'값이 부여됩니다. 그렇지 않은 경우 사용자는 'hf.Revoker'속성에 대해 'false'값이 제공됩니다.
  • attribute.maps 섹션은 LDAP 응답 값을 매핑하는 데 사용됩니다. 일반적인 사용 사례는 LDAP 그룹과 관련된 고유 이름을 ID 유형으로 매핑하는 것입니다.

LDAP 표현식 언어는 https://github.com/Knetic/govaluate/blob/master/MANUAL.md에 설명 된 govaluate 패키지를 사용합니다.

이것은 "= ~"와 같은 연산자와 정규 표현식 인 "revoker *"와 같은 리터럴을 정의합니다.

기본 govaluate 언어를 확장하는 LDAP 관련 변수 및 함수는 다음과 같습니다.

  • DN: 사용자의 고유 이름과 동일한 변수입니다.
  • affiliation: 사용자의 소속와 동등한 변수입니다.
  • attr1: 또는 2 개의 인수를 취하는 함수입니다. 첫 번째 인수는 LDAP 속성 이름입니다. 두 번째 인수는 여러 값을 단일 문자열로 조인하는 데 사용되는 구분 기호 문자열입니다. 기본 구분 기호 문자열은 ","입니다. 이 attr함수는 항상 'string'유형의 값을 반환합니다.
  • map2: 개의 인수를 취하는 함수입니다. 첫 번째 인수는 임의의 문자열입니다. 두 번째 인수는 첫 번째 인수의 문자열에 대해 문자열 대체를 수행하는 데 사용되는지도의 이름입니다.
  • if: 첫 번째 인수가 부울 값으로 해석되어야하는 3 개의 인수를 취하는 함수입니다. true로 평가되면 두 번째 인수가 반환됩니다. 그렇지 않으면 세 번째 인수가 반환됩니다.

예를 들자면, 다음 표현식은 사용자가 "O=Org1,C=US"라는 구별가능한 이름을 가지고 있거나 "admin"속성이 "true"인 경우에 true로 평가됩니다.

DN = ~ "* O = org1, C = US"|| (affiliation = ~ "org1.dept2. *"&& attr ( 'admin') = 'true')

참고 :이 attr함수는 항상 'string' 값을 반환하므로 숫자 연산자는 식을 생성하는 데 사용할 수 없습니다. 예를 들어, 다음은 유효한 표현식이 아닙니다.

value: attr("gidNumber) >= 10000 && attr("gidNumber) < 10006

또는 다음과 같이 따옴표로 묶인 정규 표현식을 사용하여 동일한 결과를 반환 할 수 있습니다.

value: attr("gidNumber") =~ "1000[0-5]$" || attr("mail") == "root@example.com"

다음은 OpenLDAP서버의 기본 설정에 대한 샘플 설정 섹션이고, OpenLDAP 서버에 다음의 docker 이미지를 가지고 있습니다.

https://github.com/osixia/docker-openldap

ldap:
   enabled: true
   url: ldap://cn=admin,dc=example,dc=org:admin@localhost:10389/dc=example,dc=org
   userfilter: (uid=%s)

OpenLDAP 도커 이미지를 시작, 구성, FABRIC_CA / cli / server / ldap / ldap_test.go에서 LDAP 테스트 실행, OpenLDAP 서버 중지를 하는 스크립트에 대해서는 FABRIC_CA / scripts / run-ldap-tests를 참조하십시오.

LDAP가 구성되면 등록은 다음과 같이 작동합니다.

  • Fabric CA 클라이언트 또는 클라이언트 SDK는 기본 인증 헤더와 함께 등록 요청을 보냅니다.
  • Fabric CA 서버는 등록 요청을 수신하고 인증 헤더에서 ID 이름과 암호를 해독하고 구성 파일에서 "userfilter"를 사용하여 ID 이름과 관련된 DN (Distinquished Name)을 조회 한 다음 해당 ID의 패스워드와 LDAP 바인딩을 시도합니다. LDAP 바인딩이 성공하면 등록 처리가 승인되고 계속 진행할 수 있습니다.

클러스터 설정

IP 스프레이어를 사용하여 Fabric CA 서버 클러스터에 로드 밸런싱을 조정할 수 있습니다. 이 섹션에서는 Fabric CA 서버 클러스터로 라우팅하도록 Haproxy를 설정하는 방법에 대한 예제를 제공합니다. Fabric CA 서버의 설정을 반영하도록 호스트 이름과 포트를 변경하십시오.

haproxy.conf

global
      maxconn 4096
      daemon

defaults
      mode http
      maxconn 2000
      timeout connect 5000
      timeout client 50000
      timeout server 50000

listen http-in
      bind *:7054
      balance roundrobin
      server server1 hostname1:port
      server server2 hostname2:port
      server server3 hostname3:port

참고: TLS를 사용하는 경우에는 mode tcp를 사용해야 합니다.

다중 CA 설정

fabric-ca 서버는 기본적으로 단일 기본 CA로 구성됩니다. 그러나 cafiles 또는 cacount 구성 옵션 을 사용하여 추가 CA를 단일 서버에 추가 할 수 있습니다. 각 추가 CA에는 자체 홈 디렉토리를 가지게 됩니다.

cacount:

cacount는 x개의 기본 추가 CA를 시작하는 빠른 방법을 제공합니다.

홈 디렉토리는 서버 디렉토리에 상대적입니다. 이 옵션을 사용하면 디렉토리 구조가 다음과 같이됩니다.

--<Server Home>
  |--ca
    |--ca1
    |--ca2

각각의 추가 CA는 홈 디렉토리에 생성 된 기본 설정 파일을 가져옵니다. 구성 파일에는 고유 한 CA 이름이 포함됩니다.

예를 들어, 다음 명령은 2 개의 기본 CA 인스턴스를 시작합니다.

fabric-ca-server start -b admin:adminpw --cacount 2

cafiles:

cafiles 구성 옵션을 사용할 때 절대 경로가 제공되지 않으면 CA 홈 디렉토리는 서버 디렉토리에 상대적입니다.

이 옵션을 사용하려면 시작될 각 CA에 대해 CA 구성 파일이 이미 생성되고 구성되어 있어야합니다.

각 구성 파일에는 고유 한 CA 이름과 CN (Common Name)이 있어야합니다.

그렇지 않을 경우엔 이름이 고유해야하므로 서버가 시작되지 않습니다.

CA 구성 파일은 기본 CA 구성을 무시하며 CA 구성 파일의 누락 된 옵션은 기본 CA의 값으로 대체됩니다.

선행 순서는 다음과 같습니다.

  1. CA 구성 파일
  2. 기본 CA CLI 플래그
  3. 기본 CA 환경 변수
  4. 기본 CA 구성 파일

CA 구성 파일에는 최소한 다음 내용이 포함되어야합니다.

ca:
# Name of this CA
name: <CANAME>

csr:
  cn: <COMMONNAME>

다음과 같이 디렉토리 구조를 구성 할 수 있습니다.

--<Server Home>
  |--ca
    |--ca1
      |-- fabric-ca-config.yaml
    |--ca2
      |-- fabric-ca-config.yaml

예를 들어, 다음 명령은 사용자 정의 된 두 CA 인스턴스를 시작합니다.

fabric-ca-server start -b admin:adminpw --cafiles ca/ca1/fabric-ca-config.yaml
--cafiles ca/ca2/fabric-ca-config.yaml

중간 CA 등록

중간 CA에 대한 CA 서명 인증서를 만들려면 중간 CA는 Fabric ca 클라이언트가 CA에 등록하는 것과 같은 방법으로 상위 CA에 등록해야합니다.

이 작업은 -u 옵션을 사용하여 아래 표시된 것처럼 부모 CA의 URL과 등록 ID 및 암호를 지정하여 수행됩니다.

이 등록 ID와 연관된 ID에는 이름이 "hf.IntermediateCA"이고 값이 "true"인 속성이 있어야합니다. 발급된 인증서의 CN (또는 Common Name)은 등록 ID로 설정됩니다.

중간 CA가 명시적으로 CN 값을 지정하려고하면 오류가 발생합니다.

fabric-ca-server start -b admin:adminpw -u http://<enrollmentID>:<secret>@<parentserver>:<parentport>

다른 중간 CA 플래그의 경우 Fabric CA 서버의 구성 파일 형식 섹션을 참조하십시오.

서버 업그레이드

Fabric CA 클라이언트를 업그레이드하기 전에 Fabric CA 서버를 업그레이드해야합니다. 업그레이드하기 전에 현재 데이터베이스를 백업하는 것이 좋습니다.

  • sqlite3을 사용하는 경우 현재 데이터베이스 파일 (기본적으로 fabric-ca-server.db라는 이름)을 백업하십시오.
  • 다른 데이터베이스 유형의 경우 적절한 백업 / 복제 메커니즘을 사용하십시오.

Fabric CA 서버의 단일 인스턴스를 업그레이드하려면 다음을 수행하십시오.

  1. fabric-ca-server 프로세스를 중지하십시오.
  2. 현재 데이터베이스가 백업되었는지 확인하십시오.
  3. 이전 fabric-ca-server 바이너리를 업그레이드 된 버전으로 교체하십시오.
  4. fabric-ca-server 프로세스를 시작하십시오.
  5. 다음 명령으로 fabric-ca-server 프로세스를 사용할 수 있는지 확인하십시오. 여기서 <host>는 서버가 시작된 호스트 이름입니다.
fabric - ca - 클라이언트  getcacert  - u  http : // < host > : 7054

클러스터 업그레이드

MySQL 또는 Postgres 데이터베이스를 사용하여 fabric-ca-server 인스턴스의 클러스터를 업그레이드하려면 다음 절차를 수행하십시오.

host1 및 host2의 두 fabric-ca-server 클러스터 구성원 (각각 포트 7054에서 수신 대기)에로드 밸런싱을 위해 haproxy를 사용한다고 가정합니다.

이 절차를 수행하면 업그레이드 된 fabric-ca-server 클러스터 구성원으로로드 밸런싱이 수행되고, 각각 host3 및 host4에서 포트 7054에서 수신 대기합니다.

haproxy 통계를 사용하여 변경 사항을 모니터링하려면 통계 수집을 활성화하십시오.

haproxy 구성 파일의 전역 섹션에 다음 행을 추가합니다.

stats socket /var/run/haproxy.sock mode 666 level operator
stats timeout 2m

변경 사항을 적용하려면 haproxy를 다시 시작하십시오.

# haproxy -f <configfile> -st $ (pgrep haproxy)

haproxy "show stat"명령의 요약 정보를 표시하려면 다음 함수가 반환되는 많은 양의 CSV 데이터를 구문 분석하는 데 유용 할 수 있습니다.

haProxyShowStats () {
   echo "show stat"| nc -U /var/run/haproxy.sock | sed '1s / ^ # * //'|
      awk -F ','-v fmt = "% 4s % 12s % 10s % 6s % 6s % 4s % 4s \ n" '
         (i = 1; i = NF; i ++) f [tolower ($ i)] = i}에 대해 if (NR == 1)
         $ f [ "svname"], $ f [ "status"], $ f [ "svname"],
                       $ f [ "weight"], $ f [ "act"], $ f [ "bck"]} '
}

1. 처음에 haproxy 구성 파일은 다음과 유사합니다.

server server1 host1:7054 check
server server2 host2:7054 check

이 구성을 다음과 같이 변경하십시오.

2. 다음과 같이 새 구성으로 Haproxy를 다시 시작하십시오.

haproxy -f <configfile> -st $(pgrep haproxy)

이제 "haproxyShowStats"가 2개의 활성 이전 백업 서버와 2개의 업그레이드가 된 서버(아직 시작되지 않은)가 있는 수정된 설정을 반영하게 될 것입니다.

sid   pxname      svname  status  weig  act  bck
  1   fabric-cas  server3   DOWN     1    1    0
  2   fabric-cas  server4   DOWN     1    1    0
  3   fabric-cas  server1     UP     1    0    1
  4   fabric-cas  server2     UP     1    0    1

3. host3 및 host4에 fabric-ca-server의 업그레이드 된 바이너리를 설치하십시오.

host3 및 host4의 새로운 업그레이드 된 서버는 host1 및 host2의 이전 버전과 동일한 데이터베이스를 사용하도록 구성되어야합니다.

업그레이드 된 서버를 시작하면 데이터베이스가 자동으로 마이그레이션됩니다.

haproxy는 백업 서버로 구성되지 않았기 때문에 모든 새 트래픽을 업그레이드 된 서버로 전달합니다.

"fabric-ca-client getcacert" 명령어를 사용해서 클러스터가 계속 제대로 작동 하는지 확인하는지 확인하십시오.

또한, "haProxyShowStats"는 이제 다음과 같이 모든 서버가 활성 State임을 반영하게됩니다.

sid   pxname      svname  status  weig  act  bck
  1   fabric-cas  server3    UP     1    1    0
  2   fabric-cas  server4    UP     1    1    0
  3   fabric-cas  server1    UP     1    0    1
  4   fabric-cas  server2    UP     1    0    1

4. host1과 host2에서 이전 서버를 중지하십시오. 이후 단계로 진행하기 이전에 새 클러스터가 계속 제대로 작동 하는지 확인하는 명령을 사용해여 확인하십시오.

그런 다음 haproxy 구성 파일에서 이전 서버 백업 구성을 제거하여 다음과 유사하게 만듭니다.

server server3 host3:7054 check
server server4 host4:7054 check

5. 다음과 같이 새 구성 설정으로 HA 프록시를 다시 시작하십시오.

haproxy -f <configfile> -st $(pgrep haproxy)

"haProxyShowStats"는 이제 새 버전으로 업그레이드 된 두 개의 활성 서버가 있는 수정된 구성 설정이 반영됩니다.

sid   pxname      svname  status  weig  act  bck
  1   fabric-cas  server3   UP       1    1    0
  2   fabric-cas  server4   UP       1    1    0

Fabric CA 클라이언트

이 섹션에서는 fabric-ca-client 명령어를 사용하는 방법에 대해서 설명합니다.

Fabric CA 클라이언트의 홈 디렉토리는 다음과 같이 결정됩니다:

  • -home 커맨드 라인 옵션이 설정된 경우, 해당 값을 사용합니다.
  • 그렇지 않으면 FABRIC_CA_CLIENT_HOME환경 변수가 설정되면 해당 값을 사용합니다.
  • 그렇지 않으면 FABRIC_CA_HOME 환경 변수가 설정되면 해당 값을 사용합니다.
  • 그렇지 않으면 CA_CFG_PATH 환경 변수가 설정되면 해당 값을 사용합니다.
  • 그렇지 않으면 $HOME/.fabric-ca-client를 사용합니다.

이후의 지침부터는 클라이언트 구성 파일이 클라이언트의 홈 디렉토리에 있다고 가정합니다.

부트 스트랩 ID 등록

필요한 경우에, 우선 클라이언트 구성 파일에서 CSR(Certificate Signing Request) 섹션을 사용자 정의하십시오.

csr.cn 필드는 부트 스트랩 ID로 설정되어야만 한다는 것을 참고하시길 바랍니다.

디폴트 CSR 값은 다음과 같습니다.

csr:
  cn: <<enrollment ID>>
  key:
    algo: ecdsa
    size: 256
  names:
    - C: US
      ST: North Carolina
      L:
      O: Hyperledger Fabric
      OU: Fabric CA
  hosts:
   - <<hostname of the fabric-ca-client>>
  ca:
    pathlen:
    pathlenzero:
    expiry:

필드에 대한 설명은 CSR Field를 확인하십시오.

다음으로, fabric-ca-client enroll 명령어를 실행하여 ID를 등록하십시오.

예를 들어 아래의 명령은 7054 포트에서 실행되는 Fabric CA 서버를 호출하여 ID는 admin이고, 비밀번호가 adminpw인 계정을 등록합니다.

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client enroll -u http://admin:adminpw@localhost:7054

enroll 명령어는 Enrollment Certificate(ECert), 그에 해당하는 개인 키, CA 인증서 체인 PEM 파일을 Fabric CA 클라이언트 msp 디렉토리의 하위 디렉토리에 저장합니다.

이후 PEM 파일의 저장 위치를 확인할 수 있는 메시지가 표시됩니다.

새 ID 등록

등록 요청을 수행하는 ID는 현재 등록되어 있어야하며 등록중인 ID의 유형을 등록 할 수있는 적절한 권한이 있어야합니다.

특히 다음과 같이 등록하는 동안 Fabric CA 서버에서 세 가지 권한 부여 검사가 수행됩니다.

  1. 등록자 (즉, 호출자)는 쉼표로 구분 된 값 목록이있는 "hf.Registrar.Roles"속성이 있어야합니다. 이 값 중 하나는 등록 할 ID 유형과 동일합니다. 예를 들어, 등록자가 "peer, app, user"값을 갖는 "hf.Registrar.Roles"속성을 갖는 경우, 등록자는 피어, 앱 및 사용자 유형의 ID를 등록 할 수 있지만 순서 지정자는 등록 할 수 없습니다.
  2. 등록 기관의 소속은 등록 된 가맹(affiliation) ID와의 접두사와 같아야합니다. 예를 들어, "a.b"의 가맹 ID가있는 등록 기관은 "a.b.c"의 가맹 ID를 등록 할 수 있지만 "a.c"의 가맹 ID를 등록 할 수 없습니다. ID에 루트 소속이 필요한 경우 가맹 요청은 점( ".") 이어야하며 등록 기관도 루트 가맹을 가져야합니다. 등록 요청에 가맹이 지정되지 않은 경우 등록중인 ID에 등록 기관의 소속이 부여됩니다.
  3. 등록자는 다음 조건이 모두 충족 될 경우 유저 및 유저 속성을 등록 할 수 있습니다.
    • 등록자는 접두사 'hf'가있는 Fabric CA 예약 속성을 등록 할 수 있습니다. 등록자가 속성을 소유하고 'hf.Registrar.Attributes' 속성 값의 일부인 경우에만 해당됩니다. 또한, 속성이 list 유형 인 경우, 등록되는 속성의 값은 등록자가 가지고있는 값의 부분 집합과 같아야합니다. 속성이 부울 값 인 경우 등록자는 속성에 대한 등록자 값이 '참'인 경우에만 속성을 등록 할 수 있습니다.
    • 사용자 정의 속성 (즉, 이름이 'hf.'로 시작하지 않는 속성)을 등록하려면 등록자에 속성 또는 패턴 값이 등록 된 'hf.Registar.Attributes'속성이 있어야합니다. 유일하게 지원되는 패턴은 끝에 "*"가있는 문자열입니다. 예를 들어, "a.b *"는 "a.b"로 시작하는 모든 속성 이름과 일치하는 패턴입니다. 예를 들어, 등록자가 hf.Registrar.Attributes = orgAdmin을 갖는 경우, 등록자가 ID에 추가하거나 제거 할 수있는 유일한 속성은 'orgAdmin'속성입니다.
    • 요청 된 속성 이름이 'hf.Registrar.Attributes'인 경우,이 속성에 대해 요청 된 값이 'hf.Registrar.Attributes'에 대한 등록자 값의 부분 집합과 같은지 추가 확인이 수행됩니다. 이 값이 참이 되려면 요청 된 각 값이 등록 기관의 'hf.Registrar.Attributes'속성 값과 일치해야합니다. 예를 들어 등록자의 'hf.Registrar.Attributes'값이 'a.b.*,x.y.z'이고 요청 된 속성 값이 'a.b.c,x.y.z'인 경우 'a.b.c'가 'a.b.*'와 일치하고 'x.y.z'가 등록자의 'x.y.z' 값 일치하므로 유효합니다.
 

유효한 시나리오 :

  1. 등록자에 'hf.Registrar.Attributes = a.b.*,x.y.z'속성이 있고 'a.b.c'속성을 등록하는 경우 유효한 'a.b.c'는 'a.b.*'와 일치합니다.
  2. 등록자에 'hf.Registrar.Attributes = a.b.*,x.y.z'속성이 있고 속성 'x.y.z'를 등록하는 경우 'x.y.z'가 등록자의 'x.y.z'값과 일치하므로 유효합니다.
  3. 등록자가 'hf.Registrar.Attributes = a.b.*,x.y.z'속성을 갖고 요청 된 속성 값이 'a.b.c,x.y.z'이면 'a.b.c'가 'a.b.*'와 일치하고 'x.y.z'가 등록자의 'x.y.z'값입니다.
  4. 등록자에 'hf.Registrar.Roles = peer,client' 속성가 있고 요청 된 속성 값이 'peer'또는 'peer, client'인 경우 요청 된 값이 등록자 값의 서브 세트와 같거나 유효하기 때문에 유효합니다 .

잘못된 시나리오 :

  1. 등록자에 'hf.Registrar.Attributes = a.b.*,x.y.z'속성이 있고 'hf.Registar.Attributes = a.b.c,x.y.*'속성을 등록하는 경우 요청 된 속성 'x.y.*'이 소유 된 패턴이 아니기 때문에 유효하지 않습니다. 'x.y.*' 값은 'x.y.z'의 상위 집합입니다.
  2. 등록자에 'hf.Registrar.Attributes = a.b.*,x.y.z'속성이 있고 'hf.Registar.Attributes = a.b.c,x.y.z,attr1'속성을 등록하는 경우 등록자의 'hf.Registrar.Attributes'속성이 유효하지 않으므로 유효하지 않습니다 값은 'attr1'을 포함하지 않습니다.
  3. 등록자에 'hf.Registrar.Attributes = a.b.*,x.y.z'속성이 있고 'a.b'속성을 등록하는 경우 값 'a.b'가 'ab *'에 포함되어 있지 않으므로 유효하지 않습니다.
  4. 등록자에 'hf.Registrar.Attributes = a.b.*,x.y.z'속성이 있고 속성 'x.y'를 등록하는 경우 'x.y'가 'x.y.z'에 포함되지 않아 유효하지 않습니다.
  5. 등록자에 'hf.Registrar.Roles = peer, client'속성이 있고 요청 된 속성 값이 'peer, client, orderer'인 경우 등록자에 hf.Registrar.Roles 속성 값의 순서 역할이 없으므로 유효하지 않습니다.
  6. 등록자에 'hf.Revoker = false'속성이 있고 요청 된 속성 값이 'true'인 경우 hf.Revoker 속성이 부울 속성이고 등록자 값이 'true'가 아니므로 유효하지 않습니다.

아래 표에는 ID에 등록 할 수있는 모든 속성이 나열되어 있습니다.

속성 이름은 대소 문자를 구분합니다.

Name Type Description
hf.Registrar.Roles List 등록 기관이 관리 할 수있는 역할 목록
hf.Registrar.DelegateRoles List 등록자가 'hf.Registrar.Roles'속성에 대해 등록 트리에 부여할 수 있는 역할 목록
hf.Registrar.Attributes List 등록자가 등록할 수 있는 속성 목록
hf.GenCRL Boolean Identity는 속성 값이 true 인 경우 Identity에서 CRL을 생성 가능
hf.Revoker Boolean Identity는 속성 값이 true 인 경우 사용자 및 / 또는 인증서를 철회 가능
hf.AffiliationMgr Boolean Identity는 속성 값이 true 인 경우 가맹 관리 가능
hf.IntermediateCA Boolean Identity는 속성 값이 true 인 경우 중간 CA로서 등록 가능

다음의 명령문은 등록 ID가 admin2, org1.department1로 가맹되었고, 이름이 hf.Revoker인 속성의 값이 true인 새로운 사용자를 등록하기 위해서 admin ID의 자격 증명을 사용합니다.

": ecert"접미사는 기본적으로 "admin"속성과 그 값이 사용자 등록 인증서에 삽입되어 접근 제어 결정을 내릴 수 있음을 의미합니다.

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client register --id.name admin2 --id.affiliation org1.department1 --id.attrs 'hf.Revoker=true,admin=true:ecert'

등록 암호라고도하는 암호가 인쇄됩니다. 이 암호는 ID를 등록하는 데 필요합니다. 이를 통해 관리자는 ID를 등록할 수 있고 ID를 등록하기 위한 등록 ID와 암호로서 다른 사람에게 제공 할 수 있습니다.

-id.attrs 플래그의 일부로 여러 속성을 지정할 수 있으며 각 속성은 쉼표로 구분되어야합니다. 쉼표가 들어있는 속성 값의 경우 속성을 큰 따옴표로 묶어야합니다. 아래 예를 참조하십시오.

fabric-ca-client register -d --id.name admin2 --id.affiliation org1.department1 --id.attrs '"hf.Registrar.Roles=peer,user",hf.Revoker=true'

또는

fabric-ca-client register -d --id.name admin2 --id.affiliation org1.department1 --id.attrs '"hf.Registrar.Roles=peer,user"' --id.attrs hf.Revoker=true

클라이언트의 구성 파일을 편집하여 register 명령에 사용 된 모든 필드의 기본값을 설정할 수 있습니다. 예를 들어 구성 파일에 다음과 같이 포함되어 있다고 가정합니다.

id:
  name:
  type: user
  affiliation: org1.department1
  maxenrollments: -1
  attributes:
    - name: hf.Revoker
      value: true
    - name: anotherAttrName
      value: anotherAttrValue

다음 명령은 명령 줄에서 가져 오는 등록 ID가 "admin3"인 새 ID를 등록하고, 나머지는 Identity type: "user", affiliation: "org1.department1”,

두 개의 속성인 “hf.Revoker” and “anotherAttrName”와 같은 정보를 포함하고 있는 구성 파일에서 가져옵니다.

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client register --id.name admin3

여러 속성으로 ID를 등록하려면 위와 같이 구성 파일에 모든 속성 이름과 값을 지정해야합니다.

maxenrollment를 0으로 설정 하거나 구성에서 제외하면 ID가 CA의 최대 등록 값을 사용하도록 등록됩니다.

또한 등록되는 ID의 최대 등록 값은 CA의 최대 등록 값을 초과 할 수 없습니다.

예를 들어 CA의 최대 등록 값이 5 인 경우 새 ID는 5보다 작거나 같은 값을 가져야하며 -1로 설정하면 안됩니다 (무한 등록의 문제 발생).

다음 섹션에서 피어를 등록하는 데 사용할 피어 ID를 등록 해 봅시다.

다음 명령은 peer1 ID를 등록합니다 .

우리는 서버가 우리를 위해 암호를 생성하는 대신에 우리 자신의 암호 (또는 비밀번호)를 지정하기로 결정했습니다.

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client register --id.name peer1 --id.type peer --id.affiliation org1.department1 --id.secret peer1pw

소속은 항상 소문자로 저장되는 서버 구성 파일에 지정된 리프가 아닌 소속을 제외하고 대소 문자를 구분합니다.

예를 들어 서버 구성 파일의 소속 섹션이 다음과 같은 경우:

affiliations:
  BU1:
    Department1:
      - Team1
  BU2:
    - Department2
    - Department3

BU1, Department1, BU2는 소문자로 저장됩니다. 이는 Fabric CA가 Viper를 사용하여 구성을 읽었기 때문입니다.

Viper는 맵 키의 대소 문자를 구분하지 않고 항상 소문자 값을 반환합니다.

Team1 가맹 ID를 등록하려면, bu1.department1.Team1은 -id.affiliation에 지정되어야합니다.

이에 대한 사항은 아래에서 찾아보실 수 있습니다.

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client register --id.name client1 --id.type client --id.affiliation bu1.department1.Team1

피어 ID 등록

피어 ID를 성공적으로 등록 했으므로 이제 등록 ID와 암호 (예 : 이전 섹션 의 암호) 를 사용하여 피어를 등록 할 수 있습니다 . 이것은 "-M"옵션을 사용하여 Hyperledger Fabric MSP (Membership Service Provider) 디렉토리 구조를 채우는 방법을 시연하는 것을 제외하고는 부트 스트랩 ID를 등록하는 것과 비슷합니다.

다음 명령은 peer1을 등록합니다. "-M"옵션의 값을 피어의 core.yaml 파일에있는 'mspConfigPath'설정 인 피어의 MSP 디렉토리 경로로 바꾸십시오. FABRIC_CA_CLIENT_HOME을 동료의 홈 디렉토리로 설정할 수도 있습니다.

export FABRIC_CA_CLIENT_HOME = $ HOME / fabric-ca / clients / peer1
fabric-ca-client enroll -u http : // peer1 : peer1pw @ localhost : 7054 -M $ FABRIC_CA_CLIENT_HOME / msp

Orderer 등록은 MSP 디렉토리 경로가 Orderer의 orderer.yaml 파일에있는 'LocalMSPDir'설정을 제외하고는 동일합니다.

fabric-ca-server에서 발급 한 모든 등록 인증서에는 다음과 같이 조직 단위 (또는 "OU")가 있습니다.

  1. OU 계층 구조의 루트는 ID 유형과 동일합니다.
  2. ID 정보의 각 구성 요소에 대해 OU가 추가됩니다.

예를 들어, ID 유형이  Peer고 조직이  depertment1.team1인 경우 ID의 OU 계층 구조 (리프에서 루트까지)는 OU = team1, OU = department1, OU = peer 입니다.

다른 Fabric CA 서버에서 CA 인증서 체인 가져 오기

일반적으로 MSP 디렉토리의 cacerts 디렉토리에는 피어에 대한 모든 신뢰 루트를 나타내는 다른 인증 기관의 인증 기관 체인이 있어야합니다.

fabric-ca-client getcacerts 명령은 다른 Fabric CA 서버 인스턴스에서 이러한 인증서 체인을 검색하는 데 사용됩니다.

예를 들어, 다음은 "CA2"라는 이름으로 포트 7055에서 청취하는 localhost에서 두 번째 Fabric CA 서버를 시작합니다.

이는 완전히 다른 신뢰의 루트를 나타내며 블록 체인의 다른 구성원에 의해 관리됩니다.

export FABRIC_CA_SERVER_HOME=$HOME/ca2
fabric-ca-server start -b admin:ca2pw -p 7055 -n CA2

다음 명령을 통해 CA2의 인증서 체인을 peer1의 MSP 디렉토리에 설치합니다.

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/peer1
fabric-ca-client getcacert -u http://localhost:7055 -M $FABRIC_CA_CLIENT_HOME/msp

기본적으로 Fabric CA 서버는 하위 순서로 CA 체인을 반환합니다. 즉, 체인의 각 CA 인증서 뒤에 발급자의 CA 인증서가옵니다.

Fabric CA 서버가 반대 순서로 CA 체인을 반환해야하는 경우 환경 변수 CA_CHAIN_PARENT_FIRST를 true로 설정 하고 Fabric CA 서버를 다시 시작하십시오.

Fabric CA 클라이언트는 두 가지 Order를 적절히 처리합니다.

ID(Identity) 재등록

등록 인증서가 만료 되려고하거나 손상되었다고 가정하십시오.

재등록 명령을 실행하여 다음과 같이 등록 인증서를 갱신 할 수 있습니다.

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/peer1
fabric-ca-client reenroll

인증서 또는 ID 폐기

ID 또는 인증서를 폐기 할 수 있습니다. ID를 취소하면 ID이 소유 한 모든 인증서가 폐기되고 ID이 새 인증서를 얻지 못하게됩니다. 인증서를 해지하면 단일 인증서가 무효화됩니다.

인증서 또는 ID를 해지하려면 호출 ID에 hf.Revoker 및 hf.Registrar.Roles 속성 이 있어야 합니다. 폐지 ID는 ID의 소속과 동등하거나 ID의 가맹 정보를 가진 접두사가 있는 인증서 또는 ID만을 취소 할 수 있습니다. 또한, 폐지 요청자는 요청자의 hf.Registrar.Roles 속성에 나열된 유형의 ID만 취소 할 수 있습니다 .

예를 들어, orgs.org1과 'hf.Registrar.Roles = peer,client'속성을 가진 폐기 요청자는 orgs.org1 또는 orgs.org1.department1 과 소속된 피어 또는 클라이언트 유형 ID를 취소 할 수 있지만 orgs.org2 또는 기타 유형의 가맹된 ID를 취소 할 수는 없습니다..

다음 명령은 ID를 사용 불가능하게하고 ID와 연관된 모든 인증서를 취소합니다. Fabric CA 서버가이 ID로 수신 한 모든 향후 요청이 거부됩니다.

fabric-ca-client revoke -e <enrollment_id> -r <reason>

아래의 요소들은 -r 플래그를 사용해서 지정할 수 있는 지원 가능한 사유입니다.

  1. unspecified
  2. keycompromise
  3. cacompromise
  4. affiliationchange
  5. superseded
  6. cessationofoperation
  7. certificatehold
  8. removefromcrl
  9. privilegewithdrawn
  10. aacompromise

예를 들자면, 소속 트리의 루트와 연결된 브트 스트랩 관리자는 다음과 같이 Peer1의 ID를 폐기할 수 있습니다.

export FABRIC_CA_CLIENT_HOME=$HOME/fabric-ca/clients/admin
fabric-ca-client revoke -e peer1

ID에 속하는 등록 인증서는 다음과 같이 AKI (Authority Key Identifier) ​​및 일련 번호를 지정하여 해지 할 수 있습니다.

fabric-ca-client revoke -a xxx -s yyy -r <reason>

예를 들어 openssl 명령어를 사용해서 AKI와 인증의 시리얼 키를 얻을 수 있고 그 정보를 revoke 명령어를 통해서 해당 인증서를 폐지할 수 있습니다.

이에 대한 명령어는 다음과 같습니다.

serial=$(openssl x509 -in userecert.pem -serial -noout | cut -d "=" -f 2)
aki=$(openssl x509 -in userecert.pem -text | awk '/keyid/ {gsub(/ *keyid:|:/,"",$1);print tolower($0)}')
fabric-ca-client revoke -s $serial -a $aki -r affiliationchange

-getcrl 플래그는 해지된 모든 인증서를 포함하고 있는 CRL(Certified Revocation List)를 생성 할 수 있습니다.

예를 들어 다음의 명령은 peer1 ID를 폐기, CRL을 생성, <msp폴더>/crls/crl.pem 파일에 저장합니다.

fabric-ca-client revoke -e peer1 --gencrl

CRL은 gencrl명령을 사용하여 생성 할 수도 있습니다 .

CRL(Certified Revocation List) 생성하기 섹션을 통해서 gencrl 명령어에 대한 자세한 내용을 확인할 수 있습니다.

CRL (인증서 해지 목록) 생성

Fabric CA 서버에서 인증서가 폐기 된 후에는 Hyperledger Fabric의 해당 MSP도 업데이트해야합니다. 여기에는 해당 채널 구성 블록에 피어의 로컬 MSP와 MSP가 모두 포함됩니다. 이렇게하려면 PEM으로 인코딩 된 CRL (인증서 해지 목록) 파일을 MSP 의  폴더에 저장해야합니다 . fabric-ca-client 명령을 사용하여 CRL을 생성 할 수 있습니다. gencrlhf.GenCRL 특성을 가진 모든 ID 는 특정 기간 동안 해지 된 모든 인증서의 일련 번호를 포함한 CRL을 만들 수 있습니다. 생성된 CRL은 <msp folder>/crls/crl.pem 파일에 저장됩니다. 

다음 명령은 폐기 된 모든 인증서(만료되었거나 및 만료되지 않은)를 포함하는 CRL을 만들고 ~/msp/crls/crl.pem 파일에 CRL을 저장 합니다.

export FABRIC_CA_CLIENT_HOME=~/clientconfig
fabric-ca-client gencrl -M ~/msp

다음 명령은 2017-09-13T16:39:57-08:00(-revokeafter 플래그로 지정) 이후와 2017-09-21T16:39:57-08:00(-revokebefore 플래그로 지정 ) 이전에 해지 된 모든 인증서 (만료되고 만료되지 않은)를 포함하는 CRL을 만듭니다. 그리고 그 결과를 ~/msp/crls/crl.pem파일에 CRL을 저장합니다.

export FABRIC_CA_CLIENT_HOME=~/clientconfig
fabric-ca-client gencrl --caname "" --revokedafter 2017-09-13T16:39:57-08:00 --revokedbefore 2017-09-21T16:39:57-08:00 -M ~/msp

-caname 플래그는 요청을 받은 CA의 이름을 지정합니다. 이 예시에선 gencrl 요청을 기본 CA에 전송하였습니다.

-revokedafter와 -revokedbefore 플래그는 시간 차동안 상하 바운더리를 지정합니다.

생성된 CRL은 이 시간 차 동안 폐지된 인증서만을 포함합니다. 값은 RFC3339 포멧으로 지정된 UTC 형식의 타임스템프를 가집니다.

-revokeafter 타임스탬프는 -revokebefore 타임스탬프보다 큰 값이어서는 안됩니다.

기본적으로, CRL의 다음 업데이트 날짜는 해당 일자의 다음 날로 지정됩니다. crl.expiry의 CA 구성 등록 정보는 사용자 정의 값을 지정할 수 있습니다.

gencrl 명령어는 또한 -expireafter와 -expirebefore 플래그도 받아들입니다. 해당 플래그들은 폐기된 인증서 중 기간동안 만료된 인증서 정보를 CRL에 생성합니다.

예를 들어 아래의 명령어는  2017-09-13T16:39:57-08:00부터 2017-09-21T16:39:57-08:00까지의 폐기 인증서 정보와 중  2017-09-13T16:39:57-08:00부터 2018-09-13T16:39:57-08:00까지의

기간동안 만료된 인증서 정보를 포함한 CRL을 생성합니다.

export FABRIC_CA_CLIENT_HOME=~/clientconfig
fabric-ca-client gencrl --caname "" --expireafter 2017-09-13T16:39:57-08:00 --expirebefore 2018-09-13T16:39:57-08:00  --revokedafter 2017-09-13T16:39:57-08:00 --revokedbefore 2017-09-21T16:39:57-08:00 -M ~/msp

Fabric-samples/fabric-ca 샘플은 폐지 사용자의 인증서를 포함하고 있는 CRL을 생성하고 채널의 MSP를 업데이트 하는 방법을 보여줍니다.

그런 다음에 폐지된 사용자 자격 증명을 이용해서 채널에 쿼리를 보내면 인증 오류 발생을 출력합니다.

TLS 활성화

이 섹션에서는 Fabric CA 클라이언트에 TLS를 구성하는 방법에 대해 자세히 설명합니다.

다음 섹션은 fabric-ca-client-config.yaml 구성합니다.

tls:
  # Enable TLS (default: false)
  enabled: true
  certfiles:
    - root.pem
  client:
    certfile: tls_client-cert.pem
    keyfile: tls_client-key.pem

certfile 옵션은 클라이언트가 신뢰할 수 있는 루트 인증서의 집합입니다.

이는 일반적으로 ca-cert.pem 파일에 해당하는 서버의 홈 디렉토리에 있는 루트 Fabric CA 서버 인증서 입니다.

client 옵션은 상호 TLS가 서버에서 구성되었을 경우에 필요합니다.

속성 기반 접근 제어

접근 제어 결정은 ID의 속성에 따라 체인 코드 (및 Hyperledger Fabric 런타임에 의해)로 이루어질 수 있습니다. 이를 Attribute-Based Access Control 또는 ABAC 라고 부릅니다 .

이를 가능하게하기 위해 ID의 등록 인증서(ECert)는 하나 이상의 속성 이름과 값을 포함 할 수 있습니다. 그런 다음 체인 코드는 속성 값을 추출하여 접근 제어 결정을 내립니다.

예를 들어 응용 프로그램 app1을 개발 중이며 app1 관리자 만 특정 체인 코드 작업에 접근 할 수 있도록하려고 한다고 가정합니다 . 체인 코드는 호출자의 인증서 (채널에 대해 신뢰할 수있는 CA에서 발급 받은)에 true 값을 갖는 app1Admin 이라는 속성이 있는지 확인할 수 있습니다 . 물론 속성의 이름은 무엇이든 될 수 있으며 값은 부울 값일 필요가 없습니다.

따라서 속성이있는 등록 인증서를 어떻게 얻기 위한 두 가지 방법이 있습니다.

  • ID를 등록 할 때 ID에 대해 발행 된 등록 인증서에 기본적으로 속성이 포함되도록 지정 할 수 있습니다. 이 동작은 등록 시 무시 될 수 있지만 기본 동작를 설정하는 데 유용하며 응용 프로그램 외부에서 등록이 수행된다고 가정하면 응용 프로그램을 변경할 필요가 없습니다. 다음은 app1Admin 과 email의 두 속성으로 user1 을 등록하는 방법을 보여줍니다 . ": ecert"접미사 는 사용자가 등록시 명시 적으로 속성을 요청하지 않은 경우 기본적으로 appAdmin 속성이 user1의 등록 인증서에 삽입되도록합니다. 이메일 속성은 기본적으로 등록 인증서에 추가되지 않습니다.
fabric-ca-client register --id.name user1 --id.secret user1pw --id.type user --id.affiliation org1 --id.attrs 'app1Admin=true:ecert,email=user1@gmail.com'
  • ID를 등록 할 때 하나 이상의 속성을 인증서에 추가하도록 명시적으로 요청할 수 있습니다. 요청된 각 속성에 대해 속성이 선택적인지 여부를 지정할 수 있습니다. 선택적으로 요청하지 않았고 ID에 특성이없는 경우 오류가 발생합니다.

다음은 app1Admin 속성 없이 email 속성을 사용하여 user1 을 등록하는 방법 과 사용자가 phone 속성을 소유하고있는 경우 선택적으로 phone 속성 을 등록하는 방법을 보여줍니다 .

fabric-ca-client enroll -u http://user1:user1pw@localhost:7054 --enrollment.attrs "email,phone:opt"

아래의 표는 매 ID 등록이 자동적으로 발생하는 세 가지 속성을 보여줍니다.

속성 이름 속성 값
hf.EnrollmentID 신원의 등록 ID
hf.Type 신원 유형
hf.Affiliation 신원의 소속

위의 속성을 디폴트 값으로 인증서에 추가하기 위해선, 명시적으로 "ecert" 사양에 맞추어 속성을 등록해야만 합니다.

예를 들어, 다음은 등록시 특정 속성이 요청되지 않으면 'hf.Affiliation'속성이 등록 인증서에 추가되도록 ID 'user1'을 등록합니다.

소속의 값('org1')은 '-id.affiliation'및 '-id.attrs'플래그에서 동일해야 한다는 점을 주의하세요.

fabric-ca-client register --id.name user1 --id.secret user1pw --id.type user --id.affiliation org1 --id.attrs 'hf.Affiliation=org1:ecert'

속성 기반 액세스 제어를위한 체인 코드 라이브러리 API에 대한 자세한 내용은 https://github.com/hyperledger/fabric/tree/release-1.1/core/chaincode/lib/cid/README.md를 참조 하십시오.

애트리뷰트 기반 액세스 제어 등을 보여주는 엔드 투 엔드 샘플은 https://github.com/hyperledger/fabric-samples/tree/release-1.1/fabric-ca/README.md를 참조 하십시오.

동적 서버 구성 업데이트

이 절에서는 fabric-ca-client를 사용하여 서버를 다시 시작하지 않고 fabric-ca-server 구성의 일부를 동적으로 업데이트하는 방법에 대해 설명합니다.

이 절의 모든 명령은 fabric-ca-client enroll 명령을 사용해서 등록이 되어 있는 State여야 합니다.

ID 동적 업데이트 하기

이 절에서는 fabric-ca-client를 사용하여 ID를 동적으로 업데이트하는 방법에 대해 설명합니다.

클라이언트 ID가 다음을 모두 만족시키지 않으면 인증 실패가 발생합니다.

  • 클라이언트 ID는 쉼표로 구분 된 값 목록이있는 "hf.Registrar.Roles"속성을 가져야하며 값 중 하나는 업데이트되는 ID 유형과 동일해야합니다. 예를 들어 클라이언트 ID에 "client, peer"값이있는 "hf.Registrar.Roles"속성이 있으면 클라이언트는 'client'및 'peer'유형의 ID를 업데이트 할 수 있지만 'orderer'는 업데이트 할 수 없습니다.
  • 클라이언트 ID의 소속은 업데이트되는 ID의 소속와 같거나 접두사 여야합니다. 예를 들어, "ab"의 소속을 가진 클라이언트는 "abc"의 소속으로 신원을 업데이트 할 수 있지만 "ac"의 소속으로 신원을 업데이트 할 수 없습니다. ID에 루트 소속이 필요한 경우 업데이트 요청에 소속에 대한 점 ( ".")을 지정해야하며 클라이언트에는 루트 소속이 있어야합니다.

다음은 소속을 추가, 수정 및 제거하는 방법을 보여줍니다.

신원 정보 얻기

호출자가 호출자가 위 섹션에서 강조 표시된 권한 요구 사항을 충족하는 경우 호출자는 fabric-ca 서버에서 ID에 대한 정보를 검색 할 수 있습니다. 다음 명령은 ID를 얻는 방법을 보여줍니다.

fabric-ca-client identity list --id user1

호출자는 다음 명령을 실행하여 볼 수있는 권한이있는 모든 ID에 대한 정보를 검색하도록 요청할 수도 있습니다.

fabric-ca-client identity list
신원 추가

다음은 'user1'에 대한 새로운 ID를 추가합니다. 새 ID를 추가하면 'fabric-ca-client register'명령을 통해 ID를 등록하는 것과 동일한 작업을 수행합니다. 새 ID를 추가하는 방법에는 두 가지가 있습니다. 첫 번째 방법은 JSON 문자열에서 ID를 설명하는  플래그를 사용하는 것입니다.

fabric-ca-client identity add user1 --json '{"secret": "user1pw", "type": "user", "affiliation": "org1", "max_enrollments": 1, "attrs": [{"name": "hf.Revoker", "value": "true"}]}'

다음은 루트 소속을 가진 사용자를 추가합니다. 소속 이름 "."은 루트 소속을 의미합니다.

fabric-ca-client identity add user1 --json '{"secret": "user1pw", "type": "user", "affiliation": ".", "max_enrollments": 1, "attrs": [{"name": "hf.Revoker", "value": "true"}]}'

ID를 추가하는 두 번째 방법은 직접 플래그를 사용하는 것입니다. 'user1'을 추가하는 방법은 아래 예제를 참조하십시오.

fabric-ca-client identity add user1 --secret user1pw --type user --affiliation . --maxenrollments 1 --attrs hf.Revoker=true

아래 표에는 ID의 모든 필드와 ID가 필수인지 또는 선택적인지 여부 및 기본값이있을 수있는 모든 기본값이 나열되어 있습니다.

Fields Required Default Value
ID Yes
Secret No
Affiliation No Caller’s Affiliation
Type No client
Maxenrollments No 0
Attributes No
신원 수정

기존 ID를 수정할 수있는 두 가지 방법이 있습니다. 첫 번째 방법은  플래그 를 통해 JSON 문자열의 ID에 대한 수정 사항을 설명하는 것입니다. 단일 요청으로 여러 수정 작업을 수행 할 수 있습니다. 수정되지 않은 ID의 모든 요소는 원래 값을 유지합니다.

참고 : maxenrollments 값 "-2"는 CA의 최대 등록 설정을 사용하도록 지정합니다.

아래 명령은 -json 플래그를 사용하여 ID에 대한 다중 수정을 수행합니다.

fabric-ca-client identity modify user1 --json '{"secret": "newPassword", "affiliation": ".", "attrs": [{"name": "hf.Regisrar.Roles", "value": "peer,client"},{"name": "hf.Revoker", "value": "true"}]}'

아래 명령은 직접 플래그를 사용하여 수정합니다. 다음은 ID 'user1'에 대한 등록 암호 (또는 암호)를 'newsecret'으로 갱신합니다.

fabric-ca-client identity modify user1 --secret newsecret

다음은 identity 'user1'이 'org2'에 속하는 것을 갱신합니다.

fabric-ca-client identity modify user1 --affiliation org2

다음은 ID 'user1'의 유형을 'peer'로 갱신합니다.

fabric-ca-client identity modify user1 --type peer

다음은 ID 'user1'의 maxenrollments를 5로 갱신합니다.

fabric-ca-client identity modify user1 --maxenrollments 5

maxenrollments 값을 '-2'로 지정하면 ID 'user1'이 CA의 최대 등록 설정을 사용하게됩니다.

fabric-ca-client identity modify user1 --maxenrollments -2

다음은 identity 'user1'에 대한 'hf.Revoker'속성의 값을 'false'로 설정합니다. ID에 다른 속성이 있으면 변경되지 않습니다. ID가 이전에 'hf.Revoker'속성을 소유하지 않은 경우, 속성이 ID에 추가됩니다. 속성은 속성 값을 지정하지 않아도 제거 될 수 있습니다.

fabric-ca-client identity modify user1 --attrs hf.Revoker=false

다음은 'user1'사용자에 대한 'hf.Revoker'속성을 제거합니다.

fabric-ca-client identity modify user1 --attrs hf.Revoker=

다음은 하나의  명령 에서 여러 옵션을 사용할 수 있음을 보여줍니다 . 이 경우 비밀과 유형 모두 사용자 'user1'에 대해 업데이트됩니다.

fabric-ca-client identity modify user1 --secret newpass --type peer
신원 제거

다음은 ID 'user1'을 제거하고 'user1'ID와 연관된 모든 인증서를 취소합니다.

fabric-ca-client identity remove user1

참고 : 기본적으로 fabric-ca-server에서 신원 제거는 비활성화되지만  옵션을 사용하여 fabric-ca-server를 시작하면 활성화 될 수 있습니다 .

소속 관계를 동적으로 업데이트

이 절에서는 fabric-ca-client를 사용하여 소속을 동적으로 업데이트하는 방법에 대해 설명합니다. 다음은 소속을 추가, 수정, 제거 및 나열하는 방법을 보여줍니다.

소속 추가

클라이언트 ID가 다음을 모두 만족시키지 않으면 인증 실패가 발생합니다.

다음은 'org1.dept1'이라는 새로운 소속을 추가합니다.

fabric-ca-client affiliation add org1.dept1

소속 수정

클라이언트 ID가 다음을 모두 만족시키지 않으면 인증 실패가 발생합니다.

다음은 'org2'소속의 이름을 'org3'으로 변경합니다. 또한 하위 소속의 이름을 바꿉니다 (예 : 'org2.department1'이 'org3.department1'로 이름 변경됨).

fabric-ca-client affiliation modify org2 --name org3

소속의 이름 변경에 영향을받는 ID가있는 경우 '-force'옵션을 사용하지 않으면 오류가 발생합니다. '-force'옵션을 사용하면 영향을받는 ID의 소속을 업데이트하여 새 소속 이름을 사용할 수 있습니다.

fabric-ca-client affiliation modify org1 --name org2 --force

소속 관계 제거

클라이언트 ID가 다음을 모두 만족시키지 않으면 인증 실패가 발생합니다.

다음은 소속 'org2'와 하위 소속을 제거합니다. 예를 들어 'org2.dept1'이 'org2'아래의 소속 인 경우에도 제거됩니다.

fabric-ca-client affiliation remove org2

합병의 제거에 영향을받는 ID가있는 경우 '-force'옵션을 사용하지 않으면 오류가 발생합니다. '-force'옵션을 사용하면 해당 소속과 관련된 모든 ID와 이러한 ID와 관련된 인증서가 제거됩니다.

참고 : 소속 제거는 기본적으로 fabric-ca-server에서 비활성화되지만  옵션을 사용하여 fabric-ca-server를 시작하면 활성화 될 수 있습니다 .

소속 정보 나열

클라이언트 ID가 다음을 모두 만족시키지 않으면 인증 실패가 발생합니다.

다음 명령은 특정 소속을 얻는 방법을 보여줍니다.

fabric-ca-client affiliation list --affiliation org2.dept1

호출자는 다음 명령을 실행하여 볼 수있는 권한이있는 모든 소속에 대한 정보를 검색하도록 요청할 수도 있습니다.

fabric-ca-client affiliation list

인증서 관리

이 절에서는 fabric-ca-client를 사용하여 인증서를 관리하는 방법에 대해 설명합니다. 다음은 인증서를 나열하고 삭제하는 방법을 보여줍니다.

인증서 정보 나열

발신자가 볼 수있는 인증서는 다음과 같습니다.

둘 이상의 ID 인증서를 요청하는 list 명령을 실행하는 경우 호출자의 소속과 같거나 그보다 더 가까운 소속이있는 ID의 인증서 만 나열됩니다.

나열된 인증서는 ID, AKI, 일련 번호, 만료 시간 및 / 또는 폐기 시간을 기준으로 필터링 될 수 있습니다.

ID :이 등록 ID의 인증서 나열 일련 번호 :이 일련 번호가있는 인증서 나열 AKI :이 AKI 만료 시간이있는 인증서 나열 : 만료 날짜가 만료 시간 인 인증서를 나열합니다. 해지 시간 : 해지 된 인증서를 나열합니다. 이 해지 시간

결과를 더 자세히 필터링 할 수있는 두 가지 필터가 있습니다. 해지 된 인증서를 반환하지 않거나 만료 된 인증서를 반환하지 않도록 선택할 수 있습니다. 예를 들어 만료되었지만 해지되지 않은 인증서 만 신경 쓰는 경우이 필터를 사용하여 이러한 결과를 되돌릴 수 있습니다. 이 경우의 예가 아래에 나와 있습니다.

시간은 RFC3339에 따라 지정해야합니다. 예를 들어 2018 년 3 월 1 일 오후 1 시부 터 2018 년 6 월 15 일 2시에 만료되는 인증서를 나열하려면 입력 된 시간 문자열이 2018-03-01T13 : 00 : 00z 및 2018-06과 같이 표시됩니다. -15T02 : 00 : 00z. 시간이 중요하지 않고 날짜 만 중요한 경우 시간 부분을 남겨두고 문자열은 2018-03-01 및 2018-06-15가됩니다.

다음 명령은 다양한 필터를 사용하여 인증서를 나열하는 방법을 보여줍니다.

모든 인증서 나열 :

fabric-ca-client certificate list --id admin

id가 제공하는 모든 인증순보기 :

fabric-ca-client certificate list --serial 1234 --aki 1234

시리얼 및 아키에 의한 인증서 목록 :

fabric-ca-client certificate list --id admin --serial 1234 --aki 1234

ID와 시리얼 / 아키에 의한 인증서 목록 :

fabric-ca-client certificate list --id admin --notrevoked --notexpired

revoker가 아니거나 만료 된 인증서를 ID별로 나열하십시오.

fabric-ca-client certificate list –id admin –notrevoked

id (admin)에 대해 취소되지 않은 모든 인증서 나열 : code :: bash

모든 인증서가 id (admin)에 대해 만료되지 않았 음을 나열하십시오.

"-notexpired"플래그는 "-expiration now ::"와 동일합니다. 즉 인증서가 앞으로 만료 될 것임을 의미합니다.

fabric-ca-client certificate list --id admin --notexpired

ID (admin)의 시간 범위에서 취소 된 모든 인증서 나열 :

fabric-ca-client certificate list --id admin --revocation 2018-01-01T01:30:00z::2018-01-30T05:00:00z

시간 범위 사이에 취소되었지만 만료되지 않은 모든 인증서를 ID (admin)로 나열하십시오.

fabric-ca-client certificate list --id admin --revocation 2018-01-01::2018-01-30 --notexpired

id (admin)에 대해 기간 (30 일에서 15 일 전에 취소)을 사용하여 모든 취소 된 인증서를 나열합니다.

fabric-ca-client certificate list --id admin --revocation -30d::-15d

시간 전에 모든 취소 된 인증서를 나열하십시오.

fabric-ca-client certificate list --revocation ::2018-01-30

한 번 후에 폐기 된 모든 인증서 나열

fabric-ca-client certificate list --revocation 2018-01-30::

특정 날짜 이후의 모든 취소 된 인증서 나열

fabric-ca-client certificate list --id admin --revocation 2018-01-30::now

시간 범위 사이에 만료되었지만 ID (admin)에 대해 해지되지 않은 모든 인증서 나열 :

fabric-ca-client certificate list --id admin --expiration 2018-01-01::2018-01-30 --notrevoked

id (admin)의 기간 (30 일에서 15 일 전에 만료 됨)을 사용하여 만료 된 모든 인증서를 나열합니다.

fabric-ca-client certificate list --expiration -30d::-15d

특정 시간 전에 만료되었거나 만료되는 모든 인증서 나열

fabric-ca-client certificate list --expiration ::2058-01-30

특정 기간 후에 만료되었거나 만료되는 모든 인증서 나열

fabric-ca-client certificate list --expiration 2018-01-30::

특정 날짜 이후의 모든 만료 된 인증서 나열

fabric-ca-client certificate list --expiration 2018-01-30::now

다음 10 일 내에 만료되는 인증서 나열 :

fabric-ca-client certificate list --id admin --expiration ::+10d --notrevoked

특정 CA 인스턴스에 컨택

서버에서 여러 CA 인스턴스를 실행하는 경우 특정 CA로 요청을 보낼 수 있습니다.

기본적으로 클라이언트 요청에 CA 이름이 지정되지 않은 경우 요청은 fabric-ca 서버의 기본 CA로 전달됩니다.

CA 이름은 클라이언트 명령의 명령 행에서 다음과 같이 지정할 수 있습니다.

fabric-ca-client enroll -u http://admin:adminpw@localhost:7054 --caname <caname>

HSM

기본적으로 패브릭 CA 서버 및 클라이언트는 개인 키를 PEM 인코딩 파일에 저장하지만 PKCS11 API를 통해 개인 키를 HSM (하드웨어 보안 모듈)에 저장하도록 구성 할 수도 있습니다.

이 동작은 서버 또는 클라이언트 구성 파일의 BCCSP (BlockChain Crypto Service Provider) 섹션에서 구성됩니다.

softhsm2를 사용하도록 Fabric CA 서버 구성

이 절에서는 softhsm이라는 소프트웨어 버전의 PKCS11 ( https://github.com/opendnssec/SoftHSMv2 참조 ) 을 사용하도록 Fabric CA 서버 또는 클라이언트를 구성하는 방법을 보여줍니다 .

softhsm을 설치 한 후 토큰을 만들고 "ForFabric"레이블을 지정하고 핀을 '98765432'로 설정하십시오 (softhsm 문서 참조).

구성 파일과 환경 변수를 모두 사용하여 BCCSP를 구성 할 수 있습니다. 예를 들어 Fabric CA 서버 구성 파일의 bccsp 섹션을 다음과 같이 설정하십시오. 기본 필드 값은 PKCS11입니다.

#############################################################################
# BCCSP (BlockChain Crypto Service Provider) section is used to select which
# crypto library implementation to use
#############################################################################
bccsp:
  default: PKCS11
  pkcs11:
    Library: /usr/local/Cellar/softhsm/2.1.0/lib/softhsm/libsofthsm2.so
    Pin: 98765432
    Label: ForFabric
    hash: SHA2
    security: 256
    filekeystore:
      # The directory used for the software file-based keystore
      keystore: msp/keystore

그리고 다음과 같이 환경 변수를 통해 관련 필드를 재정의 할 수 있습니다.

FABRIC_CA_SERVER_BCCSP_DEFAULT = PKCS11

FABRIC_CA_SERVER_BCCSP_PKCS11_LIBRARY = / usr / local / Cellar / softhsm / 2.1.0 / lib / softhsm / libsofthsm2.so

FABRIC_CA_SERVER_BCCSP_PKCS11_PIN = 98765432

FABRIC_CA_SERVER_BCCSP_PKCS11_LABEL = ForFabric

파일 형식

패브릭 CA 서버의 구성 파일 형식

기본 구성 파일은 서버의 홈 디렉토리에 생성됩니다 (자세한 내용은 Fabric CA 서버 섹션 참조 ). 다음 링크는 샘플 Server 구성 파일을 보여줍니다 .

패브릭 CA 클라이언트의 구성 파일 형식

클라이언트의 홈 디렉토리에 기본 구성 파일이 생성됩니다 (자세한 내용은 Fabric CA 클라이언트 섹션 참조 ). 다음 링크는 샘플 클라이언트 구성 파일을 보여줍니다 .


출처 : http://hyperledger-fabric-ca.readthedocs.io/en/latest/users-guide.html

BFT

BFT

질문 : ordering Service 의 BFT 버전은 언제 제공 될 예정입니까? 
대답 : 날짜는 아직 미정입니다. 우리는 1.x버전에 출시하기 위해 노력하고 있습니다. Fabric에서 miner버전 업그레이드가있을 것입니다. 
       업데이트를 위해 FAB-33 을 모니터링 하세요.

출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/

 

 

[포스팅개정]

2018.06.08 2차 번역 까칠한마녀

Kafka

카프카(Kafka)

질문 : ordering Service에서 노드를 어떻게 제거할 수 있나요?
대답 : 2단계 프로세스가 있습니다. 
1. Peer/ Clients가 연결할 수 없도록 노드의 인증서를 관련 orderer의 MSP CRL에 추가합니다.
2. TLS CRL과 같은 표준 Kafka 액세스 제어 수단 또는 방화벽 기능을 활용하여 노드가 Kafka 클러스터에 연결하지 못하게합니다.

질문 : Kafka/ZK 클러스터를 배포해본적이 없지만, Kafka 기반 Orderer 서비스를 사용하고 싶습니다. 어떻게해야합니까? 대답 : Hyperledger Fabric 문서에서는 일반적으로 독자가 Kafka 클러스터를 설정, 구성 및 관리 할 수있는 운영 지식을 가지고 있다고 가정합니다 (Caveat emptor 참조). 

그러한 전문 지식없이 진행하기를 원한다면 Kafka 기반 ordering Service를 시험하기 전에  최소한 Kafka Quickstart 가이드 의 처음 6 단계를 완료해야 합니다.

질문 : Kafka기반 Ordering service사용을 위한 네트워크를 지원하는 Docker 구성을 어디에서 찾을 수 있습니까? 대답 : CLI 예시를 활용하십시오. (https://github.com/hyperledger/fabric/blob/master/examples/e2e_cli/docker-compose-e2e.yaml)

질문 : Kafka가반 ordering service와 ZooKeeper 종속성이 있는 이유는 무엇입니까? 대답 : broker 간 조정을 위해 Kafka는 내부적으로 zookeeper를 사용합니다.

질문 : BYFN 예제를 수행하는 중에 "service unavailable"오류가 발생했습니다. 어떻게해야합니까? 대답 : ordering service 로그를 확인하십시오. "Rejecting deliver request because of consenter error"로그 메시지는 대개 Kafka 클러스터와의 연결 문제를 나타냅니다. 
Kafka 클러스터가 올바르게 설정되어 있고 ordering service node들이 접근할 수 있는지 확인하십시오.



출처 : http://hyperledger-fabric.readthedocs.io/en/release-1.1/

 

 

[포스팅개정]

2018.06.08 2차 번역 까칠한마녀

+ Recent posts