Hyperledger fabric 에서 express에 허가를 해줘 구축된 fabric-chaincode에 접근할 수 있도록 목표를 세웠다.
Hyperledger 예제를 통해 체인코드 배포, 테스트 네트워크 구축 등을 해봤지만 실질적으로 fabric 네트워크를 어떻게 접근 해야될지 막막했다.
그래서 일단 test-network의 코드를 통해 gateway를 구축하고 연결해 봤다.
1. 필요한 코드들 분류
먼저 fabric-samples 폴더를 설치해야한다.
하이퍼 레저 공식 github에서 클론 해오면 된다.
내가 사용할 폴더는 test-network, asset-transfer-basic,test-application/javascript 로 총 3개의 폴더를 사용할 것이다.
test-network 로 네트워크 구축, test-application/javascript에서 express에 권한부여, asset-trnasfer-basic에서는 chaincode 작성 및 express와 연결이라고 생각했다.
2. network 구축
튜토리얼을 해본 사람은 도커가 이미 깔려있을수 있다.
test-network 폴더로 이동하여 도커와 바이너리를 깔아줘야 한다.
./network.sh up createChannel -c mychannel -ca
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-javascript -ccl javascript
코드를 입력하여 network.sh 이라는 쉘을 실행 시켜 준다.
위 코드는 CA 도커를 띄우고 체인코드를 설치하고 채널을 만들어 네트워크를 구축하는 것이다.
언어는 javascript를 사용하였다.
3. gateway 코드 작성
asset-transfer-basic/application-javascript/index.js 를 보면 gateway를 구축한 main함수를 볼 수 있다.
여기의 main함수에는 예시로 체인코드까지 작성되어 있다.
여기에 작성된 contract를 export하여 express 서버에서 require로 contract를 불러오려고 한다.
contract만 불러온다면 이걸로 체인코드를 실행시켜 fabric-network에 연결할 수 있는것이다.
gateway구축 전 먼저 필요한 라이브러리를 설치해야 한다.
npm i fabric-network
npm i fabric-ca-client
게이트웨이 구축 함수
나는 폴더를 따로 빼서 경로가 다를수 있다. 경로부분만 수정하면 될것이다.
async function GateWay() {
const { Gateway, Wallets } = require("fabric-network");
const FabricCAServices = require("fabric-ca-client");
const path = require("path");
const {
buildCAClient,
registerAndEnrollUser,
enrollAdmin,
} = require("../fabric-network/test-application/javascript/CAUtil.js");
const {
buildCCPOrg1,
buildWallet,
} = require("../fabric-network/test-application/javascript/AppUtil.js");
const channelName = "mychannel";
const chaincodeName = "basic";
const mspOrg1 = "Org1MSP";
const walletPath = path.join(__dirname, "wallet");
const org1UserId = "appUser";
async function main() {
let contract;
try {
const ccp = buildCCPOrg1();
const caClient = buildCAClient(
FabricCAServices,
ccp,
"ca.org1.example.com",
);
const wallet = await buildWallet(Wallets, walletPath);
await enrollAdmin(caClient, wallet, mspOrg1);
await registerAndEnrollUser(
caClient,
wallet,
mspOrg1,
org1UserId,
"org1.department1",
);
const gateway = new Gateway();
try {
await gateway.connect(ccp, {
wallet,
identity: org1UserId,
discovery: { enabled: true, asLocalhost: true },
});
const network = await gateway.getNetwork(channelName);
contract = network.getContract(chaincodeName);
} finally {
}
} catch (error) {
console.error(`******** FAILED to run the application: ${error}`);
}
return contract;
}
const contract = await main();
return contract;
}
module.exports = GateWay;
이 gateway 함수를 express 서버가 열리면 실행하고 contract를 export하여 각 라우터에서 contract를 끌어다 쓰도록 하려고 했다.
4. express와 연결
express 서버를 실행시키는 app.js
//컨트랙트 설정
Gateway()
.then((result) => {
const contract = result;
module.exports.contract = contract;
module.exports.prettyJSONString = function prettyJSONString(inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
};
// 라우터 사용을 여기 넣은 이유 : contract를 exports한 후 라우터를 연결해야 하기 때문에 - 밖에 꺼내면 contract에 undefined가 담김
// 라우터 사용
const routers = require("../routers");
Object.values(routers).forEach((router) => {
app.use(router);
});
console.log("contract연결 완료");
})
.catch((err) => {
console.log(`contract 연결 오류 : ${err}`);
});
이 코드를 작성하기전 문제는 동기 처리였다.
gateway를 구축하는데 시간이 걸리기 때문에 동기 처리를 해주어 gateway함수의 contract가 export 된 후 값이 있는 contract를 갖다 써야 했다.
그래서 then 함수 안에서 export를 할 수 있다는 것을 이때 알았다. 혹시나 하고 해봤는데 되었다.
contract를 export 한 후 router를 실행시켰다.
5. contract 사용
const { contract, prettyJSONString } = require("app");
const reportData = await contract.submitTransaction("ReadAsset", reportId);
'개발 > HyperLedger' 카테고리의 다른 글
[HyperLedger] 네트워크, MSP, Peer (0) | 2023.02.14 |
---|---|
[HyperLedger] The odering service (0) | 2023.01.13 |
[HyperLedger] Fabric 네트워크의 구성 방식 (0) | 2023.01.08 |