Web3 - Library

Hong·2022년 12월 22일
0
post-thumbnail







📡 왜 web3.js가 필요할까?

//JSON-RPC방식
{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155","to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","gas":"0x76c0","gasPrice":"0x9184e72a000","value":"0x9184e72a","data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}],"id":1}

//web3 라이브러리 사용방식
CryptoZombies.methods.createRandomZombie("Vitalik Nakamoto 🤔")
  .send({ from: "0xb60e8dd61c5d32be8058bb8eb970870f07233155", gas: "3000000" })

이더리움 노드들은 JSON-RPC방식을 통해 서로 소통한다.

JSON-RPC방식은 사람이 읽기 어렵다.
이러한 문제를 web3.js가 해결하며 web3.js를 통해 자바스크립트 interface로 우리는 이더리움 노드들과 상호작용할 수 있다.




👨‍🏭 web3.js provider

const Web3 = require('web3');

//provider설정 : http..안에 infura등의 url이 들어간다
function getWeb3() {
  const web3 = new Web3(new Web3.providers.HttpProvider('http://...'))
  return web3;
}

Web3.js에서 Web3 provider를 설정하는 것은 내가 작성한 스마트 컨트랙트 코드의 읽기와 쓰기를 어떤 노드가 처리해줄 것인지 선택하는 것과 같다.

이는 전통적인 웹 앱에서 API 호출을 위해 원격 웹 서버의 URL을 설정하는 것과 같다.
나의 PC에 이더리움 노드를 설치하고 provider로 지정할 수 있지만, 이더리움 전체 노드의 용량이 크기 때문에 비효율적인 방법이다.
때문에 DApp의 개발자들의 편의성을 위해 각 PC에서 이더리움 노드를 운영할 필요가 없도록 하기 위해 Infura서비스가 만들어졌다.

그리고 메타마스크는 내부적으로 Infura의 서버를 Web3 provider로 사용한다
(provider변경도 가능함).




🍳 web3.js 컨트랙트 인스턴스화하기(instantiate)

// myContract 인스턴스화
var myContract = new web3js.eth.Contract(myABI, myContractAddress);



💡 Web3.js의 Contract arguments

내가 작성한 스마트 컨트랙트와 통신하기 위해(이미 배포됨) 2가지를 필요로 한다

var myContract = new web3js.eth.Contract(myABI, myContractAddress);
  • ABI
    ABI는 Application Binary Interface의 줄임말이다. 기본적으로 JSON 형태로 나의 컨트랙트 메소드를 표현하는 것이다.
    ABI는 remix등의 solidity 컴파일러로부터 얻을 수 있다.

  • 컨트랙트의 주소
    내가 작성한 코드를 remix나 truffle등을 통해 이더리움 블록체인 네트워크에 배포하면
    contract 주소를 얻을 수 있다.
    내가 배포한 contract를 가지고 web3.js를 통해 무엇인가를 하고 싶다면(javascript, html, css등으로 무엇인가 앱을 만들고 싶다면) 내가 이더리움 네트워크에 배포한 contract주소를 알아야 한다




🔔 Web3.js에서 Contract의 함수를 호출하기

배포된 Contract의 함수를 사용하기 위해서 두 개의 메소드를 써야한다

  • call
//123을 매개 변수로 myMethod라는 이름의 함수를 call했다
myContract.methods.myMethod(123).call()

call은 view와 pure 함수를 위해 사용한다.
로컬 노드에서만 실행하고, 블록체인에 트랜잭션을 만들지 않는다.
view와 pure 함수는 읽기 전용이고 블록체인에서 상태를 변경하지 않는다.
가스를 전혀 소모하지 않고, 메타마스크에서 트랜잭션에 서명하라고 사용자에게 창을 띄우지도 않는다.

  • send
//123을 매개 변수로 myMethod라는 이름의 함수를 호출하는 트랜잭션을 send했다
myContract.methods.myMethod(123).send()

send는 트랜잭션을 만들고 블록체인 상의 데이터를 변경한다.
view와 pure가 아닌 모든 함수에 대해 send를 사용해야 하는 것이다.
트랜잭션을 send하는 것은 사용자에게 가스를 지불하도록 하고, 메타마스크에서 트랜잭션에 서명하라고 창을 띄울 것이다. Web3 프로바이더로 메타마스크를 사용할 때, send()를 호출하면 자동으로 이 모든 것이 이루어지고, 내가 작성하는 코드에 어떤 특별한 것도 추가할 필요가 없다.




📚 Web3 Library

web3.js는 아래와 같은 라이브러리가 존재한다

web3.eth, web3.eth.subscribe : 노드 관련 라이브러리
web3.eth.Contract, web3.eth.abi : 컨트랙트 관련 라이브러리
web3.eth.accounts : 계정, 지갑관련 라이브러리
web3.eth.personal : 트랜잭션 관련 라이브러리
web3.*.net : 이더리움이 아닌 다른 블록체인 네트워크를 추가하여 사용하는 경우
web3.utils : 암호화 등 유틸 라이브러리
web3.eth.ens
web3.eth.Iban


기본적인 라이브러리 함수를 알아보자




web3.eth.getGasPrice()

//가스비를 resturn한다.
web3.eth.getGasPrice().then((result) => {
  console.log(result);
})

이더리움에 컨트랙트를 배포할 때는 네트워크 사용량에 따라 Gas fee가 발생함. 가스비를 잘못 책정하는 경우, 트랜잭션을 실행하다가 가스비가 고갈되면 트랜잭션이 revert되는 문제가 발생함. 따라서 적절한 가스비를 계산해야 트랜잭션을 배포할 수 있음.



web3.eth.getBlock(blockHashOrBlockNumber)

//인자로 블록의 해시값이나 블록 숫자, "earliest" "latest" "pending"의 string 값이 들어가기도 함
web3.eth.getBlock(blockHashOrBlockNumber).then((result) => {
  console.log(result);
})

아래와 같은 정보가 return됨



web3.eth.getBalance(account)

web3.eth.getBalance(계정주소).then((result) => {
  console.log(result);
})

특정 주소의 잔액을 보여준다(wei단위로 보여줌).
그래서 아래와 같이 utils의 fromWei 라이브러리를 사용해서 변환가능

web3.eth.getBalance(계정주소).then((result)=>{
	return web3.utils.fromWei(price."ether");
}) 
.then((eth)=>{
	console.log(eth);
})


web3.eth.getTransaction(txHash)

web3.eth.getTransaction(트랜잭션 해시 값).then((result) => {
  console.log(result);
})

트랜잭션을 조회할수 있는 method



web3.eth.getTransactionReceipt(txHash)

web3.eth.getTransactionReceipt(txHash).then((result) => {
  console.log(result);
})

완료된 트랜잭션의 영수증을 들고옴



web3.eth.getPendingTransactions()

web3.eth.getPendingTransactions().then((result) => {
  console.log(result);
})

provider가 요청한 contract 중 pending상태인 transaction을 들고옴







공식문서

profile
Notorious

0개의 댓글