본문 바로가기

블록체인

Hyperledger Fabric 멀티호스트 환경 구축 - Fabric-CA 기반


시작하기 전에


본 블로그는

멀티호스트 환경에서 하이퍼레저 패브릭 네트워크 환경을 구축하는 방법 및 예시를 설명하기 위함입니다.


멀티호스트에 사용하는 OS는 Ubuntu 18.04 사용하였으며, 하이퍼레저 패브릭 1.3버전을 사용합니다.

또한 멀티호스트 환경을 구성하기 위해서 virtualbox를 사용하였습니다. 


하이퍼레져 패브릭 설치하는 방법은 아래 주소를 참고하시기 바랍니다.

https://leejonggun.tistory.com/13



[목표 구성도]


※ kafka-zookeeper는 docker를 이용하여 orderer노드에서 구동




1. 멀티호스트 구축을 위한 사전 작업


1) 사전 작업


Virtualbox 에 ubuntu 18.04와 Hyperledger Fabric 1.3을 설치

(머신의 램메모리는 2GB, 하드디스크는 40GB로 설정) 


멀티호스트 간에 통신하기 위한 네트워크 어댑터 설정

Virtualbox 설정 > 네트워크 > network adaptor를 추가 > 호스트 전용 어댑터로 설정




2) 설정파일 복사 및 path 설정


패브릭 설치시에 설정된 환경 변수($GOPATH, $GOROOT, $FABRIC_HOME)

gun@gun-fabric:~$ echo $GOPATH

/home/gun/MyProjects

gun@gun-fabric:~$ echo $FABRIC_HOME

/home/gun/MyProjects/src/github.com/hyperledger/fabric

gun@gun-fabric:~/MyProjects/testnet$ echo $GOROOT

/usr/local/go


테스트네트워크 구축을 위한 디렉토리 생성 및 설정 파일 복사

mkdir $GOPATH/testnet

cp $FABRIC_HOME/sampleconfig/core.yaml $GOPATH/testnet

cp $FABRIC_HOME/sampleconfig/orderer.yaml $GOPATH/testnet


.profile 파일에 추가

export FABRIC_CFG_PATH=$GOPATH/testnet

파일 저장후 해당 내용 적용을 위해서 아래 명령어 실행

source .profile


3) hosts 파일에 호스트 등록

/etc/hosts

10.0.1.11 peer0

10.0.1.12 peer1

10.0.1.21 peer2

10.0.1.31 orderer

10.0.1.31 kafka-zookeeper

10.0.1.100 fabric-ca


4) fabric-ca 설치  


git을 fabric-ca 1.3 버전 소스코드를 다운로드하여 빌드합니다.

cd $GOPATH/src/github.com/hyperledger/

git clone -b release-1.3 https://github.com/hyperledger/fabric-ca

cd fabric-ca

make fabric-ca-server

make fabric-ca-client


.profile 파일에 환경변수를 추가합니다

export FABRIC_CA_HOME=$GOPATH/src/github.com/hyperledger/fabric-ca

export PATH=$FABRIC_CA_HOME/bin:$PATH

source .profile


4) virtualbox 머신 복제 


설치된 머신을 다음 이름으로 복제

peer0, peer1, peer2, orderer, fabric-ca


※ orderer 노드는 kafka-zookeeper를 함께 실행하므로 메모리를 4GB로 설정해 주세요



5) 머신별 ip 설정 및 호스트명 변경


상기 '목표구성도'에 맞추어서 머신별로 새로 추가된 '호스트 전용 어댑터'의 IP를 수동 설정 후 어댑터 off/on하면 반영됩니다.

아래는 peer0의 예시입니다.



추가로, 각 머신의 /etc/hostname 파일내의 호스트명을 생성된 머신의 호스트명으로 변경합니다.

네트워크 연결상태 확인을 위하여 각 호스트명으로 ping 테스트로 확인해 주세요



2. Fabric CA 서버 구동


(fabric-ca 머신에서 실행)

 .profile 파일에 추가. 

export FABRIC_CA_SERVER_HOME=/home/gun/MyProjects/testnet

source .profile 

※ 여러 개의 터미널을 열어서 작업할 경우, 환경변수 적용을 위하여 리부팅하고 작업하는 것을 추천


fabric CA 서버 실행

cd $FABRIC_CA_SERVER_HOME

fabric-ca-server start -b admin:yourpassword --cfg.affiliations.allowremove --cfg.identities.allowremove -d

-b 옵션: 서버운영자 계정/패스워드 지정

--cfg 옵션: 조직/계정에 대한 추가/삭제 가능



CA서버를 실행한 터미널은 그대로 놔두고 새로운 터미널을 열어서 생성된 CA 인증서 확인 

gun@fabric-ca:~/MyProjects/testnet$ openssl x509 -text -noout -in ca-cert.pem

Certificate:

    Data:

        Version: 3 (0x2)

        Serial Number:

            6e:1c:a6:7a:e6:b2:c5:78:d4:41:11:30:46:4d:53:a3:a7:e0:ec:cc

    Signature Algorithm: ecdsa-with-SHA256

        Issuer: C = US, ST = North Carolina, O = Hyperledger, OU = Fabric, CN = fabric-ca-server

        Validity

            Not Before: Feb 11 07:17:00 2019 GMT

            Not After : Feb  7 07:17:00 2034 GMT

        Subject: C = US, ST = North Carolina, O = Hyperledger, OU = Fabric, CN = fabric-ca-server

        Subject Public Key Info:

            Public Key Algorithm: id-ecPublicKey

                Public-Key: (256 bit)

                pub:

                    04:bb:2b:ae:c2:1b:2f:cd:0d:07:ef:8f:54:4b:37:

                    ae:0e:cb:68:2e:ef:ab:43:9c:f4:2d:25:90:fa:7c:

                    79:57:82:e9:e8:7a:43:3e:a4:bc:8b:ef:ba:a3:24:

                    bf:99:9e:9e:a4:8d:9f:12:2d:c3:56:a6:32:3d:63:

                    29:48:6d:94:d3

                ASN1 OID: prime256v1

                NIST CURVE: P-256

        X509v3 extensions:

            X509v3 Key Usage: critical

                Certificate Sign, CRL Sign

            X509v3 Basic Constraints: critical

                CA:TRUE, pathlen:1

            X509v3 Subject Key Identifier: 

                DA:2E:16:E4:A2:F7:7B:2E:BD:AD:79:67:35:88:7E:C4:74:36:7F:76

    Signature Algorithm: ecdsa-with-SHA256

         30:44:02:20:22:5d:93:21:93:03:11:83:8f:1a:04:16:5c:d5:

         b0:f2:0d:a9:e1:ec:17:18:8a:3f:37:d2:6a:19:00:98:23:da:

         02:20:25:d7:95:9e:f6:75:08:95:32:b9:4d:72:3a:a2:6d:c6:

         bd:57:21:30:9f:c4:d6:c6:b8:0d:53:5a:01:cd:03:b6



3. Fabric CA 서버운영자의 MSP 생성


(orderer 노드에서 실행)

.profile 파일에 환경변수 추가

export FABRIC_CA_CLIENT_HOME=/home/gun/MyProjects/testnet

source .profile

cd $FABRIC_CA_CLIENT_HOME


fabric CA 서버 구동 시에 지정한 운영자 계정/패스워드를 이용하여 MSP 생성 요청

gun@orderer:~$ fabric-ca-client enroll -u http://admin:yourpassword@10.0.1.100:7054

2019/02/11 16:30:28 [INFO] Created a default configuration file at /home/gun/MyProjects/testnet/fabric-ca-client-config.yaml

2019/02/11 16:30:28 [INFO] generating key: &{A:ecdsa S:256}

2019/02/11 16:30:28 [INFO] encoded CSR

2019/02/11 16:30:28 [INFO] Stored client certificate at /home/gun/MyProjects/testnet/msp/signcerts/cert.pem

2019/02/11 16:30:28 [INFO] Stored root CA certificate at /home/gun/MyProjects/testnet/msp/cacerts/10-0-1-100-7054.pem

2019/02/11 16:30:28 [INFO] Stored Issuer public key at /home/gun/MyProjects/testnet/msp/IssuerPublicKey

2019/02/11 16:30:28 [INFO] Stored Issuer revocation public key at /home/gun/MyProjects/testnet/msp/IssuerRevocationPublicKey


운영자의 개인키, 인증서, CA인증서가 MSP 디렉토리에 생성된 것을 확인할 수 있습니다




4. 조직(Org)_ 생성 및 조직 운영자의 MSP 생성


(orderer 노드에서 수행)


1) fabric-ca 내 default affiliation 삭제 


#기본 설정 조직 확인 및 삭제

gun@orderer:~/MyProjects/testnet$ fabric-ca-client affiliation list

affiliation: .

   affiliation: org1

      affiliation: org1.department1

      affiliation: org1.department2

   affiliation: org2

      affiliation: org2.department1


gun@orderer:~/MyProjects/testnet$ fabric-ca-client affiliation remove --force org1

gun@orderer:~/MyProjects/testnet$ fabric-ca-client affiliation remove --force org2


gun@orderer:~/MyProjects/testnet$ fabric-ca-client affiliation list

Error: Response from server: Error Code: 16 - No affiliations are configured on the CA


2) fabric-ca-client를 이용하여 목표로 하는 조직 구성

fabric-ca-client affiliation add org0

fabric-ca-client affiliation add org1

fabric-ca-client affiliation add ordererorg

fabric-ca-client affiliation list


3) CA 인증서를 각 조직의 admin 노드에 다운로드 


(Org0 조직의 관리자 권한을 갖는 peer0 노드에서 실행)


