Chaincode란 무엇입니까?

Chaincode는 프로그램입니다. Go, node.js, 그리고 마지막엔 자바와 같은 다른 프로그래밍 언어도 지원합니다.

이러한 Chaincode는 Interface로 규정되어 실행됩니다.

Chaincode는 보안된 Docker container에 허가된 피어 프로세스와 격리되어 실행됩니다.

Chaincode는 어플리케이션에서 제출하여 트랜잭션으로 원장 State 초기화 및 관리를 합니다.

Chaincode는 전형적으로 네트워크의 구성원으로부터 동의된 비즈니스 로직을 다루고, 그래서 Smart Contract로 간주됩니다.

Chaincode에서 만들어진 State는 배타적인 Chaincode이고 다른 Chaincode와 직접적으로 액세스가 가능하지 않은 범위에서 만들어집니다.

그러나, 같은 네트워크 안에서 적절한 허가를 얻은 Chaincode는 다른 Chaincode를 불러내어 State에 접근 가능 합니다.

두 개의 페르소나들

우리는 Chaincode에 두 개의 다른 관점을 제시합니다.

하나는 Chaincode for Developers라는 이름으로 어플리케이션 관점으로부터 개발자가 블록체인 어플리케이션이나 솔루션을 개발하게합니다.

두번째는 Chaincode for Operators라는 이름으로 블록체인 네트워크를 관리하는 업무를 하는 블록체인 네트워크 오퍼레이터로써의 역할을 지향합니다.

그리고 오퍼레이터로서 Hyperledger Fabric API를 설치하고, 인스턴스화 하고, Chaincode를 업그레이드 합니다. 그러나 Chaincode 어플리케이션 개발로서는 포함되지 않습니다.


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

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

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차 번역 까칠한마녀

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차 번역 까칠한마녀

Solo

Solo

질문 : Solo를 프로덕션에서 어떻게 배포할 수 있나요? 
대답 : Solo는 프로덕션에 포함되지 않습니다. 그것은 결코 용납하지 않습니다.

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

 

Endorsement

동의

endorsement 아키텍쳐:

Q. 네트워크 내부의 Peer 중 얼마나 트랜잭션을 동의해야하나요?

A. 동의 해야하는 피어의 수는 Chaincode 설치시에 설정된 Endorsement policy에 의해서 결정됩니다.

Q. 어플리케이션 클라이언트는 모든 피어와 연결되어 있어야만 하나요?

A. 클라이언트는 오직 Chaincode의 Endorsement policy에 의해 설정된 피어 수만큼만 연결될 필요가 있습니다.




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

Capability Requirements

Fabric은 대개 여러 국가 또는 대륙에있는 여러 조직을 포함하는 분산 시스템이기 때문에 여러 다른 버전의 Fabric 코드가 네트워크에 존재할 수 있습니다 (일반적으로). 그럼에도 불구하고 네트워크가 트랜잭션을 동일한 방식으로 처리하여 모든 사람이 현재 네트워크 State에 대해 동일한 시각을 갖도록하는 것이 중요합니다.

즉, 모든 네트워크와 네트워크 내의 모든 채널은 처리 트랜잭션에 참여할 수 있도록 "기능"이라고하는 집합을 정의해야합니다. 예를 들어, Fabric v1.1은 "피어"와 "클라이언트"의 새로운 MSP 역할 유형을 소개합니다. 그러나 v1.0 피어가 이러한 새로운 역할 유형을 이해하지 못하면 해당 역할 유형을 참조하는 Endorsement Policy를 적절히 평가할 수 없습니다. 즉, 새 역할 유형을 사용하기 전에 네트워크가 v1.1 채널 기능 요구 사항을 사용하도록 동의해야 모든 피어가 동일한 결정을 내릴 수 있습니다.

필요한 기능을 지원하는 바이너리만 채널에 참여할 수 있으며 최신 바이너리 버전에서는 해당 기능을 사용할 수있을 때까지 새로운 유효성 검사 논리를 사용할 수 없습니다. 이런 식으로 기능 요구 사항은 서로 다른 빌드와 버전이 있더라도 네트워크가 State를 포착 할 수 없음을 보장합니다.

기능 요구 사항 정의

기능 요구 사항은 채널 구성 (채널의 가장 최근 구성 블록에 있음)에서 채널별로 정의됩니다. 채널 구성에는 세 가지 위치가 있으며 각 위치는 다른 유형의 기능을 정의합니다.

 Capability Type

 Canonical Path

 JSON Path

 Channel

 /Channel/Capabilities

 .channel_group.values.Capabilities

 Orderer

 /Channel/Orderer/Capabilities

.channel_group.groups.Orderer.values.Capabilities

Application

 /Channel/Application/Capabilities

 .channel_group.groups.Application.values. Capabilities


  • 채널 :이 기능은 피어 및 Orderer 모두에게 적용되며 루트 채널 그룹에 있습니다.
  • Orderer: Orderer에게만 적용되며 Orderer 그룹에 있습니다.
  • 응용 프로그램 : 피어에만 적용되며 응용 프로그램 그룹에 있습니다.

기능은 기존 관리 구조와 일치시키기 위해 이러한 그룹으로 분류됩니다. Orderer 기능을 업데이트하는 것은 주문 조직이 응용 프로그램 조직과 독립적으로 관리하는 것입니다. 마찬가지로 응용 프로그램 기능을 업데이트하는 것은 응용 프로그램 관리자 만 관리 할 수있는 것입니다. "Orderer"와 "Application"사이의 기능을 분리함으로써 가상의 네트워크는 v1.6 피어 어플리케이션 네트워크를 지원하면서 v1.6 주문 서비스를 실행할 수 있습니다.

그러나 일부 기능은 'Application'및 'Orderer'그룹을 교차합니다. 이전에 보았 듯이 새로운 MSP 역할 유형을 추가하는 것은 Orderer 및 응용 프로그램 관리자가 모두 동의하고 인식해야하는 것입니다. Orderer는 거래가 주문서를 통과 할 수 있도록하기 위해 MSP 역할의 의미를 이해해야하며 동료는 트랜잭션을 확인하기 위해 역할을 이해해야합니다. 이러한 종류의 기능 (응용 프로그램과 Orderer 구성 요소 모두에 걸쳐 있음)은 최상위 "채널"그룹에 정의됩니다.

Orderer 및 응용 프로그램 기능이 버전 1.1 및 v1.4에 각각 정의되어있는 동안 채널 기능은 버전 v1.3에 정의 될 수 있습니다. "채널"그룹 수준에서 기능을 사용한다고해서 더 구체적인 "Orderer"및 "응용 프로그램"그룹 수준에서이 동일한 기능을 사용할 수 있음을 의미하지는 않습니다.

