Cute Bow Tie Hearts Blinking Pink Pointer

블록체인

[이더리움] web3 라이브러리 설치 및 기능 테스트

청포도 에이드 2022. 6. 28. 17:32
728x90

web3 라이브러리

 

이더리움 네트워크는 노드로 구성되어 있고, 각 노드는 블록체인의 복사본을 가지고 있더. 만약 스마트 컨트랙트의 함수를 실행하고자 한다면, 이 노드들 중 하나에 질의를 보내 아래 내용을 전달해야 한다:

  1. 스마트 컨트랙트의 주소
  2. 실행하고자 하는 함수, 그리고
  3. 그 함수에 전달하고자 하는 변수들

이더리움 노드들은 JSON-RPC라고 불리는 언어로만 소통할 수 있고, 이는 사람이 읽기는 불편하다. 컨트랙트의 함수를 실행하고 싶다고 질의를 보내는 것은 아래와 같다.

 

터미널에서 curl문법을 사용할 때:

 

curl -X POST \
-H "Content-type: application/json" \
--data '{ "jsonrpc":"2.0", "method":"eth_accounts","params":[]}' \
http://localhost:8545



(request method 기본적으로 다 post임)
(헤더부분 content-type 다 application/json)

 

간단하게 postman이나 썬더 클라이언트를 사용하면,

데이터를 실어 보낼 때, 아래처럼 작성만 해주면 된다.


{
"id":1337 (가나슈가 제공해주는 체인 아이디),
"jsonrpc":"2.0", //필수
"method":"eth_accounts", // 필수
"params":[]
}
여기서 method 항목은? core, set, getBalance, 같은 메서드이다.


etherenum jsonrpc 홈페이지에 메서드 나와있으니 읽어보면 어떻게 사용하는 지 다 알 수 있다. 


https://ethereum.github.io/execution-apis/api-documentation/

 

다행히도, Web3.js는 이런 골치 아픈 질의를 몰라도 되게 해준다. 우리는 편리하고 쉽게 읽을 수 있는 자바스크립트 인터페이스로 상호작용을 하면 되는 것!

 

그럼 설치 해보자.

 

test를 해보기 위해 jest도 다운로드 해주겠다.

 

npm init -y
npm install -D jest
npm install web3
npm install ethereumjs-tx # Transaction 객체를 이더리움 클라이언트가 이해할 수 있게 만들어주는 라이브러리
#서명 만들려고~
# 우선 이것도 깔아주자!

 

Web3가 가진 다양한 모듈

 

 

web3-eth : 이더리움 블록체인과 스마트 컨트랙트 모듈이다.
web3-utils : dApp 개발자를 위한 유용한 헬퍼 함수를 모아둔 모듈이다.
web3-bzz : 탈중앙화 파일 스토리지를 위한 스왐 프로토콜 모듈이다.
web3-shh : P2P 커뮤니케이션과 브로드캐스트를 위한 위스터 프로토콜 모듈이다.

 

 

자주 쓰이는 메서드 모음

 

web3.eth.getAccounts()	//노드에 의해 관리되는 계정들을 배열로 반환
web3.eth.getBlockNumber()	//가장 최근 블록의 번호를 반환
web3.eth.getBalance()	//주어진 주소의 잔액을 반환
web3.eth.getBlock(blockHashOrBlockNumber [, returnTransactionObjects])//블록 번호 또는 해쉬와 일치하는 블럭을 반환
web3.eth.getBlockTransactionCount(blockHashOrBlockNumber)	//주어진 블럭 안에 있는 transaction의 수 반환
web3.eth.getTransaction(transactionHash [, callback])	//주어진 해시와 일치하는 transaction 반환
web3.eth.getTransactionCount(address)	//계정으로부터 보내진 transaction의 수 반환
web3.eth.sendTransaction(transactionObject [, callback])	//network로 transaction 전송
web3.eth.sendSignedTransaction(signedTransactionData)	//서명이 완료된 transaction 전송
 

web3.utils.toHex(mixed)	//주어진 값을 Hex로 변환해서 hex 문자열로 반환
web3.utils.toWei(number [, unit])

 

 

jest.config.js 루트 디렉토리에 파일을 추가해주자.
const config = {
  verbose: true,
  testMatch: ["<rootDir>/**/*test.js"],
};
module.exports = config;

 

그리고 package 다운로드가 모두 끝났다면,

 

package.json 파일도 수정해주자.

  "scripts": {
    "test": "jest"
  }
  //scripts 안의 test 항목을 "jest"로 바꾸자.

이렇게 하면 npm run test를 터미널에 입력하여 테스트 코드를 빠르게 실행할 수 있다.

 

 

본격적으로, 테스트 코드를 작성해보자.

 

