Skip to content

Latest commit

 

History

History
155 lines (98 loc) · 6.79 KB

SC_Problem.md

File metadata and controls

155 lines (98 loc) · 6.79 KB

SmartContract 작성하면서 발생했던 문제점

문제점

뽑기

문제1 . 로직상 문제

  • NFT에 들어가는 정보는 NFT ID, 유전코드, 이미지 주소, 생성일자

  • 프론트에서 뽑기 신청 => SC 함수 호출

  • SC에서 랜덤 알고리즘을 통해 유전 생성

  • 생성된 유전자로 이미지 생성(IPFS에 생성된 이미지 등록)

  • 이미지를 생성 하려면 프론트에 피드백을 보내야함

  • 프론트에서 이미지 생성 후 SC에 이미지 주소 보냄

  • 받은 이미지 주소로 NFT 생성

  • SC에서 프론트에 답이 올 때 까지 기다릴 수가 없다(유전자 생성후 이미지 주소 보낼때 까지 기다릴 수 없다)

문제1 해결 방안

  1. 먼저 유전코드만 프론트에 던져주고 프론트에서 유전코드,이미지 주소를 받는다

    • 이 경우 소비자가 유전코드, 이미지주소 인자를 다른 값으로 조절하여 보내기가 가능
      • 블랙리스트, 화이트리스트운영하여 함수 요청하는 사람을 조절 하는 방안
        • 어떤 기준으로 할 것인가...?
    • 채택
      • 방법에 문제가 있더라도 이미지 주소는 NFT에 들어가 있어야 한다는 의견이 다수
  2. 이미지 주소 없이 NFT ID, 유전코드, 생성일자만 일단 생성 후 추후에 이미지 주소 추가

    • 위와 마찬가지로 이미지 주소에 완전 다른 값을 생성 가능
      • 마찬가지로 블랙리스트, 화이트리스트 운영
    • 소비자는 NFT 생성, NFT 이미지 주소 추가 라는 두가지 결제가 이루어짐
      • 2번에 나눠 걸쳐진 복잡한 절차를 소비자에게 납득 시킬 수 있을까?
  3. 이미지 주소를 빼버린다

    • 유전 코드 == 이미지라서 이미지 주소를 빼버려도 문제가 없다 판단하여 냈던 의견
    • 추후에 서비스 종료시 남는게 없다 (이미지라도 남기고 싶은데 남길 수 없다)
  4. 유전코드에 해당하는 이미지를 미리 IPFS에 모두 등록하자

    • 이미지 종류가 너무 많다

문제 2. JAV토큰 소비 방법(뽑기버튼을 누르면 JAV토큰을 우리에게 넘기는 것)

  1. 소비자가 직접 NFT SC의 주소에 넘겨주는 방식
    • NFT SC가 JAV토큰이 들어온 것을 어떻게 확인할 것인가?
    • 소비자는 JAV토큰을 넘겨주는 절차, NFT 생성절차 총 두번의 결재가 이루어 지는데 UX에 악영향
  2. 한번에 해결하려면 ERC-20에서 벗어날 수 밖에 없음
    • transferFrom을 수정하여 해결
    • 이 방법의 경우 해당 함수를 호출할 경우 다른 사람의 토큰을 모두 가져올 수 있는 문제 발생

문제2 해결방안

  1. 회원가입시 혹은 추후 서비스를 이용하려고 할 때 NFT SC에서 해당 유저에게 돈을 빼가는 것을 승인 받아 두자(금액을 높게 설정)
    • 일종의 충전식 개념
  2. JavToken의 SmartContract에서 뽑기를 호출
    • 로직을 바꾸면 해결이 되는 문제였음(NFT SmartContract에서 JavToken을 가져오려고 하는게 문제)
    • 채택

유전 알고리즘

문제 1. 유전 알고리즘을 프론트, Solidity 어디서 할 것인가?

  • 프론트에서 할 경우 코드 작성이 간단
  • Solidity에서 할 경우 확률 변경에 함수조작이 들어가므로 확인 가능
    • 확률에 대한 확신을 줄 수 있음
    • 채택

