본문 바로가기
Programming

[회고록 ]코드스테이츠 NFT Marketplace 프로젝트 완료 후기

by 개발자 염상진 2022. 8. 13.

 

코드스테이츠에서 블록체인 파트가 모두 종료되고, 처음으로 진행되는 첫번째 프로젝트가 완료되었다. 총 4명이 한 팀이 되어 OpenSea 와 같은 NFT Marketplace 서비스를 제작해보는 과제가 주어졌다. 처음 논의했을 때는 Bare-Minimum , Advanced, Nightmare까지 나누고 Advanced까지 진행해볼 계획이었지만 일주일이란 짧은 기간동안 Bare-Minimun까지만 진행했다. 

Project : OpenSea NFT Marketplace Clone
팀 역할 : 프론트 1명, 백엔드 1명, 컨트랙트 1명, 전체 프로젝트 관리 1명

 

 

처음 프로젝트를 진행하는데, 내가 팀장을 맡게 되었다. 전체적인 프로젝트 그림을 그리는데, 시간이 조금 걸렸는데, 결국 NFT를 발행하는 컨트랙트를 Ropsten 네트워크에 배포한 뒤 프론트에서 가져오는 간단한 로직을 가지고 있다.

 

전체 프로젝트 FLOW는 다음과 같다. 

 

프로젝트 세부 구성

 

Smart Contarct 

OpenZeppelin에서 배포한 ERC-721 컨트랙트를 참고하였고, Truffle을 통해 컴파일과 배포를 진행하였다. 사실 필요는 없어 보이지만 이더스캔 네트워크에서 truffle-plugin-verify npm 모듈로 verify&publish까지 진행하였다. 컴파일된 컨트랙트는 Ethereum Ropsten Network에 배포.

여기서 문제가 발생하는데, 실제 NFT를 민팅하는  mintNFT 함수는 onlyOwner modifier가 걸려 있어 컨트랙를 배포한 address만 NFT 민팅이 가능한 상황이 발생했다. 프로젝트 로직 상으로는 아무나 NFT를 발행할 수 있어야 하기에, onlyOwner modifier를 제거했다.

 

Front-end

사실 front에서 많은 일들이 이뤄질지는 처음에 프로젝트 진행할 때만 해도 크게 생각하지 않았다. 프로젝트 FLOW를 그리다 보니 React에서 처리해야 하는 로직은 다음과 같다.

 

 

  1. 지갑 연결
  2. 사용자 Input Value 받아 IPFS Metadata 생성
  3. 컨트랙트 mintNFT 함수 실행

React에서 컨트랙트 abi와 address를 가져와 연결하는데만 1일 이상 걸렸다. 초기에 지갑을 연결하면서 Metamask에서 제공하는 Provider를 바로 주입해야 하는데, 중간에 새로운 공급자를 주입한게 문제라는 걸 파악하고, 로직 수정후 지갑연결 까지 성공했다.

이제 사용자가 입력한 NFT 정보를 받아 IPFS에 올리고 메타데이터를 받아와 tokenURI로 가져와야 하는데, 프로젝트 진행 도중 원래 사용하던 Infura IPFS 서비스가 종료되었다. IPFS에 데이터를 어떻게 올릴지 고민하는데 또 하루가 소요되고. 결국 NFT.storage npm 모듈을 사용하기로 결정했다.

NFT를 컨트랙트 함수로 발행한 후 전체 NFT 보기를 클릭하면 서버에 axios 요청을 보내 리스트 형식으로 가져온 후 화면에 렌더링 까지 진행하였다. 

Server

서버의 역할은 두가지였다.

1. Ethereum Ropsten Network에서 주기적으로 RPC Call을 보내 현재 발행된 NFT 정보를 가져와 DB에 적재

2. 클라이언트 요청시 DB에 저장된 NFT 목록을 반환한다.

 

