티스토리 뷰

이번 게시글에서는 puppeth를 이용하여 Private Network를 구축해보고자 한다.

[그림 1] puppeth

puppeth는 이더리움 노드 배포를 쉽게 할 수 있도록 해주는 유틸리티 프로그램이다.

 

$ mkdir node

현재 디렉토리에 아래 명령어로 node 디렉토리를 생성한다.

 

[그림 2] 계정 생성

이후 새 계정을 생성한다.

 

[그림 3] make all

geth가 있는 곳(geth 설치할 때 git clone 실행한 디렉토리)에서 make로 go 소스를 build한다.

 

[그림 4] puppeth 쉘 진입

다시 현재 디렉토리로 돌아와 puppeth 쉘에 진입한다.

 

[그림 5] puppeth 설정 1

생성할 Private Network의 이름부터 몇 가지 설정을 해준다.

 

Which accounts should be pre-funded? 라는 질문은 node/keystore 디렉토리에 있는 UTC 파일의 address의 속성 값을 넣는다.

 

chainId는 임의로 7722라고 설정하였는데, 다른 넘버도 가능하다.

 

[그림 6] puppeth 설정 2

genesis specs가 생성될 디렉토리 이름은 임의로 jenny_라고 지정하였다.

 

설정을 모두 마치고 네트워크를 생성한 후에도 계속 무한 루프로 처음 질문이 반복되는데, 이때 그냥 커맨드 창을 닫고 종료하면 된다.

 

종료하기 전에 jenny_라는 디렉토리가 생성되고 내부에 jenny.json, jenny-aleth.json 등의 파일이 제대로 만들어졌는지 확인한다.

 

[그림 7] genesis 블록 초기화

geth init으로 genesis 블록을 초기화한다.

 

$ geth --datadir node --http --http.addr "0.0.0.0" --http.port 9000 --http.corsdomain "*" --http.api "admin, miner, txpool, net, web3, personal, eth" --syncmode full --networkid 7722 --port 30300 --allow-insecure-unlock

geth를 실행하는데 옵션을 몇 가지 추가한다.

 

http 통신을 하기 위해 --http를 추가한다.

--http.addr "0.0.0.0" : 모든 ip 주소와 http 통신을 허용하겠다.

--http.port 9000 : http 9000번 포트를 사용하겠다.

--http.corsdomain "*" : 모든 주소에 대해 CORS 정책을 허용하겠다.

--http.api "admin, miner, txpool, net, web3, personal, eth" : 사용하고자 하는 http api를 지정한다.

--syncmode full : 전체 동기화 모드를 사용하겠다.

--networkid 7722 : chainId를 7722로 하겠다.

--port 30300 : 30300번 포트를 사용하겠다.

--allow-insecure-unlock : 안전하지 않은 주소도 허용하겠다.

 

[그림 8] geth 실행

geth를 실행하면 node 디렉토리 내부에 geth.ipc가 생성된다.

 

[그림 9] geth attach로 콘솔 프롬프트

geth를 실행한 상태에서 다른 터미널을 켜서 get attach로 콘솔 프롬프트에 들어온다. 이는 rpc 통신 방법이다.

 

[그림 10] 트랜잭션에 참여할 2개의 계정

eth.accounts를 입력하면 맨 처음에 account new로 생성한 계정이 있다.

 

추가로 personal.newAccount()를 이용하여 새 계정을 생성한다.

 

이제 eth.accounts 배열에 있는 0번째 index에 해당하는 계정과 1번째 index에 해당하는 계정 간 트랜잭션을 만들어 보겠다.

 

[그림 11] 트랜잭션 생성

miner.start()로 0번째 index 계정에는 엄청난 양의 코인이 들어있다.

 

이와 반대로 1번째 index 계정은 채굴을 진행하지 않아 코인을 보유하고 있지 않다.

 

personal.sendTransaction()의 인자 값으로 객체와 비밀번호가 들어간다. 객체에는 보내는 계정(from), 받는 계정(to), 보낼 코인의 양(value)을 입력한다.

 

트랜잭션 해시 값이 나온다면 트랜잭션이 제대로 생성되었다는 것을 의미한다.

 

하지만, 1번째 index 계정에 대한 balance 값을 불러오면 여전히 0으로 나타난다.

 

