본문 바로가기
Programming

[회고록] 코드스테이츠 블록체인 파이널 프로젝트 완수 후기

by 개발자 염상진 2022. 9. 30.

 

코드스테이츠 블록체인 파이널 프로젝트 완료

 

 

한달의 기간이 주어졌던 파이널 프로젝트가 드디어 완료되었습니다. 프로젝트 주제는 4주동안 퍼블릭 블록체인을 활용한 DID 서비스를 제작했습니다.

팀장을 포함한 총 4명의 팀원이 구성되었고, 중간에 1명이 잠수를 타버려서 결국 한명 분은 제외하고 남은 3명이서 Backend, Frontend, Smart Contract 부분으로 Role을 나눠서 프로젝트를 진행했습니다. 프로젝트 진행하면서 꼭 1명씩은 잠수를 타버리는건 질량 보존의 법직 같은건가요?

더 최악인건 잠수탄 사람이 일부 Role을 받은 상황에서 잠수를 타버려 구현하고자 했던 기능 자체를 구현 못하는 상황에 이르게 되었습니다. 결국 해당 부분은 차후 개선하기로 표시하고, 구현 하지 못한채로 발표에 임하게 되었습니다. 

 

 

 

 

 

 

[회고록] 코드스테이츠 프로젝트 3 시작 (DID 인증 서비스)

아쉬웠던 프로젝트 2를 뒤로하고, 바로 프로젝트 3이 시작되었다. 팀 빌딩을 하고 이번에는 DID와 Klaytn을 이용한 탈중앙화 인증 서비스를 주제로 프로젝트에 참여하게 되었다. 코드스테이츠 UR Cla

about-tech.tistory.com

 

 

[회고록] 코드스테이츠 프로젝트 DID 인증 서비스의 가치는?

2022.09.01 - [Blockchain] - [회고록] 코드스테이츠 프로젝트 3 시작 (DID 인증 서비스) [회고록] 코드스테이츠 프로젝트 3 시작 (DID 인증 서비스) 아쉬웠던 프로젝트 2를 뒤로하고, 바로 프로젝트 3이 시작

about-tech.tistory.com

 

저는 Backend를 담당하게 되었고, 아래 업무를 통해 프로젝트에 참여하였습니다.

 

DID 프로젝트를 선택한 이유?

 

DID란 Decentralized Identity(탈중앙 신원증명)의 약자로 블록체인을 활용해 데이터 주권을 개인에게 주고, 제3자의 간섭/개입없이 독립적으로 본인의 신원을 증명할 수 있는 기술입니다. WWW를 창시한 팀 버너스리가 주도하는 W3C에서 표준을 만들어가고 있습니다.

코드스테이츠에서 블록체인 수업 중 DID 개념이 나오긴 했지만 실습 부분을 좀 더 확장해 전체적인 서비스를 구현해보고도 싶었고, 블록체인을 활용한 가장 현실적이고, 실생활에 접목 가능한 프로젝트라는 판단이 되어 DID 프로젝트에 참여하였습니다. 

 

 

 

 

다른 DID 서비스들과의 차이점은?

현재 운영중인 DID 서비스들은 컨소시엄 블록체인 혹은 프라이빗 블록체인을 활용하여 DID를 구현하고 있습니다. 하지만 블록체인이라는게 분산화된 원장이기 때문에 해시 파워를 독점하고 있는 중앙기관이 마음만 먹으면 새로운 체인을 만들어 낼 수도 있고, 기존의 데이터를 신뢰할 수 없다는 문제점을 가지고 있었습니다.

이 문제를 해결하고자 퍼블릭 블록체인으로 구성된 DID가 없다는 사실을 파악하고, 그럼 TPS가 빠르고, 저렴한 Klaytn 블록체인을 활용해 100%에 가깝게 탈중앙화된 블록체인 위에서 DID를 구성해보자는 의견으로 수렴되어 퍼블릭 블록체인을 활용한 DIDNOW 서비스가 탄생하였습니다. 

 

DIDNOW 프로젝트 구성

 

프로젝트 아키텍처

NoSQL MongoDB Schema

 

 

 

 

 

프로젝트 Flowchart

프로젝트 flow 요약본

 

🚀️ 배포 사이트

https://didnow.cf/

 

 

프로젝트를 진행하면서 힘들었던 점?

 

Q 개인정보가 담긴 VC 저장은 어떻게 처리했나요?

