[GitHub Repository]
https://github.com/codestates-beb/beb-09-second-blockpink
[1주차-인센티브 커뮤니티]
https://unbreakableheart.tistory.com/64
Incentive Community
코드스테이츠 두 번째 프로젝트의 주제는 인센티브 기반 커뮤니티 만들기였다. 사용자의 행동에 따라 토큰을 인센티브로 지급하는 커뮤니티 앱을 만들어야 했다. 열흘간의 시간이 주어져있던 두 번째 프로젝트도 여유가 없었다. 지난 프로젝트와 달리 팀원으로 참여하게 되면서 BackEnd 쪽 학습에는 더욱 집중할 수 있었던 시간이었던 것 같다.
이번 프로젝트에선 기능적인 측면을 이것저것 하기보단 나름 문서화와 코드리뷰에 신경을 많이 썼던 것 같다. BackEnd로써 제대로 바닥부터 작업하는 것이 처음이었기에 마음가짐을 굳게 먹은 상태로 시작했고 생각보다 작업을 진행하는 도중에 깊게 막히는 부분이 없어 다행이었다. 길지 않은 시간임에도 프로젝트를 잘 마무리할 수 있었던 건 열정 가득한 팀장과 우리 팀원들 덕분이었다.
역할
이번 프로젝트도 4명에서 팀을 이뤄 진행했다. 팀장인 박xx(총괄), 나 (BackEnd), 유 xx(FrontEnd), 한 xx(FrontEnd) 이렇게 4명이 각각의 역할을 가지고 프로젝트를 시작했다. 드디어 BackEnd 부분을 제대로 할 수 있단 생각에 설렘 반 걱정 반이었다. 팀장님이 프론트, 백을 왔다 갔다 하면서 전체적인 흐름을 많이 잡아줬고 팀원들과의 소통 또한 원활하게 해줬다. 이러한 이유와 팀원들 각자의 노력 덕분에 어려움 없이 작업을 진행할 수 있었다.
목표
Incentive Community 프로젝트의 목표이다.
- minimum
- 커뮤니티에 게시글을 작성할 수 있고 이에 따른 보상으로 ERC-20 토큰을 지급하는 기능
- ERC-20 토큰을 ERC-721 토큰과 교환할 수 있는 기능
- ERC-20의 경우 서버 <->사용자, 사용자 <-> 사용자 둘 다 가능해야 한다.
- 회원가입 시에 자동으로 지갑 주소를 받는 기능
- Daemon을 개발하여 트랜잭션을 트래킹할 수 있는 기능
- NFT를 민팅할 수 있는 기능
- 내 정보를 볼 수 있어야 한다.
- Advanced
- 댓글, 좋아요 기능
- 게시글 카테고리화
프로젝트 기획
- DB Schema
- API Docs
- WireFrame
- BackEnd Architecture
Stack
- Frontend: React, MUI(Material UI) library
- Backend: Node.js, Express.js, Pinata/SDK, ethers.js, MySQL, Sequelize, Multer
- Smart Contract: solidity, foundry(forge, anvil)
작업 내용
앞서 얘기한대로 BackEnd에서 바닥부터 끝까지 하는 첫 프로젝트라 초기 환경 세팅부터 쉽지 않았다. 1주차엔 Schema & API 작성, 초기 환경 세팅, API구현이 주된 작업 내용이였으며 상세한 내용은 아래 1주차 블로그를 확인하면 알수있다.
https://unbreakableheart.tistory.com/64
이후 작업으론 트랜잭션 트래킹을 위한 Daemon.js를 구현하였고 코드,문서 정리를 하였다. README파일들을 생성하여 정리하고 백엔드 아키텍처도 직접 작성했다.아래는 구현한 Daemon.js이다.
require('dotenv').config();
const cron = require("node-cron");
const { ethers } = require("ethers");
const { Txes } = require("./models");
// Ethereum 네트워크 연결
const provider = new ethers.providers.JsonRpcProvider(process.env.LOCAL_ENDPOINT);
// 이전에 조회한 가장 최신 블록 번호와 트랜잭션 인덱스
let lastBlockNumber = 0;
let lastTransactionIndex = 0;
// 노드의 최신 블록 번호 조회
const getLatestBlock = async () => {
return await provider.getBlockNumber();
};
// 트랜잭션 내역 DB에 저장
const saveTransactionToDB = async (transaction) => {
await Txes.create({
tx_hash: transaction.hash,
block: transaction.blockNumber,
});
};
// DB의 트랜잭션 내역 모두 삭제
const clearTransactions = async () => {
await Txes.destroy({ where: {} });
};
// DB의 트랜잭션 내역 모두 삭제
clearTransactions();
// 매 초마다 실행 (실행 주기를 설정할 수 있습니다.)
const task = cron.schedule(
"* * * * * *",
async () => {
try {
// 주기적으로 실행하고자 하는 함수
const latestBlockNumber = await getLatestBlock();
// 이전에 저장한 트랜잭션 이후의 새로운 트랜잭션 조회
for (let blockNumber = lastBlockNumber; blockNumber <= latestBlockNumber; blockNumber++) {
const block = await provider.getBlock(blockNumber);
// 이전 블록의 경우 인덱스 초기화. 이후 블록의 경우 인덱스 0부터 시작
let startTransactionIndex = 0;
if (blockNumber === lastBlockNumber) {
startTransactionIndex = lastTransactionIndex + 1;
}
for (let i = startTransactionIndex; i < block.transactions.length; i++) {
const transaction = await provider.getTransaction(block.transactions[i]);
// 트랜잭션 내역이 있는 경우에만 DB에 저장 -> 토큰 전송 트랜잭션만 저장
if (transaction.data !== "0x") {
console.log(`Data: ${transaction.data}`);
await saveTransactionToDB(transaction);
}
}
// 최신 블록 번호와 트랜잭션 인덱스 갱신
lastBlockNumber = blockNumber;
lastTransactionIndex = block.transactions.length - 1;
}
console.log("task is running");
} catch (err) {
console.error("Error in task:", err);
}
},
{
scheduled: false,
}
);
task.start();
주석을 보면 확인할 수 있듯이 위 코드는 트랜잭션들을 매초 조회하고 변경사항을 감지한다. 위 코드에선 토큰 전송 트랜잭션만 DB에 저장하도록 트랜잭션 트래킹을 구현하였다.
아래는 직접 작성한 BackEnd Architecture이다. 팀장님의 요구를 최대한 반영하여 작성했다.
아래는 직접 정리한 README 파일들이다.
contracts/README.md
server/README.md
client/README.md
결과물
- 메인 페이지
- 게시글 작성 페이지
- 게시글 상세 페이지
- 마이 페이지
- 토큰 전송 페이지
- NFT 민팅 페이지
마무리
블록체인 Application에 대한 이해도가 많이 늘었다. 직접 바닥부터 BackEnd부분을 만지면서 어떻게 블록체인, 클라이언트와 소통을 하는지 이해하게 되었고 프로젝트 진행에 앞서 작성해야 하는 문서들에 대한 지식도 얻었다. 이번 프로젝트에선 지난 프로젝트와 달리 gpt가 아직 알지 못하는 최신 문서들을 많이 찾아봐야 했고 적용시켜야 했다. 새로 나온 문서들을 찾고 사용하는 것에 있어서 부담이 항상 있었지만 이번 기회를 통해 많이 극복한 것 같다.
여전히 많이 부족함을 느끼지만 많이 성장했고 계속 성장하고 있음을 느끼는 중이다. 사실 프로젝트 진행 중에 생각보다 작업 속도가 나서 나태해졌던 것 같다. 나태해지지 않았더라면 더 많은 기능을 구현하고 더 많은 것 들을 배울 수 있었을 텐데 하는 아쉬운 마음이 있다. 이후 본 프로젝트에 들어가서는 그저 주어진 기능을 구현하기보다 주어진 시간 안에서 최선을 다하는데 집중해야겠다는 생각을 하게 되었다. 그래도 이번에 진행한 2주간의 프로젝트에서 그래도 꽤나 많은 것을 했다고 생각해서인지 본 프로젝트에 들어가서는 무엇이든 해낼 수 있지 않을까 하는 자신감이 있는 상태이다.
2주라는 짧은 기간임에도 프로젝트를 잘 마무리 하고 문서들도 정리할 수 있었던 건 다 애쓰는 팀장님, 팀원분들의 노력 덕분이었다. 그런 노력들 덕분에 근심걱정 없이 진행했던 프로젝트였다. 팀원들에게 너무 고마웠다고 전하고 싶고 각자 팀원들의 앞으로 남은 프로젝트에서도 좋은 결과가 있길 바란다.
'Project' 카테고리의 다른 글
[Review] Community management tools based on ERC6551 (1) | 2023.11.24 |
---|---|
[1주차] 인센티브 커뮤니티 (0) | 2023.07.10 |
[Review] 오픈씨 클론 코딩 (0) | 2023.06.30 |