1. v0.0.1 구현/배포/테스트 방법

1. v0.0.1 구현/배포/테스트 방법

2024년 4월 7일

v0.0.1 #

f86e4ce0-34c9-4629-ac32-1ba12634fc3b

NFT 발급 로직 #

클라이언트 #

  1. 이미지를 업로드하면, 32*32px 의 이미지로 축소 변환
  2. 이미지를 4등분 (2x2) 으로 나누고, 번호 부여
  3. 이미지 파편을 랜덤하게 조합해서 traits를 설정하고, 해당 tratis에 맞는 이미지를 조합. 원하는 갯수만큼 이미지 생성
  4. 만약 1,2,3,4 가 전부 순서대로 모여있는 경우 legend 등급이 되고 나머지는 abnormal 등급
  5. 만들어진 이미지를 10배정도 확대(320*320px)
    • 기본적으로 HTML에서는 부드러운 경계 처리가 되기 때문에 blur를 제거하는 canvas 옵션을 사용해야 한다.
  6. 이미지 URL을 포함한 메타데이터를 오픈씨 형태로 IPFS같은 p2p 스토리지에 업로드
    • infura는 현재 ipfs 관련 API를 사용할 수 없어서 pinata를 사용함
    • 이미지 URL과 메타데이터 URL은 ipfs.io 로 변경해서 저장 (pinata를 통하는 것과 속도차이가 심함)
  7. 스마트 컨트랙트에 콜렉션 이름, 심볼, 메타데이터 주소배열을 전송해서 한꺼번에 여러 NFT 발급요청

스마트컨트랙트 #

대부분의 기능은 클라이언트에서 진행하기 때문에 스마트 컨트랙트는 그냥 콜렉션/NFT 생성 후 배치민팅만 하면 된다.

  1. 전달받은 정보로 콜렉션을 생성하고 NFT 생성 (콜렉션 이름, 심볼, tokenURIs)
  2. 배치 전송으로 만들어진 NFT를 한꺼번에 요청한 지갑으로 전송

NFT 조회 로직 #

스마트 컨트랙트 #

  1. 팩토리 컨트랙트에서 콜렉션 리스트를 관리
  2. 콜렉션 컨트랙트에서는 해당 유저에 대한 NFT Metadata 리스트를 view 함수로 구현
    • view로 구현하면 가스비 없이 블록체인 조회관련 작업이 가능하다.

클라이언트 #

  1. 콜렉션 리스트를 가져옴
  2. view 함수로 현재 내 지갑의 NFT 메타데이터 리스트를 가져옴
  3. ipfs에서 메타데이터 요청
    • 이때 메타데이터는 저장할 때 ipfs.io로 저장했기 때문에 빠르게 가져올 수 있다.

발생한 버그

  • tokenURI를 사용하려면 ERC721URIStorage를 상속받아야 하고, totalSupply를 사용하려면 ERC721Enumerable을 상속받아야 한다. 샘플코드를 찾아서 그 코드를 기반으로 수정했더니 해결됨 ( https://medium.com/@juanxaviervalverde/erc721enumerable-extension-what-how-and-why-8ba3532ea195)
  • 컨트랙트 안에서 mintNFT를 호출하기 때문에 Factory 컨트랙트에 소유권을 할당해야한다. 아니면 mint 함수에서 onlyOwner 속성을 제거해야하지만 그렇게되면 뭔가 이상하다.

로컬 네트워크에서 테스트 #

1. 배포 스크립트 작성 #

 1// scripts/deploy.js
 2async function main() {
 3    // 컨트랙트 팩토리 가져오기
 4    const ScamFactory = await ethers.getContractFactory("ScamFactory");
 5
 6    // 컨트랙트 배포
 7    const scamFactory = await ScamFactory.deploy();
 8    console.log("ScamFactory deployed to:", scamFactory.target);
 9
10    // 생성된 컬렉션의 주소들 가져오기
11    const collections = await scamFactory.getCollections();
12    console.log("Created collections:", collections);
13}
14
15main()
16    .then(() => process.exit(0))
17    .catch(error => {
18        console.error(error);
19        process.exit(1);
20    });

2. 로컬 서버 실행 및 로컬서버에 배포 #

  • npx hardhat node
    노드 서버의 주소를 기억한다. ex) http://127.0.0.1:8545
  • npx hardhat run scripts/deploy.js --network localhost
    배포된 ScamFactory의 컨트랙트 주소를 기억한다.