# org0 조직의 MSP를 저장할 디렉토리 생성

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp


# org0 조직의 CA 인증서 획득

fabric-ca-client getcacert -u http://10.0.1.100:7054 -M /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp


# CA 인증서 파일 이름 변경

mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp/cacerts/ca.crt


(Org1 조직의 관리자 권한을 갖는 peer2 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp


fabric-ca-client getcacert -u http://10.0.1.100:7054 -M /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp


mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp/cacerts/ca.crt


(OrdererOrg 조직의 관리자 권한을 갖는 orderer 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/msp


fabric-ca-client getcacert -u http://10.0.1.100:7054 -M /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/msp


mv /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/msp/cacerts/ca.crt


4) 각 조직(Org)의 운영자 계정을 등록


(CA 서버 운영자 권한을 가지고 있는 orderer 노드에서 수행)


$FABRIC_CA_CLIENT_HOME/fabric-ca-client-config.yaml 파일에서 id 부분 수정

id:

  name: Admin@org0

  type: client

  affiliation: org0

  maxenrollments: -1

  attributes:

   # - name:

   #   value:

    - name: hf.Registrar.Roles

      value: client,orderer,peer,user

    - name: hf.Registrar.DelegateRoles

      value: client,orderer,peer,user

    - name: hf.Registrar.Attributes

      value: "*"

    - name: hf.GenCRL

      value: true

    - name: hf.Revoker

      value: true

    - name: hf.AffiliationMgr

      value: true

    - name: hf.IntermediateCA

      value: true

    - name: role

      value: admin

      ecert: true

(각 옵션값은 별도 확인 필요)


# 계정생성

fabric-ca-client register --id.secret=yourpassword



# org1의 운영자계정도 동일한 방식으로 생성

$FABRIC_CA_CLIENT_HOME/fabric-ca-client-config.yaml 파일 수정

id:

  name: Admin@org1

  type: client

  affiliation: org1

  maxenrollments: -1

  attributes:

   # - name:

   #   value:

    - name: hf.Registrar.Roles

      value: client,orderer,peer,user

    - name: hf.Registrar.DelegateRoles

      value: client,orderer,peer,user

    - name: hf.Registrar.Attributes

      value: "*"

    - name: hf.GenCRL

      value: true

    - name: hf.Revoker

      value: true

    - name: hf.AffiliationMgr

      value: true

    - name: hf.IntermediateCA

      value: true

    - name: role

      value: admin

      ecert: true


# 계정생성

fabric-ca-client register --id.secret=yourpassword



# ordererorg의 운영자계정도 동일한 방식으로 생성

$FABRIC_CA_CLIENT_HOME/fabric-ca-client-config.yaml 파일 수정

id:

  name: Admin@ordererorg

  type: client

  affiliation: ordererorg

  maxenrollments: -1

  attributes:

   # - name:

   #   value:

    - name: hf.Registrar.Roles

      value: client,orderer,peer,user

    - name: hf.Registrar.DelegateRoles

      value: client,orderer,peer,user

    - name: hf.Registrar.Attributes

      value: "*"

    - name: hf.GenCRL

      value: true

    - name: hf.Revoker

      value: true

    - name: hf.AffiliationMgr

      value: true

    - name: hf.IntermediateCA

      value: true

    - name: role

      value: admin

      ecert: true


# 계정생성

fabric-ca-client register --id.secret=yourpassword



5) 조직운영자의 MSP 생성

위에서 생성된 3개의 계정에 해당되는 각 조직의 운영자 노드에 MSP를 생성합니다. 


# org0 조직운영자의 MSP 생성 


(peer0 노드에서 실행)

생성된 개인키 파일 이름을 확인하여 복사하여 주시기 바랍니다.

# MSP 저장 디렉토리 생성

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/


# MSP 생성 요청

fabric-ca-client enroll -u http://Admin@org0:yourpassword@10.0.1.100:7054 -H /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/


# 생성된 MSP의 ca 인증서 파일 이름 변경

mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/cacerts/ca.crt


# 생성된 MSP의 개인키 파일 이름 변경

mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/keystore/6a785040dc00bbe895cfbe7ce97b4778ce2c19c2b0500783e597813c4bae0e39_sk /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/keystore/server.key



# org1 조직운영자의 MSP 생성


(peer2 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/


fabric-ca-client enroll -u http://Admin@org1:yourpassword@10.0.1.100:7054 -H /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/


mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/cacerts/ca.crt


mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/keystore/bed9ed46f1fb713caa29a103b22c3d23e595bee93e9aeca99f0152cadf7850e4_sk /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/keystore/server.key



# orderorg 조직운영자의 MSP 생성


(orderer 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg


fabric-ca-client enroll -u http://Admin@ordererorg:yourpassword@10.0.1.100:7054 -H /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/


mv /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/msp/cacerts/ca.crt


mv /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/msp/keystore/f27b15173d5f59f3fd8ca0c285b6b23a0a231440c2fcc40c00be50e5db51dc2c_sk /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/msp/keystore/server.key



6) admincerts 디렉토리 생성 후 조직운영자의 인증서(공개키) 복사


admincerts 디렉토리를 통하여 조직운영자(관리자)의 인증서를 참조함


(peer0  노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/admincerts


cp /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/signcerts/cert.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/admincerts/Admin@org0-cert.pem


(peer2 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/admincerts


cp /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/signcerts/cert.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/admincerts/Admin@org1-cert.pem


(orderer 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/msp/admincerts


cp /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/msp/signcerts/cert.pem /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/msp/admincerts/Admin@ordererorg-cert.pem




4. Peer 및 Orderer 노드 계정


1) org0 조직운영자가 peer0 노드의 계정 등록 


(peer0 에서 실행)

# Org0 조직 운영자의 peer0 계정 생성

/home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/fabric-ca-client-config.yaml 파일의 id 수정

id:

  name: peer0

  type: peer

  affiliation: org0

  maxenrollments: -1

  attributes:

    - name: role

      value: peer

      ecert: true


-H 옵션으로 fabric-ca-client-config.yaml 파일 경로 지정하여 CA 클라이언트 등록

fabric-ca-client register --id.secret=yourpassword -H /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/


2) org1 조직운영자가 peer2 노드의 계정 등록


(peer2 노드에서 실행)

# peer2 계정 생성

/home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/fabric-ca-client-config.yaml 파일 수정

id:

  name: peer2

  type: peer

  affiliation: org1

  maxenrollments: -1

  attributes:

    - name: role

      value: peer

      ecert: true


-H 옵션으로 fabric-ca-client-config.yaml 파일 경로 지정하여 CA 클라이언트 등록

fabric-ca-client register --id.secret=yourpassword -H /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/


3) ordererorg 조직운영자가 orderer 노드에 MSP를 생성하기 위한 계정 생성  


(orderer 노드에서 실행)

# orderer 계정 생성

/home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/fabric-ca-client-config.yaml 파일 수정

id:

  name: orderer

  type: orderer

  affiliation: ordererorg

  maxenrollments: -1

  attributes:

    - name: role

      value: orderer

      ecert: true


-H 옵션으로 fabric-ca-client-config.yaml 파일 경로 지정하여 CA 클라이언트 등록

fabric-ca-client register --id.secret=yourpassword -H /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/




5. peer/orderer 노드의 MSP 생성


1) peer0 노드의 MSP 생성


(peer0 노드에서 실행)

개인키 확인 후 복사

# MSP를 저장할 디렉토리 생성

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer0.org0/


# MSP 요청

fabric-ca-client enroll -u http://peer0:yourpassword@10.0.1.100:7054 -H /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer0.org0/


# ca인증서 파일이름 변경

mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer0.org0/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer0.org0/msp/cacerts/ca.crt


# 개인키 파일이름 변경

mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer0.org0/msp/keystore/ef54938c016be68b046eb90374634ad4f93c22dfd8a8ff6c1fe1d5817de01d25_sk /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer0.org0/msp/keystore/server.key



2) peer2 노드의 MSP 생성


(peer2 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/peers/peer2.org1/


fabric-ca-client enroll -u http://peer2:yourpassword@10.0.1.100:7054 -H /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/peers/peer2.org1/


mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/peers/peer2.org1/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/peers/peer2.org1/msp/cacerts/ca.crt


mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/peers/peer2.org1/msp/keystore/21567474c38c76a65327d79297d0a30695d4e65ba5d6f4fcd6287af617fb01bb_sk /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/peers/peer2.org1/msp/keystore/server.key



3) orderer 노드의 MSP 생성


(orderer 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg


fabric-ca-client enroll -u http://orderer:yourpassword@10.0.1.100:7054 -H /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/


mv /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/msp/cacerts/ca.crt


mv /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/msp/keystore/ae19c5d5f9780ef86d7fcda4782c4e74dc2ad5b55e36a34bb65fc7a13da70b56_sk /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/msp/keystore/server.key



6. Orderer 구동


(orderer 노드에서 실행)

1) 트랜잭션 생성을 위한 설정파일 생성


/home/gun/MyProjects/testnet/configtx.yaml 파일 생성

################################################################################

#

#   ORGANIZATIONS

#

#   This section defines the organizational identities that can be referenced

#   in the configuration profiles.

#

################################################################################

Organizations:


    - &OrdererOrg

        Name: OrdererOrg

        ID: OrdererOrgMSP

        MSPDir: crypto-config/ordererOrganizations/ordererorg/msp/


    - &Org0

        Name: Org0MSP

        ID: Org0MSP

        MSPDir: crypto-config/peerOrganizations/org0/msp/

        AnchorPeers:

          - Host: peer0

            Port: 7051


    - &Org1

        Name: Org1MSP

        ID: Org1MSP

        MSPDir: crypto-config/peerOrganizations/org1/msp/

        AnchorPeers:

          - Host: peer2

            Port: 7051