DB는 MongoDB를 사용했다. 몽고디비에서 제공하는 Cloud를 사용해야 누가 프로젝트를 실행해도 DB를 또 설치해주고 설정해줄 작업이 필요없기 때문이다. 아니면 AWS RDS를 사용해야 하는데, 일주일이라는 기간을 생각해보면 MongoDB가 최적이라는 생각이 들었다.

server에서도 Ethereum Ropsten Network에 배포된 컨트랙트와 연결해준다. 이 때는 Infura에서 제공해주는 엔드포인트 API를 사용했다. 컨트랙트에 totalSupply() 함수를 실행해 현재 발행된 NFT 갯수를 받아와 for문을 돌면서 tokenURI() 함수로 메타데이터를 수집한다. 

컨트랙트에서 받아오는 정보 즉, tokenURI()가 반환하는 값은 메타데이터를 저장하고 있는 IPFS URI기 때문에 axios 요청을 보내 파싱한 다음 스키마에 맞게 DB를 적재한다.

MongoDB에 작성해놓은 스키마에 unique 속성을 걸어서 NFT가 중복되지 않도록 처리했다. app.js 에서 10초당 한번 setInterval를 걸어 컨트랙트를 참고해서 DB에 적재를 계속한다. 

서버와 클라이언트 통신에는 proxy를 사용했다. cors를 따로 지정해줘도 되지만, 간단한 프로젝트에서 빠르게 기능구현을 해야 한다는 생각이 강해 핵심 로직이 아닌 부분들은 간단하게 작동될 수 있는 수준으로 대체했다. 

 

프로젝트 결과물

 

지갑연결 + NFT 발행

메인페이지에서 지갑을 연결하고 제목, Description + 파일업로드를 하면 IPFS에 메타데이터가 저장된다. NFT 발행 버튼을 클릭하면 IPFS에 등록한 메타데이터를 tokenURI 인자로 입력해 NFT 발행이 시작된다. 

 

 

 

전체 NFT 정보 출력

전체 NFT 보기를 클릭하면 서버에서 NFT 정보를 가져와 렌더링한다. 

 

프로젝트 1 후기

 

일주일이라는 시간이 길면 길고 짧으면 짧다지만 프로젝트를 진행하는 입장에서는 굉장히 빠르게 지나갔다. 팀원들과 처음 만나 프로젝트를 어떻게 구성할지 논의하고 각자 파트를 나눠서 진행하고 발생한 이슈에 대해 다시 만나 논의하고 하면서 결과물을 내기 까지 꽤 오랜시간이 걸렸다.

일단 프로젝트에 여러 사람이 참여하면서 Git 브랜치가 꼬이지 않을까, 팀장으로써 프로젝트를 잘 마무리 할 수 있을까 걱정이 들었지만, 생각보다 스무스하게 진행되서 다행이었고, 팀원분들도 각자 맡은 파트에서 책임감을 가지고 진행해줘서 다행이 처음에 목표한 부분까지는 완성할 수 있었다. 

 

 

web3에 컨트랙트를 발행하는 부분이 아쉬움이 많이 남는다. 실제 컨트랙트를 작성하고 OpenZepplin 코드를 어느정도 커스터마이징 해서 더 다양한 기능을 구현할 수 있는 프로젝트를 해볼 계획이다. 

 

Git Repository

 

 

 

 

 

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

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

about-tech.tistory.com

 

 

IPFS 우분투 20.04 LTS 설치 방법

IPFS(InterPlanetary File System)이란? IPFS는 P2P 파일 시스템으로 모든 컴퓨터를 연결하는 것을 넘어 행성을 연결하는 비전을 가진 차세대 파일 시스템입니다. IPFS는 기존 HTTPS Web 기반의 시스템 한계를

about-tech.tistory.com

 

 

[Git] 되돌리기 명령어 (restore, reset, clean 사용법)

Local Repository에서 작업하다 수정사항을 이전 단계로 돌려야 하는 경우 일일이 수정사항을 찾아서 되돌리기는 시간이 많이 소요됩니다. 수정 사항을 되돌리는 작업은 2가지 단계로 나눌 수 있습

about-tech.tistory.com

 

댓글