일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- server
- 솔리디티
- truffle
- 제어의역전
- erc
- web
- blockchain
- JavaScript
- NFT
- 이더리움
- Docker
- Python
- web3.js
- 스마트 컨트랙트
- 트랜잭션
- ethers
- Programming
- tcp
- Ethereum
- geth
- 네트워크
- ERC20
- erc721
- git
- 블록체인
- github
- solidity
- ERC165
- web3
- MySQL
- Today
- Total
멍개의 연구소
[ethereum] docker를 활용한 이더리움 네트워크 구축 - 1편 본문
docker를 활용하여 geth를 설치하고 이더리움 네트워크를 구축하는 방법에 대해서 알아보겠습니다. 오랜만에 도커를 다뤄서 그런지 하루종일 엄청난 삽질을 했네요 ㅠㅠ
도커를 사용하여 환경설정을 자동화 하기 위해서는 Dockerfile과 docker-compose.yml을 이용하면 간단하게 구축할 수 있습니다.
해당 글에서 도커를 설치하는 과정은 생략하고 진행합니다
● 디렉토리 구조
multi-ethereum-network
├── go-ethereum/
├── docker-compose.yml
├── Dockerfile
├── genesis.json
└── start.sh
genesis.json파일과 go-ethereum 디렉터리는 도커로 생성되는 컨테이너 안에다가 copy로 옮깁니다.
· go-ethereum 설치
$ git clone https://github.com/ethereum/go-ethereum
go-ethereum은 git에서 clone하여 받아주기만 하면 됩니다.
· genesis.json 작성하기
초기블록 정보를 가지고 있는 genesis.json 파일을 작성합니다.
{
"nonce" : "0x0000000000000042",
"timestamp" : "0x0",
"parentHash" : "0000000000000000000000000000000000000000000000000000000000000000",
"extraData" : "0x0",
"gasLimit" : "0x80000000",
"difficulty" : "0x4000",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase" : "0x3333333333333333333333333333333333333333",
"alloc" : {}
}
각 수치는 바뀌어도 됩니다.
· Dockerfile 작성하기
Dockerfile을 이미지를 만들기 위해 사용하는 파일입니다. Dockerfile에는 ubuntu를 설치하고 호스트 OS에 있는 genesis.json과 go-ethereum을 옮긴후 geth를 make합니다. 그리고 genesis.json을 이용하여 초기블록을 생성하는 작업을 합니다.
FROM ubuntu
COPY ./go-ethereum /home/go-ethereum
WORKDIR /home/go-ethereum/
RUN apt-get update
RUN apt-get install -y build-essential libgmp3-dev golang git
RUN git checkout refs/tags/v1.5.5
RUN make geth
RUN cp build/bin/geth /usr/local/bin/
WORKDIR /home/DATA_STORE/
COPY ./genesis.json /home/DATA_STORE
RUN geth --datadir "/home/DATA_STORE" init /home/DATA_STORE/genesis.json
- from ubuntu는 ubuntu를 사용하게 됩니다.
- COPY는 호스트OS에서 생성할 이미지로 복사하는 것을 의미합니다. 해당 디렉토리에 있는 go-ethereum을 생성하는 이미지의 /home/go-ethereum으로 복사하는 것을 의미합니다.
- WORKDIR은 작업 디렉토리를 의미합니다.
- RUN은 bash에서 실행되는 명령어를 의미합니다.
해당 파일은 우분투에 geth에 필요한 것들을 옮긴 후 genesis 블록을 생성한 후 이미지 파일을 만들어 줍니다.
· Dockerfile로 이미지 파일 생성
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest f975c5035748 3 weeks ago 112MB
build를 이용하여 이미지 파일을 만들어 줍니다. -t 옵션은 이미지 이름을 의미합니다.
마지막에 마침표(.)는 반드시 넣어줄 것! 없으면 에러가 발생합니다.
해당 명령어를 실행하면 Dockerfile에 적힌 명령어들을 실행하면서 이미지를 만들어 줍니다.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ethereum latest 445670501b8f 22 seconds ago 1.22GB
ubuntu latest f975c5035748 3 weeks ago 112MB
ethereum이 추가 됬습니다. 해당 이미지를 이용하여 컨테이너를 생성해보겠습니다.
· 컨테이너 생성해보기
run을 이용하면 이미지를 컨테이너로 생성할 수 있습니다.
$ docker run -it -p 8545:8545 ethereum bash
$ root@2bda185d1d5d:/home/DATA_STORE# ls
genesis.json geth keystore
ps를 활용하여 실행되고 있는 컨테이너를 확인할 수 있습니다.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2bda185d1d5d ethereum "bash" 29 seconds ago Up 28 seconds 0.0.0.0:8545->8545/tcp naughty_fermat
컨테이너를 생성할 때마다 옵션을 다 작성하는 건 상당히 비효율 적입니다. docker-compose.yml을 이용하면 컨테이너를 생성하는 과정을 자동화 할 수 있습니다.
· docker-compose.yml을 이용한 자동화
version: '2'
services:
ether.node1.com:
image: 'ethereum'
tty: true
ports:
- 8545:8545
- 30305:30305
environment:
ENV: ETHERNODE1
RPCPORT: 8545
PORT: 30305
container_name: ether.node1.com
command : geth --networkid 4649 --maxpeers 3 --datadir /home/DATA_STORE --rpc --rpcport 8545 --rpcaddr "0.0.0.0" --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --port 30305
working_dir: /home/DATA_STORE
services안에는 생성할 컨테이너 정보가 들어갑니다.
ether.node1.com이름을 가진 컨테이너를 생성한 후 컨테이저 정보를 그 아래에 포함합니다.
image는 어떤 이미지를 이용하여 컨테이너를 생성할지에 대한 정보입니다. ethereum을 로컬에서 이미지를 찾은 후 없다면 docker hub에서 찾습니다.
tty는 해당 컨테이너에서 인터프리터를 제공할지 말지에 대한 옵션입니다.
ports는 포워딩을 의미합니다. 도커는 따로 아이피를 할당받거나 하지 않습니다. 호스트 OS를 공유하기 때문에 호스트 OS로 접속된 포트번호에 따라서 해당 컨테이너로 포워딩을 해야합니다.
environment는 환경설정 값 입니다.
container_name은 컨테이너 이름입니다.
command는 해당 컨테이너가 생성되고 실행할 명령어를 입력합니다.
working_dir은 작업 디렉토리를 설정합니다
· docker-compose.yml 실행
$ docker-compose up -d
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e8a46276465f ethereum "geth --networkid ..." 12 seconds ago Up 9 seconds 0.0.0.0:8545->8545/tcp, 0.0.0.0:30305->30305/tcp ether.node1.com
docker-compose.yml에서 service만 추가하면 매우 간편하게 여러 노드를 생성할 수 있습니다.
version: '2'
services:
ether.node1.com:
image: 'ethereum'
tty: true
ports:
- 8545:8545
- 30305:30305
environment:
ENV: ETHERNODE1
RPCPORT: 8545
PORT: 30305
container_name: ether.node1.com
command : geth --networkid 4649 --maxpeers 3 --datadir /home/DATA_STORE --rpc --rpcport 8545 --rpcaddr "0.0.0.0" --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --port 30305
working_dir: /home/DATA_STORE
ether.node2.com:
image: 'ethereum'
tty: true
ports:
- 8546:8546
- 30306:30306
environment:
ENV: ETHERNODE2
RPCPORT: 8546
PORT: 30306
container_name: ether.node2.com
command : geth --networkid 4649 --maxpeers 3 --datadir /home/DATA_STORE --rpc --rpcport 8546 --rpcaddr "0.0.0.0" --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --port 30306
working_dir: /home/DATA_STORE
ether.node3.com:
image: 'ethereum'
tty: true
ports:
- 8547:8547
- 30307:30307
environment:
ENV: ETHERNODE3
RPCPORT: 8547
PORT: 30307
container_name: ether.node3.com
command : geth --networkid 4649 --maxpeers 3 --datadir /home/DATA_STORE --rpc --rpcport 8547 --rpcaddr "0.0.0.0" --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --port 30307
working_dir: /home/DATA_STORE
$ docker-compose up -d
Creating ether.node2.com ...
Creating ether.node3.com ...
Creating ether.node1.com ...
Creating ether.node2.com
Creating ether.node3.com
Creating ether.node3.com ... done
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
59c167bf69ea ethereum "geth --networkid ..." 12 seconds ago Up 10 seconds 0.0.0.0:8546->8546/tcp, 0.0.0.0:30306->30306/tcp ether.node2.com
ba0df13e0343 ethereum "geth --networkid ..." 12 seconds ago Up 9 seconds 0.0.0.0:8545->8545/tcp, 0.0.0.0:30305->30305/tcp ether.node1.com
6970e60e5a75 ethereum "geth --networkid ..." 12 seconds ago Up 9 seconds 0.0.0.0:8547->8547/tcp, 0.0.0.0:30307->30307/tcp ether.node3.com
3개의 이더리움 네트워크가 생성되었습니다.
· geth 직접실행
version: '2'
services:
ether.node1.com:
image: 'ethereum'
tty: true
ports:
- 8545:8545
- 30305:30305
environment:
ENV: ETHERNODE1
RPCPORT: 8545
PORT: 30305
container_name: ether.node1.com
command : /bin/bash
working_dir: /home/DATA_STORE
command를 /bin/bash로 바꾼 후 docker-compose를 실행하면 다음과 같이 컨테이너가 생성됩니다.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
78da5358a511 ethereum "/bin/bash" 8 seconds ago Up 8 seconds 0.0.0.0:8545->8545/tcp, 0.0.0.0:30305->30305/tcp ether.node1.com
해당 컨테이너를 접속하여 직접 다뤄보도록 하겠습니다.
$ docker exec -it ether.node1.com /bin/bash
root@78da5358a511:/home/DATA_STORE#
exec를 이용하여 실행중인 컨테이너를 직접 명령어를 줄 수 있습니다. -it는 인터프리터 형태로 사용하겠다는 의미이고 NAMES가 ether.node1.com을 찾은 후 /bin/bash를 실행합니다.
root@78da5358a511:/home/DATA_STORE# echo $RPCPORT $PORT
8545 30305
docker-compose 파일에 environment로 설정한 환경변수가 잘 설정되어 있습니다.
root@78da5358a511:/home/DATA_STORE# geth --networkid 4649 --maxpeers 3 --datadir /home/DATA_STORE --rpc --rpcport $RPCPORT --rpcaddr "0.0.0.0" --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --port $PORT console
I0401 12:38:16.672852 cmd/utils/flags.go:615] WARNING: No etherbase set and no accounts found as default
I0401 12:38:16.673008 ethdb/database.go:83] Allotted 128MB cache and 1024 file handles to /home/DATA_STORE/geth/chaindata
I0401 12:38:16.721313 ethdb/database.go:176] closed db:/home/DATA_STORE/geth/chaindata
I0401 12:38:16.722546 node/node.go:176] instance: Geth/v1.5.5-stable-ff07d548/linux/go1.6.2
I0401 12:38:16.722596 ethdb/database.go:83] Allotted 128MB cache and 1024 file handles to /home/DATA_STORE/geth/chaindata
I0401 12:38:16.752408 eth/backend.go:191] Protocol Versions: [63 62], Network Id: 4649
I0401 12:38:16.754436 eth/backend.go:219] Chain config: {ChainID: 0 Homestead: <nil> DAO: <nil> DAOSupport: false EIP150: <nil> EIP155: <nil> EIP158: <nil>}
I0401 12:38:16.755875 core/blockchain.go:219] Last header: #0 [04d8be6f…] TD=16384
I0401 12:38:16.756043 core/blockchain.go:220] Last block: #0 [04d8be6f…] TD=16384
I0401 12:38:16.756150 core/blockchain.go:221] Fast block: #0 [04d8be6f…] TD=16384
I0401 12:38:16.758519 p2p/server.go:342] Starting Server
I0401 12:38:18.909806 p2p/discover/udp.go:227] Listening, enode://e90665a79192eef1c2f9de32b6527b7dd8130d636fe50ed5f3cf4593a5a07b977adb73e367a715c3b48e4239c697ecfb3c487db1d076af044a2bcb0d81b8cd32@[::]:30305
I0401 12:38:18.911419 node/node.go:411] HTTP endpoint opened: http://0.0.0.0:8888
I0401 12:38:18.925522 p2p/server.go:610] Listening on [::]:30305
I0401 12:38:18.928201 node/node.go:341] IPC endpoint opened: /home/DATA_STORE/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.5.5-stable-ff07d548/linux/go1.6.2
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
>
컨테이너를 생성할 때 추가한 환경변수를 이용하여 RPCPORT와 PORT를 설정해주었습니다.
· 컨테이너 중지/삭제
컨테이너를 중지하거나 삭제할 수 있습니다.
$ docker stop [컨테이너 ID 또는 컨테이너 이름]
$ docker rm [컨테이너 ID 또는 컨테이너 이름]
rm을 하기위해서는 컨테이너가 동작중이면 안됩니다.
$ docker ps # docker ps -a
ps 옵션은 동작중인 컨테이너를 보여줍니다. 여기에 -a를 추가하면 모든 컨테이너를 보여주게 됩니다.
docker-compose를 이용하여 컨테이너를 생성하면 다수의 컨테이너를 동시에 실행시키게 됩니다. 모든 컨테이너를 다 중지하고 삭제하고 싶다면 다음과 같이 실행하면 됩니다.
$ docker stop $(docker ps -qa)
$ docker rm $(docker ps -qa)
이렇게 하면 모든 컨테이너를 중지하고 제거하게 됩니다.
docker-compose를 사용할 때 중요한 점은 image가 반드시 설치되어 있거나 docker hub에 존재해야 합니다. 하지만 ethereum 이미지는 도커 허브에 제공되지 않기 때문에 앞에서 Dockerfile로 반드시 추가를 해주어야 합니다.
다음번에는 geth 사용법을 다뤄보고 다수의 노드를 서로 연결하여 마이닝 경쟁을 하여 그럴듯한 private한 환경의 이더리움 네트워크를 만들어 보겠습니다.
'블록체인' 카테고리의 다른 글
[ethereum] docker를 활용한 이더리움 네트워크 구축 - 2편 (0) | 2022.08.27 |
---|---|
[블록체인] 블록체인을 위한 고랭(golang) (0) | 2022.08.27 |
[ethereum] solidity - 인터페이스를 활용한 다른 컨트랙트 호출 (0) | 2022.08.27 |
[hyperledge fabric] fabric 기반 블록체인 기술을 익히는데 필요한 용어 (0) | 2022.08.27 |
[ethereum] Token, ICO 1편 - 동작과정 (0) | 2022.08.27 |