기능 설정

기능은 채널 구성의 일부로 설정됩니다 (초기 구성의 일부로 - 잠시 후에 - 또는 재구성의 일부로).

채널 재구성의 다양한 측면을 통해 이야기하는 두 개의 문서가 있습니다. 먼저 채널에 조직 추가 프로세스를 안내하는 자습서가 있습니다 . 또한 채널 구성 업데이트를 통해 가능한 다양한 종류의 업데이트에 대한 개요와 서명 프로세스에 대한 전체적인 내용을 제공하는 문서도 있습니다 .

새 채널은 기본적으로 Orderer 시스템 채널의 구성을 복사하므로 Orderer 시스템 채널의 Orderer 및 채널 기능 및 채널 생성 트랜잭션에서 지정한 응용 프로그램 기능을 사용하도록 새 채널이 자동으로 구성됩니다. 그러나 이미 존재하는 채널은 재구성해야합니다.

Capabilities 값의 스키마는 다음과 같이 protobuf에 정의됩니다.

message Capabilities {
      map<string, Capability> capabilities = 1;
}

message Capability { }
{
    "capabilities": {
        "V1_1": {}
    }
}

초기 구성의 기능

릴리스 아티팩트의 config 디렉토리에 분산 된 configtx.yaml 파일에는 기능 유형 (채널, Orderer 및 애플리케이션)에 대해 가능한 기능을 나열하는 기능 섹션이 있습니다.

기능을 활성화하는 가장 간단한 방법은 v1.1 샘플 프로파일을 선택하고 네트워크에 맞게 사용자 정의하는 것입니다. 예 :

SampleSingleMSPSoloV1_1:
    Capabilities:
        <<: *GlobalCapabilities
    Orderer:
        <<: *OrdererDefaults
        Organizations:
            - *SampleOrg
        Capabilities:
            <<: *OrdererCapabilities
    Consortiums:
        SampleConsortium:
            Organizations:
                - *SampleOrg

루트 수준 (채널 기능 용) 및 Orderer 수준 (Orderer 기능 용)에 정의 된 기능 섹션이 있습니다. 위의 샘플은 YAML 참조를 사용하여 YAML의 맨 아래에 정의 된대로 기능을 포함합니다.

발주자 시스템 채널을 정의 할 때 응용 프로그램 섹션이 없으므로 해당 기능은 응용 프로그램 채널을 만드는 동안 정의됩니다. 채널 생성시 새로운 채널의 응용 프로그램 기능을 정의하려면 응용 프로그램 관리자가 SampleSingleMSPChannelV1_1 프로파일 다음에 채널 생성 트랜잭션을 모델링해야합니다.

SampleSingleMSPChannelV1_1:
     Consortium: SampleConsortium
     Application:
         Organizations:
             - *SampleOrg
         Capabilities:
             <<: *ApplicationCapabilities

여기서 응용 프로그램 섹션에는 YAML 끝에 정의 된 ApplicationCapabilities 섹션을 참조하는 Capabilities라는 새로운 요소가 있습니다.

Channel 및 Orderer 섹션의 기능은 주문 시스템 채널의 정의에서 상속되며 채널 생성 과정에서 Orderer가 자동으로 포함합니다.





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

Architecture Explained

 아키텍처 설명

Hyperledger Fabric이 제공하는 이점

  • Chaincode의 신뢰 유연성(Chaincode trust flexibility) : 이 아키텍처는 체인코드(블록체인 어플리케이션)을 Ordering Service와 분리하였습니다. 이는 Ordering Service의 한 노드 set에 의해 제공 될수 있으며, 일부 오류나 오작동을 수용할 수 있습니다. endorsers는 각 체인코드마다 다를 수 있습니다.
  • 확장성(Scalability) : 특정 체인코드를 담당하는 endorser 노드는 Orderer와 역할이 다르기 때문에 동일한 노드에서 기능을 수행하는 것 보다 확장성이 좋습니다. 특히 서로 다른 체인 코드가 분리된 endorser를 지정하면 endorser 사이에 체인코드를 분할하고 패러럴 하게 체인코드를 실행 하여 보증할 수 있습니다. 게다가 비용이 많이 드는 체인코드 실행은 Ordering Service 의 중요한 경로에서 제거가 됩니다.
  • 기밀유지(Confidentiality) : 컨텐츠 및 해당 트랜잭션의 State 업데이트와 관련하여 기밀성 요구 사항이 있는 체인코드 배포가 용이합니다.
  • 컨센서스의 모듈화(Consensus modularity) : 모듈식으로 컨센서스가 플러그인이 가능하도록 수성되었습니다.

시스템 아키텍처

블록체인은 서로 통신하는 많은 노드로 구성된 분산 시스템입니다. 블록체인은 chaincode 라는 프로그램으로 실행하여 트랜잭션을 발생시키며 State 및 원장 데이터를 보유하고 있습니다.체인코드는 트랜잭션을 호출하는 핵심 요소 입니다. 트랜잭션는 "보증" 되어야 되며 승인된 트랜잭션만 커밋되어 해당 State에 영향을 미칠수 있습니다.

  • 관리 기능 및 매개 변수에는 하나 이상의 특수한 체인코드(시스템 체인 코드)가 있을수 있습니다.

트랜잭션(Transactions)

트랜잭션에는 두가지 유형이 있습니다.

  • 배포 트랜잭션(Deploy transactions) : 새로운 체인코드를 생성하고 프로그램을 매개변수로 사용합니다. 배포 트랜잭션이 성공적으로 실행되면 체인코드가 블록체인 위에 설치가 됩니다.
  • 호출 트랜잭션( Invoke transactions) : 이전에 배포된 체인코드의 컨텍스트에서 작업을 수행하는 부분입니다. 호출 트랜잭션은 체인코드와 제공된 기능 중 하나를 참조합니다. 성공하면 체인코드에 지정된 함수를 실행 합니다. 이 함수는 해당 State를 수정하고 내용을 반환 합니다.

다음에 설명하듯이 배포 트랜잭션은 호출 트랜잭션의 특수한 경우이며 새로운 체인코드를 만들어서 배포 하는 것은 시스템체인코드의 호출 트랜잭션에 해당 합니다.

비고 : 이 문서는 현재 트랜잭션이 새로운 체인코드를 생성하거나 이미 배치 된 하나의 체인코드에 의해 제공되는 연산을 호출한다고 가정 합니다. 이문서에서 a 쿼리 트랜잭션, b 교차 체인 트랜잭션을 지원

블록체인 데이터 구조(Blockchain datastructures)

State