################################################################################

#

#   ORDERER

#

#   This section defines the values to encode into a config transaction or

#   genesis block for orderer related parameters.

#

################################################################################

Orderer: &OrdererDefaults


    OrdererType: kafka

    Addresses:

        - orderer:7050

    BatchTimeout: 1s


    BatchSize:


        MaxMessageCount: 30

        AbsoluteMaxBytes: 99 MB

        PreferredMaxBytes: 512 KB


    MaxChannels: 0


    Kafka:

        Brokers:

            - kafka-zookeeper:9092


    Organizations:


################################################################################

#

#   APPLICATION

#

#   This section defines the values to encode into a config transaction or

#   genesis block for application-related parameters.

#

################################################################################

Application: &ApplicationDefaults


    # Organizations lists the orgs participating on the application side of the

    # network.

    Organizations:




################################################################################

#

#   PROFILES

#

#   Different configuration profiles may be encoded here to be specified as

#   parameters to the configtxgen tool. The profiles which specify consortiums

#   are to be used for generating the orderer genesis block. With the correct

#   consortium members defined in the orderer genesis block, channel creation

#   requests may be generated with only the org member names and a consortium

#   name.

#

################################################################################

Profiles:


    TwoOrgsOrdererGenesis:

        Orderer:

            <<: *OrdererDefaults

            Organizations:

                - *OrdererOrg

        Consortiums:

            SampleConsortium:

                Organizations:

                    - *Org0

                    - *Org1


    TwoOrgsChannel:

        Consortium: SampleConsortium

        Application:

            <<: *ApplicationDefaults

            Organizations:

                - *Org0

                - *Org1

앞으로 Profiles 필드를 참조하여 트랜잭션 생성할 예정입니다.



2) genesis.block 생성시 컨소시엄 정보를 추가하기 위하여 org0, org1, ordererorg의 운영자(관리자)의 인증서(공개키)를 기관의 MSP에 복사 


orderer에서 각 기관 관리자에서 제출하는 tx의 서명검증을 위하여 필요


2-1) orderer admin의 공개키 복사

#orderer 노드에서 실행 (orderer 노드에는 orderer 노드와 ordererorg 관리자 의 MSP를 모두 포함하고 있음)

# OrdererOrg 기관의 MSP 디렉토리 내에 운영자의 인증서 디렉토리 생성

mkdir -p /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/msp/admincerts/


# OrdererOrg 기관의 운영자 인증서 복사

cp /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/users/Admin@ordererorg/msp/admincerts/Admin@ordererorg-cert.pem /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/msp/admincerts/


2-2) org0 admin의 공개키 복사

(orderer 에서 실행)

# Org0 조직의 운영자인증서와 CA 인증서를 저장할 디렉토리 생성

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp/admincerts/

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp/cacerts/


(peer0 에서 실행)

peer0 에서 orderer로 복사

scp /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/admincerts/Admin@org0-cert.pem gun@orderer:/home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp/admincerts/


scp /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp/cacerts/ca.crt gun@orderer:/home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/msp/cacerts/


2-3) org1 admin의 공개키 복사

(orderer 에서 실행)

# Org1 조직의 운영자인증서와 CA 인증서를 저장할 디렉토리 생성

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp/admincerts/

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp/cacerts/


(peer2 에서 실행)

peer2에서 orderer 노드로 복사

scp /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/admincerts/Admin@org1-cert.pem gun@orderer:/home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp/admincerts/


scp /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp/cacerts/ca.crt gun@orderer:/home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/msp/cacerts/



#tree 구조는 다음과 같다 ( $ tree crypto-config)

crypto-config/

├── ordererOrganizations

│   └── ordererorg

│       ├── msp

│       │   ├── IssuerPublicKey

│       │   ├── IssuerRevocationPublicKey

│       │   ├── admincerts

│       │   │   └── Admin@ordererorg-cert.pem

│       │   ├── cacerts

│       │   │   └── ca.crt

│       │   ├── keystore

│       │   ├── signcerts

│       │   └── user

│       ├── orderers

│       │   └── orderer.ordererorg

│       │       ├── fabric-ca-client-config.yaml

│       │       └── msp

│       │           ├── IssuerPublicKey

│       │           ├── IssuerRevocationPublicKey

│       │           ├── cacerts

│       │           │   └── ca.crt

│       │           ├── keystore

│       │           │   └── server.key

│       │           ├── signcerts

│       │           │   └── cert.pem

│       │           └── user

│       └── users

│           └── Admin@ordererorg

│               ├── fabric-ca-client-config.yaml

│               └── msp

│                   ├── IssuerPublicKey

│                   ├── IssuerRevocationPublicKey

│                   ├── admincerts

│                   │   └── Admin@ordererorg-cert.pem

│                   ├── cacerts

│                   │   └── ca.crt

│                   ├── keystore

│                   │   └── server.key

│                   ├── signcerts

│                   │   └── cert.pem

│                   └── user

└── peerOrganizations

    ├── org0

    │   └── msp

    │       ├── admincerts

    │       │   └── Admin@org0-cert.pem

    │       └── cacerts

    │           └── ca.crt

    └── org1

        └── msp

            ├── admincerts

            │   └── Admin@org1-cert.pem

            └── cacerts

                └── ca.crt


3) genesis block 생성


(orderer 노드에서 실행)

# 생성

configtxgen -profile TwoOrgsOrdererGenesis -outputBlock genesis.block


# 생성된 genesis.block 내용 확인

configtxgen -inspectBlock genesis.block


4) kafka-zookeeper 구동


(orderer 노드에서 실행)

/home/gun/MyProjects/testnet/docker-compose.yaml 파일 생성

version: '2'

services:

  zookeeper:

    image: hyperledger/fabric-zookeeper

    ports:

      - "2181:2181"

  kafka0:

    image: hyperledger/fabric-kafka

    ports:

      - "9092:9092"

    environment:

      - KAFKA_ADVERTISED_HOST_NAME=10.0.1.31

      - KAFKA_ADVERTISED_PORT=9092

      - KAFKA_BROKER_ID=0

      - KAFKA_MESSAGE_MAX_BYTES=103809024 # 99*1024*1024

      - KAFKA_REPLICA_FETCH_MAX_BYTES=103809024

      - KAFKA_UNCLEAN_LEADER_ELECTION_ENABLE=false

      - KAFKA_NUM_REPLICA_FETCHERS=1

      - KAFKA_DEFAULT_REPLICATION_FACTOR=1

      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181

    depends_on:

      - zookeeper


# kafka-zookeeper 구동

docker-compose up


# docker listening port 확인

gun@orderer:~$ sudo netstat -ltnp

[sudo] password for gun: 

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    

tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      318/systemd-resolve 

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      692/sshd            

tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      3156/cupsd          

tcp6       0      0 :::22                   :::*                    LISTEN      692/sshd            

tcp6       0      0 ::1:631                 :::*                    LISTEN      3156/cupsd          

tcp6       0      0 :::9092                 :::*                    LISTEN      3526/docker-proxy   

tcp6       0      0 :::2181                 :::*                    LISTEN      3399/docker-proxy 



5) genesis.block 복사 


(orderer 노드 실행)

mv genesis.block crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/genesis.block


6) msp에 admincerts만 추가


(orderer 노드에서 실행)

#orderer 노드에 oderer org의 관리자 공개키(인증서)를 복사 

mkdir -p /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/msp/admincerts/


cp /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/msp/admincerts/Admin@ordererorg-cert.pem  /home/gun/MyProjects/testnet/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/msp/admincerts/


7) orderer 노드 실행


(orderer 노드에서 실행)

/home/gun/MyProjects/testnet/runOrderer.sh 파일 생성

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


ORDERER_GENERAL_LOGLEVEL=info \

ORDERER_GENERAL_LISTENADDRESS=orderer \

ORDERER_GENERAL_GENESISMETHOD=file \

ORDERER_GENERAL_GENESISFILE=$FABRIC_PATH/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/genesis.block \

ORDERER_GENERAL_LOCALMSPID=OrdererOrgMSP \

ORDERER_GENERAL_LOCALMSPDIR=$FABRIC_PATH/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/msp \

ORDERER_GENERAL_TLS_ENABLED=false \

ORDERER_GENERAL_TLS_PRIVATEKEY=$FABRIC_PATH/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/tls/server.key \

ORDERER_GENERAL_TLS_CERTIFICATE=$FABRIC_PATH/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/tls/server.crt \

ORDERER_GENERAL_TLS_ROOTCAS=[$FABRIC_PATH/crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/tls/ca.crt,$FABRIC_PATH/crypto-config/peerOrganizations/org0/peers/peer0.org0/tls/ca.crt,$FABRIC_PATH/crypto-config/peerOrganizations/org1/peers/peer1.org1/tls/ca.crt] \

CONFIGTX_ORDERER_BATCHTIMEOUT=1s \

CONFIGTX_ORDERER_ORDERERTYPE=kafka \

CONFIGTX_ORDERER_KAFKA_BROKERS=[kafka-zookeeper:9092] \

/home/gun/MyProjects/src/github.com/hyperledger/fabric/.build/bin/orderer


orderer 실행시에 환경변수를 참조하여 동작하지 않아서 /home/gun/MyProjects/testnet/orderer.yaml 을 수정해 주시기 바랍니다.

(옛날에는 해당 환경변수로 동작했었는데, 왜 안되는지 모르겠네요.. 예전 VM이미지를 지워서 확인은 못 함)


# Copyright IBM Corp. All Rights Reserved.

