🦁 [PROJECT LION] NFT 블록체인 마켓 앱 만들기 with 그라운드X 3기 - 챕터 4-3 회고


KAS ( Klaytn API Service )

Klaytn에서 제공하는 클레이튼 네트워크 전용 API

클레이튼 환경에서 dApp을 개발하려면
클레이튼 네트워크에 엔드포인트(Endpoint Node) 를 띄워야 하는데

KAS를 사용하면 Endpoint Node 역할을 해줘서
따로 노드를 띄울 필요없이 API 로 개발이 가능하다


Caver-js

‘caver-js’ 는 개발자가 HTTP 또는 웹소켓 연결을 사용하여
Klaytn 노드와 상호작용할 수 있도록하는 자바스크립트 API 라이브러리

-1. 블록체인 노드에 직접적으로 콜하기 어려워서 KAS 를 사용

-2. KAS 는 우리가 블록체인에 ‘접근’ 하는걸 도와준다

-3. 스마트 컨트랙트에 있는 데이터를 읽고 실행하는걸 도와준다

-4. 이 과정에서 Caver-js 를 쓰면 우리가 사용하는 코드를

-5. 스마트 컨트랙트 블록체인이 이해할수 있는 코드로 ‘변형’ 해줘서

-6. Klaytn 노드와 상호작용할 수 있도록 도와준다


KAS 와 Caver-js를 이용한 dApp 개발 세팅

-1. KSA 웹페이지에 접속하여 키를 생성한다

https://console.klaytnapi.com/ko/security/credential
(👆 Klaytn API Service 키 생성)

생성한 키 AccessKey ID / Secret AccessKey / Authorization
따로 적어두거나 다운로드 받아서 보관해야한다 (노출되면 안됨)
👉 .env 환경변수로 설정해줘야한다


-2. 간단한 스마트 컨트랙트 코드를 작성하고 배포(Deploy)

👉 카운터 숫자를 증가시키는 예제

배포하고 나온 ABI / 컨트랙트 주소 를 복사한다


-3. npx create-react-app . 을 이용하여 리액트 개발환경을 만들어주고 코드를 입력한다

3-1. KAS 에서 발급받은 키를 변수에 담아주고
3-2. Klaytn IDE에서 배포하고 나온 ABI / 컨트랙트 주소도 변수에 담아준다
3-3. 네트워크 체인의 아이디도 입력


-4. ‘생성한 키’ 를 대입하여 Klaytn Node API를 사용하기 위한 코드를 입력한다

https://console.klaytnapi.com/ko/service/node
(👆 코드는 KAS Docs에 나와있음)


-5. Caver-js 를 이용하여 컨트랙트와 리액트 연동작업

5-1. Klaytn IDE 에서 작성한 count 메소드를 호출( Call ) 해본다

5-2. caver-js 에서 기본으로 제공하는 getBalance 함수를 이용하여 지갑의 잔고를 확인해본다


-6. npm run start 로 실행시킨뒤 콘솔을 찍어보면

👆 스마트 컨트랙트 count 의 값과
지갑의 잔고가 잘 찍히는걸 확인 할 수 있다


-7. Klaytn IDE에서 배포된 컨트랙트의 값을 변경해보면
콘솔에 실시간으로 변경된 값과 / 지갑의 잔고 변경 값이 반영이 된다


카운터 숫자를 증가시키는 스마트컨트랙트 예제 코드

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.4.24 <=0.5.6;

contract Count {
    uint256 public count = 0;

    function getBlockNumber() public view returns (uint256) {
        return block.number;
    }

    function setCount(uint256 _count) public {
        count = _count;
    }
}

KAS 와 Caver-js를 이용한 dApp 개발 셋팅코드

import "./App.css";
import Caver from "caver-js";

const COUNT_CONTRACT = "0xdB4854fd2d3c6D65F0d5f581f9d3aE2d93C821FA";
// 배포하고 나온 컨트랙트 주소
const COUNT_ABI = [
  {
    constant: true,
    inputs: [],
    name: "count",
    outputs: [
      {
        name: "",
        type: "uint256",
      },
    ],
    payable: false,
    stateMutability: "view",
    type: "function",
  },
  {
    constant: true,
    inputs: [],
    name: "getBlockNumber",
    outputs: [
      {
        name: "",
        type: "uint256",
      },
    ],
    payable: false,
    stateMutability: "view",
    type: "function",
  },
  {
    constant: false,
    inputs: [
      {
        name: "_count",
        type: "uint256",
      },
    ],
    name: "setCount",
    outputs: [],
    payable: false,
    stateMutability: "nonpayable",
    type: "function",
  },
];
// 배포하고 나온 ABI
const ACCESS_KEY_ID = "KASKQOJG0EB473CRCRCGBH3S";
// KAS에서 발급받은 엑세스 키
const SECRET_ACCESS_KEY = "zkjGXV5JakSEyVtOX3Iy3RdU0lZpgQ3CJYt_YeO0";
// KAS에서 발급받은 비밀 키
const CHAIN_ID = "1001";
// 체인 아이디 바오밥테스트넷은 1001 / 클레이튼 메인넷은 8217

const option = {
  // Klaytn Node API를 사용하기 위한 코드 (Docs에 나와있음)
  headers: [
    {
      name: "Authorization",
      value:
        "Basic " +
        Buffer.from(ACCESS_KEY_ID + ":" + SECRET_ACCESS_KEY).toString("base64"),
    },
    { name: "x-chain-id", value: CHAIN_ID },
  ],
};

const caver = new Caver(
  new Caver.providers.HttpProvider(
    "https://node-api.klaytnapi.com/v1/klaytn",
    option
  )
); // Klaytn Node API를 사용하기 위한 코드 (Docs에 나와있음)

const CountContract = new caver.contract(COUNT_ABI, COUNT_CONTRACT);
// ⭐ 개발자는 '스마트 컨트랙트 주소'와 'ABI'를 알면 'caver' 를 통해
// ⭐ 스마트 컨트랙트를 생성하고 / 특정 함수를 실행할 수 있다
const readCount = async () => {
  const _count = await CountContract.methods.count().call();
  // 스마트컨트랙트 배포후에 나오는 함수
  console.log(_count);
};

// 블록체인 노드에 직접적으로 콜하기 어려워서 KAS 를 사용
// KAS 는 우리가 블록체인에 접근하는걸 도와준다
// 스마트컨트랙트에 있는 데이터를 읽고 실행하는걸 도와준다
// 이 과정에서 Caver-js 를 쓰면 인간이 사용하는 코드를
// 스마트컨트랙트 블록체인이 이해할수 있는 코드로 변형해줘서
// Klaytn 노드와 상호작용할 수 있도록 도와준다
//
const getBalance = (address) => {
  return caver.rpc.klay.getBalance(address).then((res) => {
    // 클레이 잔고를 확인 (다른코인이 있다면 klay말고 적으면 된다)
    const balance = caver.utils.convertFromPeb(
      // convertFromPeb 👉 10 ** 18 로 클레이단위를 변경
      caver.utils.hexToNumberString(res)
      // hexToNumberString 👉 16진수문자열로 변경
    );
    console.log(balance);
    return balance;
  });
};

function App() {
  readCount();
  getBalance("0x21e90d232a37530041469a2d7e7fa3e62fe9d18a");
  return <div className="App"></div>;
}

export default App;