docker를 이용해서 이더리움 노드 3개와 웹서버 1개를 만들고 웹서버에서 회원가입을 하고 투표를 하는 정보들을 이더리움 네트워크에 저장시켜보는 실습을 해본다.
1
2
|
$ docker pull ubuntu
$ docker run -it -p 10001:10001 ubuntu
|
ubuntu os에 설치하려고한다. 이유는 설치하는 과정을 보여주려고….
1
2
3
4
5
|
$ apt-get install software-properties-common
$ apt-get install software-properties-common python-software-properties
$ add-apt-repository -y ppa:ethereum/ethereum
$ apt-get update
$ apt-get install ethereum
|
이후에
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ geth
$ geth version
>>>
WARN [08-17|08:21:11.660] Sanitizing cache to Go's GC limits provided=1024 updated=666
Geth
Version: 1.8.13-stable
Git Commit: 225171a4bfcc16bd12a1906b1e0d43d0b18c353b
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10.1
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.10
|
라고 하면 잘 실행 될 것이다.
아래의 명령어를 사용하면 geth console에 명령어를 입력 할 수 있다.
준비할 것이 2가지 있다.
- private network에서 사용할 계좌
- 제네시스 블록 정보.
계좌 생성하기
1
|
$ geth --datadir "./data" account new
|
—datadir 옵션은 network가 구동될 때 블록정보, 계좌정보를 저장할 폴더를 지정하는 옵션이다.
1
2
3
4
|
$ ls data/keystore/
>>>
UTC--2018-08-17T08-24-17.766131786Z--49a13ee73d2fc8c1578ce1512530aa1724ee42b7
|
계좌주소 출력하기
1
2
3
4
5
6
|
$ geth --datadir "./data" account list
>>>
WARN [08-17|08:26:02.392] Sanitizing cache to Go's GC limits provided=1024 updated=666
INFO [08-17|08:26:02.392] Maximum peer count ETH=25 LES=0 total=25
Account #0: {49a13ee73d2fc8c1578ce1512530aa1724ee42b7} keystore:///home/data/keystore/UTC--2018-08-17T08-24-17.766131786Z--49a13ee73d2fc8c1578ce1512530aa1724ee42b7
|
다음과 같이 쓰면 생성된 계좌의 리스트가 출력된다.
제네시스 블록 생성하기
private network를 구동하기 위해서는 첫 번째 블록을 생성해야한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"difficulty": "200000000",
"gasLimit": "2100000",
“coinbase”: "0x{위에 생성한 계좌주소}",
"alloc": {
"0x{위에 생성한 계좌주소}": { "balance": "1000000000000000000000000" },
}
}
|
제네시스 블록을 만들때 필요한 json 파일의 구성이다.
-
config는 생성할 private network의 버전을 정하는 설정이다. chainId, homesteadBlock, eip155Block, eip158Block 모두 이더리움 속성과 관련된 설정이다.
chainId는 replay protection을 사용하는 설정이다. homestead는 이더리움의 두 번째 메인 릴리즈를 사용하기 위해 설정하는 속성이고 0으로 설정하면 해당 릴리즈를 사용한다. eip155은 gas 비용에 관련된 하드포커 설정이며 eip158은 state cleanig과 관련된 설정이다.
-
difficulty 는 이더리움에서 채굴의 난이도를 설정하는 옵션
-
gas limit 한 블록이 담을 수 있는 gas의 수치를 말한다. gas 수치가 높을 수록 한 블록이 담을 수 있는 거래가 많아진다.
-
coinbase는 network를 구동할 때 기본으로 사용할 계좌를 설정하는 옵션 ( 채굴할 때 코인을 받을 계좌 )
-
alloc 는 private network를 구동할 떄 미리 계좌에 이더를입금 시킬지를 설정하는 옵션이다. 설정하기 원하는 계좌와 이더 값을 명시한다.
제네시스 json파일을 생성후
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$ geth --datadir "./data" init "./genesis.json"
>>>
WARN [08-17|08:31:55.253] Sanitizing cache to Go's GC limits provided=1024 updated=666
INFO [08-17|08:31:55.254] Maximum peer count ETH=25 LES=0 total=25
INFO [08-17|08:31:55.254] Allocated cache and file handles database=/home/data/geth/chaindata cache=16 handles=16
INFO [08-17|08:31:55.261] Writing custom genesis block
INFO [08-17|08:31:55.261] Persisted trie from memory database nodes=1 size=150.00B time=41.229µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [08-17|08:31:55.261] Successfully wrote genesis state database=chaindata hash=e47869…3ca16c
INFO [08-17|08:31:55.261] Allocated cache and file handles database=/home/data/geth/lightchaindata cache=16 handles=16
INFO [08-17|08:31:55.264] Writing custom genesis block
INFO [08-17|08:31:55.264] Persisted trie from memory database nodes=1 size=150.00B time=37.247µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [08-17|08:31:55.265] Successfully wrote genesis state database=lightchaindata hash=e47869…3ca16c
|
성공적으로 genesis block이 생성 되었다고 출력된다.
Private network 구동하기
첫 번째 블록을 만들었으니 네트워크 실행해보자.
private network를 구동할 때 유의해야 할 옵션은 —networkid이다. networkid를 1로 지정시 메인 이더리움에 연결이 되고 2는 테스트 네트워크로 사용중이다. 따라서 1과 2를 제외한 수를 지정해야 한다.
또한 –identity 옵션을 사용해 네트워크에 이름을 지정할 수 있다. networkid와 identity는 node들 간에 연결 할 때 사용되는 옵션이다.
그리고 –mine 옵션을 설정해서 geth를 구동했을 때 채굴을 할 수 있게 한다. –nodiscover 옵션을 사용해서 다른 노드를 찾는 설정을 끈다.
1
|
$ geth --networkid 1988 --identity "mynetwork" --datadir "./data" --nodiscover console
|
아래와 같이 콘솔창이 나오면 성공이다.
1
2
3
4
5
6
7
8
9
|
>>>
... 생략
INFO [08-17|08:35:18.788] Etherbase automatically configured address=0x49A13ee73D2FC8C1578cE1512530Aa1724EE42b7
coinbase: 0x49a13ee73d2fc8c1578ce1512530aa1724ee42b7
at block: 0 (Thu, 01 Jan 1970 00:00:00 UTC)
datadir: /home/data
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
>
|
eth.accounts를 입력하면 현재 생성되어 있는 계좌들이 출력된다.
1
2
|
> eth.accounts
["0x49a13ee73d2fc8c1578ce1512530aa1724ee42b7"]
|
eth.accounts[0]은 첫번째 생성된 계좌를 출력
1
2
|
> eth.accounts[0]
"0x49a13ee73d2fc8c1578ce1512530aa1724ee42b7"
|
이더 잔고를 조회 할때는 eth.getBalance()함수를 사용하고 인자로 계좌 주소를 적어준다.
1
2
|
> eth.getBalance(eth.accounts[0])
1e+24
|
새로운 계좌를 만들어보면
1
2
3
4
5
6
|
> personal.newAccount()
Passphrase:
Repeat passphrase:
"0xaefa6e0f4b91fd67e31498f82f34ae95762aac71"
> eth.accounts
["0x49a13ee73d2fc8c1578ce1512530aa1724ee42b7", "0xaefa6e0f4b91fd67e31498f82f34ae95762aac71"]
|
두개가 출력된걸 확인 할 수 있다.
이제 이더를 옮겨보자
반드시 해야하는 작업이 이더를 전송하려는 계좌의 락을 풀어줘야한다.!!!
1
2
3
4
|
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x0a39454d85c9ff43f5aba2025da36d67ccfa50d9
Passphrase:
true
|
이제 보내보자
1
2
3
|
> eth.sendTransaction({from: eth.accounts[0], to:eth.accounts[1], value:100})
INFO [08-18|06:27:14.550] Submitted transaction fullhash=0xd592ae1540ae288979caa5fe8bcfc4bc41c625190b978bb505587b241fdb346e recipient=0xa6ae554222c1Ac7cB98eEF8abFd3b8f8CD9C2817
"0xd592ae1540ae288979caa5fe8bcfc4bc41c625190b978bb505587b241fdb346e"
|
전송을 해도
잔고에 변화가 없다.
1
2
3
4
|
> eth.getBalance(eth.accounts[0])
1e+24
> eth.getBalance(eth.accounts[1])
0
|
블록 체인이기 때문에 채굴이 되어야 발생한 거래가 적용이 된다. 채굴을 해보자
1
2
3
4
5
6
7
8
9
10
11
12
|
$ miner.start()
$ minet.stop()
INFO [08-18|06:32:51.972] Generating DAG in progress epoch=1 percentage=97 elapsed=3m4.253s
INFO [08-18|06:32:53.809] Generating DAG in progress epoch=1 percentage=98 elapsed=3m6.089s
INFO [08-18|06:32:56.898] Generating DAG in progress epoch=1 percentage=99 elapsed=3m9.179s
INFO [08-18|06:32:56.905] Generated ethash verification cache epoch=1 elapsed=3m9.184s
INFO [08-18|06:35:20.852] Successfully sealed new block number=1 hash=a9c709…37cf8b
INFO [08-18|06:35:20.866] 🔨 mined potential block number=1 hash=a9c709…37cf8b
INFO [08-18|06:35:20.869] Commit new mining work number=2 txs=0 uncles=0 elapsed=3.373ms
INFO [08-18|06:35:36.470] Successfully sealed new block number=2 hash=7f96ee…bf362a
INFO [08-18|06:35:36.473] 🔨 mined potential block number=2 hash=7f96ee…bf362a
|
Generating DAG in progress 가 반복되다가 블럭이 생성되는 경우가 있다.!!
1
2
3
4
|
> eth.getBalance(eth.accounts[0])
1.0000099999999999999999e+24
> eth.getBalance(eth.accounts[1])
100
|
이후에 이더가 전송된 것을 확인 가능하다.!!
간단한 geth 명령어는 다음과 같다.
블록 갯수 체크
채굴에 성공시 보상받는 계좌 조회
다른 계정으로 옮기고 싶을때
1
2
|
> miner.setEtherbase(eth.accounts[1])
> eth.coinbase
|
진행 기다리는 트랜잭션 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
> eth.pendingTransactions
[{
blockHash: null,
blockNumber: null,
from: "0x241530b417837cdcce8036a7b7f095995509d5c9",
gas: 90000,
gasPrice: 18000000000,
hash: "0x8aff56402bbbe8547dca097ba443a3d668bbac4cd73477e8613fc2c74ca8b002",
input: "0x",
nonce: 1,
r: "0xc029343dac203271bee3de5d73a586e8740a547342b61f3aebdbbbb0ac4bd0a8",
s: "0x27112e6e766ddfccf55123d057fe130f7b39e99f76b36c0aefa140168cdd36f9",
to: "0xca09b7785f4179988e14ee87cfe7e93933a002c7",
transactionIndex: 0,
v: "0x41",
value: 1000
}]
|