#

# SPDX-License-Identifier: Apache-2.0

#


---

################################################################################

#

#   Orderer Configuration

#

#   - This controls the type and configuration of the orderer.

#

################################################################################

General:


    # Ledger Type: The ledger type to provide to the orderer.

    # Two non-production ledger types are provided for test purposes only:

    #  - ram: An in-memory ledger whose contents are lost on restart.

    #  - json: A simple file ledger that writes blocks to disk in JSON format.

    # Only one production ledger type is provided:

    #  - file: A production file-based ledger.

    LedgerType: file


    # Listen address: The IP on which to bind to listen.

    ListenAddress: orderer


    # Listen port: The port on which to bind to listen.

    ListenPort: 7050


    # TLS: TLS settings for the GRPC server.

    TLS:

        Enabled: false

        PrivateKey: tls/server.key

        Certificate: tls/server.crt

        RootCAs:

          - tls/ca.crt

        ClientAuthRequired: false

        ClientRootCAs:


    # Keepalive settings for the GRPC server.

    Keepalive:

        # ServerMinInterval is the minimum permitted time between client pings.

        # If clients send pings more frequently, the server will

        # disconnect them.

        ServerMinInterval: 60s

        # ServerInterval is the time between pings to clients.

        ServerInterval: 7200s

        # ServerTimeout is the duration the server waits for a response from

        # a client before closing the connection.

        ServerTimeout: 20s


    # Log Level: The level at which to log. This accepts logging specifications

    # per: fabric/docs/Setup/logging-control.md

    LogLevel: debug


    # Log Format:  The format string to use when logging.  Especially useful to disable color logging

    LogFormat: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}'


    # Genesis method: The method by which the genesis block for the orderer

    # system channel is specified. Available options are "provisional", "file":

    #  - provisional: Utilizes a genesis profile, specified by GenesisProfile,

    #                 to dynamically generate a new genesis block.

    #  - file: Uses the file provided by GenesisFile as the genesis block.

    GenesisMethod: file


    # Genesis profile: The profile to use to dynamically generate the genesis

    # block to use when initializing the orderer system channel and

    # GenesisMethod is set to "provisional". See the configtx.yaml file for the

    # descriptions of the available profiles. Ignored if GenesisMethod is set to

    # "file".

    GenesisProfile: TwoOrgsOrdererGenesis


    # Genesis file: The file containing the genesis block to use when

    # initializing the orderer system channel and GenesisMethod is set to

    # "file". Ignored if GenesisMethod is set to "provisional".

    GenesisFile: crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/genesis.block


    # LocalMSPDir is where to find the private crypto material needed by the

    # orderer. It is set relative here as a default for dev environments but

    # should be changed to the real location in production.

    LocalMSPDir: crypto-config/ordererOrganizations/ordererorg/orderers/orderer.ordererorg/msp


    # LocalMSPID is the identity to register the local MSP material with the MSP

    # manager. IMPORTANT: The local MSP ID of an orderer needs to match the MSP

    # ID of one of the organizations defined in the orderer system channel's

    # /Channel/Orderer configuration. The sample organization defined in the

    # sample configuration provided has an MSP ID of "SampleOrg".

    LocalMSPID: OrdererOrgMSP


    # Enable an HTTP service for Go "pprof" profiling as documented at:

    # https://golang.org/pkg/net/http/pprof

    Profile:

        Enabled: false

        Address: 0.0.0.0:6060


    # BCCSP configures the blockchain crypto service providers.

    BCCSP:

        # Default specifies the preferred blockchain crypto service provider

        # to use. If the preferred provider is not available, the software

        # based provider ("SW") will be used.

        # Valid providers are:

        #  - SW: a software based crypto provider

        #  - PKCS11: a CA hardware security module crypto provider.

        Default: SW


        # SW configures the software based blockchain crypto provider.

        SW:

            # TODO: The default Hash and Security level needs refactoring to be

            # fully configurable. Changing these defaults requires coordination

            # SHA2 is hardcoded in several places, not only BCCSP

            Hash: SHA2

            Security: 256

            # Location of key store. If this is unset, a location will be

            # chosen using: 'LocalMSPDir'/keystore

            FileKeyStore:

                KeyStore:


    # Authentication contains configuration parameters related to authenticating

    # client messages

    Authentication:

        # the acceptable difference between the current server time and the

        # client's time as specified in a client request message

        TimeWindow: 15m


################################################################################

#

#   SECTION: File Ledger

#

#   - This section applies to the configuration of the file or json ledgers.

#

################################################################################

FileLedger:


    # Location: The directory to store the blocks in.

    # NOTE: If this is unset, a new temporary location will be chosen every time

    # the orderer is restarted, using the prefix specified by Prefix.

    Location: /var/hyperledger/production/orderer


    # The prefix to use when generating a ledger directory in temporary space.

    # Otherwise, this value is ignored.

    Prefix: hyperledger-fabric-ordererledger


################################################################################

#

#   SECTION: RAM Ledger

#

#   - This section applies to the configuration of the RAM ledger.

#

################################################################################

RAMLedger:


    # History Size: The number of blocks that the RAM ledger is set to retain.

    # WARNING: Appending a block to the ledger might cause the oldest block in

    # the ledger to be dropped in order to limit the number total number blocks

    # to HistorySize. For example, if history size is 10, when appending block

    # 10, block 0 (the genesis block!) will be dropped to make room for block 10.

    HistorySize: 1000


################################################################################

#

#   SECTION: Kafka

#

#   - This section applies to the configuration of the Kafka-based orderer, and

#     its interaction with the Kafka cluster.

#

################################################################################

Kafka:


    # Retry: What do if a connection to the Kafka cluster cannot be established,

    # or if a metadata request to the Kafka cluster needs to be repeated.

    Retry:

        # When a new channel is created, or when an existing channel is reloaded

        # (in case of a just-restarted orderer), the orderer interacts with the

        # Kafka cluster in the following ways:

        # 1. It creates a Kafka producer (writer) for the Kafka partition that

        # corresponds to the channel.

        # 2. It uses that producer to post a no-op CONNECT message to that

        # partition

        # 3. It creates a Kafka consumer (reader) for that partition.

        # If any of these steps fail, they will be re-attempted every

        # <ShortInterval> for a total of <ShortTotal>, and then every

        # <LongInterval> for a total of <LongTotal> until they succeed.

        # Note that the orderer will be unable to write to or read from a

        # channel until all of the steps above have been completed successfully.

        ShortInterval: 5s

        ShortTotal: 10m

        LongInterval: 5m

        LongTotal: 12h

        # Affects the socket timeouts when waiting for an initial connection, a

        # response, or a transmission. See Config.Net for more info:

        # https://godoc.org/github.com/Shopify/sarama#Config

        NetworkTimeouts:

            DialTimeout: 10s

            ReadTimeout: 10s

            WriteTimeout: 10s

        # Affects the metadata requests when the Kafka cluster is in the middle

        # of a leader election.See Config.Metadata for more info:

        # https://godoc.org/github.com/Shopify/sarama#Config

        Metadata:

            RetryBackoff: 250ms

            RetryMax: 3

        # What to do if posting a message to the Kafka cluster fails. See

        # Config.Producer for more info:

        # https://godoc.org/github.com/Shopify/sarama#Config

        Producer:

            RetryBackoff: 100ms

            RetryMax: 3

        # What to do if reading from the Kafka cluster fails. See

        # Config.Consumer for more info:

        # https://godoc.org/github.com/Shopify/sarama#Config

        Consumer:

            RetryBackoff: 2s

    # Settings to use when creating Kafka topics.  Only applies when

    # Kafka.Version is v0.10.1.0 or higher

    Topic:

        # The number of Kafka brokers across which to replicate the topic

        ReplicationFactor: 3

    # Verbose: Enable logging for interactions with the Kafka cluster.

    Verbose: false


    # TLS: TLS settings for the orderer's connection to the Kafka cluster.

    TLS:


      # Enabled: Use TLS when connecting to the Kafka cluster.

      Enabled: false


      # PrivateKey: PEM-encoded private key the orderer will use for

      # authentication.

      PrivateKey:

        # As an alternative to specifying the PrivateKey here, uncomment the

        # following "File" key and specify the file name from which to load the

        # value of PrivateKey.

        #File: path/to/PrivateKey


      # Certificate: PEM-encoded signed public key certificate the orderer will

      # use for authentication.

      Certificate:

        # As an alternative to specifying the Certificate here, uncomment the

        # following "File" key and specify the file name from which to load the

        # value of Certificate.

        #File: path/to/Certificate


      # RootCAs: PEM-encoded trusted root certificates used to validate

      # certificates from the Kafka cluster.

      RootCAs:

        # As an alternative to specifying the RootCAs here, uncomment the

        # following "File" key and specify the file name from which to load the

        # value of RootCAs.

        #File: path/to/RootCAs


    # SASLPlain: Settings for using SASL/PLAIN authentication with Kafka brokers

    SASLPlain:

      # Enabled: Use SASL/PLAIN to authenticate with Kafka brokers

      Enabled: false

      # User: Required when Enabled is set to true

      User:

      # Password: Required when Enabled is set to true

      Password:


    # Kafka protocol version used to communicate with the Kafka cluster brokers

    # (defaults to 0.10.2.0 if not specified)

    Version:


################################################################################

#

#   Debug Configuration

#

#   - This controls the debugging options for the orderer

#

################################################################################

Debug:


    # BroadcastTraceDir when set will cause each request to the Broadcast service

    # for this orderer to be written to a file in this directory

    BroadcastTraceDir:


    # DeliverTraceDir when set will cause each request to the Deliver service

    # for this orderer to be written to a file in this directory

    DeliverTraceDir:


실행

chmod +x runOrderer.sh

sudo ./runOrderer.sh



7. Peer 구동


1) Peer0 구동


(peer0 노드에서 실행)

# org0의 admin인증서 복사 

# admincerts 디렉토리 생성

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer0.org0/msp/admincerts/


# Org0 운영자 인증서 복사

cp /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/admincerts/Admin@org0-cert.pem  /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer0.org0/msp/admincerts/


/home/gun/MyProjects/testnet/runPeer.sh 파일 생성

#!/bin/bash

# arg1 <= The number of Org

# arg2 <= The number of peer


help()

{

    echo "Usage: $0 [org] [peer]"

}



if [ $# -ne 2 ]

then

    help

    exit 0

fi


FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


CORE_PEER_ENDORSER_ENABLED=true \

CORE_PEER_ADDRESS=peer$2:7051 \

CORE_PEER_CHAINCODELISTENADDRESS=peer$2:7052 \

CORE_PEER_ID=org$1-peer$2 \

CORE_PEER_LOCALMSPID=Org$1MSP \

CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer$2:7051 \

CORE_PEER_GOSSIP_USELEADERELECTION=true \

CORE_PEER_GOSSIP_ORGLEADER=false \

CORE_PEER_TLS_ENABLED=false \

CORE_PEER_TLS_KEY_FILE=$FABRIC_PATH/crypto-config/peerOrganizations/org$1/peers/peer$2.org$1/tls/server.key \

CORE_PEER_TLS_CERT_FILE=$FABRIC_PATH/crypto-config/peerOrganizations/org$1/peers/peer$2.org$1/tls/server.crt \

CORE_PEER_TLS_ROOTCERT_FILE=$FABRIC_PATH/crypto-config/peerOrganizations/org$1/peers/peer$2.org$1/tls/ca.crt \

CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer$2 \

CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org$1/peers/peer$2.org$1/msp \

/home/gun/MyProjects/src/github.com/hyperledger/fabric/.build/bin/peer node start


peer 실행시에 환경변수를 참조하여 동작하지 않아서 /home/gun/MyProjects/testnet/core.yaml 을 수정해 주시기 바랍니다.

(옛날에는 해당 환경변수로 동작했었는데, 왜 안되는지 모르겠네요.. 예전 VM이미지를 지워서 확인은 못 함)

# Copyright IBM Corp. All Rights Reserved.

#

# SPDX-License-Identifier: Apache-2.0

#


###############################################################################

#

#    LOGGING section

#

###############################################################################

logging:


    # Default logging levels are specified here.


    # Valid logging levels are case-insensitive strings chosen from


    #     FATAL | PANIC | ERROR | WARNING | INFO | DEBUG


    # The overall default logging level can be specified in various ways,

    # listed below from strongest to weakest:

    #

    # 1. The --logging-level=<level> command line option overrides all other

    #    default specifications.

    #

    # 2. The environment variable CORE_LOGGING_LEVEL otherwise applies to

    #    all peer commands if defined as a non-empty string.

    #

    # 3. The value of `level` that directly follows in this file.

    #

    # If no overall default level is provided via any of the above methods,

    # the peer will default to INFO (the value of defaultLevel in

    # common/flogging/logging.go)


    # Default for all modules running within the scope of a peer.

    # Note: this value is only used when --logging-level or CORE_LOGGING_LEVEL

    #       are not set

    level:       info


    # The overall default values mentioned above can be overridden for the

    # specific components listed in the override section below.


    # Override log levels for various peer modules.

    cauthdsl:   warning

    gossip:     info

    grpc:       error

    ledger:     info

    msp:        info

    policies:   warning

    peer:

        gossip: warning


    # Message format for the peer logs

    format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}'


###############################################################################

#

#    Peer section

#

###############################################################################

