13. kaia (실제 블록체인 네트워크)에 배포

동동주·2025년 11월 28일


Todo :
0. 파일 정리
1. API 콜을 이용한 데이터 요청
2. Block explorer
3. 배포
4. 다음에 할 내용 :




0. 파일 정리

  • git mv 사용해서
    사용하지 않을 파일 archived 폴더로 옮겨주고 (+이름변경)

  • git checkout 사용해서
    Decentralized access control (분산형 접근 제어) 사용 전 commit 당시의
    TinyBank.sol & TinyBank.ts 파일 가져와줌
    (기존 파일은 archived로 옮긴 뒤 이름 변경해줌)

* TinyBank.ts는 사용 전 버전에서 event emit 체크 안되어 있던 부분 수정 따로 해줌 (= 12-2. TinyBank.vy 완성 글에 있는 2.이벤트 구현 부분 설명 참고)

+ 명령어 사용 방법 참고 : git 명령어 메모..,,


파일은
MyToken.sol , TinyBank.sol(수정), ManagedAccess.sol
이렇게 3가지만 필요함 (각각 test 파일도 당연히 필요)




1. API 콜을 이용한 데이터 요청

기본 정보

  • ethernodes.org
    이더리움 노드에 대한 정보를 볼 수 있는 사이트

  • ethereum.org >> json-rpc
    노드랑 상호작용 할 수 있게 해주는 것이 json-rpc API이다.
    (그동안은 hardhat이 알아서 해줌.)
    → 원하는 기능의 api 페이지에서 사용법, 사용예제 볼 수 있다

// Request                                                                         ─╯
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1b4", true],"id":1}'

zsh: permission denied: //
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information

물론 그냥 example 부분만 사용하면 curl: no URL specified! 가 뜨기에
상호작용할 노드의 링크가 필요하다.


1-1) block 정보 가져오기

- getBlockByNumber

// Request                                                                         ─╯
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1b4", true],"id":1}' https://ethereum-rpc.publicnode.com

zsh: permission denied: //
{"jsonrpc":"2.0","id":1,"result":{"difficulty":"0x4ea3f27bc","extraData":"0x476574682f4c5649562f76312e302e302f6c696e75782f676f312e342e32","gasLimit":"0x1388","gasUsed":"0x0","hash":"0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0xbb7b8287f3f0a933474a79eae42cbca977791171","mixHash":"0x4fffe9ae21f1c9e15207b1f472d5bbdd68c9595d461666602f2be20daf5e7843","nonce":"0x689056015818adbe","number":"0x1b4","parentHash":"0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x220","stateRoot":"0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d","timestamp":"0x55ba467c","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}}

이렇게 잘 입력하면 로그가 길게 뜬다.

위의 결과는 transaction이 없어서 그 부분이 비어있지만,
"params":["0x1b4", true] 부분의 숫자를 바꿔주면 (ex.0x999999) transaction 부분이 채워져서 엄청 길게 출력된다....
(해당 파라미터 부분을 사용하는 방법은 아까 API 문서에서 보면 된다.)


입력한 내용 뒤에 | jq를 적어서 jq라는 툴을 사용하면 이렇게 보인다고 한다... 뭔가 설치해야하는 것 같다?
jq


1-2) transaction 정보 가져오기

- getTransactionByHash

❯ curl -X POST --data
'{"jsonrpc":"2.0","method":"eth_getTransactionByHash",
"params":["0x88cd8a125e766e2842c25c4e7d7de7cb12275a4e7075881f4c49946e535dd870"],"id":1}' 
https://ethereum-rpc.publicnode.com

{"jsonrpc":"2.0","id":1,
"result":
{"blockHash":"0x13b20820ee2c6e0c123b3407813a5f9357a84431d67fa68570221c932e33605b",
"blockNumber":"0x999999",
"from":"0xae2d4617c862309a3d75a0ffb358c7a5009c673f",
"gas":"0x186a0",
"gasPrice":"0x6288af880",
"hash":"0x88cd8a125e766e2842c25c4e7d7de7cb12275a4e7075881f4c49946e535dd870",
"input":"0xc658695c000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000f0f79cefd16b64b7e7e41cac6cadfcb659ee22d600000000000000000000000050a14bb6f3bfd3ac44ddbfe08e70fabbe77ea5b90000000000000000000000000000000000000000000000000000000d81d8485000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"nonce":"0x30e2",
"to":"0xa24787320ede4cc19d800bf87b41ab9539c4da9d",
"transactionIndex":"0x20",
"value":"0x0",
"type":"0x0",
"v":"0x1c",
"r":"0xd0608a9bed6d87530e824ce314b29c3efbcfce967afd07c2c71c67d898144adf",
"s":"0x6d9f73ef1346c3bd9f16712436fdfeab7b8fdaf4cc8271b3279cc6f7923498ef"}}