프로젝트를 처음 시작할 때 서비스의 가치를 정하는 부분이 힘들었습니다. 최초 컨셉은 VC를 발급받아 IPFS에 비대칭키 암호화 + 대칭키 암호화 방식으로 개인정보를 암호화 하여 저장하는 방식이었습니다. VC는 개인정보가 담긴 데이터로 외부에 노출되면 안됩니다. 이 때 디지털 서명을 위해 RS256 알고리즘을 사용했고, 비대칭키로는 brypt 모듈을 사용했습니다.

이 방식은 문제점이 2가지가 있었습니다. 먼저 Issuer가 발급한 VC의 길이가 1300Byte가 넘어가면서 디지털 서명 방식에서 공개키보다 긴 문자열은 암호화가 불가능한점이었습니다. 따라서 350Byte씩 쪼개서 암호화를 진행해서 구현은 했지만 길어진 문자열을 Verifier가 인증을 마칠 때 까지 비대칭키 암/복호화만 19번 되는 문제가 발생합니다. 결국 서버에서 Response Rate가 6000ms가 넘어가버립니다.

 

 

 

 

암복호화를 19번 해서 탄생한 VP 암호문

애초에 프로젝트를 진행할 때 DAU를 1만명 정도 가정하고 API제작을 시작했고, 빠른 응답을 위해 NoSQL MongoDB를 채택한 의미가 없어지는 순간이었습니다. 최초 프로젝트 가치를 '보안'에 둔 결과였습니다.

결국 보안을 조금 희생하더라도 검증 자체에 프로젝트 가치를 더 두고 RS256 알고리즘을 secp256k1 타원 곡선 알고리즘으로 변경하고, VC 저장방식을 IPFS가 아닌 DB에 담아 검증 기능에만 집중하였습니다. 암복호화 과정도 기존 19번에서 2번 정도로 줄여 Response Rate를 2000ms까지 줄일 수 있었습니다. 

DB 보안을 강화하기 위해 Nginx Reverse Proxy를 구현해 방화벽을 검토했고, MongoDB Atlas Network Access 권한을 축소하면서 보안에 신경을 썼습니다. 또한 MSA를 적용해 서버를 SOA 배포 단위로 분리해 DB를 분할 관리할 수도 있도록 구성하였습니다.

 

Q 서버 성능 개선을 위해 어떤 작업이 들어갔나요?

① MSA(Micro Service Architecture) 도입

🚀️ MSA, SOA란?
 

MSA 아키텍처란? SOA를 구현해보자 🚀️

MSA? 개발자들은 뭐든지 분리하는 것을 선호합니다. 잡동사니들이 쌓여있는 방에서 필요한 물건을 찾는건 어렵죠? 같은 논리로 하나의 파일에 모든 기능이 담겨있으면, 프로그램이 작동하다가

about-tech.tistory.com

프로젝트 시작단계에서 최소 DAU가 1만명 정도 들어왔을 때 제대로 된 성능을 내는 서버를 구성해야 한다는 생각을 가지고 있었습니다. DID 서비스에서 Issuer, Holder, Verifier 3명의 주체가 있고, 그 중 Holder의 트래픽이 가장 많은 것으로 예상되었습니다.

 

 

 

 

MSA를 도입한 이유

결국 기능별로 서버 스케일업을 해야 하는 상황이므로, 배포 단위 기준으로 3-Tier로 구성된 독립적인 SOA를 구성하고 MSA(Micro Service Architecture)를 도입해 서버를 4대 제작하게 되었습니다. 각각의 서버는 Docker로 컨테이너화 되어 독립된 환경에서 작동합니다. Nginx가 로드밸런싱 기능을 하므로, 트래픽이 몰리는 서버를 스케일업 한다면 대규모 트래픽을 처리할 수 있을 것으로 판단되었습니다.

MSA 도입 서버 아키텍처

MSA를 도입한 가장 큰 이유는 트래픽 분산이었습니다. Holder가 요청하는 트래픽이 서비스의 80% 이상이 될 것으로 판단하였고, 에러발생율이나 서버 증설이 가장 필요한 곳도 Holder의 기능을 담당하는 서버로 판단되었습니다. 따라서 트래픽을 적절히 부산하기 위해 MSA를 생각했습니다.

또한 Monolithic으로 구성한 서버에 연결된 DB 하나만을 두는 경우 Auth DB 접근에 대한 보안 이슈가 남아있어 차후 Auth 서버에서 사용하는 DB따로 관리하기 용이하도록 하기 위해 MSA를 적용했습니다.

Verifier의 Unit Test [4대의 서버가 독립적으로 작동]

마지막으로 Single Failure이 발생하는 경우 서버가 서비스 단위로 분리되어 있으므로 에러 핸들링이 용이할 것으로 판단되었습니다. 

