[연재] geth로 private network 구성하기

geth로 private network 구성하기


geth는 ethereum에서 공식 지원하는 클라이언트 툴이다. testrpc가 개발용이라면, geth는 제품용이라고할까.
ethereum 공식 네트웍에 붙어 채굴을 할 때 geth를 사용한다. Mist와 같은 개인 지갑툴도 내부적으로는 geth를 포함하고 있다.
geth에 대한 자세한 사항은 geth 공식 git사이트를 참고하기 바란다.
여기서는 geth를 이용하여 어떻게 사설망을 구성하는가에 집중하도록 하겠다.
사설망을 구축한다는 것은 ethereum 공식망이 아니라, 자신만의, 자기 회사만의 새로운 블럭체인 망을 구성한다는 뜻이다.

제네시스 블럭 생성

새로운 망을 구성하는데 있어 가장 중요한 것은 가장 첫번째 블럭, 즉 제네시스 블럭을 설정하는 작업이다.
다음은 샘플 제네시스 블럭이다. genesis.json으로 저장하자.

{
    "config": {
        "chainId": 88,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },  
    "difficulty": "400",
    "gasLimit": "2100000",
    "alloc": {
    }   
}


위 내용 중 config 항목에서 가장 중요한 것은 chainId 항목이다. chainId는 네트웍 상에서 각각의 망을 식별하는 식별자로서 Public 망은 모두 고유의 번호가 다음과 같이 있다.

    0: Olympic, Ethereum public pre-release testnet
    1: Frontier, Homestead, Metropolis, the Ethereum public main network
    1: Classic, the (un)forked public Ethereum Classic main network, chain ID 61
    1: Expanse, an alternative Ethereum implementation, chain ID 2
    2: Morden, the public Ethereum testnet, now Ethereum Classic testnet
    3: Ropsten, the public cross-client Ethereum testnet
    4: Rinkeby, the public Geth PoA testnet
    42: Kovan, the public Parity PoA testnet
    77: Sokol, the public POA Network testnet
    99: Core, the public POA Network main network
    7762959: Musicoin, the music blockchain


위의 번호를 피해 자신만의 번호를 부여하면 된다. 물론 chainId가 동일하다고 하더라도 제네시스 블럭이 다르면 서로 다른 네트웍으로 인식한다.

homesteadBlock,eip155Block,eip158Block  지원 여부는 모두 false(0)로 하자.

difficulty는 채굴 난이도를 설정하는 것으로 테스트로 만드는 것이기에 지나친 컴퓨터 자원을 사용하지 않도록 낮은 값을 주도록한다.


네트웍 초기화

제네시스 블럭을 생성하였으면 이제 네트웍을 초기화해보자. 네트웍 초기화는 아래와 같이 단순하다.

geth init genesis.json  --datadir ./data
위 명령을 수행하면 다음과 같이 성공적으로 제네시스 상태를 작성하였다고 출력할 것이다.



아울러 데이터 디렉터리도 초기화 되었는지 확인한다. geth 디렉토리 밑에 chaindata가, keystore 밑에는 계정 정보가 저장된다.



클라이언트 가동

이제 네트웍을 초기화 하였으니, 블럭체인 망을 가동해보자.

네트웍 가동은 네트웍 식별 아이디를 옵션으로 아래와 같이 실행하면 된다.

geth --datadir ./data --networkid 88 

명령을 실행하면 다음과 같아 나올 것이다.


제네시스 블럭에 설정한대로 제대로 실행되었는지는 6번째 행을 보면 된다.

INFO [02-05|11:20:59] Initialised chain configuration          
config="{ChainID: 88 Homestead: 0 DAO: <nil> DAOSupport: false 
EIP150: <nil> EIP155: 0 EIP158: 0 Byzantium: <nil> Engine: 
unknown}"

config가 우리가 앞서 genesis.json에서 설정한대로 제대로 물고 올라왔는지를 제일 먼저확인하고 마지막으로 enode 아이디 및 ipc 를 확인하여야 한다.

INFO [02-05|11:21:04] UDP listener up                          
self=enode://c6e2aa79b3561c973fe719c6800c9d1f2d88e4e01afdcc979769c55558abc2d32ce2e320469c883cf58aedef97a3b10a82e9bb708d46877885a4129337fe5d15@[::]:30303
INFO [02-05|11:21:04] RLPx listener up                         self=enode://c6e2aa79b3561c973fe719c6800c9d1f2d88e4e01afdcc979769c55558abc2d32ce2e320469c883cf58aedef97a3b10a82e9bb708d46877885a4129337fe5d15@[::]:30303
INFO [02-05|11:21:04] IPC endpoint opened: /home/vingorius/projects/ethereum/geth/data/geth.ipc

