Writing Your First Application(첫번째 애플리케이션 작성)

[Note]
패브릭 네트워크의 기본 아키텍처에 익숙하지 않은 경우 계속하기 전에 먼저 소개 및 기본 네트워크 구성 설명서를 참조하십시오.

이 섹션에서는 Fabric 앱의 작동 방식을 보여주는 몇 가지 샘플 프로그램을 살펴 보겠습니다.  fabcar 라고 하는 이러한 앱 (그리고 그들이 사용하는 스마트 계약(smart contract ))은 Fabric 기능에 대한 폭 넓은 시연을 제공합니다. 특히 우리는 인증 기관과 상호 작용하고 등록 인증서를 생성하는 프로세스를 보여줄 것이며 그 후에 이러한 ID를 활용하여 장부를 쿼리하고 업데이트 할 것입니다.

우리는 세 가지 주요 단계를 거칩니다.



  1. 개발 환경 설정. 우리의 응용 프로그램은 상호 작용할 네트워크가 필요하기 때문에 신청(registration)/등록(enrollment), 쿼리(queries) 및 업데이트(updates)에 필요한 구성 요소 만 다운로드합니다.
  2. 앱에서 사용할 샘플 스마트 계약(Smart contract)의 매개 변수를 학습합니다. 우리의 현명한 계약에는 다양한 방법으로 원장과 상호 작용할 수있는 다양한 기능이 포함되어 있습니다. 우리는 응용 프로그램이 사용할 기능에 대해 배우기 위해 스마트 계약서(Smart contract)를 조사 할 것입니다.
  3. 원장에서 자산을 쿼리하고 업데이트 할 수 있는 응용 프로그램 개발. 앱 코드 자체 (자바 스크립트로 작성된 앱)에 들어가서 변수를 수동으로 조작하여 다양한 종류의 쿼리와 업데이트를 실행합니다.

이 튜토리얼을 완료 한 후에는 Fabric 네트워크에서 장부 (예 : 피어)와 상호 작용할 수있는 스마트 계약서와 함께 애플리케이션을 프로그래밍하는 방법에 대한 기본적인 이해가 필요합니다.

Setting up your Dev Environment(개발자 환경 설정하기)

첫 번째 네트워크 구축을 통해 이미 실행 한 적이 있다면 dev 환경을 설정하고 함께 제공된 패브릭 샘플과 함께 아티팩트를 다운로드해야합니다. 이 자습서를 실행하려면 현재 수행중인 기존 네트워크를 모두 제거해야합니다. 다음을 실행하여 수행 할 수 있습니다.

./byfn.sh -m down

네트워크 및 응용 프로그램에 대한 개발 환경 및 관련 아티팩트가 없는 경우 전제 조건 페이지를 방문 하여 시스템에 필요한 종속성을 설치했는지 확인하십시오.

다음으로, Hyperledger Fabric Samples 페이지를 방문 하여 제공된 지시 사항을 따르십시오. fabric-samples저장소를 복제 한 후에 이 튜토리얼로 돌아가서 최신의 안정된 Fabric 이미지와 사용 가능한 유틸리티를 다운로드하십시오.

이 시점에서 모든 것이 설치되어야합니다. 저장소 fabcar내의 하위 디렉토리로 이동하여 fabric-samples내부 내용을 살펴보십시오.

cd fabric-samples/fabcar  && ls

다음이 보입니다.

enrollAdmin.js     invoke.js       package.json    query.js        registerUser.js startFabric.sh

시작하기 전에 우리는 또한 약간의 정리 작업이 필요합니다.  오래되거나 활성되어 있는 컨테이너를 강제 종료하려면 다음 명령을 실행하십시오.

docker rm -f $(docker ps -aq)

캐시 된 네트워크를 지우십시오.

# Press 'y' when prompted by the command

docker network prune

마지막으로이 튜토리얼을 이미 실행 한 경우 fabcar스마트 계약 의 기본 체인 코드 이미지를 삭제할 수도 있습니다 . 이 콘텐츠를 처음으로 사용하는 사용자는 시스템에 이 체인 코드 이미지가 없습니다.

