[Project] DDYY market 개발 회고
처음으로 진행해본 프로젝트였다! 화려한 기능을 가진 화려한 사이트를 구현한 것은 아니었지만, 처음으로 협업하며 개발을 해보았다는 점에서 나에겐 큰 의미가 있는 프로젝트였다.
✏️ 역할 분담
- Front-end (내가 담당한 🙋🏻♀️)
클라이언트 웹페이지 및 web3 일부 로직 구현- Back-end
모랄리스 사용을 위한 api 개발 및 web3 로직 구현- Smart Contract
ERC-721 발행 및 조회, 전송을 위한 컨트랙트 개발 및 배포
1. DDYY NFT market
우리 팀은 필수적으로 필요한 최소 기능만을 빠르게 구현한 뒤, 배포까지의 전 과정을 경험해 보는 것을 목표로 하였다. 우리 사이트는 검색어를 통해 rinkeby 테스트넷 상에 발행된 NFT를 조회할 수 있고, 메타마스크 지갑을 연결하여 직접 NFT를 발행 하고 특정 주소로 전송할 수도 있다.
📦 truffle-react-box 라이브러리
이 라이브러리를 사용하면리액트 클라이언트 개발, 스마트 컨트랙트 개발 및 배포, web3 연동까지 통합된 하나의 프로젝트 안에서 개발할 수 있어 매우 편리하다! 간단한 토이 프로젝트 개발에는 무조건 사용하는 것이 좋을 것 같다. (truffle-react-box tutoral page)
truffle-react-box
깃헙 페이지에서는 아래와 같이 소개하고 있다.
Pages 상세
📃 explore
'dog' 라는 키워드로 검색하면, Token 이름에 'dog'가 포함되는 NFT들이 리스팅된다.
📃 create - NFT minting
NFT name, description을 입력하고 원하는 파일을 선택하면 민팅을 할 수 있다. 메타마스크를 통해 지갑에 서명까지 하면 NFT가 성공적으로 발행되었다는 메시지와 함께 해당 발행 트랜잭션에 대한 정보를 확인할 수 있는 이더스캔 링크를 제공한다.
📃 mypage - NFT transfer
현재 로그인된 지갑 계정이 소유하고 있는 NFT들을 확인할 수 있다. 각 NFT 하단에 수신인의 지갑 주소를 입력하고 transfer 버튼을 누르면 NFT를 전송할 수 있다. 이 때도 역시 메타마스크를 통한 서명이 필요하다. NFT가 성공적으로 전송되면 해당 트랜잭션에 대한 이더스캔 링크가 제공된다.
2. Frontend 개발 회고
리액트로 개발되었으며, 매우 간단한 사이트이기 때문에 truffle-react-box
외에 특별한 라이브러리나 기술스택은 사용하지 않았다.
🖥 client 코드 구조
🖥 통신 결과에 따른 메시지 출력
블록체인과 통신하는 것은 비동기이며, 일반적인 클라이언트와 서버의 통신보다 훨씬 오래 걸린다. 사용자 경험을 위해 loading indicator
의 구현은 필수적이었다.
또한 message
라는 state를 정의하고, 통신 결과에 따라 달라지는 message state에 따라서 적절한 결과 메시지가 노출되도록 하였다. 이러한 내용이 구현됨으로써 사용자 경험이 크게 개선될 수 있었다. 매우 간단하고 또 당연한 로직이지만 앞으로 또 다른 클라이언트를 개발할 때에도 세심하게 신경써야할 부분이라고 생각한다.
통신 결과 메시지 출력 example - NFT minting
NFT를 민팅하는 컴포넌트에서 해당 내용을 구현한 전체적인 흐름은 다음과 같다.
const MintForm = () => {
// message state 정의
const [message, setMessage] = useState('');
// NFT 발행을 위한 정보를 메타데이터 생성 서버에 제출하는 함수
const handleSubmit = async (event) => {
// 입력된 정보가 올바르지 않으면 📌message = 'formError'
if (nameRef === '' || descRef === '' || imgFile === undefined) {
setMessage('formError');
return;
}
// 서버에 정보를 제출하고 응답을 기다리는 동안 📌message = 'loading'
setMessage('loading');
...
}
// 생성된 메타데이터로 NFT를 민팅하는 함수
const mintNFT = async (metaData) => {
...
try {
...
setTxAddress(txHash);
// 거래가 성공하면 📌message = 'success'
setMessage('success');
} catch (error) {
...
// 거래가 실패하면 📌message = 'failure'
setMessage('failure');
}
}
return (
...
// message의 상태에 따라, 아래 div에 표시되는 내용이 달라진다.
<div className="mintfomr-alert-message-wrapper">
{
message === 'formError' &&
<div className="mintform-filling-error-message">
All fields must be filled in.
</div>
}
{
message === 'success' &&
<div className="mintform-success-message">
NFT has been successfully issued!<br />
Check your Transaction
<a target="_blank" href={'https://rinkeby.etherscan.io/tx/' + txAddress}>HERE!</a>
</div>
}
{
message === 'failure' &&
<div className="mintform-failure-message">
Something wrong! Try again
</div>
}
{
message === 'loading' &&
<div className="mintform-loading-message">
Please wait...
<img className="loading-indicator2" alt="now loading..." src="loading2.gif" />
</div>
}
</div>
...
)
}
🖥 useRef
이번 프로젝트 이전까지는 거의 사용해보지 않았던 hook인데, 사용법이 너무 간단해서 이걸 왜 이제야 활용하게 되었나 싶다. 리액트를 한참 배울 때에는 useRef를 사용하지 않고, 각 input
에 해당하는 state
를 새로 생성하여 input
태그의 event.target.value
를 새로운 state
의 값으로 setState
하는 방법을 이용했었는데, useRef
를 이용하는 것이 비교도 안 될 정도로 간단하다.
컴포넌트 안에서 아래처럼 정의하면 input
에 입력되는 값을 nameRef
로 손쉽게 접근할 수 있다.
const nameRef = useRef();
return (
<input ref={nameRef} type="text" />
)
🖥 CSS
postCSS나 styled-components를 이용할 수도 있었지만, 간단한 프로젝트이기 때문에 app.css
에 모든 css를 몰아 넣었다. 정리되지 않은 무식한 방법일 수 있지만 주석만 잘 달아놓으면 단 하나의 css 파일만 이용하기 때문에 이 방법도 나름 괜찮기는 했다. 하지만 개선이 필요하다.
3. 기타 이슈 사항
Moralis
Opensea는 api 키 발급에 오랜 시간이 걸린다. 우리팀은 오픈씨와 비슷한 Moralis라는 플랫폼의 api를 이용하여 rinkeby 테스트넷에 접근하기로 했다.
Metamask Signature 기능 구현
NFT를 민팅하거나 전송할 때, 사용자가 메타마스크를 통해 서명할 수 있도록 구현해야 했다. 이를 구현하는 과정에서 어려움이 있었고, 구글링을 통해 솔루션을 찾아 아래와 같이 적용하여 해결하였다.
우리 컨트랙트에 eth_sendTransaction
이라는 method
로 request
를 날리는 방식이다. MetaMask Docs에서 이 내용이 안내되고 있는 걸 보니 아마 메타마스크에서 제공하는 기능인 것 같다. 이곳에서 관련 내용을 참고할 수 있다.
docs 내용을 참고하여 우리 사이트에서는 아래와 같이 구현하였다.
const mintNFT = async (metaData) => {
window.contract = await new web3.eth.Contract(ABI, deploy_address);
const transactionParameters = {
to: deploy_address, // Required except during contract publications.
from: window.ethereum.selectedAddress, // must match user's active address.
'data': window.contract.methods.mintNFT(window.ethereum.selectedAddress, metaData).encodeABI() //make call to NFT smart contract
};
//sign transaction via Metamask
try {
const txHash = await window.ethereum
.request({
method: 'eth_sendTransaction',
params: [transactionParameters],
})
setTxAddress(txHash);
setMessage('success');
} catch (error) {
console.log(error);
setMessage('failure');
}
}
4. 이번 협업을 통해 배운 점
- git을 사용한 협업
git과 github에 대해서는 막연하게 알고 있었는데, 이번 프로젝트를 통해 git의 막강함을 느낄 수 있었다. git이 없을 때 개발자들은 어떻게 협업을 했을까...? 단, 충돌이 나지 않도록 팀원들과 잘 소통해가며 개발하는 것이 매우 중요한 것 같다. git 개념과 명령어가 아직 친숙하지 않아 별도로 더 공부해볼 예정이다.
- 로딩 인디케이터 이미지 무료 제작 사이트
서버와 비동기적으로 통신해야하는 사이트들은 로딩 인디케이터 구현이 필수적이다. 이 사이트에서 간단하게 원하는 대로 인디케이터 이미지를 손쉽게 제작할 수 있다.
git과 github에 대해서는 막연하게 알고 있었는데, 이번 프로젝트를 통해 git의 막강함을 느낄 수 있었다. git이 없을 때 개발자들은 어떻게 협업을 했을까...? 단, 충돌이 나지 않도록 팀원들과 잘 소통해가며 개발하는 것이 매우 중요한 것 같다. git 개념과 명령어가 아직 친숙하지 않아 별도로 더 공부해볼 예정이다.
서버와 비동기적으로 통신해야하는 사이트들은 로딩 인디케이터 구현이 필수적이다. 이 사이트에서 간단하게 원하는 대로 인디케이터 이미지를 손쉽게 제작할 수 있다.
5. 보완해야 할 사항들
NFT searcing, minting, tranfering 기능만을 간단하게 구현해본 사이트이기 때문에 실제로 서비스하기에는 부족한 부분이 많다. 다음 프로젝트에서는 더욱 완성도 높은 서비스를 개발하기 위해 이 내용들을 잘 기억해둬야겠다.
- 로직 분리가 세분화되지 않아서 컴포넌트/페이지가 무겁고 똑똑함
하나의 컴포넌트 코드가 100줄을 넘지 않게 작성하고 싶은데,Minform
컴포넌트의 경우 150줄이 넘어가고 있다. 서비스 로직은 따로 모듈화하여 구현하는 연습을 해야 하는데 아직은 한 파일에 몰아서 작성하는 것이 편하다..😭
- 리덕스 등의 상태 관리 라이브러리 사용 안함
하지만 가벼운 앱은useState
Hook으로도 충분할 듯 하다. 다음 프로젝트에서는redux
나useReducer
를 활용해볼 예정이다.
- css 코드 작성이 비효율적
App.css
파일에 모든 CSS 코드를 다 담았는데, 사이트의 규모가 좀 더 크거나 유지보수가 필요한 상황에서는 아마 크게 고생할 것이다. syled-Component나 postCSS를 적용해 보는 것도 좋았을 것 같다.
memo
,useCallback
등을 통한 성능 최적화를 하지 않음
성능 최적화를 아예 하지 않았다. 불필요한 리렌더링을 줄이는 최적화가 필요하다.
- 브라우저 콘솔에 뜨는 수많은 warning들을 손보지 않음
이 warning들은 사실 고쳐볼 엄두가 나지 않았다..
- NFT 이미지가 잘 로딩되지 않음
NFT를 검색하거나, mypage를 조회할 때 아래와 같이 이미지가 잘 로딩되지 않는 경우가 많았다. 새로고침을 반복하면 이미지가 뜨기도 한다. 아마 Moralis에서 제공하는 API가 불안정한 것이 아닐까? (뇌피셜)
- 검색시 리스팅이 48개까지 밖에 되지 않음
키워드를 입력하여 검색을 실행하면 검색 결과로 최대 48개의 NFT만 로딩된다. 무한 스크롤 기능을 통한 개선이 필요하다.
Author And Source
이 문제에 관하여([Project] DDYY market 개발 회고), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yooni/DDYY-market저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)