MSA를 적용하면서 기존에 작성했던 Monolithic 구조에 비해 Unit Test 구성이나 API 제작에 코드 복잡도는 상승했고, 서버 구성 비용도 증가하는 단점도 분명 있지만 대규모 트래픽을 처리하기 위한 기본 작업이라 생각되었고, 장기적으로 이익이 되는 방향이라 판단되었습니다.

 

② 블록체인 데이터 Loss를 줄여라

블록체인은 굉장히 느린 데이터베이스라고 할 수 있습니다. 즉, Node.js에서 작동하는 서버의 속도를 블록체인 I/O가 따라오지 못해 데이터 누수가 발생하는 경우가 있었습니다. 이 문제를 해결하기 위해 3가지 정도 솔루션을 제안했고, 프로젝트에 도입하였습니다.

 

 

우선 블록체인에 접근하는 API를 최대한 분리하였습니다. 한개의 API controller에서 2개의 블록체인 메소드를 구현하면 데이터 누수가 발생하여 API당 최대 1개의 블록체인 메소드를 구현하였습니다.

또한 비동기 메소드로 구성하여 혹여나 데이터가 늦게 들어오더라도 100% 정확성을 가지고 데이터를 처리할 수 있도록 하였습니다. Caver.js를 통해 Klaytn 블록체인에서 들어가고 나오는 함수를 모두 비동기 함수로 사용해 혹시나 발생할 수 있는 데이터 누수를 예방했습니다. 

마지막으로 블록체인에 R/W 하는 부분에서 사용되는 데이터의 양을 최대한 줄였습니다. 데이터의 길이가 길어지면 데이터 누수의 가능성이 존재하기 때문입니다. 에를 들어 블록체인에서 32Byte의 데이터를 가져와서 비교검증하기 보단 solidity로 작성된 컨트랙트에서 true/false 값만 반환하는 형식으로 데이터 입출력의 길이를 줄였습니다.

 

Q 백업 Database는 어떻게 구성하였나요?

DIDNOW 프로젝트에 사용한 DB는 MongoDB Atlas M0 Tier 입니다. 하지만 무료 버전인 M0에서는 자동 백업 기능을 제공하지 않습니다. M0의 스토리지 스펙은 512MB 입니다. 사용량이 많이지면 턱없이 부족한 스펙입니다.

 

 

따라서 AWS EC2 서버 컴퓨터에 crontab을 사용해 mongodump / mongorestore 명령을 주단위로 실행되도록 설정하여 백업 DB를 구성하였습니다. 

추가적으로 시스템 장애에 대비하기 위해 PRIMARY + SECONDARY 2개 DB로 구성된 레플리카 셋을 구성하여 장애에 대비하였습니다. (MongoDB Atlas M0에서 기본 제공되는 기능입니다)

차후 사용자의 트래픽이 많아지는 경우 Auth 서버만을 위한 DB를 추가로 생성하고 전체 DB 스펙도 M0에서 M10~M30으로 업그레이드할 예정입니다. 이 때 MongoDB Atlas에서 제공하는 continuous cloud backup 기능을 사용해 백업 DB를 구성할 예정입니다. 

 

향후 MSA 적용 예상 아키텍처

 

 

Q 부하 테스트는 어떻게 진행했나요?

DAU를 1만명 정도 가정하고 최악의 상황을 가정해봤습니다. 1초에 8명이 동시접속하는 경우 과연 트래픽을 처리할 수 있는지를 기준으로 잡아 Stress Test를 진행했습니다. 툴은 Artillery를 사용했습니다. 

부하테스트 시나리오는 다음과 같습니다. 

  1. Holder 로그인 한다. (이 후 5초 대기)
  2. Holder가 Issuer에게 VC를 요청한다(이 후 5초 대기)
  3. Holder가 VP를 생성 후 Verifier에게 인증 요청한다

 

 

Monolithic으로 구성한 서버에서 부하테스트를 진행했을 때 Response Rate 비율은 50%가량이었습니다. 하지만 API가 처리하는 데이터의 길이를 줄이고, 블록체인 메소드를 수정하고, MSA를 도입한 결과 95%에 가까운 Response Rate 비율을 올릴 수 있었습니다. 

 

Q 왜 수료증에 한정했는가?

DIDNOW에서 발급해줄 수 있는 증명서는 수료증, 출입국증명서, 거주증명서, 졸업증명서 등 다양한 발급서를 Issuer가 개별적으로 결정하여 발급할 수 있습니다. Verifier는 해당 기관에서 검증할 증명서의 종류를 결정하여 VP 인증 프로세스를 처리할 수 있습니다.

 

파이널 프로젝트 배포

 

DIDNOW 서비스 배포는 AWS EC2Docker, Github Actions을 사용하여 CI/CD(Continuous Integration / Continuous Delivery) 파이프라인 형태로 배포를 진행하였습니다. 

 

