react NFT application 서사 2장

Poo·2021년 12월 15일
0

ERC721 스마트 컨트랙트 수정하기

Web3.js를 사용해 특정 계정의 ERC721 토큰 목록을 가져오기 위해서는
ERC721에 정의된 totalSupply 함수를 사용해야 한다.
totalSupply 함수는 해당 스마트 컨트랙트에서 발행된 토큰의 갯수를 반환한다

penzeppelin에서 totalSupply 함수를 사용하기 위해서는 ERC721Enumerable 컨트랙트를 사용한다.

ERC721Enumerable를 추가한 ERC721 스마트 컨트랙트를 새롭게 발행해보자!

web3-pratice와 리믹스 부터 연동하자

remixd -s <remixd_practice 폴더의 절대경로> --remix-ide https://remix.ethereum.org/

요건 먼지 알지?
자 연동해주고 나면 리믹스에서
src 부분에 새로운 파일을 만들어주자 내가 만들 파일의 이름은
shipNFT.sol
원래 shipscam 으로 할랬는데 이미지를 생각해서
scam은 뺐다. 코드는 다음과 같다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";

contract shipNFTs is ERC721URIStorage, Ownable, ERC721Enumerable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() public ERC721("shipNFT", "NFT"){}

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal
      override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function _burn(
        uint256 tokenId
    ) internal
      override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

  function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
    function tokenURI(
        uint256 tokenId
    ) public view
      override(ERC721, ERC721URIStorage) returns (string memory) {
        return super.tokenURI(tokenId);
    }
    
    function mintNFT(address recipient, string memory tokenURI) public onlyOwner returns (uint256) {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}

openzeppelin을 통해 상속받은 컨트랙트 중 겹치는 함수에 대해 override를 했다고 한다. 뭔말인지는 잘모르겠다ㅎ

여튼 특정 컨트랙트에 있는 함수를 사용하기 위해서는 컨트랙트의 ABI가 필요하다

네? ABI요? API요? 뭐요? 이 뭔 개소리야 라고 생각하는 분들을 위해 사족을 붙입니다.
자 여기서 컨트랙트의 ABI가 무엇이냐?

ABI란 컨트랙트 함수와 매개변수들을 JSON 형식으로 나타낸 리스트이다.

네 뭔 개소린가 싶습니다.

잘 정리되있는 블로그 링크를 첨부한다.

https://velog.io/@younghwan/ABI

요약해보자면
ABI는 보통 두 프로그램 모듈의 인터페이스 역할을 한다. 인터페이스는 데이터를 기계 코드로 인코딩/디코딩 하기 위한 방법이다. 이더리움에서 EVM에 솔리디티 컨트랙트를 호출 할 시 인코딩 하거나 트랜잭션 들로부터 데이터를 읽는 방법이다.
ABI는 컨트랙트 내의 함수를 호출하거나 컨트랙트로 부터 데이터를 얻는 방법이다.
컨트랙트 내에 여러 함수가 존재한다. ABI는 컨트랙트 내의 어떤 함수를 호출할지 지정하는데 필요하며 우리가 생각했던 대로 함수가 데이터를 리턴한다는 것을 보장하기 위해 반드시 필요하다.

좀만 더 요약해보자면 나에게 필요한 컨트랙트를 호출하기 위한 수단이 ABI이다.

몇가지 함수 interface 규격을 정해 만족하는 함수를 모아 놓은 것이 ERC20이고
totalSupply 등 과 같은 함수들이 존재하는 것을 알고 있기 때문에 ABI를 통하여 호출해 사용 할 수 있는 것이다. 컨트랙트는 블록체인의 특정 주소에 바이트코드로 저장 되어 있다

자 우리는 ABI가 뭔지 이제 알았다. 그럼 ABI를 어떻게 어디서 가져오느냐도 궁금할 것이다.

코드를 컴파일 하게 되면

어머 사진크기 어떻게 줄이니
사진 제일 밑에 보면 쪼매낳게 ABI와 바이코드가 나와있다 ABI를 눌러주자

다음은 src 폴더 안에 erc721Abi.js 파일을 생성하고 요렇게 작성해주자

// src/erc721Abi.js
let erc721Abi =  // 복사한 ABI를 붙여넣자
export default erc721Abi;

그다음은 APP.js에서 import 해준다 어떻게?
요렇게

import erc721Abi from "./erc721Abi"
function App() {
	//..

자 이제 메타마스크 지갑과 연동해야 한다. 지갑을 켜고 로그인을 한뒤
메인넷을 롭스텐테스트넷으로 바꿔주자.

environment는 injected web3
account 는 자기 지갑 주소
컨트랙트는 내가 발행하고자 하는 아까 만든 src/shipNFT(필자의 파일명이 이렇지 그대들은 그대들의 컨트랙트를 찾아보라)

해주고 transact!!

리믹스 하단 cli 화면에서 배포가 끝난걸 확인하고

배포 후 mintNFT 함수로 NFT 2개를 민팅한다.
recipient는 리액트 어플리케이션과 연결한 계정의 주소를 기입하고
tokenURI는 자신의 블로그 혹은 올릴만한 이미지의 링크를 기입한다.

아 여기서 잠깐 tokenURI 부분을 자세히 살펴보자
uri가 https://ipfs.io 뭐시기로 나와있다.

이 부분은 ipfs 사용 방법 블로깅을 따로 하도록 하겠다.
(ha 때 이거 좀 가르쳐주지;)

어어 그러고 트랜잭트 눌러눌러

아따 힘들다 좀만 쉬었다가 다시 달려보자

profile
죽을 때 까지 공부하다 죽을 인생, 로봇공학자에서 블록체인 개발자가 되기 까지

0개의 댓글