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

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

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

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

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

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

cd fabric-samples/first-network

Want to run it now?

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

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

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

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

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

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

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

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

./byfn.sh -m generate

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

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

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

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

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

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

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

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

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

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

./byfn.sh -m up

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

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

./byfn.sh -m up -l node

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

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


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

Channel name : mychannel
Creating channel...

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

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

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


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

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

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

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

./byfn.sh -m down

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

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

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

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

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

Crypto Generator(암호 생성기)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Run the tools(툴즈 실행)

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

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

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

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

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

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

org1.example.com
org2.example.com

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

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

export FABRIC_CFG_PATH=$PWD

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

docker start cli

Environment variables(환경 변수)

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

# Environment variables for PEER0

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

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

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

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

docker exec -it cli bash

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

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

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

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

export CHANNEL_NAME=mychannel

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

peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

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

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

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

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

peer channel join -b mychannel.block

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

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

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

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

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

peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

이제 채널 정의를 업데이트하여 Org2의 앵커 피어를  peer0.org2.example.com 으로 정의합니다. Org2 피어의 피어 채널 조인 명령과 동일하게 이 호출을 적절한 환경 변수로 시작해야 합니다.

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 
CORE_PEER_ADDRESS=peer0.org2.example.com:7051 
CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

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

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

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

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

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

Golang

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

Node.js

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

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

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

Golang

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

peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')"

Node.js

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

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

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

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

Query(쿼리)

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

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

Invoke(호출, 업데이트)

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

# -C와 -n 플래그를 적절하게 설정해야한다.
peer chaincode invoke -o orderer.example.com:7050  --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

Query(쿼리)

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

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

결과는 다음과 같습니다.

Query Result: 90

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

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

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

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

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

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

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

docker logs -f cli

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

Using CouchDB(CouchDB 사용)

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

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

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

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

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

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

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

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

peer chaincode install -n marbles -v 1.0 -p github.com/chaincode/marbles02/go
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -v 1.0 -c '{"Args":["init"]}' -P "OR ('Org0MSP.peer','Org1MSP.peer')"
  • 몇개의 구슬을 만들어 이동시켜 보세요.
# $CHANNEL_NAME 변수를 적절히 수정해야합니다.

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["delete","marble1"]}'
  • docker-compose에서 CouchDB 포트를 매핑하도록 선택한 경우 브라우저를 열고 다음 URL로 이동하여 CouchDB 웹 인터페이스 (Fauxton)를 통해 State 데이터베이스를 볼 수 있습니다.

http://localhost:5984/_utils

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Why CouchDB(왜 CouchDB인가?)

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

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

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

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

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

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

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

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

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

Troubleshooting(문제해결)

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

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

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

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

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

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

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

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

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

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

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


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

 Identity란 무엇인가요?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

PKI는 무엇인가요?

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

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


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

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

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

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

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

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

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

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

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

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

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

디지털 인증

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Authentication & Public keys and Private keys

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



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

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

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

인증 권한자

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Fabric CA

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

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

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

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

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

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

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

인증 폐지 리스트

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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


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


Hyperledger Fabric 모델

 

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

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



자산

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

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

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

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




Chaincode

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

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

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

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




원장 특성

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

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

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

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

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

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

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




채널 간의 프라이버시

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

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

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

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

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

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

더욱 데이터를 애매하게 만들기 위해서, Chaincode 안의 Value값은 순서 시스템에 트랜잭션으로 보내지기 이전이나 원장에 씌여지기 이전에 AES와 같은 일반적인 암호호 알고리즘을 이용하여 부분적이거나 전체적으로 암호화 될 수 있습니다. 한번 암호화된 데이터가 원장에 씌여지면, 오직 암호키를 생성하기 위한 관계키를 보유한 유저에 의해서만 복호화 할 수 있습니다.

Chaincode 암호화에 대해서 더욱 궁금하시면, Chaincode for Developer 토픽을 확인해보세요.

 

보안성과 사용자 서비스

Hyperledger Fabric은 사용자가 각자의 신원을 알 수 있는 트랜잭션적인 네트워크를 지원합니다.

퍼블릭 키 인프라는 조직, 네트워크 요소, 그리고 엔드 유져나 클라이언트 어플리케이션과 관련된 암호 인증을 생성하는 것에 사용됩니다.

결과적으로, 데이터 접근 관리를 이용해서 더 넓은 네트워크와 채널 단위를 관리하고 조절할 수 있습니다.

채널의 실존성과 가능성의 묶음인 Hyperledger Fabric에서 Permissioned라는 개념은 프라이버시와 기밀성이 중요한 관련 정보인 시나리오가 어드레싱되게 합니다.

Member Service Provider(MSP) 토픽을 확인하시면 암호 구현물을 더 잘 이해할 수 있을 것입니다. 그리고 Hyperledger Fabric의 서명, 검증, 인증도 또한 이해할 수 있습니다.




합의

분산 원장 기술에서, 합의는 최근 하나의 Function 안의 특정한 알고리즘이 되었습니다. 그러나, 합의는 트랜잭션의 순서를 동의하는 것이나 차별점은 제안, Endorsement부터 순서, 인증, 커밋까지 전체적인 트랜잭션 흐름에서 기본적인 역할을 Hyperledger Fabric에서 강조하고 있다. 한 마디로, 합의는 트랜잭션 구성 블락에 대한 집합의 정확성 인증을 전부 확인하는 것으로 정의 될 수 있습니다.

합의는 궁극적으로 트랜잭션이 명시적 규정 범위 확인에 대한 오더와 결과를 얻어집니다. 이러한 확인과 균형은 트랜잭션의 수명 주기동안 발생하며 사용자로 하여금 트랜잭션 클래스를 Endorsement하도록 서술되어 있는 것과 이러한 Endorsement Policy가 시행되고 유지되기 위한 시스템의 Chaincode를 서술 하기 위해서 Endorsement Policy를 사용하는 것을 포함하고 있습니다. 커밋이 되기 이전에, 충분한 Endorsement가 존재하도록 하는 시스템 Chaincode를 피어가 이용할 것입니다. 그리고 이러한 Endorsement은 적절한 실체로부터 얻어졌을 것입니다. 더욱이, 트랜잭션이 포함되어 있는 블록이 원장에 씌여지기 이전에 현재 State의 원장이 동의를 얻는 시점에 버전 확인이 될 것 입니다.

최종적인 확인 과정은 오퍼레이션이 중복 시행되거나 데이터 통합성을 위협할만한 점으로부터 지켜주고, function을 non-static 변수로 실행되도록 허가합니다.

합의, 타당성과 버전 확인의 다중 발생 이외에도, 모든 트랜잭션 흐름 동안 신원확인을 진행합니다. 접근 제어 리스트는 네트워크의 상하 단계(순서 서비스부터 채널까지)에서 구현되고, 보내지는 데이터가 각자 다른 구조 요소에서 트랜젝션 제안으로서 서명되고, 타당성을 인증받고, 확인됩니다. 결론 짓자면, 합의는 트랜잭션 집단 순서 동의를 제한하는 것이 아니고, 오히려 트랜잭션이 발생하여 등록되는 동안의 계속되는 인증의 부산물로서 얻어지는 것입니다.

Transaction Flow 다이어그램을 확인하여 합의의 시각적 표현을 확인하십니오.


 

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


+ Recent posts