v,r,s는 서명값.

⇒ number(blockNumber) : 여기서는 0x999999
⇒ hash : getBlockByNumber 했을 때 transaction 부분에 나온 것들. (한 transacion? 내에서는 아무거나 사용해도 동일하게 나오는 것 같음)
⇒ index(transactionIndex) : 여기서는 0x20

- getTransactionByBlockNumberAndIndex

로 호출해도 같은 블록의 값을 넣으면 동일한 결과(블록)가 나온다

이것 말고도 많이 있고 같은 블록을 다르게 가져올 수도 있다~


1-3) receipt 정보 가져오기

getTransactionReceipt

❯ curl -X POST --data
'{"jsonrpc":"2.0","method":"eth_getTransactionReceipt",
"params":["0x88cd8a125e766e2842c25c4e7d7de7cb12275a4e7075881f4c49946e535dd870"],"id":1}' 
https://ethereum-rpc.publicnode.com

{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x13b20820ee2c6e0c123b3407813a5f9357a84431d67fa68570221c932e33605b",
"blockNumber":"0x999999","contractAddress":null,"cumulativeGasUsed":"0x4613a5","effectiveGasPrice":"0x6288af880","from":"0xae2d4617c862309a3d75a0ffb358c7a5009c673f",
"gasUsed":"0xa907",
"logs":
[
	{
	"address":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
	"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x00000000000000000000000050a14bb6f3bfd3ac44ddbfe08e70fabbe77ea5b9","0x000000000000000000000000ae2d4617c862309a3d75a0ffb358c7a5009c673f"],
	"data":"0x0000000000000000000000000000000000000000000000000000000d81d84850",
	"blockNumber":"0x999999",
	"transactionHash":"0x88cd8a125e766e2842c25c4e7d7de7cb12275a4e7075881f4c49946e535dd870",
	"transactionIndex":"0x20",
	"blockHash":"0x13b20820ee2c6e0c123b3407813a5f9357a84431d67fa68570221c932e33605b",
	"blockTimestamp":"0x5ebda821",
	"logIndex":"0x49",
	"removed":false
    },
    
	{
    "address":"0x50a14bb6f3bfd3ac44ddbfe08e70fabbe77ea5b9",
		"topics":["0xd0ed88a3f042c6bbb1e3ea406079b5f2b4b198afccaa535d837f4c63abbc4de6","0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0x000000000000000000000000ae2d4617c862309a3d75a0ffb358c7a5009c673f"],
        "data":"0x0000000000000000000000000000000000000000000000000000000d81d84850",
        "blockNumber":"0x999999",
        "transactionHash":"0x88cd8a125e766e2842c25c4e7d7de7cb12275a4e7075881f4c49946e535dd870",
        "transactionIndex":"0x20",
        "blockHash":"0x13b20820ee2c6e0c123b3407813a5f9357a84431d67fa68570221c932e33605b",
        "blockTimestamp":"0x5ebda821",
        "logIndex":"0x4a",
        "removed":false
	}
],
"logsBloom":"0x00000000000000000000000000000000000080000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000008000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000208000000010000000000000000000000000100000000200000000000000000000000000000004000000000002000000000000002000000000000000000000000000000000000000008880000000000000800000000000000000200200000000004000000000000000000000000000000",
"status":"0x1",
"to":"0xa24787320ede4cc19d800bf87b41ab9539c4da9d","transactionHash":"0x88cd8a125e766e2842c25c4e7d7de7cb12275a4e7075881f4c49946e535dd870","transactionIndex":"0x20","type":"0x0"}}
  • status
    revert 되면 0, 아니면 1

  • log, gasUsed..
    아까랑 비슷하지만(비슷한 부분 안보이게 해둬서 크게 티가 안나지만)
    log, gas사용량 등을 볼 수 있음

  • topic 내용
    가장 먼저 올라오는 건 어떤 이벤트였는지에 대한 정보 (해시값으로 표현)
    그 뒤는 인덱스를 붙인 항목에 대한 해시값
    +나머지 정보는 data 항목에 인코딩되어서 표현

  • logBloom
    빠르게 원하는 이벤트의 유무를 검색할 수 있게 해주는 항목이다?