peer:


    # The Peer id is used for identifying this Peer instance.

    id: org0-peer0


    # The networkId allows for logical seperation of networks

    networkId: dev


    # The Address at local network interface this Peer will listen on.

    # By default, it will listen on all network interfaces

    listenAddress: peer0:7051


    # The endpoint this peer uses to listen for inbound chaincode connections.

    # If this is commented-out, the listen address is selected to be

    # the peer's address (see below) with port 7052

    # chaincodeListenAddress: 0.0.0.0:7052


    # The endpoint the chaincode for this peer uses to connect to the peer.

    # If this is not specified, the chaincodeListenAddress address is selected.

    # And if chaincodeListenAddress is not specified, address is selected from

    # peer listenAddress.

    # chaincodeAddress: 0.0.0.0:7052


    # When used as peer config, this represents the endpoint to other peers

    # in the same organization. For peers in other organization, see

    # gossip.externalEndpoint for more info.

    # When used as CLI config, this means the peer's endpoint to interact with

    address: peer0:7051


    # Whether the Peer should programmatically determine its address

    # This case is useful for docker containers.

    addressAutoDetect: false


    # Setting for runtime.GOMAXPROCS(n). If n < 1, it does not change the

    # current setting

    gomaxprocs: -1


    # Keepalive settings for peer server and clients

    keepalive:

        # MinInterval is the minimum permitted time between client pings.

        # If clients send pings more frequently, the peer server will

        # disconnect them

        minInterval: 60s

        # Client keepalive settings for communicating with other peer nodes

        client:

            # Interval is the time between pings to peer nodes.  This must

            # greater than or equal to the minInterval specified by peer

            # nodes

            interval: 60s

            # Timeout is the duration the client waits for a response from

            # peer nodes before closing the connection

            timeout: 20s

        # DeliveryClient keepalive settings for communication with ordering

        # nodes.

        deliveryClient:

            # Interval is the time between pings to ordering nodes.  This must

            # greater than or equal to the minInterval specified by ordering

            # nodes.

            interval: 60s

            # Timeout is the duration the client waits for a response from

            # ordering nodes before closing the connection

            timeout: 20s



    # Gossip related configuration

    gossip:

        # Bootstrap set to initialize gossip with.

        # This is a list of other peers that this peer reaches out to at startup.

        # Important: The endpoints here have to be endpoints of peers in the same

        # organization, because the peer would refuse connecting to these endpoints

        # unless they are in the same organization as the peer.

        bootstrap: peer0:7051


        # NOTE: orgLeader and useLeaderElection parameters are mutual exclusive.

        # Setting both to true would result in the termination of the peer

        # since this is undefined state. If the peers are configured with

        # useLeaderElection=false, make sure there is at least 1 peer in the

        # organization that its orgLeader is set to true.


        # Defines whenever peer will initialize dynamic algorithm for

        # "leader" selection, where leader is the peer to establish

        # connection with ordering service and use delivery protocol

        # to pull ledger blocks from ordering service. It is recommended to

        # use leader election for large networks of peers.

        useLeaderElection: true

        # Statically defines peer to be an organization "leader",

        # where this means that current peer will maintain connection

        # with ordering service and disseminate block across peers in

        # its own organization

        orgLeader: false


        # Overrides the endpoint that the peer publishes to peers

        # in its organization. For peers in foreign organizations

        # see 'externalEndpoint'

        endpoint:

        # Maximum count of blocks stored in memory

        maxBlockCountToStore: 100

        # Max time between consecutive message pushes(unit: millisecond)

        maxPropagationBurstLatency: 10ms

        # Max number of messages stored until a push is triggered to remote peers

        maxPropagationBurstSize: 10

        # Number of times a message is pushed to remote peers

        propagateIterations: 1

        # Number of peers selected to push messages to

        propagatePeerNum: 3

        # Determines frequency of pull phases(unit: second)

        # Must be greater than digestWaitTime + responseWaitTime

        pullInterval: 4s

        # Number of peers to pull from

        pullPeerNum: 3

        # Determines frequency of pulling state info messages from peers(unit: second)

        requestStateInfoInterval: 4s

        # Determines frequency of pushing state info messages to peers(unit: second)

        publishStateInfoInterval: 4s

        # Maximum time a stateInfo message is kept until expired

        stateInfoRetentionInterval:

        # Time from startup certificates are included in Alive messages(unit: second)

        publishCertPeriod: 10s

        # Should we skip verifying block messages or not (currently not in use)

        skipBlockVerification: false

        # Dial timeout(unit: second)

        dialTimeout: 3s

        # Connection timeout(unit: second)

        connTimeout: 2s

        # Buffer size of received messages

        recvBuffSize: 20

        # Buffer size of sending messages

        sendBuffSize: 200

        # Time to wait before pull engine processes incoming digests (unit: second)

        # Should be slightly smaller than requestWaitTime

        digestWaitTime: 1s

        # Time to wait before pull engine removes incoming nonce (unit: milliseconds)

        # Should be slightly bigger than digestWaitTime

        requestWaitTime: 1500ms

        # Time to wait before pull engine ends pull (unit: second)

        responseWaitTime: 2s

        # Alive check interval(unit: second)

        aliveTimeInterval: 5s

        # Alive expiration timeout(unit: second)

        aliveExpirationTimeout: 25s

        # Reconnect interval(unit: second)

        reconnectInterval: 25s

        # This is an endpoint that is published to peers outside of the organization.

        # If this isn't set, the peer will not be known to other organizations.

        externalEndpoint:

        # Leader election service configuration

        election:

            # Longest time peer waits for stable membership during leader election startup (unit: second)

            startupGracePeriod: 15s

            # Interval gossip membership samples to check its stability (unit: second)

            membershipSampleInterval: 1s

            # Time passes since last declaration message before peer decides to perform leader election (unit: second)

            leaderAliveThreshold: 10s

            # Time between peer sends propose message and declares itself as a leader (sends declaration message) (unit: second)

            leaderElectionDuration: 5s


        pvtData:

            # pullRetryThreshold determines the maximum duration of time private data corresponding for a given block

            # would be attempted to be pulled from peers until the block would be committed without the private data

            pullRetryThreshold: 60s

            # As private data enters the transient store, it is associated with the peer's ledger's height at that time.

            # transientstoreMaxBlockRetention defines the maximum difference between the current ledger's height upon commit,

            # and the private data residing inside the transient store that is guaranteed not to be purged.

            # Private data is purged from the transient store when blocks with sequences that are multiples

            # of transientstoreMaxBlockRetention are committed.

            transientstoreMaxBlockRetention: 1000

            # pushAckTimeout is the maximum time to wait for an acknowledgement from each peer

            # at private data push at endorsement time.

            pushAckTimeout: 3s

            # Block to live pulling margin, used as a buffer

            # to prevent peer from trying to pull private data

            # from peers that is soon to be purged in next N blocks.

            # This helps a newly joined peer catch up to current

            # blockchain height quicker.

            btlPullMargin: 10

            # the process of reconciliation is done in an endless loop, while in each iteration reconciler tries to

            # pull from the other peers the most recent missing blocks with a maximum batch size limitation.

            # reconcileBatchSize determines the maximum batch size of missing private data that will be reconciled in a

            # single iteration.

            reconcileBatchSize: 10

            # reconcileSleepInterval determines the time reconciler sleeps from end of an iteration until the beginning

            # of the next reconciliation iteration.

            reconcileSleepInterval: 5m


    # TLS Settings

    # Note that peer-chaincode connections through chaincodeListenAddress is

    # not mutual TLS auth. See comments on chaincodeListenAddress for more info

    tls:

        # Require server-side TLS

        enabled:  false

        # Require client certificates / mutual TLS.

        # Note that clients that are not configured to use a certificate will

        # fail to connect to the peer.

        clientAuthRequired: false

        # X.509 certificate used for TLS server

        cert:

            file: tls/server.crt

        # Private key used for TLS server (and client if clientAuthEnabled

        # is set to true

        key:

            file: tls/server.key

        # Trusted root certificate chain for tls.cert

        rootcert:

            file: tls/ca.crt

        # Set of root certificate authorities used to verify client certificates

        clientRootCAs:

            files:

              - tls/ca.crt

        # Private key used for TLS when making client connections.  If

        # not set, peer.tls.key.file will be used instead

        clientKey:

            file:

        # X.509 certificate used for TLS when making client connections.

        # If not set, peer.tls.cert.file will be used instead

        clientCert:

            file:


    # Authentication contains configuration parameters related to authenticating

    # client messages

    authentication:

        # the acceptable difference between the current server time and the

        # client's time as specified in a client request message

        timewindow: 15m


    # Path on the file system where peer will store data (eg ledger). This

    # location must be access control protected to prevent unintended

    # modification that might corrupt the peer operations.

    fileSystemPath: /var/hyperledger/production


    # BCCSP (Blockchain crypto provider): Select which crypto implementation or

    # library to use

    BCCSP:

        Default: SW

        # Settings for the SW crypto provider (i.e. when DEFAULT: SW)

        SW:

            # TODO: The default Hash and Security level needs refactoring to be

            # fully configurable. Changing these defaults requires coordination

            # SHA2 is hardcoded in several places, not only BCCSP

            Hash: SHA2

            Security: 256

            # Location of Key Store

            FileKeyStore:

                # If "", defaults to 'mspConfigPath'/keystore

                KeyStore:

        # Settings for the PKCS#11 crypto provider (i.e. when DEFAULT: PKCS11)

        PKCS11:

            # Location of the PKCS11 module library

            Library:

            # Token Label

            Label:

            # User PIN

            Pin:

            Hash:

            Security:

            FileKeyStore:

                KeyStore:


    # Path on the file system where peer will find MSP local configurations

    mspConfigPath: crypto-config/peerOrganizations/org0/peers/peer0.org0/msp


    # Identifier of the local MSP

    # ----!!!!IMPORTANT!!!-!!!IMPORTANT!!!-!!!IMPORTANT!!!!----

    # Deployers need to change the value of the localMspId string.

    # In particular, the name of the local MSP ID of a peer needs

    # to match the name of one of the MSPs in each of the channel

    # that this peer is a member of. Otherwise this peer's messages

    # will not be identified as valid by other nodes.

    localMspId: Org0MSP


    # CLI common client config options

    client:

        # connection timeout

        connTimeout: 3s


    # Delivery service related config

    deliveryclient:

        # It sets the total time the delivery service may spend in reconnection

        # attempts until its retry logic gives up and returns an error

        reconnectTotalTimeThreshold: 3600s


        # It sets the delivery service <-> ordering service node connection timeout

        connTimeout: 3s


        # It sets the delivery service maximal delay between consecutive retries

        reConnectBackoffThreshold: 3600s


    # Type for the local MSP - by default it's of type bccsp

    localMspType: bccsp


    # Used with Go profiling tools only in none production environment. In

    # production, it should be disabled (eg enabled: false)

    profile:

        enabled:     false

        listenAddress: 0.0.0.0:6060


    # The admin service is used for administrative operations such as

    # control over log module severity, etc.

    # Only peer administrators can use the service.

    adminService:

        # The interface and port on which the admin server will listen on.

        # If this is commented out, or the port number is equal to the port

        # of the peer listen address - the admin service is attached to the

        # peer's service (defaults to 7051).

        #listenAddress: 0.0.0.0:7055


    # Handlers defines custom handlers that can filter and mutate

    # objects passing within the peer, such as:

    #   Auth filter - reject or forward proposals from clients

    #   Decorators  - append or mutate the chaincode input passed to the chaincode

    #   Endorsers   - Custom signing over proposal response payload and its mutation

    # Valid handler definition contains:

    #   - A name which is a factory method name defined in

    #     core/handlers/library/library.go for statically compiled handlers

    #   - library path to shared object binary for pluggable filters

    # Auth filters and decorators are chained and executed in the order that

    # they are defined. For example:

    # authFilters:

    #   -

    #     name: FilterOne

    #     library: /opt/lib/filter.so

    #   -

    #     name: FilterTwo

    # decorators:

    #   -

    #     name: DecoratorOne

    #   -

    #     name: DecoratorTwo

    #     library: /opt/lib/decorator.so

    # Endorsers are configured as a map that its keys are the endorsement system chaincodes that are being overridden.

    # Below is an example that overrides the default ESCC and uses an endorsement plugin that has the same functionality

    # as the default ESCC.

    # If the 'library' property is missing, the name is used as the constructor method in the builtin library similar

    # to auth filters and decorators.

    # endorsers:

    #   escc:

    #     name: DefaultESCC

    #     library: /etc/hyperledger/fabric/plugin/escc.so

    handlers:

        authFilters:

          -

            name: DefaultAuth

          -

            name: ExpirationCheck    # This filter checks identity x509 certificate expiration

        decorators:

          -

            name: DefaultDecorator

        endorsers:

          escc:

            name: DefaultEndorsement

            library:

        validators:

          vscc:

            name: DefaultValidation

            library:


    #    library: /etc/hyperledger/fabric/plugin/escc.so

    # Number of goroutines that will execute transaction validation in parallel.

    # By default, the peer chooses the number of CPUs on the machine. Set this

    # variable to override that choice.

    # NOTE: overriding this value might negatively influence the performance of

    # the peer so please change this value only if you know what you're doing

    validatorPoolSize:


    # The discovery service is used by clients to query information about peers,

    # such as - which peers have joined a certain channel, what is the latest

    # channel config, and most importantly - given a chaincode and a channel,

    # what possible sets of peers satisfy the endorsement policy.

    discovery:

        enabled: true

        # Whether the authentication cache is enabled or not.

        authCacheEnabled: true

        # The maximum size of the cache, after which a purge takes place

        authCacheMaxSize: 1000

        # The proportion (0 to 1) of entries that remain in the cache after the cache is purged due to overpopulation

        authCachePurgeRetentionRatio: 0.75

        # Whether to allow non-admins to perform non channel scoped queries.

        # When this is false, it means that only peer admins can perform non channel scoped queries.

        orgMembersAllowedAccess: false

###############################################################################

#

#    VM section

#

###############################################################################

vm:


    # Endpoint of the vm management system.  For docker can be one of the following in general

    # unix:///var/run/docker.sock

    # http://localhost:2375

    # https://localhost:2376

    endpoint: unix:///var/run/docker.sock


    # settings for docker vms

    docker:

        tls:

            enabled: false

            ca:

                file: docker/ca.crt

            cert:

                file: docker/tls.crt

            key:

                file: docker/tls.key


        # Enables/disables the standard out/err from chaincode containers for

        # debugging purposes

        attachStdout: false


        # Parameters on creating docker container.

        # Container may be efficiently created using ipam & dns-server for cluster

        # NetworkMode - sets the networking mode for the container. Supported

        # standard values are: `host`(default),`bridge`,`ipvlan`,`none`.

        # Dns - a list of DNS servers for the container to use.

        # Note:  `Privileged` `Binds` `Links` and `PortBindings` properties of

        # Docker Host Config are not supported and will not be used if set.

        # LogConfig - sets the logging driver (Type) and related options

        # (Config) for Docker. For more info,

        # https://docs.docker.com/engine/admin/logging/overview/

        # Note: Set LogConfig using Environment Variables is not supported.

        hostConfig:

            NetworkMode: host

            Dns:

               # - 192.168.0.1

            LogConfig:

                Type: json-file

                Config:

                    max-size: "50m"

                    max-file: "5"

            Memory: 2147483648


