블록체인 공부 RPC,web3 라이브러리

이명진·2024년 2월 5일
0

블록체인

목록 보기
2/2

RPC 란?

Remote Procedure Call 원격 프로시저 호출로
원격 제어를 위한 코딩 없이 다른 주소 공간에서 함수나 프로시저를 실행할수 있게 하는 프로세스 간 통신 기술.
RPC를 이용하면 코드의 함수가 실행 프로그램의 원격에 위치한 것을 동일하게 이용할수 있게 된다.

이를 통해, 내 추측으로 정리한 거지만 동시성이 가능해져서 블록체인상 같은 정보를 공유해야 하는데 한곳에서 실행하면 다른곳에서 실행것처럼 되서 정보를 동일하게 유지할수 있게 되는것 같다.

web 3라이브러리

Curl이란 방식을 사용해 RPC 요청을 보내서 원격 조종을 할수가 있다.

Curl이란 통신을 하다보면 알수 있는 데 모양은 아래와 같다.

$ curl -X POST -H “header 내용 ” —data ‘{name:”데이타”}’

-x: 요청 메소드를 작성한다.
-H :헤더를 작성한다.
-data/-d : 바디 내용을 작성한다.

이런식으로 RPC 요청을 이더리움 클라이언트에 보낸다.

참고로 이더리움은 아래와 같은 형식으로 요청을 보내야 한다고 한다.

* request method  :  POST
* request header option  :  "Content-type: application/json"
* request body

바디 내용도 속성이 정해져 있다.

  • id  :  체인 아이디
    • 이더리움 메인넷 : 1 
    • 이더리움 테스트넷 : 2, 3, 4, 5
    • 가나쉬가 제공하는 네트워크의 체인 아이디 : 1337
  • jsonrpc  :  JSON으로 인코딩된 원격 프로시저 호출
  • method  :  이더리움 클라이언트에서 구현되어 있는 메소드명
  • params  :  메소드의 인자값

이렇게 불편하게 통신을 해야 하지만 Web3 라이브러리는 쉽게 요청을 보낼수 있게 하는 라이브러리 이다.

연결 메소드


const Web3 = require('web3');

let web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:8545'));

HttpProvider 를 사용해 web3 인스턴스를 생성해준다.

전체 accounts 가져오기


 accounts = await web3.eth.getAccounts();

eth.getAccounts 를 통해서 전체 계정을 가져올수 있다 return은 배열 값이고 index로 하나하나에 접근이 가능하다.

특정 계정의 잔액조회

web3.eth.getBalance( ) 메소드를 사용해 특정 계정의 잔액을 조회할 수 있다.
이더리움 네트워크 상에서 잔액의 기본 단위는 wei이다.

const balance = await web3.eth.getBalance(accounts[0]);

0번째 계정의 잔액에 대해서 가져온다.
wei 단위로 Ether를 표현해주는데 아래와 같이 자주 사용되는 단위가 있다.

  • wei  :  1
  • 1 Gwei  =  10 ** 9 wei
  • 1 Ether  =  10 ** 18 wei

트랜잭션 횟수 조회

web3.eth.getTransactionCount( ) 메소드를 사용해 인자값으로 전달한 계정이 발생시킨 트랜잭션의 횟수를 조회할 수 있다.

 const transaction = await web3.eth.getTransactionCount(accounts[0]);

트랜잭션 발생시키기

이 부분은 다른 라이브러리가 필요하다. 이부분은 조금 어려워서 공부하고 있던 페이지의 글과 코드를 다 가지고 온다.

출처 : https://bitkunst.tistory.com/entry/Ethereum%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80-Web3

정리를 해서 순서를 변경했고 전체 코드는 출처에서 상세히 다루기 때문에 참고하면 좋을것 같다.


npm install ethereumjs-tx

// 트랜잭션 객체를 만들고 이더리움 클라이언트가 이해할수 있게 하기 위해서 위의 라이브러리를 활용한다.