2. Block explorer

블록 익스플로러(Block Explorer)
: 블록체인 거래 정보를 검색하고 확인할 수 있는 웹 기반 도구
etherscan.io

기능

- block & transaction

  • 네이밍 서비스(주소를 이름으로 등록 가능),
  • 담긴 transaction 및 internal(contract가 발생시킨 contract) transaction 정보,
  • 사용된 가스를 ETH / 현재 달러가치로 환산한 금액정보 제공
    등 정보를 가공해서 알려줌

- FT & NFT

  • FT = Token (우리가 만든 MyToken 같은 거)
    내가 가진 토큰 1개랑 친구가 가진 토큰 1개가 같음
    *ERC-20 = 스마트 컨트랙트 기반 토큰의 표준

  • NFT = 동일한 것이 없이 유일함 (대체불가)

  • Wrapped BTC = ERC-20으로(wrapped) BTC랑 같은 가치의 토큰을 만든 것
    *원리
    실제 비트코인 네트워크의 코인을 잠그고, 그 동일한 개수만큼 토큰을 발행
    잠긴 것을 안전한 방법으로 보장하면 가치가 동일해짐

Token (=smart contract based)
native token (자체 블록체인 네트워크를 가지고 있는 암호화폐)
참고 : 4-3. Token Contract 만들어보기


- transfer 확인 기능

이더리움에서 생기는 transfer event를 모두 모아두고 볼 수 있다

  • Blockchain, Token, NFT에 대한 transfer
  • 특정 smart contract 에 대한 transfer 모아보기
    *원리
    아까 본 logs들을 파싱(원하는 데이터를 추출하여 가공하기 쉬운 상태로 바꾸는 것)하여 데이터베이스에 쌓아둠
    → 확인하는 기능을 제공함
    (transaction hash와 위에 다룬 api로 제공하는 정보가 진짜 존재하는지 확인 가능)

- Token 정보

예시 사이트

  • Contract Source Code
    소스코드를 볼 수 있음!!
    Ownerable, ifAdmin.. 등의 접근제어자나 transferFrom 같은 함수도 볼 수 있따 (위의 사이트에서는 ifAdmin만 찾음)
    → 직접 개발자가 올려줘야 함 (바이트코드만으로 완전하게 복원할 수 없음)

  • ABI
    contract 함수들의 정의 (파라미터, 리턴값) 를 모아서 정리한 리스트
    참고 : [Blockchain] ABI 란? / JSON-RPC 란? / web3.js 란?

  • Creation Code
    블록체인에 배포할 때 사용하는 코드
    (transaction 에 input으로 넣고 배포함)

  • Deployed Bytecode
    컴파일 된 결과물




3. 배포


3-1) 환경설정

- ignition/modules/Mytoken.ts

(없어도 됨!)

❯ git mv ignition/modules/MyToken.ts ignition/modules/Deploy.ts

4-3. Token Contract 만들어보기 에서 컨트랙트를 만들고 배포해본 파일이 있었다.
그 파일로 이름 바꿔서 사용했다

- ignition/modules/Deploy.ts

import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

export default buildModule("MyTokenDeploy", (m) => {
  const myTokenC = m.contract("MyToken", ["MyToken", "MT", 18, 100]);
  const tinyBankC = m.contract("TinyBank", [myTokenC]);
  return { myTokenC, tinyBankC };
});

- 터미널 (배포테스트)

npx hardhat ignition deploy ignition/modules/MyToken.ts --network localhost

hardhat 로컬 네트워크 환경에서 배포 테스트
(4-3과 동일한 내용이라 설명 생략)


- hardhat.config.ts

testnet token을 얻기 쉬운 카이아 테스트넷(kairos) 환경에 배포해볼 예정이다.

import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@nomiclabs/hardhat-vyper";

const config: HardhatUserConfig = {
  solidity: "0.8.28",
  vyper: {
    version: "0.3.0",
  },
  networks: { //추가
    kairos: {
      url: "https://public-en-kairos.node.kaia.io",
      accounts: [
  "0x8fd393db54c281c39d0aa62c2de891c0e9c720faad3be3ecec2cda723baf2eca",
      ],
    },
  },
};