###############################################################################

#

#    Chaincode section

#

###############################################################################

chaincode:


    # The id is used by the Chaincode stub to register the executing Chaincode

    # ID with the Peer and is generally supplied through ENV variables

    # the `path` form of ID is provided when installing the chaincode.

    # The `name` is used for all other requests and can be any string.

    id:

        path:

        name:


    # Generic builder environment, suitable for most chaincode types

    builder: $(DOCKER_NS)/fabric-ccenv:latest


    # Enables/disables force pulling of the base docker images (listed below)

    # during user chaincode instantiation.

    # Useful when using moving image tags (such as :latest)

    pull: false


    golang:

        # golang will never need more than baseos

        runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION)


        # whether or not golang chaincode should be linked dynamically

        dynamicLink: false


    car:

        # car may need more facilities (JVM, etc) in the future as the catalog

        # of platforms are expanded.  For now, we can just use baseos

        runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION)


    java:

        # This is an image based on java:openjdk-8 with addition compiler

        # tools added for java shim layer packaging.

        # This image is packed with shim layer libraries that are necessary

        # for Java chaincode runtime.

        runtime: $(DOCKER_NS)/fabric-javaenv:$(ARCH)-$(PROJECT_VERSION)


    node:

        # need node.js engine at runtime, currently available in baseimage

        # but not in baseos

        runtime: $(BASE_DOCKER_NS)/fabric-baseimage:$(ARCH)-$(BASE_VERSION)


    # Timeout duration for starting up a container and waiting for Register

    # to come through. 1sec should be plenty for chaincode unit tests

    startuptimeout: 300s


    # Timeout duration for Invoke and Init calls to prevent runaway.

    # This timeout is used by all chaincodes in all the channels, including

    # system chaincodes.

    # Note that during Invoke, if the image is not available (e.g. being

    # cleaned up when in development environment), the peer will automatically

    # build the image, which might take more time. In production environment,

    # the chaincode image is unlikely to be deleted, so the timeout could be

    # reduced accordingly.

    executetimeout: 30s


    # There are 2 modes: "dev" and "net".

    # In dev mode, user runs the chaincode after starting peer from

    # command line on local machine.

    # In net mode, peer will run chaincode in a docker container.

    mode: net


    # keepalive in seconds. In situations where the communiction goes through a

    # proxy that does not support keep-alive, this parameter will maintain connection

    # between peer and chaincode.

    # A value <= 0 turns keepalive off

    keepalive: 0


    # system chaincodes whitelist. To add system chaincode "myscc" to the

    # whitelist, add "myscc: enable" to the list below, and register in

    # chaincode/importsysccs.go

    system:

        cscc: enable

        lscc: enable

        escc: enable

        vscc: enable

        qscc: enable


    # System chaincode plugins: in addition to being imported and compiled

    # into fabric through core/chaincode/importsysccs.go, system chaincodes

    # can also be loaded as shared objects compiled as Go plugins.

    # See examples/plugins/scc for an example.

    # Like regular system chaincodes, plugins must also be white listed in the

    # chaincode.system section above.

    systemPlugins:

      # example configuration:

      # - enabled: true

      #   name: myscc

      #   path: /opt/lib/myscc.so

      #   invokableExternal: true

      #   invokableCC2CC: true


    # Logging section for the chaincode container

    logging:

      # Default level for all loggers within the chaincode container

      level:  info

      # Override default level for the 'shim' module

      shim:   warning

      # Format for the chaincode container logs

      format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}'


###############################################################################

#

#    Ledger section - ledger configuration encompases both the blockchain

#    and the state

#

###############################################################################

ledger:


  blockchain:


  state:

    # stateDatabase - options are "goleveldb", "CouchDB"

    # goleveldb - default state database stored in goleveldb.

    # CouchDB - store state database in CouchDB

    stateDatabase: goleveldb

    # Limit on the number of records to return per query

    totalQueryLimit: 100000

    couchDBConfig:

       # It is recommended to run CouchDB on the same server as the peer, and

       # not map the CouchDB container port to a server port in docker-compose.

       # Otherwise proper security must be provided on the connection between

       # CouchDB client (on the peer) and server.

       couchDBAddress: 127.0.0.1:5984

       # This username must have read and write authority on CouchDB

       username:

       # The password is recommended to pass as an environment variable

       # during start up (eg LEDGER_COUCHDBCONFIG_PASSWORD).

       # If it is stored here, the file must be access control protected

       # to prevent unintended users from discovering the password.

       password:

       # Number of retries for CouchDB errors

       maxRetries: 3

       # Number of retries for CouchDB errors during peer startup

       maxRetriesOnStartup: 12

       # CouchDB request timeout (unit: duration, e.g. 20s)

       requestTimeout: 35s

       # Limit on the number of records per each CouchDB query

       # Note that chaincode queries are only bound by totalQueryLimit.

       # Internally the chaincode may execute multiple CouchDB queries,

       # each of size internalQueryLimit.

       internalQueryLimit: 1000

       # Limit on the number of records per CouchDB bulk update batch

       maxBatchUpdateSize: 1000

       # Warm indexes after every N blocks.

       # This option warms any indexes that have been

       # deployed to CouchDB after every N blocks.

       # A value of 1 will warm indexes after every block commit,

       # to ensure fast selector queries.

       # Increasing the value may improve write efficiency of peer and CouchDB,

       # but may degrade query response time.

       warmIndexesAfterNBlocks: 1

       # Create the _global_changes system database

       # This is optional.  Creating the global changes database will require

       # additional system resources to track changes and maintain the database

       createGlobalChangesDB: false


  history:

    # enableHistoryDatabase - options are true or false

    # Indicates if the history of key updates should be stored.

    # All history 'index' will be stored in goleveldb, regardless if using

    # CouchDB or alternate database for the state.

    enableHistoryDatabase: true


###############################################################################

#

#    Metrics section

#

#

###############################################################################

metrics:

        # enable or disable metrics server

        enabled: false


        # when enable metrics server, must specific metrics reporter type

        # currently supported type: "statsd","prom"

        reporter: statsd


        # determines frequency of report metrics(unit: second)

        interval: 1s


        statsdReporter:


              # statsd server address to connect

              address: 0.0.0.0:8125


              # determines frequency of push metrics to statsd server(unit: second)

              flushInterval: 2s


              # max size bytes for each push metrics request

              # intranet recommend 1432 and internet recommend 512

              flushBytes: 1432


        promReporter:


              # prometheus http server listen address for pull metrics

              listenAddress: 0.0.0.0:8080


Peer0 실행

chmod +x runPeer.sh

sudo ./runPeer.sh 


2) peer2 구동


(peer2 노드에서 실행)

mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/peers/peer2.org1/msp/admincerts/


cp  /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/admincerts/Admin@org1-cert.pem  /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org1/peers/peer2.org1/msp/admincerts/


peer0 의 core.yaml 파일 참조하여 /home/gun/MyProjects/testnet/core.yaml 파일의  org 번호, peer 번호를 맞춰 주시기 바랍니다


sudo ./runPeer.sh



8. 채널 생성


1) 채널 트랙잭션(ch1.tx) 생성 후 peer0(org0의 관리자) 노드로 전송


(OrdererOrg 관리자 권한이 있는 orderer 노드에서 실행)

configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ch1.tx -channelID ch1


# 채널 트랜잭션 확인

configtxgen -inspectChannelCreateTx ch1.tx


# 채널 트랜잭션을 peer0로 전송

scp ch1.tx gun@peer0:/home/gun/MyProjects/testnet



2) 채널 생성 


(Org0의 관리자 권한이 있는 peer0에서 실행)

/home/gun/MyProjects/testnet/create-channel.sh 스크립트 파일 생성

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


CORE_PEER_LOCALMSPID="Org0MSP" \

CORE_PEER_TLS_ROOTCERT_FILE=$FABRIC_PATH/crypto-config/peerOrganizations/org0/peers/peer0.org0/tls/ca.crt \

CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp \

CORE_PEER_ADDRESS=peer0:7051 \

peer channel create -o orderer:7050 -c ch1 -f ch1.tx


# 채널 생성 실행

chmod +x create-channel.sh

./create-channel.sh


#생성된 ch1.block 을 admin@org1에도 전송 (향후 Org1도 채널에 참여시키기 위함)

scp ch1.block gun@peer2:/home/gun/MyProjects/testnet



9. Peer의 채널 참여


(peer0에서 실행)

$FABRIC_CFG_PATH/join-channel-peer0.sh 스크립트 파일 생성

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org0MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp

export CORE_PEER_ADDRESS=peer0:7051

peer channel join -b ch1.block


peer0 채널 참여 실행

./join-channel-peer0.sh



(peer2에서 실행)

$FABRIC_CFG_PATH/join-channel-peer2.sh

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org1MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org1/users/Admin@org1/msp

export CORE_PEER_ADDRESS=peer2:7051

peer channel join -b ch1.block


peer2 채널 참여 실행

./join-channel-peer2.sh



10. Anchor peer 업데이트


1) Anchor peer 업데이트 트랜잭션 생성


(orderer 노드에서 실행)

# Anchor 업데이트 트랙잭션 생성 

$ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate Org0MSPanchors.tx -channelID ch1 -asOrg Org0MSP

$ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate Org1MSPanchors.tx -channelID ch1 -asOrg Org1MSP


# 생성된 각 tx를 admin@org0 / admin@org1 으로 각각 전송

$ scp Org0MSPanchors.tx gun@peer0:/home/gun/MyProjects/testnet

$ scp Org1MSPanchors.tx gun@peer2:/home/gun/MyProjects/testnet



2) Anchor peer 업데이트