const Web3 = require("web3");
const ethTx = require("ethereumjs-tx").Transaction;
describe("Web3 테스트코드", () => {
  let web3;
  let accounts;
  let sender;
  let receiver;
  it("web 연결 테스트", () => {
    web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.01:8545"));
    console.log(web3);
  });

  //최신블럭의 번호 가져오기

  it("Latest Block 높이 가져오기", async () => {
    const latestBlock = await web3.eth.getBlockNumber();
    console.log(latestBlock);
    // eth.getBalance
  });

  it("전체 accounts 가져오기", async () => {
    accounts = await web3.eth.getAccounts();
    sender = accounts[0];
    receiver = accounts[1];
    console.log(accounts, sender, receiver);
  });

  it("첫번째 계정 밸런스 가져오기", async () => {
    const balance = await web3.eth.getBalance(accounts[0]);
    console.log(balance); // wei 단위로 이더를 표현했다.
    console.log(balance / 10 ** 18);
    // 1 ETH = 10^18
  });

  it("ETH 단위 변경해보기", () => {
    //eth
    //gwei
    //wei
    console.log(web3.utils.toWei("1", "gwei"));
    console.log(web3.utils.toWei("1", "ether"));
  });

  it("트랜잭션 횟수 구해오기", async () => {
    const txCount = await web3.eth.getTransactionCount(sender);
    console.log(txCount);

    console.log(web3.utils.toHex(txCount));
  });

  it("트랜잭션 실행하기", async () => {
    const txCount = await web3.eth.getTransactionCount(sender);
    // e2df70dfa0b038f4c2d1d7ec5262c411d3380bde3f1f5471b016a65a2cc44878
    const privateKey = Buffer.from(
      "e2df70dfa0b038f4c2d1d7ec5262c411d3380bde3f1f5471b016a65a2cc44878",
      "hex"
    );
    const txObject = {
      nonce: web3.utils.toHex(txCount),
      from: sender,
      to: receiver,
      value: web3.utils.toHex(web3.utils.toWei("1", "ether")), //단위 Wei로 보내야함 10 ** 18 -> toHex
      gasLimit: web3.utils.toHex(6721975), // 아반떼 연료통이 55 L
      gasPrice: web3.utils.toHex(web3.utils.toWei("1", "gwei")), // 1L 당 = 2,000
      data: web3.utils.toHex(""),
    };
    const tx = new ethTx(txObject);
    tx.sign(privateKey);
    console.log(tx);
    const serializedTx = tx.serialize();
    // console.log(serializedTx.toString("hex"));
    const TransactionObject = await web3.eth.sendSignedTransaction(
      "0x" + serializedTx.toString("hex")
    );
    console.log(TransactionObject);
  });

  it("balance확인", async () => {
    const SenderBalance = await web3.eth.getBalance(sender);
    const ReceivedBalance = await web3.eth.getBalance(receiver);

    console.log("sender balance : ", SenderBalance / 10 ** 18);
    console.log("Received balance : ", ReceivedBalance / 10 ** 18);
  });

  it("가스 사용량 확인하기", async () => {
    // 가스 사용량 21004
    // 21000 + 4
    // 가스 사용량 21004 // 기름 10L 넣을거야. -> 한번에 넣을 kg
    // 가스최대치 6721975 
    // 가스비 = 가스가격 * 가스한도

    const gas_price = 4; //4gwei를 사용하면 2분 내로 전송가능
    console.log((gas_price * 21004) / 10 ** 8 + "ETH");
  });
});

 

이 코드를 실행하기 전에는, 늘 터미널에서 ganache-cli를 먼저 실행시킨 상태여야한다.

 

1 wei = 10^18 Eth

1 Gwei = 10^9 wei

 

(10의 9 승 표기 = G (Giga, 기가))

(10의 18승은 E로 표기하고 Exa(엑사)라고 읽는데, 이더리움의 E를 따와서,

아마 이더의 최소단위인 1wei가 10^18 이더가 되지 않았나 하는 추측.....(뇌피셜임))

 

Reference:

 

https://velog.io/@citron03/web3.js%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C

 

web3.js에 대해서

web3는 각 사용자가 노드가 되어 탈중앙화된 분산네트워크를 구성하여, 네트워크에서 정보를 읽거나 쓸 뿐만 아니라, 서비스를 제공할 수도 있는 이코노미를 의미한다.

velog.io

https://yellow-w.tistory.com/340

 

이더리움3. web3 라이브러리

목차 web3란? 셋팅 클래스 및 인스턴스 주요 메서드를 이용한 기능 구현 테스트 1. Web3란? 이더리움 생태계를 구축하기 위한 함수들을 포함하고 있는 모듈들의 집합인 라이브러리 2. 셋팅 2-1. 프로

yellow-w.tistory.com

 

728x90