docker rmi dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba

Install the clients & launch the network( 클라이언트 설치 및 네트워크 시작)

[Note]
다음 지침에서는 fabric-samples repo의 로컬 복제본 내의 fabcar 하위 디렉토리에 있어야합니다. 이 튜토리얼의 나머지 부분에 대해서는이 서브 디렉토리의 루트에 남아 있어야한다.

다음 명령을 실행하여 응용 프로그램에 대한 Fabric 종속성을 설치하십시오. 우리는 우리의 앱 (들)이 CA 서버와 통신하고 신원 자료(identity material)를 검색 할 수있게 해주는 fabric-ca-client에 관심을 가지고 있으며 신원 자료를 로드하고 피어 및 ordering service 와 대화할 수 있는  fabric-client를 사용합니다.

npm install

startFabric.sh  쉘 스크립트를 사용하여 네트워크를 시작하십시오. 이 명령은 다양한 Fabric 엔티티를 회전시키고 Golang으로 작성된 체인 코드 용 스마트 계약 컨테이너를 시작합니다.

./startFabric.sh

또한 Node.js로 작성된 체인 코드에 대해이 자습서를 실행할 수 있습니다 . 이 경로를 찾으려면 다음 명령을 대신 실행하십시오.

./startFabric.sh node

How Applications Interact with the Network(응용 프로그램이 네트워크와 상호 작용하는 방법)

fabcar네트워크의 구성 요소(및 배포 방법)와 응용 프로그램이 세부적인 수준에서 구성 요소와 상호 작용하는 방법에 대한 자세한 내용은 Fabcar 네트워크 이해를 참조하십시오.

응용 프로그램을 보는 데 더 관심이있는 개발자는 물론 응용 프로그램이 어떻게 구성되어 있는지보기 위해 코드 자체를 살펴 보는 등의 작업을 계속해야합니다. 현재 가장 중요한 점은 응용 프로그램이 소프트웨어 개발 키트 (SDK)를 사용하여 원장에 대한 쿼리 및 업데이트를 허용하는 API에 액세스한다는 것입니다.

Enrolling the Admin User(관리 사용자 등록)

[Note]
다음 두 섹션에는 인증 기관과의 통신이 포함됩니다. 다가오는 프로그램을 실행할 때 CA 로그를 스트리밍하는 것이 유용 할 수 있습니다.

CA 로그를 스트리밍하려면 터미널을 분할하거나 새 쉘을 열고 다음을 실행하십시오.

docker logs -f ca.example.com

이제 fabcar콘텐츠로 터미널로 돌아 가세요 ...

네트워크를 시작했을 때 관리자 인 admin이 우리의 인증 기관에 등록되었습니다. 이제 CA 서버에 등록 호출을 보내고 이 사용자의 등록 인증서 (eCert)를 검색해야합니다. 등록 세부 정보는 여기에서 다루지 않겠지만 SDK 및 확장 프로그램에서 관리자 용 사용자 개체를 구성하기 위해이 인증서가 필요하다고 말하는 것으로 충분합니다. 그런 다음이 admin 객체를 사용하여 새 사용자를 등록하고 등록합니다. 관리자 등록 호출을 CA 서버로 보냅니다.

node enrollAdmin.js

이 프로그램은 인증서 서명 요청 (CSR)을 호출하고 궁극적으로 eCert 및 주요 자료를이 프로젝트의 루트에 새로 생성 된 폴더  – hfc-key-store –로 출력합니다. 그러면 Google Apps는 다양한 사용자를 위해 ID 개체를 만들거나 로드해야 할 때이 위치를 찾습니다.

Register and Enroll user1 (user1 의 신청과 등록)

새로 생성 된  admineCert를 사용하여 이제 CA 서버와 통신하여 새 사용자를 등록하고 등록합니다. 이 사용자 – user1 –는 원장을 쿼리하고 업데이트 할 때 사용하는 ID입니다. 새로운 사용자 (즉,이 사용자는 등록 기관의 역할을 맡고 있음)에 대한 등록 및 등록 요청을 발행하는 것이 관리자 ID임을 유의해야합니다. 등록자를 보내고  user1 에 대한 호출을 등록하십시오.

