이전에 truffle과 remix로 NFT를 발행할 때 tokenUri에 IPFS에 업로드한 파일 uri를 넣었다.
이때는 따로 IPFS에 업로드를 하고 uri를 받아와서 mintNFT 함수를 실행시켜 발행했었는데
이번에는 ipfs-http-client 모듈을 사용하여 오픈씨에서 create 하는 방식처럼
로컬에 있는 이미지를 웹으로 업로드하고 바로 NFT를 만들 수 있도록 구현해보았다.
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) 저장하도록 코드를 작성하였다.
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 생성 완료..!
NFT 생성
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 목록을 가져올 수 있다.
내가 등록한 NFT 목록
안녕하세요! 글 너무 잘 보았습니다. 덕분에 열심히 공부중입니다.
개발자님의 깃허브에서 압축파일을 다운받아 vscode에서 실행해보려는데 이더리움과 클레이튼의 컨트랙주소는 스마트컨트랙의 주소를 말씀하시는건가요??