네트워크 구성도는 다음과 같습니다.

 

main브랜치로 작업 결과물을 push 하면 trigger가 작동하여 EC2에 설치한 github runner가 작동하면서 build와 deploy 순서로 아래 작업들을 자동으로 수행합니다.

  • 서버 Unit Test 진행
  • Nginx Proxy, React, Express Server 4대 각각 Docker Image 빌드(Docker Compose 사용)
  • Docker Hub에 이미지 push
  • EC2에서 Docker Hub에 접속 후 Image Pull 및 컨테이너 실행

 

배포 구조

 

 

 

배포에는 2대의 Nginx 서버가 작동합니다. 첫번째 Nginx는 Reverse Proxy 기능을 담당하면서 각 서버로 들어온 요청을 적절히 로드밸런싱을 해줍니다. 현재는 프로토타입 형태로 서버는 1대씩 밖에 없지만 차후 트래픽이 증가하는 경우 스케일업을 통해 서버를 증설하여 로드밸런싱을 해줄 수 있습니다.

Reverse Proxy 기능을 담당하는 Nginx에는 gzip 옵션을 사용해 서버가 응답하는 데이터를 압축하여 서버의 성능을 최대한으로 올리려고 노력하였습니다. 미미한 차이지만 성능이 개선되었습니다. (Response Rate가 10ms 만 개선되어도 충분히 도전해볼 필요가 있다고 생각합니다. 대규모 트래픽이 들어올 경우 10,000명 * 10ms = 1분 40초가 되어 버리니까요)

사용자가 우리 서비스를 안전하게 사용하기 위해 HTTPS를 적용했습니다. NGINX에 SSL 인증서를 설치하려고 했는데, 그 보단 AWS에서 제공하는 Certificate Manager와 Route 53을 사용해 인증서를 등록하고 HTTPS 프로토콜을 사용하는 서비스로 개선하였습니다. 

두번째 Nginx는 React로 작성된 Frontend를 build한 static file을 반환해주는 역할을 담당하고 있습니다. build된 React 파일은 Nginx html 디렉토리에 저장되고 사용자가 https://didnow.cf 로 접속하였을 때 UI를 렌더링할 수 있는 static file을 반환합니다. 

 

 

파이널 프로젝트 후기

 

프로젝트를 진행하면서 팀원 한명이 잠수를 타면서 그 분이 맡았던 랜딩 페이지 UI 수정사항과 반응형 웹 페이지, 그리고 Issuer, Verifier가 현재 요청된 VC, VP 인증 목록을 차트로 그리는 기능을 구현하지 못한게 아쉬움이 남습니다. 

또한 서버 배포 자금이 충분하다면 MSA의 SOA를 완전한 독립적인 단위로 만들고 로드밸런싱을 통해 얼마정도 까지의 트래픽을 견고하게 처리할 수 있는지에 대한 실험을 진행해보고 싶은 욕심이 있습니다.

또한 이번 프로젝트에서는 DID 인증 서비스를 제작했지만 블록체인을 사용해 해볼 수 있는 DEX, SWAP, ERC-1155 NFT 민팅 서비스를 실생활의 문제를 해결하는데 사용하는 다양한 프로젝트를 해보고 싶은 욕심이 남습니다.

인생은 길고 해볼만한 프로젝트는 많으니 행복합니다 ㅋ

 

 

 

Reference

 

 

 

 

개발 공부 하기전 알면 좋은 것들 회고록

본격적으로 프로그램 개발 공부를 시작한지 1년이 넘어가고 있다. 진작에 알면 좋았을 것들 많았지만 지금 생각해보면 그 과정들이 다 필요한 과정이 아니었나 하는 생각이 든다. 개발 방향 정

about-tech.tistory.com

 

 

[회고록] 코드스테이츠 인센티브 기반 커뮤니티 프로젝트 2 후기

프로젝트 1에 이어서 2주간 이어지는 프로젝트 2가 진행되었다. 4명의 팀원이 모여서 인센티브 기반 토큰 이코노미를 적용한 커뮤니티 웹 서비스를 개발하는것이 프로젝트의 메인 주제고, 클라

about-tech.tistory.com

 

 

[회고록] 첫번째 프로젝트(Opensea) 시작

첫번째 프로젝트를 진행하게 되었습니다. 목표는 Opensea 클론이고, 모든 기능을 다 넣기에는 시간도 우리의 지식도 부족하므로, 제한적인 기능을 Bare-Minimum으로 두고, 추가 기능은 Advanced, Nightmare

about-tech.tistory.com

 

댓글