3. 스마트 컨트랙트 ABI를 클라이언트와 연결 #

  1. blockchain/artifacts/contracts/ScamFactory.sol/ScamFactory.json 파일을 그대로 web/src/ScamFactory.json 경로에 복사한다.
    또는 import 할때 import NewCollection from '../../blockchain/artifacts/contracts/NewCollection.sol/NewCollection.json'; 처럼 작성

  2. 클라이언트 소스코드에서 배포한 로컬 블록체인 네트워크 연결
    노드 서버 주소를 클라이언트의 Web3 생성자에 넣는다.
    const web3 = new Web3('http://localhost:8545');

  3. nft 팩토리 컨트랙트를 연결한다.
    const contract = new web3.eth.Contract(ScamFactory.abi, CONTRACT_ADDRESS);


4. 브라우저 메타마스크에서 네트워크와 계정 세팅 #

  • 네트워크 추가
    메타마스크에서 네트워크 직접 추가로 네트워크를 추가한다. hardhat 로컬 네트워크의 체인 ID는 31337 이며, 통화기호는 ETH를 쓰면 된다.
    나는 SCAMNET을 이미 연결해서 중복된다고 표시된다.. c7cdcd02-034a-4512-ace2-6e4daa2138f6

  • 계정 추가
    hardhat 노드를 실행시키면 테스트를 위한 계정들이 생성되고 프라이빗 키가 출력된다. 0b4536fd-f8e5-4be9-b558-eb261a34a112 이 키를 이용해서 계정을 가져온다. a1cf2a8c-9262-4492-b236-429aad58295a


5. 클라이언트 실행 #

npm run dev


테스트넷 배포 #

  1. polygonscan api 키 획득하기
    polygonscan에서 회원가입 후 API 키 획득 2fb68030-ac8c-4311-acc9-12e9a5133796

  2. hardhat.config.js 설정
    npm install dotenv

 1require("@nomicfoundation/hardhat-toolbox");
 2require("dotenv").config();
 3/** @type import('hardhat/config').HardhatUserConfig */
 4module.exports = {
 5  solidity: "0.8.24",
 6  networks: {
 7    amoy: {
 8      url: "https://rpc-amoy.polygon.technology",
 9      accounts: [`${process.env.PRIVATE_KEY}`]
10    }
11  },
12  etherscan: {
13    apiKey: `${process.env.POLYSCAN_APIKEY}`,
14  },
15};
  1. 테스트넷에 배포
    npx hardhat run scripts/deploy.js --network amoy

  2. 매일 코인 출석해서 모으기
    https://www.alchemy.com/faucets/polygon-amoy
    https://faucet.chainstack.com/amoy-faucet
    https://www.alchemy.com/faucets/ethereum-sepolia

88c8b806-5a89-4e5d-8947-157ef1509454

  1. 테스트넷 opensea에서 볼 수 있음
    https://testnets.opensea.io/

메인넷에 배포 #

rpc 주소만 달라질 뿐 모든 작업이 같다.

1    polygon: {
2      url: "https://polygon-rpc.com",
3      accounts: [`0x${process.env.PRIVATE_KEY}`],
4    },

d9989d4b-c073-44a5-b767-652dc3a0771c

배포 완료하고 nft 테스트로 생성해봤는데, openSea에서도 보인다.

92bdd630-b582-4df7-b6ec-e4b8a0ffef96

comments powered by Disqus