NFT 마켓플레이스 개발(OpenSea 클론 코딩) - 2

JangJooCool·2022년 2월 20일
0
post-thumbnail

2. 새로운 NFT 생성

이전에 truffle과 remix로 NFT를 발행할 때 tokenUri에 IPFS에 업로드한 파일 uri를 넣었다.
이때는 따로 IPFS에 업로드를 하고 uri를 받아와서 mintNFT 함수를 실행시켜 발행했었는데
이번에는 ipfs-http-client 모듈을 사용하여 오픈씨에서 create 하는 방식처럼
로컬에 있는 이미지를 웹으로 업로드하고 바로 NFT를 만들 수 있도록 구현해보았다.

2-1. IPFS

const client = create("https://ipfs.infura.io:5001/api/v0");

const onChange = async (e) => {
    const file = e.target.files[0];
    setImage(URL.createObjectURL(file));
    try {
      const added = await client.add(file);
      const url = `https://ipfs.infura.io/ipfs/${added.path}`;
      updateFileUrl(url);
    } catch (error) {
      console.log("Error uploading file: ", error);
    }
};

우선 업로드한 파일을 IPFS로 POST 요청을 보내고, request로 IPFS에 업로드된 파일의 path를 받아온다.
받아온 값을 만들어둔 상태에(fileUrl) 저장하도록 코드를 작성하였다.

2-2. Minting

const createNewNFT = async () => {
    let tokenContract;
    let newTokenId;

    if (walletType === "eth") {
      tokenContract = await new web3.eth.Contract(erc721Abi, newErc721addr, {
        from: account,
      });
      tokenContract.options.address = newErc721addr;
      newTokenId = await tokenContract.methods.mintNFT(account, fileUrl).send();
    } else {
      tokenContract = await new caver.klay.Contract(erc721Abi, newKip17addr, {
        from: account,
      });
      tokenContract.options.address = newKip17addr;
      newTokenId = await tokenContract.methods.mintNFT(account, fileUrl).send({ from: account, gas: 0xf4240 });
    }
  
    const name = await tokenContract.methods.name().call();
    const symbol = await tokenContract.methods.symbol().call();
    const totalSupply = await tokenContract.methods.totalSupply().call();

    setIsMint(true);
};

createNewNFT는 화면에서 이미지를 올린 후 createNFT 버튼을 클릭했을 때 실행되는 함수로,
앞서 지갑연결과 같이 walletType에 따라 이더리움이나 클레이튼 컨트랙트로 접근하여 mintNFT 함수를 실행시킨다. 파라메터로 연결된 지갑 주소와 업로드한 파일의 IPFS 주소 값을 넘겨준다.
이렇게 하면 나만의 NFT 생성 완료..!

2-3. 시연

NFT 생성

3. NFT 목록 조회

3-1. totalSupply 함수

mynft.js

  useEffect(async () => {
    saveMyToken()
  }, []);

 const saveMyToken = async () => {
    const tokenContract = "";
    if (walletType === "eth") {
      tokenContract = await new web3.eth.Contract(erc721Abi, newErc721addr);
    } else {
      tokenContract = await new caver.klay.Contract(kip17Abi, newKip17addr);
    }
    const name = await tokenContract.methods.name().call();
    const symbol = await tokenContract.methods.symbol().call();
    const totalSupply = await tokenContract.methods.totalSupply().call();
    let arr = [];
    for (let i = 1; i <= totalSupply; i++) {
      arr.push(i);
    }

    for (let tokenId of arr) {
      let tokenOwner = await tokenContract.methods.ownerOf(tokenId).call();
      if (String(tokenOwner).toLowerCase() === account) {
        let tokenURI = await tokenContract.methods.tokenURI(tokenId).call();
        setNftlist((prevState) => {
          return [...prevState, { name, symbol, tokenId, tokenURI }];
        });
      }
    }
    setIsLoading(false);
  };

지갑에 있는 NFT 목록을 가져오는 로직이다.
위 코드를 보면 지갑 연결할 때 할당한 walletType 상태에 따라 이더리움과 클레이튼 컨트랙트를 가져올 수 있도록 구현하였다.
이더리움을 기반으로 클레이튼이 만들어져서 그런지 caver-js 모듈을 사용하면,
기본적으로 Web3에서 사용하는 코드들은 web3 -> caver, eth -> klay 로 치환하여 사용가능하다고 한다.
위 로직에서 핵심적인 코드는 totalSupply 함수로 컨트랙트에서 발행된 토큰 갯수를 반환하여 지갑에 있는 NFT 목록을 가져올 수 있다.

3-2. 시연

내가 등록한 NFT 목록

2개의 댓글

comment-user-thumbnail
2022년 3월 13일

안녕하세요! 글 너무 잘 보았습니다. 덕분에 열심히 공부중입니다.

개발자님의 깃허브에서 압축파일을 다운받아 vscode에서 실행해보려는데 이더리움과 클레이튼의 컨트랙주소는 스마트컨트랙의 주소를 말씀하시는건가요??

1개의 답글