enode는 p2p 네트웍에서 우리가 방금 실행한 노드를 식별하는 주소로 나중에 다른 클라이언트를 실행할 때 참조 주소로 활용한다.

위의 경우 enode 주소는 [::]  부분을 해당 서버의 ip 주소로 대체하면 된다.

enode://c6e2aa79b3561c973fe719c6800c9d1f2d88e4e01afdcc979769c55558abc2d32ce2e320469c883cf58aedef97a3b10a82e9bb708d46877885a4129337fe5d15@192.168.191.158:30303


노드 하나 더 추가하기

자 이제 노드를 하나 더 만들어보자, 이 노드는 앞서 만든 노드를 참조하도록 할 것이다.

노드를 하나 더 만들 때 가장 중요한 것은 제네시스 블럭과 chainId를 동일하게 구성하는 것이다.

ssh나 telnet으로 다른 서버에 로그인하자.


두번째 노드 초기화

그 다음 앞서 사용한 제네시스 블럭으로 초기화 한다.

geth init genesis.json  --datadir ./data

두번째 노드 실행

앞에서와 마찬가지로 클라이언트를 실행해보겠다, 다만 여기서는 먼저 실행한 것을 enode로 참조하는 코드와 rpc 연결과 콘솔이 뜨도록 하는 코드를추가하겠다.

참조할 enode가 하나 이상이면 ','로 분리하여 작성하면 된다.

geth --datadir ./data \
     --networkid 88 \
     --rpc --rpcaddr "127.0.0.1" --rpccorsdomain "*" --rpcapi "admin,db,eth,net,web3,miner,personal" \
     --bootnodes "enode://c6e2aa79b3561c973fe719c6800c9d1f2d88e4e01afdcc979769c55558abc2d32ce2e320469c883cf58aedef97a3b10a82e9bb708d46877885a4129337fe5d15@192.168.191.158:30303" \
    console

이 명령을 실행했을 때 올바르게 실행되었는지를 확인하려면


앞에서와 같이 config 부분을 제대로 물고 올라왔는지 확인해야 한다. chainid가 제네시스에서 지정한 88번이 아닌 경우는 잘못 연결된 것이다.

그 다음 ipc와 rpc가 제대로 올라왔는지 확인하자

INFO [02-05|14:01:05] IPC endpoint opened: /home/ds/geth/data/geth.ipc 
INFO [02-05|14:01:05] HTTP endpoint opened: http://127.0.0.1:854

계정 생성

마지막으로 콘솔 입력을 할 수 있는 '>' 프롬프트가 뜨면 된다.

이제 계정을 하나 만들어서 채굴을 해보도록 하자.

콘솔에서 다음과 같이 입력하자.

 > personal.newAccount()

그러면 다음과 같이 생성할 계정에서 사용할 패스워드를 입력하라고 나오고, 이를 확인하고 넘어가면 계정 주소가 나타날 것이다.



채굴

여기서 바로 채굴을 하려면 다음과 같이 명령을 실행한다.

> miner.start();


채굴이 시작된 것이다. 채굴을 해서 ether를 얻어야만, 스마트 컨트렉트를 컴파일할 수 있고, 트랜잭션을 발생할 수 있다.

물론 클라이언트 시작 시 다음과 같이 채굴을 바로 하도록 할 수 있다.

Ctrl-C로 서비스를 종료하고 다음과 같이 다시 시작해보자.

geth --datadir ./data \
     --networkid 88 \
     --rpc --rpcaddr "127.0.0.1" --rpccorsdomain "*" --rpcapi "admin,db,eth,net,web3,miner,personal" \
     --bootnodes "enode://c6e2aa79b3561c973fe719c6800c9d1f2d88e4e01afdcc979769c55558abc2d32ce2e320469c883cf58aedef97a3b10a82e9bb708d46877885a4129337fe5d15@192.168.191.158:30303" \
     --etherbase "0x42734bd8218a1b26e6dc742024e560f2f6182e5d" \
     --mine --minerthreads=1 \
     console

--etherbase 옵션에는 앞에서 만든 계정을 넣으면 된다. 채굴하여 생성한 ether는 바로 이 계정으로 귀속된다.

그다음 --mine 은 채굴을 하라는 의미이고, --minerthreads는 채굴에 사용할 쓰레드 개수로 1로 주면 테스트하는데 무리가 가지 않는다.

자 여기까지해서 블럭체인 사설 네트워크를 구성해보았다.