트랜잭션 객체 속성값

  • nonce  :  발신자 계정이 발생시킨 총 트랜잭션 횟수
  • from  :  발신자 계정
  • to  :  수신자 계정
  • value  :  보낼 금액 ( 단위 : wei )
  • gasLimit  :  해당 트랜잭션이 사용할 수 있는 가스의 최대치 ( 단위 : gas )
  • gasPrice  :  발신자가 지불하고자 하는 가스 당 가격 ( 단위 : Gwei / gas )
  • data  :  스마트 컨트랙트와 관련된 데이터
// web3 테스트 코드
 
const Web3 = require('web3');
const ethTx = require('ethereumjs-tx').Transaction;
 
describe('web3 테스트 코드', () => {
    let web3;
    let accounts;
 
    let sender; // 보내는 사람
    let received; // 받는 사람
 
    it('web3 연결 테스트', () => {
        // new Web3.providers.HttpProvider("http://127.0.0.1:8545");
        web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:8545'));
    });
 
    it('전체 accounts 가져오기', async () => {
        // 현재 가나쉬에 있는 accounts
        accounts = await web3.eth.getAccounts();
        sender = accounts[0];
        received = accounts[1];
        console.log(accounts);
    });
 
    it('트랜잭션 실행하기', async () => {
 
        // 0xca4d95b225d1a7a48b994da481c7d7fb3eedf0a33f84f89b28868499bcc794da (보내는 사람 개인키)
        // 앞의 0x 제거
        const privateKey = Buffer.from('ca4d95b225d1a7a48b994da481c7d7fb3eedf0a33f84f89b28868499bcc794da', 'hex');
        const txCount = await web3.eth.getTransactionCount(sender);
        const txObject = {
            nonce: web3.utils.toHex(txCount), // 보내는 사람이 발생시킨 트랜잭션 횟수
            from: sender,
            to: received,
            value: web3.utils.toHex(web3.utils.toWei('1', 'ether')), // 보낼 금액 (단위를 wei로 해야한다. 10 ** 18 -> hex)
            gasLimit: web3.utils.toHex(6721975), // 해당 트랜잭션이 사용할 수 있는 가스의 최대치
            gasPrice: web3.utils.toHex(web3.utils.toWei('1', 'gwei')), // 발신자가 지불하는 가스 당 가격
            data: web3.utils.toHex(''), // 스마트 컨트랙트와 관련된 data
        };
 
        const tx = new ethTx(txObject);
        tx.sign(privateKey); // tx.sign() 메소드를 사용하면 tx 객체 안에 서명 값을 추가해준다.
        console.log(tx);
 
        const serializedTx = tx.serialize();
        console.log(serializedTx.toString('hex'));
 
        const TxObject = await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex'));
        console.log(TxObject);
    });
});

마무리

web3 와 RPC 에 대해서 알아보았다. 공부를 더하면서 블록체인에 관해서 더 알아봐야겠다.

+) 추가
공부하던글은 2022년도 글이다. 최근에 공부하면서 알아봤을때

트랜잭션 코드를 실행하는것에 간편화 방법이 있어서 작성해둔다.
자세한것은 위에서 공부한 코드와 같지만 간단하게 사용하려면 아래와 같이 사용이 가능하다.
현재는 2024년인데 코드가 변경된것도 있는것 같다. 테스트해보면서 버전도 많이 업데이트 되었기 때문이다.

 const web3 = new Web3(window.ethereum || "http://localhost:7545");
    const accounts = await web3.eth.requestAccounts(); // 메타마스크에 선택된 지갑으로 트랜잭션 서명을 함. 메타마스크 어카운트를 가져온다. 
    console.log(accounts);

    const tx = await web3.eth.sendTransaction({
      from: accounts[0],
      to: "0x01802213BF288C7435a77181a23eE61C6A4fF67E",
      value: web3.utils.toWei("0.1", "ether"),
    });
    //트랜잭션 보내기 
    console.log(tx);

메타 마스크를 사용해서 그런지 코드가 간략해 진것 같다. 지금 2024년도에 잘된다.

profile
프론트엔드 개발자 초보에서 고수까지!

0개의 댓글