node registerUser.js

관리자 등록과 마찬가지로이 프로그램은 CSR을 호출하고 키와 eCert를 hfc-key-store 하위 디렉토리로 출력합니다. 이제– admin & user1이라는 두 명의 개별 사용자에 대한 신원 자료가 생겼습니다. 장부와 상호 작용할 시간입니다.

Querying the Ledger(원장 조회)

쿼리는 원장에서 데이터를 읽는 방법입니다. 이 데이터는 일련의 키 - 값 쌍으로 저장되며 단일 키, 여러 키의 값을 쿼리 할 수 ​​있습니다. 또는 - 원장이 JSON과 같은 풍부한 데이터 저장 형식으로 작성된 경우 복잡한 키를 검색 할 수 있습니다 ( 예를 들어 특정 키워드가 포함 된 모든 자산을 찾습니다. )

이는 쿼리가 작동하는 방식을 나타냅니다.



먼저  query.js프로그램을 실행하여 원장에있는 모든 자동차의 목록을 반환합시다. 두 번째 ID 인 – user1 –을이 애플리케이션의 서명 엔티티로 사용합니다. 우리 프로그램의 다음 행은  user1을 서명자로 지정합니다.

fabric_client.getUserContext('user1', true);

user1 등록 자료는  hfc-key-store하위 디렉토리에 이미 배치되어 있으므로 응용 프로그램에 해당 ID를 부여하기 만하면됩니다. 정의 된 사용자 객체를 사용하여 이제 장부에서 읽는 작업을 진행할 수 있습니다. 모든 자동차  queryAllCars 를 쿼리하는 함수는 앱에 미리 로드되어 있으므로 간단히 프로그램을 실행할 수 있습니다.

node query.js

다음과 같이 반환되어야 합니다.

