하이퍼레저 패브릭 - Writing Your First Application

choko's avatar
Jun 29, 2024
하이퍼레저 패브릭 - Writing Your First Application
 
  • 이번 튜토리얼 에서는 자바스크립트 체인코드를 사용한다.
  • Fabric 애플리케이션이 블록체인 네트워크와 상호작용하는 방법을 소개한다. 이 튜토리얼 에서는 Fabric SDK를 사용한 샘플 프로그램을 이용한다. 스마트 컨트랙트 API를 사용하여 ledger를 invoke, update하는 스마트 컨트랙트를 호출한다. 또한 샘플 프로그램과 인증 기관 사이에는 X.509 인증서를 생성한다.
 
네트워크 실행 및 체인코드 delpoy - 2 peer, 1 orderer, 2Org
./network.sh up createChannel -c mychannel -ca ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-javascript/ -ccl javascript
 
 

1, Admin 등록

async function main() { try { // 채널 path 설정 const ccp = buildCCP(); // 채널 구성에 따라 ca 클라이언트 인스턴스 빌드 const caClient = buildCAClient(FabricCAServices, ccp); // 사용자의 지갑 설정 const wallet = await buildWallet(Wallets, walletPath); // 실제 애플리케이션에서, admin 등록은 한 번만 실행된다. await enrollAdmin(caClient, wallet);
 

2, 애플리케이션 사용자 등록

// 애플리케이션에 사용자가 추가될 때 호출 await registerAndEnrollUser(caClient, wallet, mspOrg1, org1UserId, 'org1.department1');
 

3, 애플리케이션의 channel 및 smart contract 연결 준비

자격 증명이 가능한 애플리케이션 사용자는 channel, smart contract 이름에 대한 참조를 얻은 후 체인코드 기능을 호출할 수 있다. → Gateway 사용
// Gateway 인스턴스 생성 // 실제 애플리케이션에서는 사용자에 대한 검증이 완료된 후에 이루어짐 const gateway = new Gateway(); try { // Gateway 인스턴스 셋업, 이제 이 유저는 fabric network와 연결할 수 있고, transaction과 query를 보낼 수 있다. // 이 게이트웨이로 보내진 모든 트랜잭션은 wallet에 저장된 crendentials를 이용하여 서명된다. await gateway.connect(ccp, { wallet, identity: userId, discovery: {enabled: true, asLocalhost: true} // using asLocalhost as this gateway is using a fabric network deployed locally }); // smart contract가 배포된 채널을 기반으로 네트워크 인스턴스를 구축 const network = await gateway.getNetwork(channelName); // 네트워크로부터 contract를 가져온다. const contract = network.getContract(chaincodeName);
 

4, 애플리케이션은 일부 sample data로 ledger를 초기화 시킨다.

submitTransaction() 함수로 InitLedger 함수를 호출하여, Ledger를 일부 샘플 데이터로 초기화 시킬 수 있다.
// 이 유형의 트랜잭션은 애플리케이션이 처음 시작할 때 한 번만 실행된다. // 체인코드가 업데이트 될 때에는 실행되지 않는다. console.log('\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger'); await contract.submitTransaction('InitLedger'); console.log('*** Result: committed');
InitLedger 예시 → Ledger에 여섯개의 asset이 생성된 상태로 시작된다.
async InitLedger(ctx) { const assets = [ { ID: 'asset1', Color: 'blue', Size: 5, Owner: 'Tomoko', AppraisedValue: 300, }, { ID: 'asset2', Color: 'red', Size: 5, Owner: 'Brad', AppraisedValue: 400, }, { ID: 'asset3', Color: 'green', Size: 10, Owner: 'Jin Soo', AppraisedValue: 500, }, { ID: 'asset4', Color: 'yellow', Size: 10, Owner: 'Max', AppraisedValue: 600, }, { ID: 'asset5', Color: 'black', Size: 15, Owner: 'Adriana', AppraisedValue: 700, }, { ID: 'asset6', Color: 'white', Size: 15, Owner: 'Michel', AppraisedValue: 800, }, ]; for (const asset of assets) { asset.docType = 'asset'; await ctx.stub.putState(asset.ID, Buffer.from(JSON.stringify(asset))); console.info(`Asset ${asset.ID} initialized`); } }
 

5, 애플리케이션은 각 체인코드 기능을 호출한다.

// GetAllAssets 호출 let result = await contract.evaluateTransaction('GetAllAssets'); console.log(`*** Result: ${prettyJSONString(result.toString())}`); // CreateAsset 호출 await contract.submitTransaction('CreateAsset', 'asset13', 'yellow', '5', 'Tom', '1300'); console.log('*** Result: committed'); // GetAllAssets 정의 // GetAllAssets returns all assets found in the world state. async GetAllAssets(ctx) { const allResults = []; // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace. const iterator = await ctx.stub.getStateByRange('', ''); let result = await iterator.next(); while (!result.done) { const strValue = Buffer.from(result.value.value.toString()).toString('utf8'); let record; try { record = JSON.parse(strValue); } catch (err) { console.log(err); record = strValue; } allResults.push({ Key: result.value.key, Record: record }); result = await iterator.next(); } return JSON.stringify(allResults); } // CreateAsset 정의 // CreateAsset issues a new asset to the world state with given details. async CreateAsset(ctx, id, color, size, owner, appraisedValue) { const asset = { ID: id, Color: color, Size: size, Owner: owner, AppraisedValue: appraisedValue, }; return ctx.stub.putState(id, Buffer.from(JSON.stringify(asset))); }
Share article

Tom의 TIL 정리방