블록체인의 최신 State는 Key 값이 이름이고 Value가 내용이 key-value store 로 모델링이 되어있습니다. 이 부분은 블록체인에 put 과 get kvs 로 체인코드로 작업이 진행 되고 있습니다.

State는 지속적으로 저장되고 State에 대한 업데이트가 기록되게 됩니다. kvs가 State 모델로 채택되어 사용되고 있지만 RDBMS 또는 다른 솔루션으로 대체하여 사용할 수도 있습니다.

KVS의 s(State)는 K -> (V X N) 으로 매핑 됩니다.

  • K는 키의 집합
  • V는 값의 집합
  • N은 제한 없이 순서대로 설정되는 버전 번호입니다. 다음 함수 : N -> N은 N의 구성요소를 바탕으로 다음 버전 번호를 반환합니다

V와 N은 모두 특수 요소 ⊥ (빈 유형)를 포함하며, N은 가장 낮은 요소입니다. 처음에는 모든 키가 (⊥, ⊥)에 매핑됩니다. s (k) = (v, ver)에 대해 우리는 v를 s(k).value로 표시하고 ver은 s(k)로 나타내게 됩니다.

KVS 운영은 다음과 같이 모델링됩니다.

  • k ∈ K와 v ∈ V에 대해 put (k, v)를 취하고 블록 체인 State s를 취하여
    s'(k) = (v, next (s) (k') = s (k') k' != k
  • get(k)는 s(k)를 반환 합니다.

State는 peer에 의해 유지되지만 Orderer 및 Client에 의해 유지되지는 않습니다.

State파티션 : KVS의 키는 특정 체인코드의 트랜잭션만이 체인코드에 속하는 키를 수정 할수 있다는 의미에서 특정 체인코드에 속하도록 이름에서 인식 할 수 있습니다. 원칙적으로 모든 체인코드는 다른 체인코드에 속한 키를 읽을 수 있습니다. 두개 이상의 체인코드에 속하는 State를 수정하는 교차 트랜잭션에 대한 지원이 v1 이후 가능해 졌습니다.

원장

Ledger는 시스템 운영 중에 발생하는 모든 성공적인 State 변경(유효한 트랜잭션에 한하여) 및 State 변경 시도 실패(유효하지 않는 트랜잭션에 대하여) 의 검증이 가능하도록 기록을 제공합니다.

Ledger는 Ordering Serivce에 의해 트랜잭션 블록을 완전히 정렬 된 해시 체인으로 구성합니다. 해시 체인은 원장에 블록의 전체 순서를 정하고 각 블록에 정렬된 트랜잭션의 배열을 포함시킵니다. 이렇게 하면 모든 트랜잭션에서 전체 Orerer에 순서가 부과(타임 스탬프) 되는 것입니다.

Ledger는 모든 peer 및 선택적으로 orderer와의 하위 집합으로 보관 됩니다. orderer 입장에서 원장을 원고 (OrdererLedger)라고 부르지 만 피어 (PeerLedger)에 대해서는 원장을 참조하는 것입니다. PeerLedger는 Orderer Ledger와 다른 점은 peer은 유효하지 않은 트랜잭션과 유효하지 않은 트랜잭션을 구별하는 비트 마스크를 로컬에서 유지한다는 점입니다

PeersLedger는 피어 투 피어를 할 수 있습니다. OrdererLedger는 내결함성 및 가용성 (PeerLedger)을 유지 관리하며 Ordering Service 에 속하게 됩니다.

노드(Node)

노드는 블록체인의 통신 엔티티 입니다. 노드(Node)는 동일한 유형의 여러 노드가 동일한 실제 서버에서 실행 될 수 있다는 점에서는 논리적인 기능입니다. 신뢰도메인(trust domains)에서 노드를 그룹화하고 노드를 제어하는 논리 엔티티와 관련된 노드의 수를 계산 합니다.

노드에는 3가지 유형이 있습니다.

  1. 클라이언트 또는 submitting-client : 실제 클라이언트 호출을 endorser에게 제출하고 Transaction Proposal를 Ordering Service의 브로드 캐스팅 하는 클라이언트
  2. 피어(peer) : 트랜잭션을 커밋하고 State와 원장의 복사본을 유지하는 노드. peer가 특별한 endorser의 역할도 수행할 수도 있습니다.
  3. Ordering Service 노드 또는 Orderer(Ordering-service-node or orderer)  : atomic 또는 Order의 브로드캐스팅과 같은 delivery 보증을 구현한 통신 서비스를 실행하는 노드

Client

클라이언트는 최종 사용자를 대신하여 작동하는 엔티티를 나타냅니다. 블록체인과 통신하기 위해서는 peer에 연결해야 합니다. 클라이언트는 원하는 peer에 연결 할 수 있습니다. 클라이언트 트랜잭션을 작성하고 이를 통하여 트랜잭션을 호출 합니다.

PEER

peer은 Ordering Servic의 블록형태로 요청된 State를 업데이트 받고 State와 원장의 관계를 유지 관리합니다.

peer은 endorsing peer이나 endorser의 역할을 수행 할 수 있습니다. endorsing peer의 특수 기능은 특정 체인코드와 관련하여 발생하며 커밋 되기 전에 트랜잭션을 승인 하는 것으로 구성됩니다. 모든 체인코드는 Endorsement Policy을 지정할 수 있습니다. 이 Policy는 유효한 트랜잭션 보증에 필요한 충분 조건으로 정의합니다. 새로운 체인코드를 설치하고 배포 트랜잭션의 특별한 (배포) 은 다음과 같습니다. 이는 시스템 체인코드의 보증 정책으로 지정됩니다.

Ordering service nodes (Orderers)

orderers의 형태는 Ordering Service, 즉 배달의 보장을 제공하는 통신 패브릭입니다. Ordering Service는 여러가지 방법으로 구현 될 수 있습니다. 예를 들어 개발 및 테스트에 사용되는 중앙 집중식 서비스 부터 다양한 네트워크 및 노드의 결함 모델을 대상으로 하는 분산된 프로토콜에 이르기 까지 다양합니다.

Ordering Service는 클라이언트와 peer에게 공유하는 통신채널을 제공하여 트랜잭션이 포함된 메시지에 대한 브로드 캐스트 서비스를 제공합니다. 클라이언트를 채널에 연결하고 채널에서 메시지를 브로드캐스팅 한 다음 모든 피어에 전달 할수 있습니다. 이 채널은 모든 메시지의 배달, 즉 총 Order, 배송 및 메시지 전달의 안정성을 지원합니다. 즉 채널은 연결된 모든 피어에게 동일한 메시지를 보내게 되고 논리적 순서로 모든 피어에게 내용을 전달 합니다. 이 통신의 보장은 총 Ordere에 대한 브로드캐스트 또는 합의라고도 합니다. 분산 시스템과 관련하여 전달된 메시지는 블록체인의 State에 포함될 후보 트랜잭션입니다.

Partitioning (ordering service channels) : Ordering Service의 publicsh/subscrbe 에 관한 메시징 시스템의 주제를 비슷한 여러 채널에 지원할 수 있습니다. 클라이언트는 주어진 채널에 연결 할 수 있으며 메시지를 보내고 도착한 메시지를 확인 할수 있습니다. 채널을 파티션으로도 생각할 수 있습니다. 한 채널에 연결하는 클라이언트는 다른 채널의 존재를 인식하지 못하지만 클라이언트는 여러 채널에 연결 할 수 있습니다. Hyperledger Fabric에 포함된 일부 Ordering Service의 구현은 여러 채널을 지원하지만 여기서는 편의를 위해 Ordering Service가 단일 채널/ 주제로 구성 된다고 가정 합니다.

Ordering service API. : peer은 Ordering Service에서 제공하는 인터페이스를 통해 Ordering Service에서 제공하는 채널에 연결합니다. Ordering ServiceAPI는 두가지 기본 작업(비동기 이벤트)으로 구성됩니다.

TODO  : 클리이언트/peer의 시퀀스 번호 아래 특정 블록을 패치하기 위한 API를 추가 할 예정입니다.

  • broadcast(blob) : 클라이언트는 채널을 통한 전파를 위해 임의의 메시지 BLOB를 브로드 캐스트하기 위해 이를 호출합니다. 이것은 서비스에 요청을 보낼 때 BFT 컨텍스트에서 요청 (blob)이라고도합니다.
  • deliver(seqno, prevhash, blob) : Ordering Service는 peer에 대해 이것을 호출하여 지정된 음수가 아닌 정수 시퀀스 번호 (seqno)와 가장 최근에 전달 된 blob (prevhash)의 해시를 사용하여 메시지 blob을 전달합니다. 즉, Ordering Service의 출력 이벤트입니다. deliver ()는 pub-sub 시스템에서는 notify () 또는 BFT 시스템에서 commit ()이라고도합니다.

원장및 블록 형성 : 원장에는 ordering serivce가 보낸 모든 데이터가 포함됩니다. 이것은 deliver (seqno, prevhash, blob) 이벤트의 시퀀스이며, 앞에서 설명한 prevhash의 계산에 따라 해시 체인을 형성합니다. 

효율성을 위해 대부분의 경우 개별 트랜잭션 (blob)을 출력하는 대신 Ordering Service 단일 전달 이벤트 내에서 blob 및 내용 블록을 그룹화합니다 (일괄 처리). 이 경우, Ordering Service 는 각 블록 내의 blob 순서를 부과하고 전달합니다. 블럭 내의 blob수는 Ordering Service 구현에 의해 동적으로 선택 될 수있다.

다음에서는 표현의 편의를 위해 서비스 속성(이 하위 섹션의 나머지 부분)를 정의하고 전달 이벤트 당 하나의 BLOB를 가정하여 트랜잭션 승인 워크 플로 (섹션 2)를 설명합니다. 블록에 대한 전달 이벤트가 블럭 내의 BLOB의 위에서 언급 한 결정 순서에 따라 블록 내의 각 BLOB에 대한 개별 전달 이벤트의 시퀀스에 해당한다고 가정하면 이러한 이벤트는 블록으로 쉽게 확장됩니다.

Ordering Service 속성(Ordering service properties)

Ordering Serivce에서 보장되는 것은 브로드캐스팅 된 메시지에 어떤 일이 일어나고 전달된 메시지 간에 어떤 관계가 존재 하는지 규정하는 것입니다. 이러한 보증은 다음과 같습니다.

  1. 안전성 (일관성 보장) : 피어가 채널에 충분히 오랫동안 연결되어있는 경우 (연결이 끊어 지거나 중단 될 수는 있지만 다시 시작되고 다시 연결되는 경우) 동일한 일련의 전달 된 (seqno, prevhash, blob) 메시지가 표시됩니다. 즉, 출력 (deliver () 이벤트)은 모든 피어에서 동일한 순서로 시퀀스 번호에 따라 발생하며 동일한 시퀀스 번호에 대해 동일한 내용 (blob 및 prevhash)을 전달합니다. 이것은 논리적 순서 일 뿐이며, 한 피어의 deliver (seqno, prevhash, blob)는 다른 피어에서 동일한 메시지를 출력하는 deliver (seqno, prevhash, blob)에 대한 실시간 관계에서 발생할 필요가 없습니다. 다르게 말하자면 특정 seqno가 주어지면 두 개의 올바른 피어가 다른 prevhash 또는 blob 값을 제공하지 않습니다. 또한, 일부 클라이언트 (피어)가 실제로 브로드 캐스트 (blob)를 호출하지 않고, 바람직하게는 모든 브로드 캐스트 된 브롭 (blob)이 단지 한 번만 전달되는 경우가 아니라면, 값 Blob이 전달되지 않습니다. 또한 deliver () 이벤트는 이전 deliver () 이벤트 (prevhash)의 데이터에 대한 암호화 해시를 포함합니다. 순서 서비스가 원자 적 브로드 캐스트(atomic-broadcast) 보장을 구현하면 prevhash는 시퀀스 번호 seqno-1을 사용하는 deliver () 이벤트의 매개 변수를 암호화 해시합니다. 이렇게하면 나중에 섹션 4와 5에서 설명하는대로 Ordering Service출력의 무결성을 확인하는 데 사용되는 deliver () 이벤트에서 해시 체인을 설정합니다. 첫 번째 deliver () 이벤트의 특별한 경우 prevhash는 기본값을가집니다.
  2. Liveness (배달 보장) : Orderin Service의 배달 보장은 Ordering Service 구현에 의해 지정됩니다. 정확한 보증은 네트워크 및 노드 결함 모델에 따라 달라 질 수 있습니다. 원칙적으로 제출 클라이언트가 실해하지 않으면 Ordering Service 는 Ordering Service에 연결된 모든 피어가 제출된 모든 트랜잭션을 제공하도록 보장해야 합니다.

요약하면 Ordering Service에서는 다음과 같은 속성을 보장 해야 합니다.

  • 협정(Agreement) : 올바른 seagno, prevhash0 == prevhash1 및 blob0 == blob1을 사용하여 올바른 피어에서 전달되는 두 이벤트 (예 : seqno, prevhash0, blob0) 및 deliver (seqno, prevhash1, blob1)
  • Hashchain 무결성(Hashchain integrity) : 올바른 피어에서의 두 이벤트가 (seqno-1, prevhash0, blob0) 및 deliver (seqno, prevhash, blob) 인 경우 prevhash = HASH (seqno-1 || prevhash0 || blob0).
  • No skipping : Ordering Service가 seqno> 0과 같은 올바른 피어 p에서 deliver (seqno, prevhash, blob)를 출력하면 p는 이미 이벤트 전달을 전달합니다 (seqno-1, prevhash0, blob0).
  • No creation : 올바른 피어의 모든 이벤트 전달 (seqno, prevhash, blob) 앞에는 일부 (가능하면 별개의) 피어에서 브로드 캐스트 (blob) 이벤트가 있어야합니다.
  • No duplication (optional, yet desirable) : 2 개의 이벤트 전달 (seqno0, prevhash0, blob) 및 deliver (seqno1, prevhash1, blob ')가 올바른 피어 및 blob == blob'에서 발생하는 두 개의 이벤트 브로드 캐스트 (blob) 및 브로드 캐스트 (blob ')의 경우 seqno0 = = seqno1 및 prevhash0 == prevhash1.
  • Liveness : 올바른 클라이언트가 이벤트 브로드 캐스트 (blob)를 호출하면 모든 올바른 피어는 이벤트 전달 (*, *, blob)을 발행합니다. 여기서 *는 임의의 값을 나타냅니다.

트랜잭션 보증의 기본 workflow

트랜잭션에 대한 요청 플로우를 개괄적으로 설명합니다.

참고 : 다음 프로토콜 *은 모든 트랜잭션이 결정적이라고 가정 하지 않습니다. 즉, 비 결정적 트랜잭션을 허용합니다.

클리이언트는 트랜잭션을 생성하고 선택한 피어를 승인하는 곳으로 보내게 됩니다.

트랜잭션을 호출하기 위해 클라이언트는 자신이 선택한 피어 투 피어 집합에 PROPOSE 메시지를 보냅니다 지정된 chaincodeID에 대한 승인 피어 세트는 피어를 통해 클라이언트에 제공되며, 이는 인증 계약에서 보증하는 피어 세트를 구성하게 됩니다. 예를 들어, 트랜잭션은 주어진 chaincodeID의 모든 endorsers에게 전송 될 수 있습니다. 즉, 일부 최종 사용자는 오프라인 일 수 있고, 다른 사용자는 반대 할 수 있으며 트랜잭션를 승인하지 않을 수도 있습니다. 제출하는 클라이언트는 사용 가능한 endorser를 사용하여 정책 표현식을 만족 시키려고 시도합니다.

다음에서는 먼저 PROPOSE메시지 형식을 자세히 설명한 다음 제출하는 클라이언트와 엔도 서 간의 상호 작용 패턴을 논의합니다.

PROPOSE message format

PROPOSE메시지 포맷은 <PROPOSE,tx,[anchor]> 이며 tx는 필수이고 anchor은 옵셔널한 입력 변수 입니다.

  • tx=<clientID,chaincodeID,txPayload,timestamp,clientSig>
    • clientID는 제출 클라이언트의 ID
    • chaincodeID는 트랜잭션이 속한(발생시키는) 체인코드 ID
    • txPayload : 제출된 트랜잭션을 포함하는 페이로드
    • timestamp : 모든 새로운 트랜잭션마가 가지는 단순하게 증가하는 정수
    • clientSig : tx의 다른 필드에 있는 클라이언트의 서명 txPayload의 세부 사항은 호출 트랜잭션과 배치 트랜잭션 (즉, 배치 특정 시스템 체인 코드를 참조하는 트랜잭션 호출) 사이에서 달라집니다. invoke 트랜잭션의 경우 txPayload는 두 개의 필드로 구성됩니다.
    • txPayload = <operation, metadata>
      • operation은 체인 코드 연산 (함수)과 인수를 나타내며,
      • 메타 데이터(metadata)는 호출과 관련된 속성을 나타냅니다. 배포 트랜잭션의 경우 txPayload는 세 개의 필드로 구성됩니다.
    • txPayload = <source, metadata, policies>
      • source는 체인 코드의 소스 코드를 나타내며
      • 메타 데이터(metadata)는 체인 코드 및 애플리케이션과 관련된 속성을 나타내며,
      • 정책(policies)에는 보증 정책과 같이 모든 피어가 액세스 할 수있는 체인 코드와 관련된 정책이 포함됩니다. 배포 트랜잭션에는 보증 정책이 txPayload와 함께 제공되지 않지만 배포의 txPayload에는 보증 정책 ID와 해당 매개 변수가 포함됩니다.
  • 앵커(anchor)는 KVS의 지정된 버전의 키에 대해 PROPOSE 요청을 바인딩하거나 "앵커"하는 키 버전 쌍 (즉, 앵커는 KxN의 하위 집합)을 포함합니다. 클라이언트가 앵커 인수를 지정한 경우 endorser는 로컬 앵커의 KVS에있는 해당 키의 읽기 버전 번호에서만 트랜잭션을 승인합니다 .

tx의 암호화 해시는 모든 노드에서 고유 한 트랜잭션 식별자 tid (즉, tid = HASH (tx))로 사용됩니다. 클라이언트는 메모리에 tid를 저장하고 피어를 승인하는 응답을 기다립니다.

Message patterns

고객은 endorser와의 상호 작용의 순서를 결정합니다. 예를 들어 클라이언트는 전형적으로 앵커 인자없이 <PROPOSE, tx>를 하나의 endorser에게 보내면, 나중에 클라이언트가 PROPOSE 메시지의 인자로 사용할 수있는 버전 의존성 (anchor)을 생성하게됩니다. 다른 endorsers. 또 다른 예로, 클라이언트는 자신이 선택한 모든 endorsers에 직접 <PROPOSE, tx> (앵커 없음)를 보낼 수 있습니다. 서로 다른 의사 소통 패턴이 가능하며 고객은 자유롭게 결정할 수 있습니다.

피어는 트랜잭션를 시뮬레이션 하고 보증의 서명을 생성합니다.

endorser피어 epID는 클라이언트로부터 <PROPOSE, tx, [anchor]> 메시지를 받으면 먼저 클라이언트의 서명인 clientSig를 확인한 다음 트랜잭션을 시뮬레이트합니다. 클라이언트가 앵커를 특정하면, 엔도 싱 피어는 로컬 KVS 내의 대응하는 키의 판독 버전 번호 (즉, 아래에 정의 된 바와 같은 판독 세트)가 앵커에 의해 지정된 버전 번호와 일치 할 때만 트랜잭션을 시뮬레이트한다.

트랜잭션 시뮬레이션은 트랜잭션이 참조하는 체인 코드 (chaincodeID)를 호출하고 승인하는 피어가 로컬로 보유하고있는 State의 복사본을 호출하여 피어를 임시로 실행 (txPayload)하는 것을 보증합니다.

실행의 결과로, 승인하는 피어는 DB 언어로 MVCC + postimage 정보라고도하는 읽기 버전 종속성 (readset) 및 State 업데이트 (writeset)를 계산합니다.

State는 키 - 값 쌍으로 구성됩니다. 모든 키 - 값 엔트리는 버전 관리됩니다. 즉, 모든 항목에는 키 아래에 저장된 값이 업데이트 될 때마다 증가하는 순서화 된 버전 정보가 들어 있습니다. 트랜잭션을 해석하는 피어는 읽기 또는 쓰기를 위해 체인 코드에 의해 액세스 된 모든 키 - 값 쌍을 기록하지만 피어는 해당 State를 아직 업데이트하지 않습니다.

  • 보증하는 피어가 트랜잭션을 실행하기 전에 State가 주어지면 트랜잭션이 읽는 모든 키 k에 대해 pair (k, s (k) .version)가 readset에 추가됩니다.
  • 또한 트랜잭션에 의해 새로운 값 v '로 수정 된 모든 키 k에 대해 pair (k, v')가 쓰기 세트에 추가됩니다. 또는 v '는 이전 값 (s (k) .value)에 대한 새 값의 델타가 될 수 있습니다.

클라이언트가 PROPOSE 메시지에서 앵커를 지정하면 클라이언트 지정 앵커는 트랜잭션을 시뮬레이션 할 때 피어를 승인하여 생성 된 readset과 같아야합니다.

그런 다음 피어는 트랜잭션을 승인하는 피어의 로직 (승인 논리라고 함)으로 내부적으로 제안 (및 가능하면 tx)을 전달합니다. 기본적으로 피어의 논리를 승인하면 트랜잭션 제안을 받아들이고 간단히 트랜잭션 제안에 서명합니다. 그러나, 승인 논리는 임의의 기능을 해석하여 예를 들어 트랜잭션- 제안 및 레거시 시스템과 상호 작용하여 트랜잭션을 보증할지 여부에 대한 결정에 도달하는 입력으로 사용할 수있다.

승인 로직이 트랜잭션을 승인하기로 결정하면 <TRANSACTION-ENDORSED, tid, tran-proposal, epSig> 메시지를 제출 클라이언트 (tx.clientID)로 전송합니다.

  • 여기서 txContentBlob는 체인 코드 / 트랜잭션 관련 정보입니다. txContentBlob를 tx의 일부 표현으로 사용하는 것입니다 (예 : txContentBlob = tx.txPayload).
  • epSig는 tran-proposal에서 승인하는 피어의 서명입니다.

그렇지 않으면, 보증 논리가 트랜잭션를 승인하는 것을 거부하는 경우, 보증인은 제출 클라이언트에게 메시지 (TRANSACTION-INVALID, tid, REJECTED)를 보낼 수 있습니다.

endorser가 이 단계에서 State를 변경하지 않는다는 것에 주의 하십시오. 승인 컨텍스트에서 트랜잭션 시뮬레이션에 의해 생성된 업데이트는 State에 영향을 미치지 않습니다.

제출 클라이언트는 트랜잭션에 대한 보증을 수집하고Ordering Service를 통해 브로드 캐스트 합니다.

제출 클라이언트는 "충분한"메시지와 서명 (TRANSACTION-ENDORSED, tid, *, *)을 수신 할 때까지 기다렸다가 트랜잭션 제안서가 승인되었다고 결론을 내립니다. 논의 된 바와 같이, 이것은 하나 이상의 endorsers와의 상호 작용의 왕복 여행을 포함 할 수 있습니다.

"충분 함"의 정확한 수는 chaincode 보증 정책에 따라 다릅니다. 보증 정책이 충족되면 트랜잭션가 승인되는 것이고 아직 커밋되지 않았다는 것에 유의하십시오. 트랜잭션이 승인되었다는 것을 보증하는 peer로부터 서명 된 TRANSACTION-ENDORSED 메시지의 모음을 승인 (endorsement)이라고하며 보증으로 표시합니다.

제출 클라이언트가 트랜잭션 제안서에 대한 보증을 수집하지 못하면 나중에 재시도 할 수 있는 옵션을 사용하여 트랜잭션을 포기하게 됩니다.

유효한 보증서가있는 트랜잭션의 경우 이제 Ordering Service를 사용하기 시작합니다. 제출 클라이언트는 blob = endorsement 인 브로드 캐스트 (blob)를 사용하여 Ordering Service를 호출합니다. 클라이언트가 직접 Ordering Service를 호출 할 능력이없는 경우, 클라이언트는 자신이 선택한 피어를 통해 브로드 캐스트를 프록시 할 수 있습니다. 그러한 피어는 보증인으로부터 어떠한 메시지도 제거하지 않도록 클라이언트에 의해 신뢰되어야하며 그렇지 않으면 트랜잭션가 무효로 간주 될 수 있습니다. 그러나 프록시 피어는 유효한 보증을 만들지 못할 수 있습니다.

Ordering Service는 트랜잭션을 peer에게 전달합니다.

이벤트 전달 (seqno, prevhash, blob)이 발생하고 피어가 시퀀스 번호가 seqno보다 낮은 blob에 대한 모든 State 업데이트를 적용하면 피어는 다음을 수행합니다.

  • blob.endorsement가 참조하는 chaincode (blob.tran-proposal.chaincodeID)의 정책에 따라 blob.endorsement가 유효한지 확인합니다.
  • 일반적인 경우에는 종속성 (blob.endorsement.tran-proposal.readset)도 위반하지 않았다는 것을 확인합니다. 보다 복잡한 유스 케이스에서는 보증서의 트란 - 제안 필드가 다를 수 있으며이 경우 보증 정책은 State의 변화 방식을 지정합니다.

종속성 확인은 State 업데이트에 대해 선택되는 일관성 속성 또는 "격리 보증"에 따라 다양한 방법으로 구현 될 수 있습니다. 연쇄 코드 보증 정책이 다른 연쇄 보증 정책을 지정하지 않는 한 연속성은 기본 격리 보증입니다. readset의 모든 키와 관련된 버전을 해당 State의 키 버전과 같게 요구하고 이 요구 사항을 충족시키지 않는 트랜잭션을 거부함으로써 직렬화 기능을 제공 할 수 있습니다.

  • 이러한 모든 검사가 통과되면 트랜잭션은 유효하거나 완료된 것으로 간주됩니다. 이 경우 피어는 PeerLedger의 비트 마스크에서 트랜잭션을 1로 표시하고 blob.endorsement.tran-proposal.writeset을 블록 체인 State에 적용합니다
  • blob.endorsement의 보증 정책 확인이 실패하면 트랜잭션은 유효하지 않으며 피어는 PeerLedger의 비트 마스크에서 트랜잭션을 0으로 표시합니다. 유효하지 않은 트랜잭션으로 인해 State가 변경되지는 않는 것입니다.

주어진 시퀀스 번호로 배달 이벤트 (블록)를 처리 한 후 모든 (올바른) 피어가 동일한 State를 유지하기에 충분하다는 점에 유의하십시오. 즉, Ordering Service의 보증에 의해, 모든 올바른 피어는 동일한 전달 순서 (seqno, prevhash, blob)로 이벤트를 수신합니다. 보증 정책의 평가와 readset의 버전 종속성 평가가 결정적이기 때문에 올바른 모든 피어는 BLOB에 포함 된 트랜잭션이 유효한지 동일한 결론에 도달하게됩니다. 따라서 모든 피어는 동일한 순서의 트랜잭션을 커밋하고 적용하며 같은 방식으로 State를 업데이트합니다.




추천정책

보증 정책 요소

보증 정책은 트랜잭션을 보증하는 조건입니다. 블록 체인 피어는 특정 체인 코드를 설치하는 배포 트랜잭션에 의해 참조되는 사전 지정된 일련의 보증 정책을 가지고 있습니다. 보증 정책을 매개 변수화 할 수 있으며 이러한 매개 변수는 배포 트랜잭션에 의해 지정 될 수 있습니다.

블록 체인 및 보안 속성을 보장하기 위해 보증 정책 집합은 한정된 실행 시간 (종료), 결정론, 성능 및 보안 보장을 보장하기 위해 제한된 기능 세트로 입증 된 정책 집합이어야합니다.

승인 정책의 동적 추가는 제한적 정책 평가 시간 (종료), 결정론, 성능 및 보안 보장 측면에서 매우 민감합니다. 따라서 승인 정책의 동적 추가는 허용되지 않지만 향후 지원 될 수 있습니다.(예 : 체인 코드 배포 시간에 배포 트랜잭션을 통한)

보증 정책에 대한 트랜잭션 평가

트랜잭션은 정책에 따라 승인 된 경우에만 유효한 것으로 선언됩니다. 체인 코드에 대한 호출 (invoke) 트랜잭션은 먼저 체인 코드의 정책을 만족시키는 보증 을 획득해야하며 그렇지 않으면 커밋되지 않습니다. 이것은 제출 클라이언트와 승인하는 동료 간의 상호 작용을 통해 발생합니다.

공식적으로 보증 정책은 보증에 대한 내용이며, TRUE 또는 FALSE로 평가 될 가능성이있는 추가 State 일 수 있습니다. 배포 트랜잭션의 경우 시스템 전반의 정책 (예 : 시스템 체인 코드)에 따라 보증을받습니다.

보증 정책 에 입각한 특정 변수를 나타냅니다. 잠재적으로 다음을 참조 할 수 있습니다.

  1. 체인 코드의 메타 데이터에있는 체인 코드와 관련된 키 또는 ID
  2. 체인 코드의 추가 메타 데이터
  3. endorsement, endorsement.tran-proposa 구성요소
  4. 잠재적으로 더 많은 것들

위의 목록은 표현력과 복잡성이 증가함에 따라 정렬됩니다. 즉, 노드의 키와 ID만을 참조하는 정책을 지원하는 것이 비교적 간단합니다.

보증 정책 내용의 평가는 결정 론적이어야합니다. endorsement는 모든 피어로 평가되어야 하고 다른 동료들과 상호 작용해야 하며 같은 방법으로 승인 정책을 평가 해야 합니다.

보증정책의 예

보증정책의 내용은 논리 표현식을 포함 할 수 있으며 TRUE 또는 FALSE로 평가됩니다. 일반적으로 조건은 체인 코드에 대해 피어를 보증함으로써 발행 된 트랜잭션 호출에서 디지털 서명을 사용합니다.

체인 코드가 endorser  집합 E = {Alice, Bob, Charlie, Dave, Eve, Frank, George}를 지정한다고 가정합니다.

  • E의 모든 구성원의 동일한 tran-proposal에있는 유효한 서명.
  • E의 단일 회원으로부터 유효한 서명
  • 조건 (Alice OR Bob) AND (Charlie, Dave, Eve, Frank, George 중 둘 중 하나)에 따라 동료를 승인하는 것과 동일한 tran-proposal에 유효한 서명.
  • 7 명의 endorsers 중 5 명이 동일한 tran-proposal에서 유효한 서명. (보다 일반적으로, n> 3f endorsers의 chaincode, n endorsers 중 2f + 1에 의한 유효한 서명 또는 (n + f) / 2 endorsers 이상의 그룹에 의한 유효한 서명)
  • {Alice = 49, Bob = 15, Charlie = 15, Dave = 10, Eve = 7, Frank = 3, George = 1}과 같이 endorsers에 "stake"또는 "weights" 총 지분은 100입니다 : 정책은 {Alice, X}와 George와 다른 X가있는 지분의 대부분 (즉, 스테이크가 결합 된 그룹)이 유효한 세트의 유효한 서명이 필요합니다. 앨리스를 제외한 모두 함께}.
  • 앞의 예제 조건에서 스테이크의 할당은 정적 (체인 코드의 메타 데이터에 고정) 또는 동적 (예 : 체인 코드의 State에 따라 다르며 실행 중에 수정 될 수 있음) 일 수 있습니다.
  • tran-proposal1의 (Alice or Bob)에서 유효한 서명과 tran-proposal2의 Charlie, Dave, Eve, Frank, George 중 어느 하나의 유효한 서명. 여기서 tran-proposal1과 tran-proposal2는 승인하는 동료에서만 서로 다릅니다.

이러한 정책이 얼마나 유용한지는 응용 프로그램, endorsers의 실패 또는 오작동 및 다양한 기타 속성에 대한 솔루션의 원하는 복원력에 따라 달라집니다.

검증된 원장 및 PeerLedger 체크포인트

검증된 원장(VLedger)

유효하고 커밋된 트랜잭션을 포함하는 원장의 추상화를 위해 peer는 주 원장 이외에도 유효 원장을 유지 관리 할수 있습니다. 유효하지 않은 트랜잭션을 필터링 하여 원장에서 파생된 해시 체인입니다.

VLedger 블록 (여기서 vBlocks라고 함)의 구성은 다음과 같이 진행됩니다. PeerLedger 블록에는 유효하지 않은 트랜잭션 (즉, 잘못된 보증 또는 잘못된 버전 종속성이있는 트랜잭션)이 포함될 수 있으므로 블록에서 트랜잭션이 vBlock에 추가되기 전에 그러한 트랜잭션이 피어에 의해 필터링됩니다. 모든 피어는 (PeerLedger와 관련된 비트 마스크를 사용하여) 스스로 처리합니다. vBlock은 필터링 된 잘못된 트랜잭션이없는 블록으로 정의됩니다. 이러한 vBlocks은 기본적으로 크기면에서 동적이며 비어있을 수 있습니다. vBlock 구성에 대한 그림은 아래 그림과 같습니다.



vBlock은 모든 피어에 의해 해시 체인에 연결됩니다. 보다 구체적으로, 검증 된 원장의 모든 블록에는 다음이 포함됩니다.

  • 이전 vBlock의 해시값
  • vBlock 번호
  • 마지막 vBlock이 계산 된 이후에 피어가 커밋 한 모든 유효한 트랜잭션 (즉, 해당 블록의 유효한 트랜잭션 목록)의 정렬 된 목록
  • 현재 vBlock이 파생되는 블록의 해시값

이 모든 정보는 피어에 의해 연결되고 해시되어 유효성 검사기에서 vBlock의 해시를 생성합니다.

PeerLedger 체크포인팅

원장에 유효하지 않은 트랜잭션이 포함되어있어 영원히 기록되지 않을 수도 있습니다. 그러나 PeerLedger 블록을 폐기 한 후에 PeerLedger를 삭제하면 해당되는 vBlock을 만들 수 없습니다. 즉,이 경우 새 피어가 네트워크에 조인하면 다른 피어가 PeerLedger와 관련된 버려진 블록을 참여 피어로 전송할 수 없으며 참가 피어에게 해당 vBlock의 유효성을 알리지 못합니다.

PeerLedger의 제거 (pruning)를 용이하게하기 위해 이 문서는 검사점 메커니즘을 설명합니다. 이 메커니즘은 피어 네트워크에서 vBlock의 유효성을 확인하고 체크 포인트 된 vBlock이 폐기 된 PeerLedger 블록을 대체 할 수있게합니다. 이렇게하면 유효하지 않은 트랜잭션을 저장할 필요가 없으므로 저장 공간이 줄어 듭니다. 또한 PeerLedger를 재생하여 State를 재구성 할 때 개별 트랜잭션의 유효성을 확인할 필요가 없으므로 유효성을 검사 한 원장에 포함 된 State 업데이트를 재생할 수 있으므로 네트워크에 가입 한 새 피어의 State를 재구성하는 작업이 줄어 듭니다.

Checkpointing protocol

검사 점 지정은 CHK 블록마다 피어에 의해 주기적으로 수행되며 CHK는 구성 가능한 매개 변수입니다. 검사 점을 초기화하기 위해 피어는 다른 피어에게 <CHECKPOINT, blocknohash, blockn, stateHash, peerSig> 메시지를 브로드 캐스트합니다. 여기서 blockno는 현재 블록 번호이고 blocknohash는 해당 해시이고 stateHash는 최신 State의 해시입니다 (예를 들어, Merkle 해시에 의해 생성 된) blockPNO의 유효성을 검사하고 peerSig는 (CHECKPOINT, blocknohash, blockno, stateHash)에 대한 피어의 서명이며, 확인 된 원장을 참조합니다.

피어는 유효한 checkpoint를 설정하기 위해 blockno, blocknohash 및 stateHash가 일치하는 서명 된 메시지를 충분히 얻을 때까지 CHECKPOINT 메시지를 수집합니다

blocknohash를 사용하여 블록 번호 blockno에 대한 유효한 검사 점을 설정하면 피어가 다음을 수행합니다.

  • blockno> latestValidCheckpoint.blockno이면 피어가 latestValidCheckpoint = (blocknohash, blockno)를 지정합니다.
  • 유효한 체크 포인트를 구성하는 각각의 피어 서명들의 세트를 세트의 latestValidCheckpointProof
  • stateHash에 해당하는 State를 latestValidCheckpointedState에 저장합니다.
  • (선택 사항) 블록 번호 blockno (포함)까지 PeerLedger를 제거합니다.

Valid checkpoints

명확하게, 체크 포인트 프로토콜은 다음과 같은 질문을 제기합니다 . 피어가 언제 "PeerLedger"를자를 수 있습니까? 얼마나 많은``CHECKPOINT`` 메시지가``충분히 많습니까? . 이것은 검사 점 유효성 정책에 의해 정의되며, 두 가지 가능한 접근법이 결합되어 있습니다.

  • 로컬 (피어 전용) 검사 점 유효성 정책 (LCVP). 주어진 피어 p의 로컬 정책은 피어 P 트러스트와 그의 CHECKPOINT 메시지가 유효한 체크 포인트를 설정하기에 충분한 피어 세트를 지정할 수있다. 예를 들어, 피어 앨리스의 LCVP는 앨리스가 밥 또는 찰리와 데이브 모두로부터 CHECKPOINT 메시지를 수신해야한다고 정의 할 수 있습니다.
  • 글로벌 체크 포인트 유효성 정책 (GCVP). 체크 포인트 유효성 정책은 전 세계적으로 지정 될 수 있습니다. 이는 로컬 피어 정책과 유사하지만 피어 세분성보다는 시스템 (블록 체인) 세밀도에서 규정된다는 점만 다릅니다. 예를 들어, GCVP는 다음을 지정할 수 있습니다.
    • 11 명의 서로 다른 동료 가 확인한 경우 각 피어는 체크 포인트를 신뢰할 수 있습니다 .
    • 모든 발주자가 동일한 시스템 (즉, 신뢰 도메인)의 피어와 함께 배치되고 f 명의 발주자가 (비잔틴) 오류가있을 수 있는 특정 배포에서는 f + 1 명의 다른 피어에 의해 확인 된 경우 각 피어가 체크 포인트를 신뢰할 수 있습니다.

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

Hyperledger Fabric CA는 Hyperledger Fabic 용 CA (Certificate Authority)입니다. fabric-ca client 및 fabric-ca server에 사용 가능한 명령은 아래 링크에 설명되어 있습니다.

Fabric-CA Client

fabric-ca-client 명령을 사용하면 ID 관리(특성 관리 포함) 및 인증서 (갱신 및 해지 포함)를 관리 할 수 있습니다.

fabric-ca-client 명령에 대한 자세한 내용은 여기를 참조하십시오.

Fabric-CA Server

fabric-ca-server 명령을 사용하면 하나 이상의 인증 기관을 호스트 할 수있는 서버 프로세스를 초기화하고 시작할 수 있습니다.

fabric-ca-server명령에 대한 자세한 사항은 여기를 참조하십시오.




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

+ Recent posts