txpool을 실행하면 pending에 객체가 있는 것을 볼 수 있다. 이 시점에서 트랜잭션은 txpool 안에는 존재하지만, 아직 블록에 저장되지 않은 상태이다.

 

채굴을 진행하면, txpool에 pending 상태인 트랜잭션이 새로 생성되는 블록에 담기게 된다.

 

miner.start()를 한 후, geth 실행 창으로 와서 블록이 채굴되는지 지켜본다.

 

[그림 12] gas fee 확인

gas=21000이라는 부분을 확인할 수 있다. 트랜잭션이 txpool에서 나와 블록에 추가되었을 것이므로, miner.stop()으로 채굴을 중지한다.

 

현재 작업 중인 디렉토리(node의 상위 디렉토리)에 돌아온 뒤 트랜잭션에 대한 정보를 알 수 있는 explorer에 대한 코드를 작성해보고자 한다.

 

$ mkdir explorer
$ npm init -y
$ npm i web3 jest

explorer 디렉토리를 생성한 후 내부에서 web3와 jest를 설치한다.

 

/* jest.config.js */

const config = {
    verbose: true,
    testMatch: ['<rootDir>/**/*.test.(js|ts)'],
};

module.exports = config;

jest.config.js 파일을 만든 후 위와 같이 내용을 적는다.

 

/* block.test.js */

const Web3 = require('web3');

describe('Block', () => {
    let web3;

    it('web3 test', async () => {
        web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:9000'));
        const block_number = await web3.eth.getBlockNumber();
        console.log(block_number);

        for (let i = 1; i <= block_number; i++) {
            const block = await web3.eth.getBlock(i, true);
            // console.log(block);
            for (let j = 0; j < block.transactions.length; j++) {
                // console.log(block.transactions[j]);
            }
        }

        console.log(await web3.eth.getBlock(block_number, true));
    });

    it('getTransaction', async () => {
        const tx = await web3.eth.getTransaction('0x7714aebc8965351092d4fdae72681392dd3ce56557cf96858b45adb7197f8be4');
        console.log('tx : ', tx);
    });

    it('getTransactionReceipt', async () => {
        const tx = await web3.eth.getTransactionReceipt('0x7714aebc8965351092d4fdae72681392dd3ce56557cf96858b45adb7197f8be4');
        console.log('tx Receipt : ', tx);
    });
});

이제 테스트를 진행할 block.test.js 파일에 위와 같이 내용을 적고, npx jest 명령어로 파일을 실행한다.

 

[그림 13] 트랜잭션 hash 값

web3.eth.getBlock()으로 마지막 블록을 가져오면 위와 같이 나타난다.

 

트랜잭션의 hash 값을 web3.eth.getTransaction()과 getTransactionReceipt()의 인자 값으로 넣는다.

 

[그림 14] 트랜잭션 및 트랜잭션 리시트

마지막 블록에 포함된 트랜잭션과 트랜잭션 리시트에 대한 내용을 볼 수 있다.

 

이제 MetaMask의 네트워크에 Private Network를 추가하여 계정을 불러와 현재 balance를 확인해 볼 것이다.

 

linux에서 ifconfig 명령어로 현재 네트워크 주소를 가져온다.

 

[그림 15] ifconfig

eth0 주소인 172.21.150.227을 사용할 것이다.

 

[그림 16] MetaMask 네트워크 추가

새 RPC URL에 ip 주소를 적고, 포트 번호와 체인 ID도 geth에서 실행할 때 옵션으로 넣어준 값과 일치하도록 한다.

 

네트워크 이름과 통화 기호는 임의로 지정한다.

 

[그림 17] 계정 가져오기

node/keystore 디렉토리에 있는 UTC 파일을 선택하여 계정을 가져온다.

 

[그림 18] 보낸 계정의 balance

보낸 계정의 코인 보유량은 처음부터 너무 많았어서 위와 같이 나타난다.

 

[그림 19] 받은 계정의 balance

받은 계정은 10만큼의 코인을 보유하게 되었다.

'Geth' 카테고리의 다른 글

[Geth] Private Network 구축 (feat. IPC)  (0) 2022.06.30
[Geth] 동기화 모드 및 명령어  (0) 2022.06.30
Linux에 GoLang, Geth 설치  (0) 2022.06.27
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함