Skip to content

Commit

Permalink
#29 Feat: 신원증명 fabric Service & Controller 로직 작성
Browse files Browse the repository at this point in the history
  • Loading branch information
pjhcsols committed Oct 16, 2024
1 parent f4c3f41 commit 65b2a9e
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 4 deletions.
1 change: 0 additions & 1 deletion .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions web3-credential-server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dependencies {
implementation 'org.springframework.security:spring-security-crypto'

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation 'org.hyperledger.fabric:fabric-gateway-java:2.2.0'

}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,40 @@
package web3.controller.Identity;public class IdentityController {
package web3.controller.Identity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import web3.service.Identity.IdentityService;
import web3.service.dto.Identity.StudentCertificationDto;

@RestController
@RequestMapping("/api/certifications")
public class IdentityController {

private final IdentityService identityService;

@Autowired
public IdentityController(IdentityService identityService) {
this.identityService = identityService;
}

@PostMapping("/register")
public ResponseEntity<String> registerCertification(@RequestBody StudentCertificationDto certificationDto) {
try {
identityService.registerStudentCertification(certificationDto);
return ResponseEntity.ok("재학증이 성공적으로 등록되었습니다.");
} catch (Exception e) {
return ResponseEntity.status(500).body("재학증 등록 중 오류 발생: " + e.getMessage());
}
}

@GetMapping("/{key}")
public ResponseEntity<StudentCertificationDto> getCertification(@PathVariable String key) {
try {
StudentCertificationDto certificationDto = identityService.queryStudentCertification(key);
return ResponseEntity.ok(certificationDto);
} catch (Exception e) {
return ResponseEntity.status(404).body(null);
}
}
}

Original file line number Diff line number Diff line change
@@ -1,2 +1,113 @@
package web3.service.Identity;public class IdentityService {
package web3.service.Identity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import web3.service.dto.Identity.StudentCertificationDto;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeoutException;

import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.ContractException;
import org.hyperledger.fabric.gateway.Gateway;
import org.hyperledger.fabric.gateway.Network;
import org.hyperledger.fabric.gateway.Wallet;
import org.hyperledger.fabric.gateway.Wallets;

@Service
public class IdentityService {
private static final Logger logger = LoggerFactory.getLogger(IdentityService.class);
private Gateway gateway;
private Network network;

public IdentityService() {
try {
// Wallet 설정 및 connection.yaml 로드
Path walletPath = Paths.get("wallet");
Wallet wallet = Wallets.newFileSystemWallet(walletPath);

// InputStream을 통해 connection.yaml 로드
InputStream networkConfigStream = new ClassPathResource("connection.yaml").getInputStream();

// "admin" ID 확인
if (wallet.get("admin") == null) {
throw new IllegalArgumentException("Identity 'admin' not found in wallet.");
}

Gateway.Builder builder = Gateway.createBuilder();
builder.identity(wallet, "admin").networkConfig(networkConfigStream).discovery(true);

this.gateway = builder.connect();
this.network = gateway.getNetwork("mychannel");
logger.info("블록체인 네트워크에 성공적으로 연결되었습니다.");
} catch (IOException e) {
logger.error("블록체인 네트워크 연결 실패: {}", e.getMessage());
throw new RuntimeException("블록체인 네트워크 초기화 실패", e);
}
}


// 재학증 등록
public void registerStudentCertification(StudentCertificationDto certificationDto) {
// 블록체인에 저장할 StudentCertification 데이터 형식 생성
String certificationData = String.format("email:%s/univName:%s/univ_check:%b",
certificationDto.getEmail(),
certificationDto.getUnivName(),
certificationDto.isUnivCheck());

// 블록체인에 데이터 저장
try {
putDataOnBlockchain(certificationDto.getKey(), certificationData);
} catch (ContractException | TimeoutException | InterruptedException e) {
logger.error("체인코드 트랜잭션 제출 중 오류 발생: {}", e.getMessage());
throw new RuntimeException("블록체인에 데이터 등록 실패", e); // 언체크 예외
}
}

// 재학증 조회
public StudentCertificationDto queryStudentCertification(String key) {
// 블록체인에서 데이터 조회
String data;
try {
data = getDataFromBlockchain(key);
} catch (ContractException | TimeoutException e) {
logger.error("체인코드 데이터 조회 중 오류 발생: {}", e.getMessage());
throw new RuntimeException("블록체인 데이터 조회 실패", e); // 언체크 예외
}

if (data == null) {
throw new IllegalArgumentException("재학증이 발견되지 않았습니다."); // 언체크 예외
}

// 데이터 파싱
String[] parts = data.split("/");
String email = parts[0].split(":")[1];
String univName = parts[1].split(":")[1];
boolean univCheck = Boolean.parseBoolean(parts[2].split(":")[1]);

return new StudentCertificationDto(key, email, univName, univCheck);
}

private void putDataOnBlockchain(String key, String data) throws ContractException, TimeoutException, InterruptedException {
submitTransaction("putData", key, data);
}

private String getDataFromBlockchain(String key) throws ContractException, TimeoutException {
return evaluateTransaction("getData", key);
}

private void submitTransaction(String functionName, String... args) throws ContractException, TimeoutException, InterruptedException {
byte[] result = this.network.getContract("certification").submitTransaction(functionName, args);
logger.info("트랜잭션이 제출되었습니다: " + new String(result));
}

private String evaluateTransaction(String functionName, String... args) throws ContractException, TimeoutException {
byte[] result = this.network.getContract("certification").evaluateTransaction(functionName, args);
return new String(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public Mono<String> sendCertificationRequest(String email, String univName) {
}

// 인증 코드 검증 메서드
// 검증 완료되면 사용자 초기화 후 지갑 생성 후 지갑 id를 포함해서 재학증_walletId_0을 저장한다
// 재학증을 새로 등록 할때마다 -> 재학증_walletId_0 -> 재학증_walletId_1 -> 재학증_walletId_2 처럼 +1씩 증가되어서 블록에 키로 저장됨
public Mono<String> verifyCertificationCode(String email, String univName, int code) {
String jsonRequest = "{\n" +
" \"key\": \"" + CERT_KEY + "\",\n" +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,48 @@
package web3.service.dto.Identity;public class StudentCertificationDto {
package web3.service.dto.Identity;

public class StudentCertificationDto {
private String key; //재학증_walletId
private String email;
private String univName;
private boolean univCheck;

public StudentCertificationDto(String key, String email, String univName, boolean univCheck) {
this.key = key;
this.email = email;
this.univName = univName;
this.univCheck = univCheck;
}

// Getters and Setters
public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getUnivName() {
return univName;
}

public void setUnivName(String univName) {
this.univName = univName;
}

public boolean isUnivCheck() {
return univCheck;
}

public void setUnivCheck(boolean univCheck) {
this.univCheck = univCheck;
}
}

0 comments on commit 65b2a9e

Please sign in to comment.