(peer0 노드에서 실행)

/home/gun/MyProjects/testnet/org0-anchor.sh 스크립트 파일 생성

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org0MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp

export CORE_PEER_ADDRESS=peer0:7051

peer channel create -o orderer:7050 -c ch1 -f Org0MSPanchors.tx


Org0 조직의 anchor peer 업데이트 실행

$ chmod +x org0-anchor.sh 

$ ./org0-anchor.sh


(peer2 노드에서 실행)

/home/gun/MyProjects/testnet/org1-anchor.sh 스크립트 파일 생성

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org1MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org1/users/Admin@org1/msp

export CORE_PEER_ADDRESS=peer2:7051

peer channel create -o orderer:7050 -c ch1 -f Org1MSPanchors.tx


Org1 조직의 anchor peer 업데이트 실행

$ chmod +x org1-anchor.sh 

$ ./org1-anchor.sh



11. 체인코드 설치


1) peer0에 설치


(peer0 노드에서 실행)

# admin@org 관리자의 MSP 권한으로 설치 

/home/gun/MyProjects/testnet/installCCpeer0.sh 스크립트 파일 생성

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org0MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp

export CORE_PEER_ADDRESS=peer0:7051

peer chaincode install -n testnetCC -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd


체인코드 설치 실행

$ chmod +x installCCpeer0.sh 

$ ./installCCpeer0.sh



2) peer2에 설치


# admin@org1 관리자의 MSP 권한으로 설치 

/home/gun/MyProjects/testnet/installCCpeer2.sh 스크립트 파일 생성

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org1MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org1/users/Admin@org1/msp

export CORE_PEER_ADDRESS=peer2:7051

peer chaincode install -n testnetCC -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd


체인코드 설치 실행

$ chmod +x installCCpeer2.sh 

$ ./installCCpeer2.sh



3) 설치 확인


(peer0 노드에서 실행)

/home/gun/MyProjects/testnet/installCClist.sh 스크립트 파일 생성

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org0MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp

export CORE_PEER_ADDRESS=peer0:7051

peer chaincode list -C ch1 --installed


설치 상태 

$ chmod +x installCClist.sh 

$ ./installCClist.sh



12. 체인코드 인스턴스 생성


(peer0  노드에서 실행)


1) instantiate 체인코드 


/home/gun/MyProjects/testnet/instantiateCC.sh

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org0MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp

export CORE_PEER_ADDRESS=peer0:7051

peer chaincode instantiate -o orderer:7050 -C ch1 -n testnetCC -v 1.0 -c '{"Args":["init","a","200", "b", "300"]}' -P "OR ('Org0MSP.member', 'Org1MSP.member')"


실행

$ chmod +x instantiateCC.sh 

$ ./instantiateCC.sh



2) 인스턴스 목록 확인


/home/gun/MyProjects/testnet/instantiateCClist.sh

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org0MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp

export CORE_PEER_ADDRESS=peer0:7051

peer chaincode list -C ch1 --instantiated


실행

$ chmod +x instantiateCClist.sh

$ ./instantiateCClist.sh



13. 동작 확인 


1. 분산원장 데이터 읽기


(peer0 노드에서 실행)


/home/gun/MyProjects/testnet/query.sh

help()

{

    echo "Usage: $0 [variable]"

}


if [ $# -ne 1 ]

then

    help

    exit 0

fi


FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org0MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp

export CORE_PEER_ADDRESS=peer0:7051

peer chaincode query -C ch1 -n testnetCC -c "{\"Args\":[\"query\",\"$1\"]}"


실행

$ chmod +x query.sh

#스크립트 인자로 a, b 변수를 넣어서 확인

$ ./query.sh a


2. 분산원장에 데이터 기록


(peer0  노드에서 실행)


/home/gun/MyProjects/testnet/invoke.sh

FABRIC_PATH=/home/gun/MyProjects/testnet

echo $FABRIC_PATH


export CORE_PEER_LOCALMSPID="Org0MSP"

export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp

export CORE_PEER_ADDRESS=peer0:7051

peer chaincode invoke -o orderer:7050 -C ch1 -n testnetCC -c '{"Args":["invoke","a","b","50"]}'


실행

$ chmod +x invoke.sh

$ ./invoke.sh

$ ./query.sh a

$ ./query.sh b



14.  Org0 조직에 신규 노드(peer1) 추가

1) peer1 노드의 계정 생성

org0 조직관리자 권한으로 실행

(Org0 조직 관리자의 MSP가 있는 peer0 노드에서 실행)

#peer1 계정 생성 
/home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/fabric-ca-client-config.yaml 파일의 id 수정
id:
  name: peer1
  type: peer
  affiliation: org0
  maxenrollments: -1
  attributes:
    - name: role
      value: peer
      ecert: true

-H 옵션으로 fabric-ca-client-config.yaml 파일 경로 지정
fabric-ca-client register --id.secret=dlwhdrjs -H /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/

2) peer1의 MSP 생성 

org0 조직관리자가 등록한 계정의 패스워드로 peer1의 개인키 생성 및 인증서 발급

(peer1 노드에서 실행)
mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer1.org0/

fabric-ca-client enroll -u http://peer0:dlwhdrjs@10.0.1.100:7054 -H /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer1.org0/

mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer1.org0/msp/cacerts/10-0-1-100-7054.pem /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer1.org0/msp/cacerts/ca.crt

# [개인키] 파일이름 확인 후 복사
mv /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer1.org0/msp/keystore/cb2069c15665e8d19ec9d737370bd55419309d2ae93e333e698f536c186bd8de_sk /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer1.org0/msp/keystore/server.key

3) peer1 구동 

# org0의 admin인증서 복사 
(peer0 노드에서 실행)
scp /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/users/Admin@org0/msp/admincerts/Admin@org0-cert.pem gun@peer1:/home/gun/MyProjects/testnet

(peer1 노드에서 실행)
mkdir -p /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer1.org0/msp/admincerts/

mv /home/gun/MyProjects/testnet/Admin@org0-cert.pem  /home/gun/MyProjects/testnet/crypto-config/peerOrganizations/org0/peers/peer1.org0/msp/admincerts/

/home/gun/MyProjects/testnet/runPeer.sh 파일 생성 (peer0 노드에 있는 스크립트 파일 복사해서 사용)
peer0 의 core.yaml 파일 참조하여 /home/gun/MyProjects/testnet/core.yaml 파일의  org 번호, peer 번호를 맞춰 주시기 바랍니다

실행
chmod +x runPeer.sh
sudo ./runPeer.sh 


4) peer1을 채널(ch1)에 참여

(org0 조직 관리자 권한이 있는 peer0에서 실행)
$FABRIC_CFG_PATH/join-channel-peer1.sh
FABRIC_PATH=/home/gun/MyProjects/testnet
echo $FABRIC_PATH

export CORE_PEER_LOCALMSPID="Org0MSP"
export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp
export CORE_PEER_ADDRESS=peer1:7051
peer channel join -b ch1.block

실행
./join-channel-peer1.sh

5) peer1에 chaincode 설치

(org0의 관리자 권한을 갖는 peer0에서 실행)
/home/gun/MyProjects/testnet/installCCpeer1.sh
FABRIC_PATH=/home/gun/MyProjects/testnet
echo $FABRIC_PATH

export CORE_PEER_LOCALMSPID="Org0MSP"
export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/users/Admin@org0/msp
export CORE_PEER_ADDRESS=peer1:7051
peer chaincode install -n testnetCC -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd

실행
$ chmod +x installCCpeer1.sh 
$ ./installCCpeer1.sh

# 설치 상태 확인
/home/gun/MyProjects/testnet/installCClist.sh (peer0 노드에서 생성한 스크립트 복사)

실행 결과 확인



6) 분산원장 읽기/쓰기 시험

(peer1에서 실행)

(peer1에서 실행)
# MSPID는 Org0MSP 로 설정하고, MSP path는 peer1.org0의 MSP로 설정 
/home/gun/MyProjects/testnet/query.sh
help()
{
    echo "Usage: $0 [variable]"
}

if [ $# -ne 1 ]
then
    help
    exit 0
fi

FABRIC_PATH=/home/gun/MyProjects/testnet
echo $FABRIC_PATH

export CORE_PEER_LOCALMSPID="Org0MSP"
export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/peers/peer1.org0/msp
export CORE_PEER_ADDRESS=peer1:7051
peer chaincode query -C ch1 -n testnetCC -c "{\"Args\":[\"query\",\"$1\"]}"


/home/gun/MyProjects/testnet/invoke.sh
FABRIC_PATH=/home/gun/MyProjects/testnet
echo $FABRIC_PATH

export CORE_PEER_LOCALMSPID="Org0MSP"
export CORE_PEER_MSPCONFIGPATH=$FABRIC_PATH/crypto-config/peerOrganizations/org0/peers/peer1.org0/msp
export CORE_PEER_ADDRESS=peer1:7051
peer chaincode invoke -o orderer:7050 -C ch1 -n testnetCC -c '{"Args":["invoke","a","b","50"]}'

query 및 invoke 실행 결과 확인



[부록]  Hyperledger fabric 데이터 삭제 

#test network 에 참여한 모든 노드에서 실행 
rm -rf $FABRIC_CFG_PATH/crypto-config/
sudo rm -rf /var/hyperledger/

# kafka-zookeeper 노드에서 실행
docker network prune
docker system prune
docker volume prune


이상으로 Fabric-CA를 이용한 멀티호스트 환경 구축 예제를 마칩니다.

세부적인 내용보다는 핵심적인 절차와 수행을 위한 fabric 명령어 중심으로 이해하시면 좋을 것 같습니다