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

+ Recent posts