export default config;
  • url :
    kaia Docs > 레퍼런스 > Public JSON RPC Endpoints 페이지
    Testnet (Kairos) Public JSON-RPC Endpoints 중에서
    https://public-en-kairos.node.kaia.io 이걸 사용했다.

  • account :
    kaia toolkit > Account > Account from private key 에서
    Generate 누르면 나오는 private key 를 사용하면 된다.
    + Confirm을 누르면 주소 등의 정보도 나온다. (주소 필요함!)

  • 테스트를 위한 잔고 채우는 법
    kaia faucet에서
    주소를 넣고 run faucet을 눌러주면 50KAIA를 받을 수 있다.
    하루 (24시간)에 한번만 된다고 알림이 뜬다
    kaia faucet

3-2) 배포하기

- 터미널 (배포)

❯ npx hardhat ignition deploy ignition/modules/Deploy.ts --network kairos  

(이미 배포했는데 다시하는 경우 뒤에 --reset 추가)

실패하면 이렇게 보이고
deploy validation failed
성공하면 이렇게 나온다!
successfully deployed

- kaiascan.io (Block explorer)

처음에 살펴보았던 Block explorer가 kaia에도 있다.
kaiascon.io 에 들어가서 메인넷 설정 말고
테스트넷(카이로스)으로 변경해준 사이트 로 들어간다.
(페이지 우측 상단 영어/한국어 언어 설정하는 쪽에 있다)

여기 커서가 있는 입력창에 아까 배포한 MyToken의 주소를 입력하면
배포된 상태인 것을 볼 수 있다!!
kaia scan - contract

이제 여기 하단에 보이는 Contract 부분에 소스코드를 올려보려고 한다.

3-3) verify contract (소스코드 올리기)

소스코드를 올리는 과정은 올리고자 하는 소스코드가 배포된 바이트코드와 배포할 때 사용한 constructor parameter와 동일한지 확인한다. (verify)

- hardhat.config.ts

hardhat 환경이기 때문에 Smart Contract VerificationHardhat Verify 페이지에서 가져와 입력해줬고 (,입력조심)

import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@nomiclabs/hardhat-vyper";

const config: HardhatUserConfig = {
  solidity: "0.8.28",
  vyper: {
    version: "0.3.0",
  },
  networks: {
    kairos: {
      url: "https://public-en-kairos.node.kaia.io",
      accounts: [
        "0x8fd393db54c281c39d0aa62c2de891c0e9c720faad3be3ecec2cda723baf2eca",
      ],
    },
  },
  etherscan: {
    apiKey: {
      kairos: "unnecessary",
    },
    customChains: [
      {
        network: "kairos",
        chainId: 1001,
        urls: {
          apiURL: "https://kairos-api.kaiascan.io/hardhat-verify",
          browserURL: "https://kairos.kaiascan.io",
        },
      },
    ],
  },
};

export default config;

- 터미널 (MyToken 소스코드 올리기)

❯ npx hardhat verify --network kairos 0x1314~~(주소) MyToken MT 18 100 

네트워크 이름, 배포한 컨트랙트의 주소, constructor parameter를 쉼표/따옴표 없이 그대로 적어주면
Successfully verified contract MyToken on the block explorer.
성공했다는 설명이 뜨고 (Successfully verified contract MyToken on the block explorer.)
![Contract (MyToken source code)](

)
처음에 살펴봤던 다른 컨트랙트들처럼 소스코드가 잘 보이는 것을 볼 수 있다!!

이렇게 소스코드를 올리면 투명하게 누구나 볼 수 있다는 장점도 있지만
계약 읽기
계약 쓰기
이렇게 코드로 확인하고 하던 것들을 UI로 볼 수 있다...
(영어 설정 해놔도 창 바뀔 때마다 한국어로 돌아가서 그냥 캡쳐함)

- 터미널 (TinyBank 소스코드 올리기)

❯ npx hardhat verify --network kairos 0xDcCF~(TinyBank주소) 0x1314~(MyToken주소)

얘는 constructor parameter 가 MyToken주소였으니 그걸 넣어주면
Contract (TinyBank source code)

4. 다음에 할 내용 :

배포한 contract랑 상호작용을 해 볼 예정
→ Web3.. 같이 어플리케이션을 만드는 것과 관련 있다..?

profile
배운 내용 정리&기록, 스크랩

0개의 댓글