- 인쇄
- PDF
Smart Contracts
- 인쇄
- PDF
VPC 환경에서 이용 가능합니다.
채널 관리
채널은 컨소시엄 내 특정 그룹(MSP의 집합)의 트랜잭션을 처리하기 위한 하나의 서브 네트워크 역할을 수행합니다.
Orderer의 컨소시엄 관리는 Orderer가 관리하는 모든 MSP를 지정하는 것이며, 채널의 구성원 관리는 컨소시엄 내 다수의 MSP 중 특정 채널에만 참여하는 MSP를 별도로 지정하는 것을 의미합니다.
채널 생성
채널을 생성하는 방법은 다음과 같습니다.
채널을 생성하기 전에 구성원(MSP)에 대해 컨소시엄을 우선 구성해야 합니다. 자세한 내용은 Orderer 컨소시엄 구성을 참조해 주십시오.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
- 네트워크 이름 드롭다운 목록에서 채널을 생성할 네트워크를 클릭해 주십시오.
- [Channels] 탭을 클릭한 후 [Channel 생성] 버튼을 클릭해 주십시오.
- 채널 생성 정보를 지정한 후 [생성] 버튼을 클릭해 주십시오.
- 채널이 생성됩니다.
- 채널 구성원의 역할은 Operator(운영자)와 Participant(참여자) 중 선택할 수 있으며, Operator는 한 명(필수)만 지정 가능합니다. Operator 1명이 지정되면 이후 지정되는 MSP는 모두 Participant(참여자) 역할을 가지게 됩니다.
- 채널은 Orderer가 관리하며, 하나의 Orderer는 다수의 채널을 관리할 수 있습니다.
채널은 해당 채널에 연결된 Orderer가 삭제되는 경우 채널 목록에서 제거되지만, 실제로 삭제되지는 않습니다. 채널 이름은 삭제한 기존 이름과 다른 이름을 사용해 주십시오.
채널 상세 정보 확인
채널 상세 정보를 확인하는 방법은 다음과 같습니다.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
- 네트워크 이름 드롭다운 목록에서 채널을 확인할 네트워크를 클릭해 주십시오.
- [Channels] 탭을 클릭해 주십시오.
- 확인할 채널을 클릭해 주십시오.
- 채널의 상세 정보가 표시됩니다.
채널 목록 화면의 각 항목에 대한 설명은 다음과 같습니다.
영역 | 설명 |
---|---|
① Channel 생성 | 새로운 채널 생성 |
② Channel 설정 | 선택한 채널의 채널 구성원(MSP) 및 Peer 관리, Block 생성 정책 설정 |
③ 채널 항목 | 채널 기본 정보 확인 |
④ 상세정보 | 채널 상세 정보 확인 |
⑤ Block 조회 | 채널의 블럭 및 트랜잭션 조회 |
⑥ Channel 구성원 | 채널 구성원(MSP) 정보 확인 |
⑦ Peer 정보 | 채널에 참여하는 Peer 정보 확인 |
Block&Transaction 조회
생성한 채널에 속한 Block이나 Transaction을 조회할 수 있습니다.
Block 또는 Transaction을 조회하는 방법은 다음과 같습니다.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
- 네트워크 이름 드롭다운 목록에서 해당 네트워크를 클릭해 주십시오.
- [Channels] 탭을 클릭해 주십시오.
- 채널 목록에서 채널을 선택한 후 [Block 조회] 버튼을 클릭해 주십시오.
- 조회하길 원하는 BlockNumber 또는 TransactionID를 입력한 후 버튼을 클릭해 주십시오.
- 트랜잭션의 자세한 정보를 알고 싶다면 조회한 TransactionID 값을 클릭해 주십시오.
- 최초 팝업 로딩 시 최신 블럭이 자동으로 조회됩니다.
채널 구성원(MSP) 관리
생성한 채널에 구성원을 새로 추가하거나 기존 구성원을 삭제할 수 있습니다.
채널 구성원(MSP)을 관리하는 방법은 다음과 같습니다.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
- 네트워크 이름 드롭다운 목록에서 해당 네트워크를 클릭해 주십시오.
- [Channels] 탭을 클릭해 주십시오.
- 채널 목록에서 채널 구성원(MSP)을 관리할 채널을 선택한 후 [Channel 설정] 버튼을 클릭해 주십시오.
- Channel 구성원(MSP) 관리를 클릭해 주십시오.
- 채널 구성원(MSP) 관리 팝업창에서 구성원 추가 또는 삭제한 후 [확인] 버튼을 클릭해 주십시오.
- 이미 Operator가 지정되어 있는 경우 Operator를 삭제하거나 새 Operator를 추가할 수 없습니다.
채널 내 Peer 관리
생성한 채널에 실제 통신에 참여하는 Peer를 새로 추가(join)하거나 Peer에 Anchor Peer를 적용할 수 있습니다.
채널 내 Peer를 관리하는 방법은 다음과 같습니다.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
- 네트워크 이름 드롭다운 목록에서 해당 네트워크를 클릭해 주십시오.
- [Channels] 탭을 클릭해 주십시오.
- 채널 목록에서 채널 구성원(MSP)을 관리할 채널을 선택한 후 [Channel 설정] 버튼을 클릭해 주십시오.
- Peer 관리를 클릭해 주십시오.
- Peer 추가 및 Anchor Peer 설정을 완료하면 [닫기] 버튼을 클릭해 주십시오.
- 추가(join)된 Peer는 해지할 수 없습니다.
- Peer는 모두 동일한 데이터베이스를 사용해야 합니다.
Anchor Peer는 다른 조직(organization)의 Peer에 대해 서로 정보를 교환하는 역할을 합니다. 자세한 내용은 다음을 참조해 주십시오.
블록 생성 정책 설정
채널에 블록(Block) 생성 정책을 설정하는 방법은 다음과 같습니다.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
- 네트워크 이름 드롭다운 목록에서 해당 네트워크를 클릭해 주십시오.
- [Channels] 탭을 클릭해 주십시오.
- 채널 목록에서 채널 구성원(MSP)을 관리할 채널을 선택한 후 [Channel 설정] 버튼을 클릭해 주십시오.
- Block 생성 정책 설정를 클릭해 주십시오.
- Block 생성 정책을 설정한 후 [확인] 버튼을 클릭해 주십시오.
- 기준 블록 크기, 최대 블록 크기는 정수형 또는 소수점 한 자리까지만 입력할 수 있습니다.
- 기본값을 변경할 경우 트랙잭션 처리 성능에 영향을 줄 수 있습니다.
채널 구성(Configuration)에 대한 자세한 내용은 다음을 참조해 주십시오.
체인코드 관리
체인코드 설치
네트워크 내에 생성된 Peer에 체인코드를 설치할 수 있습니다.
체인코드 설치를 위해서는 먼저 CDS 패키지를 생성해야 합니다. CDS 패키지 생성에 관한 내용 및 예제 다운로드는 체인코드(CDS) 패키징을 참조해 주십시오.
체인코드와 CDS 패키지에 대한 자세한 내용은 다음을 참조해 주십시오.
- 체인코드: Hyperledger Fabric 가이드 바로가기
- CDS 패키지: Hyperledger Fabric 가이드 바로가기
- Kubernetes 클러스터의 네트워크타입을 Private Subnet으로 사용하는 경우, 체인코드에서 외부 라이브러리를 사용하거나, 다른 VPC 간 네트워크를 초대하려면 NATGW를 사용해야 합니다.
체인코드를 설치하는 방법은 다음과 같습니다.
네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
네트워크 이름 드롭다운 목록에서 체인코드를 설치할 네트워크를 클릭해 주십시오.
[Chaincodes] 탭을 클릭한 후 [Chaincode 설치] 버튼을 클릭해 주십시오.
체인코드 설치 팝업 창의 마우스로 파일을 끌고 오거나 여기를 클릭하세요 영역에 CDS 패키지 파일을 끌어넣거나, 마우스로 파일을 끌고 오거나 여기를 클릭하세요를 클릭해 CDS 패키지 파일을 선택한 후 [다음] 버튼을 클릭해 주십시오.
주의CDS 패키지에 포함되어 있는 체인코드 메타 정보(이름, 버전)가 같은 패키지를 다시 업로드하는 경우, 기존에 업로드된 패키지가 사용됩니다. 버전 관리에 주의해 주십시오.
업로드한 체인코드(CDS 패키지)를 설치할 Peer를 선택한 후 [설치] 버튼을 클릭해 주십시오.
- 체인코드가 이미 설치된 Peer에는 설치됨으로 표시됩니다.
- 체인코드 2.2 버전은 노드 기능 레벨이 1.4 버전으로 배포되기 때문에 체인코드 라이프사이클(chaincode lifecyle) 기능은 현재 사용할 수 없습니다. 이외 2.2 버전의 신규 기능은 정상 적용됩니다.
- 설치된 체인코드로 실제 트랜잭션 처리가 되려면 설치된 체인코드를 인스턴스화해야 합니다. 자세한 내용은 체인코드 인스턴스화를 참조해 주십시오.
설치된 체인코드는 삭제할 수 없습니다. 인스턴스화까지 완료된 경우 [로그 보기] 버튼을 클릭한 후 체인코드 컨테이너 로그를 확인하실 수 있습니다.
체인코드 상세 정보 확인
네트워크에 설치된 체인코드 상세 정보를 확인하는 방법은 다음과 같습니다.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
- 네트워크 이름 드롭다운 목록에서 체인코드를 확인할 네트워크를 클릭해 주십시오.
- [Chaincodes] 탭을 클릭해 주십시오.
- 확인할 체인코드를 클릭해 주십시오.
- 체인코드의 상세 정보가 표시됩니다.
체인코드 목록 화면의 각 항목에 대한 설명은 다음과 같습니다.
영역 | 설명 |
---|---|
① Chaincode 설치 | 새로운 체인코드 설치 |
② 인스턴스화 | 체인코드를 인스턴스화 |
③ 버전 변경 | 인스턴스화된 체인코드 버전을 변경 |
④ 검색 창 | 검색 조건 설정 후 버튼을 클릭해 항목 검색 |
⑤ 체인코드 상세 정보 | 설치된 체인코드 및 인스턴스화된 체인코드 정보 확인 |
⑥ 체인코드 실행 | 인스턴스화된 체인코드 실행 |
체인코드 인스턴스화
체인코드를 설치한 후 인스턴스화 과정을 거쳐야 트랜잭션 처리를 할 수 있습니다.
체인코드를 인스턴스화하는 방법은 다음과 같습니다.
네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
네트워크 이름 드롭다운 목록에서 체인코드를 확인할 네트워크를 클릭해 주십시오.
[Chaincodes] 탭을 클릭한 후 [인스턴스화] 버튼을 클릭해 주십시오.
체인코드 인스턴스화 항목을 설정한 후 [확인] 버튼을 클릭해 주십시오.
- 트랜잭션 보증 구성원: 트랜잭션 보증 구성원에 MSP를 추가하려면 Orderer 컨소시엄 구성 기능을 통해 MSP를 추가해야 합니다.
- 트랜잭션 보증 정책: 트랜잭션 보증 구성원이 다수일 경우 트랜잭션 보증 정책을 1/2, 2/3과 같이 설정할 수 있습니다. 트랜잭션 보증 정책이 2/3라면 총 3개의 보증 구성원 중 2개 이상의 보증 구성원으로부터 보증을 받아야 한다는 것을 의미합니다.
- 초기화 함수 실행: 체인코드에 초기화 함수를 지정해 놓은 경우, 인스턴스 시 해당 함수를 실행할 수 있습니다.
- 인스턴스화는 수 분이 소요될 수 있으며, 콘솔 오른쪽 최상단 [알림] 버튼을 통해 결과를 확인할 수 있습니다.
- 인스턴스화를 성공적으로 완료하면 인스턴스화된 체인코드 목록에서 조회할 수 있습니다.
- 인스턴스화된 체인코드는 삭제가 불가능합니다.
체인코드 버전 변경 (업그레이드)
한 번 인스턴스화된 체인코드는 새로운 버전을 설치하면 다시 인스턴스화하는 대신 버전 변경을 진행합니다.
현재 인스턴스화된 체인코드 버전보다 높은 버전이 설치된 경우, 인스턴스화된 체인코드 목록의 해당 체인코드 버전에 업그레이드 가능 배지가 표시됩니다.
인스턴스화된 체인코드 버전을 변경하는 방법은 다음과 같습니다.
네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
네트워크 이름 드롭다운 목록에서 체인코드를 업그레이드할 네트워크를 클릭해 주십시오.
[Chaincodes] 탭을 클릭한 후 [버전 변경] 버튼을 클릭해 주십시오.
체인코드 업그레이드 항목을 설정한 후 [확인] 버튼을 클릭해 주십시오.
- 트랜잭션 보증 구성원: 트랜잭션 보증 구성원에 MSP를 추가하려면 Orderer 컨소시엄 구성 기능을 통해 MSP를 추가해야 합니다.
- 트랜잭션 보증 정책: 예) 트랜잭션 보증 정책이 2/3라면 총 3개의 보증 구성원 중 2개 이상의 보증 구성원으로부터 보증을 받아야 한다는 것을 의미합니다.
- 초기화 함수 실행: 체인코드에 초기화 함수를 지정해 놓은 경우, 인스턴스 시 해당 함수를 실행할 수 있습니다.
- 설치한 체인코드의 이름이 같아야 버전 변경이 가능합니다.
- 버전 변경은 수 분이 소요될 수 있으며, 콘솔 오른쪽 최상단 [알림] 버튼을 통해 결과를 확인할 수 있습니다.
- 버전 변경을 성공적으로 완료하면 인스턴스화된 체인코드 목록에서 조회하실 수 있습니다.
체인코드 실행
인스턴스화된 체인코드는 [Chaincode실행] 버튼을 통해 실행할 수 있습니다.
체인코드를 실행하는 방법은 다음과 같습니다.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Smart Contracts 메뉴를 차례대로 클릭해 주십시오.
- 네트워크 이름 드롭다운 목록에서 실행하고자 하는 체인코드가 설치 된 네트워크를 클릭해 주십시오.
- [Chaincodes] 탭을 클릭한 후 인스턴스화된 Chaincode목록 에서 호출하고자 하는 체인코드를 선택한 후 [Chaincode실행] 버튼을 클릭해 주십시오.
- 원하는 커맨드(Invoke/Query), 계약이름, 함수이름 그리고 매개변수를 넣고 [실행] 버튼을 클릭해 주십시오.
- 계약이름은 체인코드가 Multi Contract로 이루어져 있을 경우 입력해 주십시오.
- 체인코드 호출 시 체인코드를 호출한 mspId, Identity, 체인코드 응답값을 확인할 수 있습니다.
- 매개변수는 호출 할 함수의 매개변수 순서와 동일하게 추가해 주십시오.
- 만약 보낼 매개변수가 객체라면 아래와 같이 JSON형식으로 추가해 주십시오.
{"carNumber":"CAR1001","color":"red"}
체인코드 배포 구조의 변경
Ncloud Kubernetes Service는 향후 worker node에서 docker.sock 파일을 제거하여 운영하게 됨에 따라, 아래와 같이 docker.sock 파일이 설치된 컨테이너에 체인코드 컨테이너를 배포하는 방식으로 변경됩니다.
AS-IS
TO-BE
2023.12.21 이전에 노드를 구성하고 체인코드를 배포한 경우, 다음과 같은 절차를 통해 노드 구성을 변경하고 재시작하여야 합니다.
- Kubernetes 클러스터에서 Peer 노드의 deployment.yaml 을 input.yaml 파일로 저장합니다.
$ kubectl -n [namespace] get deploy [peer deployment yaml] - o yaml > input.yaml
namespace를 확인하는 방법은 다음과 같습니다.
- 네이버 클라우드 플랫폼 콘솔의 VPC 환경에서 Services > Blockchain > Blockchain Service > Networks 메뉴를 차례대로 클릭해 주십시오.
- [네트워크 목록] 탭에서 namespace를 확인할 네트워크를 클릭해 주십시오.
- 상세정보의 로드밸런서 이름(Instance No) 값에서 bc로 시작하는 문자열 중 ingress 이후를 제외한 부분이 namespace 입니다.
다음의 변환 도구를 이용하여 1에서 생성한 input.yaml의 내용을 변경합니다.
변환도구 파일 (압축 해제 후 OS 환경에 맞는 파일을 사용하세요)$ ./blockchain-migrtation_darwin_amd64 -r blockchain.kr.private-ncr-ntruss.com -i input.yaml -o output.yaml
변경된 output.yaml 파일을 적용합니다.
$ kubectl apply -f output.yaml -n [namespace]
- 위 작업에 따라 기존에 배포된 노드들은 변경 및 재기동을 수행하며, 그 과정에서 약 1분 가량의 downtime이 발생할 수 있습니다.
- 위 작업을 수행하지 않을 경우, Kubernetes 클러스터의 버전 업그레이드, worker node를 추가하는 등 변경사항이 발생하면 기존 동작에 영향이 있을 수 있습니다.
애플리케이션 개발
Hyperledger Fabric에서 애플리케이션을 개발하는 단계는 다음과 같이 구성됩니다.
1. 체인코드 개발
Hyperledger Fabric에서는 Go, Java, Javascript 3개 언어에 대해 체인코드 개발을 지원하는 라이브러리인 Chaincode Shim API를 제공합니다. 라이브러리는 Hyperledger Fabric의 버전에 따라 차이가 있으므로 블록체인 서비스를 이용할때는 버전에 맞는 라이브러리를 사용해야 합니다. 각 언어별로 버전에 맞는 라이브러리를 선택해서 빌드 환경을 구성하는 방법은 아래 참고 링크 중 체인코드 샘플을 참조해 주십시오.
블록체인에 데이타를 저장하거나 읽기 위한 인터페이스는 ChaincodeStubInterface
입니다. ChaincodeStubInterface
는 putState(key, value)
와 getState(key)
등의 함수를 제공해서 key/value 형식으로 블록체인에 데이타를 저장하도록 지원합니다. 자세한 내용은 아래 참고 링크 중 체인코드 개발 가이드를 참조해 주십시오.
체인코드 개발에 대한 자세한 내용은 다음을 참조해 주십시오.
Hyperledger Fabric 1.4 버전 릴리즈 이후 Go 언어의 Chaincode Shim API는 라이브러리의 경로가 일부 변경되었습니다. 따라서 1.4 버전용 체인코드 샘플에서는 import 구문은 다음의 변경 후 구문으로 변경해 주십시오.
변경 전
import ( "github.com/hyperledger/fabric/core/chaincode/shim" sc "github.com/hyperledger/fabric/protos/peer" )
변경 후
import ( "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-chaincode-go/shimtest" sc "github.com/hyperledger/fabric-protos-go/peer" )
Hyperledger Fabric 2.x 버전에서는 Chaincode Shim API 이외에 Contract API를 제공해서 체인코드 개발을 지원하고 있습니다. Contract API는 Hyperledger Fabric 1.4 버전용 라이브러리도 제공되어 네이버 클라우드의 Blockchain Service에서도 사용할 수 있습니다. 단, Contract API를 이용한 체인코드 샘플들은 Hyperledger Fabric 2.x 버전을 기준으로 작성되어 있으므로 주의해 주십시오.
2. 체인코드(CDS) 패키징
체인코드 개발이 완료되면 CDS 포맷으로 패키징이 필요합니다. CDS는 체인코드의 코드, 이름, 버전과 같은 속성들을 Hyperledger Fabric에서 정의하는 방식이며, 이 CDS를 통해 체인코드 설치를 할 수 있습니다.
CDS 패키지는 Fabric SDK, CLI를 통해서 생성할 수 있습니다.
CDS 패키징에 대한 자세한 사항은 다음을 참조해 주십시오.
이 가이드에서는 fabric-tools 컨테이너를 이용하여 CDS를 생성하는 방법을 예제로 설명합니다.
예제 사전 준비(필수)
이 예제를 수행하기 위해 로컬 환경에 다음의 애플리케이션을 설치해 주십시오.해당 애플리케이션 다운로드 및 자세한 사용법은 링크를 참조해 주십시오.
- Docker 19.03 이상 (https://www.docker.com/products/docker-desktop)
- Git (https://git-scm.com/)
- Go (https://go.dev/)
예제 코드 다운로드
로컬 환경에서 다음 명령어를 수행하여 예제 코드를 다운로드해 주십시오.
$ mkdir -p $GOPATH/src/github.com/hyperledger
$ cd $GOPATH/src/github.com/hyperledger
$ git clone -b v1.4.12 https://github.com/hyperledger/fabric.git
fabric-tools 컨테이너 실행 및 CDS 파일 패키징
다음 명령어를 수행하여 CLI 파일을 포함하고 있는 fabric-tools 컨테이너를 실행해 주십시오.
$ docker run -ti --rm -v $GOPATH/src:/opt/gopath/src hyperledger/fabric-tools:1.4.12 /bin/bash
다음 명령어를 수행하여 fabric-tools 컨테이너 내
$GOPATH
가/opt/gopath
인지 확인하고, 로컬의$GOPATH
경로가 해당 경로에 마운트되었는지 확인해 주십시오.root@073c6694cadb echo $GOPATH /opt/gopath
$GOPATH/src
폴더로 이동한 후 다음 명령어를 수행하여 예제 코드를 CDS 파일로 패키징해 주십시오.root@073c6694cadb: cd $GOPATH/src root@073c6694cadb:/opt/gopath/src# peer chaincode package -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd -v 1.0 mycc.cds 2021-04-27 12:53:18.821 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc 2021-04-27 12:53:18.821 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
peer chaincode package
커맨드를 이용해서 1.0 버전인 CDS 파일을 사용 언어별로 생성하는 예제는 다음과 같습니다.
peer chaincode package [패키지명] -n [체인코드명] -v [버전] -p [체인코드절대경로] -l [체인코드언어]
java
체인코드의 경우peer chaincode package fabcar.v1.cds -n fabcar -v 1.0 -p chaincode/fabcar/java -l java
javascript
체인코드의 경우peer chaincode package fabcar.v1.cds -n fabcar -v 1.0 -p chaincode/fabcar/javascript -l node
go
체인코드의 경우go 체인코드의 경우 -p 값으로 $GOPATH/src의 상대경로를 사용합니다. cp -r chaincode/fabcar/go/* $GOPATH/src/fabcar peer chaincode package fabcar.v1.cds -n fabcar -v 1.0 -p fabcar
- CDS 패키징 완료 후 로컬 내
$GOPATH/src
에mycc.cds
파일이 생성되었는지 확인해 주십시오.
3. 체인코드 설치 및 인스턴스화, 업그레이드
CDS 패키지 파일이 생성되면 Blockchain Service의 콘솔을 이용해 Peer 노드에 설치하고 인스턴스화합니다. 자세한 내용은 다음을 참조해 주십시오.
한 번 인스턴스화된 체인코드는 새로운 버전을 설치하면 다시 인스턴스화하는 대신 업그레이드를 진행합니다. 자세한 내용은 다음을 참조해 주십시오.
4. 애플리케이션 개발, 빌드, 실행
체인코드 인스턴스화가 완료되면 체인코드를 이용해 블록체인에 접근하는 애플리케이션을 개발하고 실행할 수 있습니다.
애플리케이션 개발에 대한 자세한 사항은 다음을 참조해 주십시오.
아래 예시는 1.4 버전을 기반으로 설명되었습니다.
Hyperledger Fabric에서는 체인코드와 마찬가지로 애플리케이션 개발을 위한 라이브러리인 Fabric SDK를 go, java, javascript 3가지 버전으로 제공합니다. Fabric SDK는 1.4 버전과 2.x 버전으로 구분되어 있으며, 1.4 버전을 사용하면 됩니다. 호환성에 이슈가 없는 경우 최신 버전의 SDK를 사용해도 무방합니다.
Fabric SDK는 체인코드를 호출하는 기능 외에도 Peer 노드에 접근해 네트워크의 상세 정보를 얻어오는 기능(service discovery), CA 노드에 접근해 ID를 생성하거나 인증서를 발급받는 기능, 발급받은 인증서를 wallet 파일로 저장하는 기능, 채널을 생성하거나 체인코드를 등록하는 기능 등 다양한 기능을 제공합니다.
이 가이드에서는 애플리케이션 구성 요소를 node.js 예제를 통해 설명합니다.
사전 준비
애플리케이션을 실행하려면 Peer 노드 접속 주소와 Peer 노드에 접근하기 위한 CA(인증서)가 필요합니다. 이 정보들은 Blockchain Service의 콘솔을 통해 다운로드 받을수 있습니다.
- connection profile: Blockchain Service의 Organizations 메뉴에서 다운로드한 파일을
download/connection_profile.json
으로 저장해 주십시오.(MSP 접속 정보 다운로드 참조) - 인증서: Nodes 메뉴에서 내보내기(export)한 파일을
download/user.json
으로 저장해 주십시오. CA 사용자 ID 관리 참조)
콘솔에서 인증서를 다운로드 받지 않고, 애플리케이션 샘플과 같이 CA 서버로부터 직접 인증서를 등록(enroll)해서 지갑(wallet)을 생성할 수도 있습니다.
애플리케이션(javascript) 예제
- 예제를 참고하여 콘솔에서 다운로드한 인증서로 지갑(wallet)을 생성하고, 이를 이용해
fabcar
라는 체인코드를 호출해서 결과를 출력하는 애플리케이션을 작성해 주십시오(query.js
).
/*
* Copyright IBM Corp. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
'use strict';
const { Gateway, Wallets } = require('fabric-network');
const path = require('path');
const fs = require('fs');
async function main() {
try {
// load the network configuration
const ccpPath = path.resolve(__dirname, 'download/connection_profile.json');
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
const mspId = ccp.client.organization;
// load the exported user
const userPath = path.resolve(__dirname, 'download/user.json');
const user = JSON.parse(fs.readFileSync(userPath, 'utf8'));
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = await Wallets.newFileSystemWallet(walletPath);
var identity = await wallet.get(user.name);
if (!identity) {
const x509Identity = {
credentials: {
certificate: Buffer.from(user.cert, 'base64').toString('utf8'),
privateKey: Buffer.from(user.key, 'base64').toString('utf8'),
},
mspId: mspId,
type: 'X.509',
};
await wallet.put(user.name, x509Identity);
identity = await wallet.get(user.name);
}
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccp, {wallet: wallet, identity: user.name, discovery: { enabled: true, asLocalhost: false } });
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('defaultchannel');
// Get the contract from the network.
const contract = network.getContract('fabcar');
// Evaluate the specified transaction.
// queryCar transaction - requires 1 argument, ex: ('queryCar', 'CAR4')
// queryAllCars transaction - requires no arguments, ex: ('queryAllCars')
const result = await contract.evaluateTransaction('queryAllCars');
console.log(`Transaction has been evaluated, result is: ${result.toString()}`);
// Disconnect from the gateway.
await gateway.disconnect();
} catch (error) {
console.error(`Failed to evaluate transaction: ${error}`);
process.exit(1);
}
}
main();
package.json
파일을 다음과 같이 생성해 주십시오.
{
"name": "fabcar",
"version": "1.0.0",
"description": "FabCar application implemented in JavaScript",
"engines": {
"node": ">=8",
"npm": ">=5"
},
"scripts": {
"lint": "eslint ."
},
"engineStrict": true,
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
"fabric-network": "^2.1.0"
}
}
- 다음과 같이 빌드하고 실행해 주십시오.
- 블록체인에 저장된 정보를 출력합니다.
$ npm install
$ node query.js
Transaction has been evaluated, result is: [{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
애플리케이션 (java) 예제
- 콘솔에서 다운로드한 인증서로 wallet을 생성하고, 이를 이용해
fabcar
라는 체인코드를 호출해서 결과를 출력하는 애플리케이션을 작성해 주십시오(ClientApp.java
).
/*
SPDX-License-Identifier: Apache-2.0
*/
package org.example;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.Gateway;
import org.hyperledger.fabric.gateway.Network;
import org.hyperledger.fabric.gateway.Wallet;
import org.hyperledger.fabric.sdk.NetworkConfig;
import org.hyperledger.fabric.sdk.security.CryptoPrimitives;
import javax.json.Json;
import javax.json.JsonObject;
public class ClientApp {
static {
System.setProperty("org.hyperledger.fabric.sdk.service_discovery.as_localhost", "false");
}
public static void main(String[] args) throws Exception {
// Load a file system based wallet for managing identities.
Path walletPath = Paths.get("wallet");
Wallet wallet = Wallet.createFileSystemWallet(walletPath);
// load a CCP
Path networkConfigPath = Paths.get("download", "connection_profile.json");
InputStream is = new FileInputStream(networkConfigPath.toFile());
NetworkConfig ccp = NetworkConfig.fromJsonStream(is);
String mspId = ccp.getClientOrganization().getMspId();
// load the exported user
Path userPath = Paths.get("download", "user.json");
is = new FileInputStream(userPath.toFile());
JsonObject userObject = (JsonObject) Json.createReader(is).read();
String userId = userObject.getString("name");
boolean userExists = wallet.exists(userId);
if (!userExists) {
CryptoPrimitives crypto = new CryptoPrimitives();
Wallet.Identity user = Wallet.Identity.createIdentity(mspId,
new String(Base64.getDecoder().decode(userObject.getString("cert"))),
crypto.bytesToPrivateKey(Base64.getDecoder().decode(userObject.getString("key"))));
wallet.put(userId, user);
}
Gateway.Builder builder = Gateway.createBuilder();
builder.identity(wallet, userId).networkConfig(networkConfigPath).discovery(true);
// create a gateway connection
try (Gateway gateway = builder.connect()) {
// get the network and contract
Network network = gateway.getNetwork("defaultchannel");
Contract contract = network.getContract("fabcar");
byte[] result;
result = contract.evaluateTransaction("queryAllCars");
System.out.println(new String(result));
System.exit(0);
}
}
}
pom.xml
파일을 다음과 같이 생성해 주십시오.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fabcar-java</groupId>
<artifactId>fabcar-java</artifactId>
<version>1.4.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>oss-sonatype</id>
<name>OSS Sonatype</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.hyperledger.fabric</groupId>
<artifactId>fabric-gateway-java</artifactId>
<version>1.4.1</version>
</dependency>
</dependencies>
</project>
- 다음과 같이 빌드하고 실행해 주십시오.
- 블록체인에 저장된 정보가 출력됩니다.
$ mvn compile
$ mvn exec:java -Dexec.mainClass=org.example.ClientApp
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]