문제2. Solidity에서 랜덤 구현

  • Solidity에서 완전한 랜덤은 없음
  • 시간을 이용하여 구현
    • uint(keccak256(abi.encodePacked(block.timestamp))) % 100;
  • 위 방법으로 구현 했을 때의 문제점
    • 다음 랜덤을 구할때 위 코드로 얻은 결과를 block.timestamp에 넣어 구현
    • Solidity가 연산에 적합한 언어가 아님
      • Remix를 이용하여 배포하였을 시 해당 코드와 랜덤을 가공하는 알고리즘에서 시간이 너무 오래걸려 작동이 잘 안됨
  • 알고리즘 최적화 작업을 진행
    • 주로 비효울적인 연산을 줄임

문제3. block.timestamp의 문제

  • 문제 2를 개선하여 알고리즘을 작성
  • 해당 알고리즘을 이용하여 시도 했더니 한동안 같은값이 나옴(약 10초)
    • block.timestamp의 갱신이 너무 느림

문제2&3 해결방안

  • Solidity만의 힘으로 랜덤을 해결 하기엔 어렵다고 판단
  • Front에서 랜덤 값을 받아 오는 것으로 변경

Store(NFT 거래, SaleFactory)

문제 1. 판매등록(NFT를 건네 주는 권한에 관하여)

  • 판매자 -> SaleFactory SC -> Sale SC 구조
    • 결국 Sale SC에서 NFT 전송 권한을 가져야함
    • 판매자가 Sale SC에 직접 허가를 할 경우 모든 판매 등록에 있어 2번의 결제
      • SaleFactory에서 Sale Contract를 생성에서 1번 결제
      • 새롭게 생성된 Sale Contract에게 전송 권한을 허가하는 2번째 결제
    • SaleFactory에서 판매자의 NFT 전송에 관한 전권을 가지고 해결 하려고 함
  • SaleFactory SC에서 판매 등록시 NFT SC를 Import 하여 건네는 권한 설정을 하려고 함
    • Import된 NFT SC에서 ERC-721의 setApprovalForAl호출하여
    • setApprovalForAll는 msg.sender(함수 호출자)가 지갑(address,인자로 받음)에게 허용(true)해주는 함수
    • msg.sender가 판매 등록자가 아닌 SaleFactory의 주소가 되는 것을 확인

문제1 해결방안

  1. ERC-721의 표준을 벗어나서 전송 함수 or 권한 허가 작성

    • 모든 NFT의 소유권을 함수 호출자가 가질수 있게 되는 문제 발생
  2. 뽑기 문제2와 동일하게 NFT 판매 첫 시도시 혹은 사전에 SaleFactory가 거래 관한 권한을 받아두자

    • 최초 이용시 단 한번 추가 결제가 일어남

    • 채택

문제 2. 구매(NFT 구매시)

  • 위 문제와 마찬가지로 ERC-20의transferFrom함수 호출에 있어서 msg.sender가 Sale SC가 됨
  • Sale Contract는 SaleFactory와 다르게 매번 새로운 주소
    • 대상자가 매번 바뀌기에 전권을 넘겨주는 함수가 필요가 없음

결론

  • 구매자는 1차로 Sale SC에게 구매 금액을 인출할 수 있는 권한을 넘겨주는 계약 작성
  • Sale SC에서 구매자에게서 구매 금액을 인출하고 NFT를 전송

개인이 소유중인 NFT 목록 조회

문제 1. 자료구조

  • Solidity의 기본 자료 구조는 stack 구조
  • 소유중인 NFT ID를 맵핑하여 [1,2,3,4,5,6,7,...] 으로 array형태로 저장
  • 조합에 사용되는 NFT 소각시 array에서 해당 id를 소각하는데 비 효율적 => NFT 한 개 소각 할 때 마다 전체 array를 탐색 해야함
  • 프로젝트 특성상 소각되는 일이 많기에 매우 비효율적

결론

  • 개인이 소유중인 NFT 목록은 백엔드에서 관리 후 목록 비교 형식