Successfully loaded user1 from persistence
Query has completed, checking results
Response is  [{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},
{"Key":"CAR1",   "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},
{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},
{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},
{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},
{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"205","owner":"Michel"}},
{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},
{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},
{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},
{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]

이들은 10 대입니다. Adriana 소유의 검은 색 Tesla Model S, Brad 소유의 빨간색 포드 머스탱, Pari 소유의 보라색 Fiat Punto 등등. 원장은 키 - 값을 기반으로하며 구현시 키는  CAR0-  CAR9입니다. 이것은 특히 중요하게 될 것입니다.

이 프로그램을 자세히 살펴 보겠습니다. 편집기 (예 : atom 또는 visual studio)를 사용하고 query.js 를 엽니 다.

응용 프로그램의 초기 섹션에서는 채널 이름, 인증서 저장소 위치 및 네트워크 끝점과 같은 특정 변수를 정의합니다. 우리의 샘플 앱에서는 이러한 변수가 구워졌지만 실제 앱에서는 이러한 변수가 앱 개발자에 의해 지정되어야합니다.

var channel = fabric_client.newChannel('mychannel');
var peer = fabric_client.newPeer('grpc://localhost:7051');
channel.addPeer(peer);

var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store');
console.log('Store path:'+store_path);
var tx_id = null;

이것은 쿼리를 구성하는 청크입니다.

// queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
// queryAllCars chaincode function - requires no arguments , ex: args: [''],
const request = {
  //targets : --- letting this default to the peers assigned to the channel
  chaincodeId: 'fabcar',
  fcn: 'queryAllCars',
  args: ['']
};

응용 프로그램이 실행되면 피어에서  fabcar chaincode를 호출하고 그 안에  queryAllCars함수를 실행 한 다음 인수를 전달하지 않았습니다.

스마트 계약에서 사용 가능한 기능을 살펴 보려면 fabric-samples 의 루트에서 chaincode/fabcar/go  하위 디렉토리로 이동 한 다음 편집기에서 fabcar.go를여십시오.

[Note]
이러한 동일한 기능은 Node.js 버전의 fabcarchaincode 에서 정의됩니다.

initLedgerqueryCarqueryAllCarscreateCar,   changeCarOwner와 같이 호출 할 수 있는 함수가 있음을 알 수 있습니다.

queryAllCars함수가 장부와 어떻게 상호 작용하는지 확인하기 위해 함수를 자세히 살펴 보겠습니다.

func (s *SmartContract) queryAllCars(APIstub shim.ChaincodeStubInterface) sc.Response {

      startKey := "CAR0"
      endKey := "CAR999"

      resultsIterator, err := APIstub.GetStateByRange(startKey, endKey)

queryAllCars의 범위를 정의합니다. CAR0와 CAR999 사이의 모든 자동차 (모든 키가 올바르게 태그되었다고 가정 할 때 1,000 대)가 쿼리에 의해 반환됩니다.

다음은 앱이 chaincode에서 다른 기능을 호출하는 방법을 나타낸 것입니다. 각 함수는 chaincode shim 인터페이스에서 사용 가능한 API에 대해 코딩되어야하며 스마트 계약 컨테이너가 피어 원장과 적절하게 인터페이스 할 수 있습니다.



queryAllCars 함수와  createCar 함수를 볼 수 있습니다. 그러면 createCar 함수를 통해 원장을 업데이트하고 궁극적으로 새로운 블록을 체인에 추가 할 수 있습니다.

하지만 먼저  query.js 프로그램으로 돌아가서 생성자 요청을 편집하여  CAR4를 쿼리합니다.  query.js의 함수를  queryAllCars에서  queryCar로 변경하고  CAR4를 특정 키로 전달하여이를 수행합니다.

query.js 프로그램은 이제 다음과 같이 보입니다.

const request = {
  //targets : --- letting this default to the peers assigned to the channel
  chaincodeId: 'fabcar',
  fcn: 'queryCar',
  args: ['CAR4']
};

프로그램을 저장하고 fabcar디렉토리로 다시 이동하십시오 . 이제 프로그램을 다시 실행하십시오.

node query.js

다음을 보아야합니다.

{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}

돌아가서 전에 모든 차량을 질의 한 결과를 보면 CAR4 가 Adriana의 검정색 Tesla 모델 S임을 알 수 있습니다.이 모델은 여기에 반환 된 결과입니다.

queryCar 함수를 사용하여 모든 키 (예 : CAR0)에 대해 쿼리하고 해당 자동차와 관련된 모든 제조사, 모델, 색상 및 소유자를 가져올 수 있습니다.

좋습니다. 이 시점에서 스마트 컨트렉트의 기본 쿼리 기능과 쿼리 프로그램의 소수의 매개 변수에 익숙해야합니다.

Updating the Ledger(원장 업데이트)

이제는 원장 쿼리를 수행하고 약간의 코드를 추가 했으므로 원장을 업데이트 할 준비가되었습니다. 우리가 할 수있는 많은 잠재적인 업데이트가 있지만 자동차를 만드는 것으로 시작합시다.

아래에서 우리는 이 과정이 어떻게 작동하는지 볼 수 있습니다. 업데이트가 제안되고 승인된 다음 응용 프로그램으로 돌아가서 응용 프로그램에 보내지고 모든 피어의 원장에게 작성되고 순서가 정해집니다.

원장에 대한 우리의 첫 번째 업데이트는 새 차를 만드는 것입니다. 우리는 invoke.js업데이트를 위해 사용할 별도의 자바 스크립트 프로그램을 가지고 있습니다. 쿼리와 마찬가지로 편집기를 사용하여 프로그램을 열고 호출을 구성하는 코드 블록으로 이동합니다.

// createCar chaincode function - requires 5 args, ex: args: ['CAR12', 'Honda', 'Accord', 'Black', 'Tom'],
// changeCarOwner chaincode function - requires 2 args , ex: args: ['CAR10', 'Barry'],
// must send the proposal to endorsing peers
var request = {
  //targets: let default to the peer assigned to the client
  chaincodeId: 'fabcar',
  fcn: '',
  args: [''],
  chainId: 'mychannel',
  txId: tx_id
};

createCar또는changeCarOwner의 두 함수 중 하나를 호출 할 수 있습니다. 먼저 빨간색 Chevy Volt를 만들어 Nick이라는 소유자에게 주자. 우리는 원장 위에서  CAR9 를 사용하기 때문에 여기서 CAR10을 식별 키로 사용합니다. 이 코드 블록을 다음과 같이 편집하십시오.

var request = {
  //targets: let default to the peer assigned to the client
  chaincodeId: 'fabcar',
  fcn: 'createCar',
  args: ['CAR10', 'Chevy', 'Volt', 'Red', 'Nick'],
  chainId: 'mychannel',
  txId: tx_id
};

저장하고 프로그램을 실행하십시오.

node invoke.js

ProposalResponse및 약속과 관련하여 터미널에 약간의 출력이 있을 것입니다. 그러나 우리가 염려하는 것은이 메시지입니다.

The transaction has been committed on peer localhost:7053

이 트랜잭션이 기록되었는지 확인하려면 query.js로 돌아가서 인수를  CAR4에서  CAR10으로 변경하십시오.

즉, 다음과 같이 변경하십시오.

const request = {
  //targets : --- letting this default to the peers assigned to the channel
  chaincodeId: 'fabcar',
  fcn: 'queryCar',
  args: ['CAR4']
};

다시 저장하고 다음 쿼리를 수행하십시오.

node query.js

어떤 결과가 나옵니까?

Response is  {"colour":"Red","make":"Chevy","model":"Volt","owner":"Nick"}

축하. 당신은 차를 만들었습니다!

이제 우리는 그렇게 해 Nick 이 기분이 좋고 데이브 (Dave)라는 누군가에게 시보레 볼트 (Chevy Volt)를 주고 싶다고 합시다.

이를 수행하려면 invoke.js  로 돌아가서 함수를  createCar에서  changeCarOwner로 변경하고 다음과 같은 인수를 입력하십시오.

var request = {
  //targets: let default to the peer assigned to the client
  chaincodeId: 'fabcar',
  fcn: 'changeCarOwner',
  args: ['CAR10', 'Dave'],
  chainId: 'mychannel',
  txId: tx_id
};

첫번째 논쟁 – CAR10 –는 소유자를 바꿀 차를 반영합니다. 두 번째 인수 인 – Dave –는 자동차의 새 소유자를 정의합니다.

저장하고 프로그램을 다시 실행하십시오.

node invoke.js

이제 장부에 다시 ​​쿼리하여 Dave가 이제 CAR10키 와 연결되었는지 확인하십시오 .

node query.js

이 결과를 반환해야합니다.

Response is  {"colour":"Red","make":"Chevy","model":"Volt","owner":"Dave"}

CAR10의 소유권이 Nick에서 Dave로 변경되었습니다.

[Note]
실제 응용 프로그램에서 chaincode에는 액세스 제어 논리가 있을 수 있습니다. 예를 들어 특정 승인 된 사용자만 새 자동차를 만들 수 있으며 자동차 소유자만 자동차를 다른 사람에게 양도 할 수 있습니다.

Summary(요약)

이제는 몇 가지 쿼리와 업데이트를 수행 했으므로 응용 프로그램이 네트워크와 상호 작용하는 방식을 이해해야합니다. 스마트 계약, API 및 SDK가 쿼리 및 업데이트에서 수행하는 역할의 기본 사항을 확인했으며 다른 비즈니스 작업 및 작업을 수행하는 데 사용할 수있는 다양한 종류의 응용 프로그램에 대한 느낌을 알고 있어야합니다.

후속 문서에서는 스마트 계약을 실제로 작성하는 방법과 이러한 낮은 수준의 응용 프로그램 기능 중 일부를 활용할 수있는 방법 (특히 신원 및 멤버십 서비스 관련)을 배우게됩니다.

Additional Resources(추가 자료)

Hyperledger Fabric Node SDK Repo는 더 자세한 문서 및 샘플 코드를 위한 훌륭한 리소스입니다. 패브릭 커뮤니티 및 Hyperledger Rocket Chat의 구성 전문가에게 문의 할 수도 있습니다.


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

+ Recent posts