[Go lang] ccp & CA - Register & Enroll
register / enroll / ccp / CA / Admin
⭐ 하이퍼레저 패브릭 2.2 ver 기준
‘디앱’ 은 블록체인 네트워크에 있는 특정 체인코드의 특정 기능을 요청해서 실행하면 결과를 받는것이 디앱의 목적이다
-
디앱은 요청하기 전에 디앱은 ‘인증서’ 를 가지고 있어야한다 👉 그래야 로그인을 할수있다
-
디앱은 ‘CA (Certificate Authority)’ 에 인증서를 요청해서 인증서를 받아와야한다
-
‘CA’에 접속할 수 있는 주소를 가지고 있어야하는데
-
블록체인 네트워크를 실행 시키면
peer / orderer / CA
까지 같이 켜진다 -
네트워크를 키면 주소가 결정되는데 이때 다같이 생성된
peer / orderer / CA
주소를 모아서 ‘cpp’ json 파일을 만든다 ⭐ (ccp = abi 와 비슷함) -
디앱은 ‘ccp’ 를 읽어와서 ‘CA’ 에 접속할수있다 (주소를 아니까)
-
‘CA’ 에 접속을 해서 인증서를 받아오고
-
받아온 인증서는 지갑(Wallet) 에 저장한다
-
디앱은 인증서를 꺼내서 ‘인증’을 함과 동시에 / 체인코드를 요청하고 결과를 받는다
준비물 생성 👉 네트워크 구동 👉 채널 조인 👉 앵커피어 설정 👉 체인코드 설치 & 배포
Register & Enroll
관리자의 입장으로서 유저를 등록 👉 Register
‘CA’ 에 관리자 계정을 등록하는 행위를 ‘Register’ 라고 한다
유저의 입장으로는 발급 👉 enroll
등록되어있는 사용자 인증서를 발급 받아오는 행위를 ‘Enroll’ 이라고 한다
-
enrollAdmin 👉 관리자 지갑 생성 👉 인증서받기
-
registerUser 👉 사용자 지갑 생성 👉 인증서받기
-
관리자가 사용자를 등록시킬때 관리자 인증서를 확인
-
관리자가 본인의 권한으로 사용자를 등록해줘야 사용자가 인증서를 발급받을수있다
-
유저 등록을 위해서는 관리자(Admin) 권한이 필요하다
-
관리자의 권한으로 ‘CA’ 에 등록 👉 사용자 인증서 발급
네트워크 동작 👉 네트워크에 맞는 CCP 생성 👉 CCP를 이용하여 CA 접속 👉 필요한 인증서 발급 👉 wallet에 저장 & 꺼내쓰기
⭐ 실제 서비스에서는
회원가입, 핸드폰 인증
등 같은 과정을 거쳐서 인증서를 발급 (Enroll)
예를들어
회사(CA)에 처음 입사했을때 회사 DB에 넣을
나의 개인정보를 최초로 등록하는 과정 👉 Register회사(CA)에 내가 출입카드를 발급요청하면 출입카드를 준다
회사 DB에는 나의 정보가 등록되어있을 것이다
👉 등록되어있는 DB를 기준으로 출입카드를 발급해준다 (Enroll)
출입카드를 분실했어도 DB를 기준으로 재발급이 가능하다
enrollAdmin 코드
- ‘ccp’ 에 접근해서 CA 주소를 찾는 작업
- 지갑 유무 확인 체크 (관리자 권한 체크)
- 관리자 권한으로 인증서 발급 후 지갑에 저장
"use strict";
const FabricCAServices = require("fabric-ca-client");
const { Wallets } = require("fabric-network");
const fs = require("fs");
const path = require("path");
async function main() {
try {
const ccpPath = path.resolve(__dirname, "ccp", "connection-org1.json");
// ccp 파일 json 에 접근 👉 접속할 주소를 찾아야함
const ccp = JSON.parse(fs.readFileSync(ccpPath, "utf8"));
// json을 parse 시킨다
const caInfo = ccp.certificateAuthorities["ca.org1.example.com"];
// json 파일에서 접속할 url 주소를 찾음
const caTLSCACerts = caInfo.tlsCACerts.pem;
// 찾은 url CA 주소
const ca = new FabricCAServices(
caInfo.url,
{ trustedRoots: caTLSCACerts, verify: false },
caInfo.caName
);
const walletPath = path.join(process.cwd(), "wallet");
// wallet 열기 / 없으면 생성 / 현재경로에
const wallet = await Wallets.newFileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
const identity = await wallet.get("admin");
// admin 이라는 인증서가 있는지 확인
if (identity) {
console.log(
'An identity for the admin user "admin" already exists in the wallet'
);
return;
}
// ⭐ CA가 켜질때 admin 하나는 register 된 상태로 켜진다
// 최초의 관리자
const enrollment = await ca.enroll({
enrollmentID: "admin", // 최초 이미 등록되어있는 관리자 아이디
enrollmentSecret: "adminpw", // 관리자 비밀번호
});
const x509Identity = {
credentials: {
certificate: enrollment.certificate, // 관리자권한으로 발급
privateKey: enrollment.key.toBytes(), // 관리자권한으로 발급
},
mspId: "Org1MSP",
type: "X.509",
};
await wallet.put("admin", x509Identity);
// 지갑에 관리자 인증서가 한개 발급되어 저장(put)
console.log(
'Successfully enrolled admin user "admin" and imported it into the wallet'
);
} catch (error) {
console.error(`Failed to enroll admin user "admin": ${error}`);
process.exit(1);
}
}
main();
registerUser 코드
- ‘ccp’ 에 접근해서 CA 주소를 찾는 작업
- 지갑 유무 확인 체크 (관리자 권한 체크)
- 관리자의 권한으로 유저를 등록
"use strict";
const { Wallets } = require("fabric-network");
const FabricCAServices = require("fabric-ca-client");
const fs = require("fs");
const path = require("path");
async function main() {
try {
const ccpPath = path.resolve(__dirname, "ccp", "connection-org1.json"); // ccp 파일 json 에 접근 👉 접속할 주소를 찾아야함
const ccp = JSON.parse(fs.readFileSync(ccpPath, "utf8"));
// json을 parse 시킨다
const caURL = ccp.certificateAuthorities["ca.org1.example.com"].url;
// json 파일에서 접속할 url 주소를 찾음
const ca = new FabricCAServices(caURL); // 찾은 url CA 주소
const walletPath = path.join(process.cwd(), "wallet");
const wallet = await Wallets.newFileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
const userIdentity = await wallet.get("appUser");
if (userIdentity) {
console.log(
'An identity for the user "appUser" already exists in the wallet'
);
return;
}
const adminIdentity = await wallet.get("admin");
// admin(관리자) 권한 불러오기
if (!adminIdentity) {
console.log(
'An identity for the admin user "admin" does not exist in the wallet'
);
console.log("Run the enrollAdmin.js application before retrying");
return;
}
const provider = wallet
.getProviderRegistry()
.getProvider(adminIdentity.type);
const adminUser = await provider.getUserContext(adminIdentity, "admin"); // 관리자권한 생성
const secret = await ca.register(
{
affiliation: "org1.department1", // 소속
enrollmentID: "appUser", // 아이디
role: "client", // 역할(권한)
}, // admin / peer / client 3개중 하나
adminUser // 관리자 권한으로 User 등록
);
//------------ admin (관리자)의 역할 끝
//------------ dapp 에서 조작해야할 영역 👇👇
const enrollment = await ca.enroll({
enrollmentID: "appUser",
enrollmentSecret: secret,
});
const x509Identity = {
credentials: {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
},
mspId: "Org1MSP",
type: "X.509",
};
await wallet.put("appUser", x509Identity);
console.log(
'Successfully registered and enrolled admin user "appUser" and imported it into the wallet'
);
} catch (error) {
console.error(`Failed to register user "appUser": ${error}`);
process.exit(1);
}
}
main();