Ethereum private network 구축

in erc20 •  6 years ago 

이더리움 CLI 클라이언트인 geth를 private network로 구축하여 다양한 명령어들을 살펴 보려고 합니다.
geth는 이더리움의 전체 기능을 사용할 수 있는 풀 클라이언트로서 다중 인터페이스를 제공합니다.
JSON-RPC 서버 기능등을 사용할 수 있게끔 해줍니다.

geth는 go ethereum의 약자로 go 언어로 프로그래밍된 이더리움 엔진입니다.

본 포스팅에서는 geth를 구동하고, 계정 생성 및 마이닝을 통한 계정 간의 이더리움을 송금하는 기능까지 테스트 해보려고 합니다.

본인은 Mac 환경에서 테스트 하였으므로 Mac 중심의 실습 과정을 작성할 것입니다. 하지만 윈도우나 리눅스에서도 크게 명령어는 다르지 않으므로 이해하는데에 문제는 없을것이라고 생각합니다.

본론

  1. 사전 준비
    1. go 언어 설치
      geth는 go 언어로 작성되었으므로 소스코드를 빌드 하기 위하여 go 언어가 로컬에 설치되어 있어야 합니다.

      아래 링크에서 pkg 파이을 다운로드 받아서 설치합니다. 본 포스팅에서는 1.9.2 버전을 사용합니다.

      http://golang.org/dl

  1. geth 설치
    go-ethereum github에서 다운로드합니다. 본 포스팅을 작성하는 시점에서의 최신 버전은 1.7.2입니다.

    https://github.com/ethereum/go-ethereum/releases

    소스코드를 다운로드 받아서 적절한 폴더에 저장합니다.

    예) /src/geth_172/go-ethereum-1.7.2.zip

   직접 다운로드 받거나 git을 사용하시면 아래 명령어를 통하여 clone 할 수도 있습니다.

   git clone -b release/1.7 https://github.com/ethereum/go-ethereum.git



   압축 파일을 다운로드 받으셨다면 압축 해제를 한 후에 해당 디렉토리(ex. /src/geth_172/)에서 소스코드를 컴파일합니다.

   $ make geth



   컴파일이 완료되면 현재 폴더에 /build/bin/ 폴더가 생성되고 그 안에 geth라는 실행파일이 있습니다.

   위에서도 언급했듯이 geth는 go 언어로 작성되었기 때문에 컴파일 에러가 나면 go 언어를 설치했는지, 버전이 맞는지 다시 한번 체크 하시길 바랍니다.
  1. geth 실행
    사전 준비는 끝났으니 이제 geth 엔진을 실행해보도록 하겠습니다.

    명령어는 wiki 문서에 자세히 나와있으니 먼저 한번 살펴보시기 바랍니다.

    https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options

1) 커스텀 제네시스 파일 생성
    모든 블록체인은 제네시스 블록으로부터 시작합니다. 기본 설정과 함께 geth를  최초로 실행하게되면 메인넷에 있는 제네시스 블록을 db에서 사용하게 됩니다. 하지만 본 포스팅처럼 private network를 구축하여 메인넷과 다른 제네시스 블록을 사용하고자 한다면 아래처럼 제네시스 파일을 생성하여 사용하면 됩니다.

{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"difficulty": "200000000",
"gasLimit": "2100000",
"alloc": {
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" },
"f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" }
}
}

위 파일을 CustomGenesis.json 으로 저장 후 적당한 디렉토리에 위치시킵니다. 본 포스팅에서는 /src/geth_172/build/bin/CustomGenesis.json 에 위치시켰습니다.

2) data 폴더 생성
    private network에서 사용할 data 폴더를 생성합니다. 이 폴더는 geth가 실행후 생성되는 계정 정보들이 저장됩니다.

    본 포스팅은 /src/geth_172/build/bin/ 폴더에 node1이라는 폴더를 생성하여 data folder로 사용하였습니다.

    /src/geth_172/build/bin/node1



3) 커서 이동
    geth를 실행하기 위하여 geth가 있는 폴더로 쉘 프롬프트를 옮기겠습니다.

    $ cd /src/geth_172/build/bin



4) 제네시스 블록 생성
    init 명령어로 CustomGenesis 파일을 이용한 제네시스 블록을 생성해보겠습니다.

    $ ./geth --datadir ./node1 init CustomGenesis.json



     성공적으로 생성되었다면 아래와 같은 메시지를 볼 수 있습니다.

$ ./geth --datadir ./node1 init CustomGenesis.json

WARN [11-12|22:02:48] No etherbase set and no accounts found as default

INFO [11-12|22:02:48] Allocated cache and file handles database=/srv/geth_172/build/bin/node1/geth/chaindata cache=16 handles=16

INFO [11-12|22:02:48] Writing custom genesis block

INFO [11-12|22:02:48] Successfully wrote genesis state database=chaindata hash=614a31…9df7ba

INFO [11-12|22:02:48] Allocated cache and file handles database=/srv/geth_172/build/bin/node1/geth/lightchaindata cache=16 handles=16

INFO [11-12|22:02:48] Writing custom genesis block

INFO [11-12|22:02:48] Successfully wrote genesis state database=lightchaindata hash=614a31…9df7ba

    만약, 모든 블록을 초기화 하고 싶으면 data 디렉토리에 있는 파일을 모두 삭제하시면 됩니다.

    이후에 위에서 수행한 명령어로 제네시스 블록을 다시 생성하면 됩니다.

    $ rm -rf /src/geth_172/build/bin/node1/*



5) geth 실행
    이제 다음 명령어로 geth 엔진을 실행해보겠습니다. 블록 초기화는 이미 이전 단계에서 하였으므로, 

    앞으로 geth 엔진을 실행 할때에는 아래 명령어를 사용하시길 바랍니다.

    $ ./geth --dev console

 

    --dev옵션을 사용하지 않으면 DAG를 생성하는데 상당한 시간이 소요됩니다. 

       또한 마이닝 하는 시간도 굉장히 오래 걸리기 때문에, 테스트를 위한 환경에는 적합하지 않습니다.

       dev옵션을 사용했을때와 사용하지 않았을때를 한번 비교해보시기 바랍니다. ^^

    console 옵션은 command line을 사용하기 위함입니다. 

    다양한 명령어는 위에서 언급드렸지만, 아래 링크에서 확인 하실 수 있습니다.

    https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options



    위 명령어를 실행하면 아래와 같이 콘솔모드를 보실 수 있습니다.

$ ./geth --dev console

INFO [11-12|22:30:51] Starting peer-to-peer node
instance=Geth/v1.7.2-stable/darwin-amd64/go1.9.1

INFO [11-12|22:30:51] Allocated cache and file handles database=/var/folders/v1/x4hsr2cd6fng32yfkjs3pqym0000gn/T/ethereum_dev_mode/geth/chaindata cache=128 handles=1024

INFO [11-12|22:30:51] Initialised chain configuration config="{ChainID: 1337 Homestead: 0 DAO: <nil;;> DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium: 0 Engine: ethash}"

WARN [11-12|22:30:51] Ethash used in test mode

INFO [11-12|22:30:51] Initialising Ethereum protocol versions="[63 62]" network=1

INFO [11-12|22:30:51] Loaded most recent local header number=6 hash=5cc111…a3c09a td=918464

INFO [11-12|22:30:51] Loaded most recent local full block number=6 hash=5cc111…a3c09a td=918464

INFO [11-12|22:30:51] Loaded most recent local fast block number=6 hash=5cc111…a3c09a td=918464

INFO [11-12|22:30:51] Loaded local transaction journal transactions=0 dropped=0

INFO [11-12|22:30:51] Regenerated local transaction journal transactions=0 accounts=0

WARN [11-12|22:30:51] Blockchain not empty, fast sync disabled

INFO [11-12|22:30:51] Starting P2P networking

INFO [11-12|22:30:51] started whisper v.5.0

INFO [11-12|22:30:51] RLPx listener up self="enode://e6b3d8764f70726c6be1bf78a63e311ffedecd3ee521821050c987b35cd213f4a5f08010b17cde21898d8f9f52472a2897d9975ec175a60247e6e4c21f7f482b@[::]:59117?discport=0"

INFO [11-12|22:30:51] IPC endpoint opened: /var/folders/v1/x4hsr2cd6fng32yfkjs3pqym0000gn/T/ethereum_dev_mode/geth.ipc

Welcome to the Geth JavaScript console!

instance: Geth/v1.7.2-stable/darwin-amd64/go1.9.1

coinbase: 0xeb54fc1e2e4a0df9ace10d8b11deee4601b90fc0

at block: 6 (Sun, 12 Nov 2017 22:13:30 KST)

datadir: /var/folders/v1/x4hsr2cd6fng32yfkjs3pqym0000gn/T/ethereum_dev_mode

modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0

  1. 계정 생성, 마이닝, 송금 등 기본 동작 사용
    private network가 동작하고 있으니 해당 네트워크에서 geth가 지원하는 여러 명령어를 사용해보겠습니다.
시나리오 : Alice가 Bob에게 10이더 송금하기.



1) 계정 생성
> personal.newAccount("Alice")

"0xeb54fc1e2e4a0df9ace10d8b11deee4601b90fc0"



2) 계정 목록 조회
> eth.accounts

["0xeb54fc1e2e4a0df9ace10d8b11deee4601b90fc0"]



3) 마이닝 계정 지정
송금을 수행하기 위해서는 트랜잭션을 검증하기 위하여 마이닝을 해야 하는데, 마이닝을 할 계정을 지정합니다. 

이 말인 즉, 마이닝 후 보상을 받을 이더베이스를 지정하는 명령어입니다.

> miner.setEtherbase("0xeb54fc1e2e4a0df9ace10d8b11deee4601b90fc0")

또는

> miner.setEtherbase(personal.listAccounts[0])



4) 마이닝 실행
Bob에게 보낼 이더리움을 채굴하기 위하여 마이닝을 합니다.

> miner.start()

> miner.start(3) // 마이닝 쓰레드를 3개로 지정

DAG 생성 로그 생략...

INFO [11-12|22:43:46] Generating DAG in progress epoch=1 percentage=99 elapsed=52.361ms

INFO [11-12|22:43:48] Successfully sealed new block number=7 hash=e11f0e…a9f4f9

INFO [11-12|22:43:48] 🔨 mined potential block number=7 hash=e11f0e…a9f4f9

INFO [11-12|22:43:48] Commit new mining work number=8 txs=0 uncles=0 elapsed=2.131ms

INFO [11-12|22:43:48] Successfully sealed new block number=8 hash=63599c…5dd484

INFO [11-12|22:43:48] 🔨 mined potential block number=8 hash=63599c…5dd484

INFO [11-12|22:43:48] Commit new mining work number=9 txs=0 uncles=0 elapsed=221.492µs

INFO [11-12|22:43:48] Successfully sealed new block number=9 hash=47cf8b…ab5d8f

INFO [11-12|22:43:48] 🔨 mined potential block number=9 hash=47cf8b…ab5d8f

중략...

dev 모드이기 때문에 상당히 빠르게 DAG를 생성하고, 마이닝 하면서 블록을 생성하는것을 볼 수 있습니다.



마이닝을 멈추기 위해서는 아래 명령어를 사용합니다. 명령어를 입력하는 동안에 계속해서 로그들이 출력되는데 무시하고 계속 입력하시면 됩니다.

> miner.stop()



5) 계정 잔액 조회
> eth.getBalance(eth.accounts[0])

36000000000000000000

> web3.fromWei(eth.getBalance(eth.coinbase), "ether")

36

> web3.fromWei(eth.getBalance(eth.coinbase), "shannon")

36000000000



잔액 조회 기본 명령어를 사용하면 Wei 단위로 표시되기 때문에 1/10^18로 계산됩니다.

하지만, web3 모듈을 사용하여 단위를 지정하면 일반적으로 알고 있는 이더 단위로도 표시 할 수 있습니다.

조금전 마이닝으로 인하여 총 36이더를 채굴하였습니다. 현 포스팅 시점은 블록당 보상이 3개이므로 총 12개의 블록이 생성 되었을것입니다.



단위에 관련하여 아래 링크를 한번 참고 해보시길 바랍니다.

https://www.cryptocompare.com/coins/guides/what-is-ether-in-ethereum/

6) 생성된 블록 수 조회
> eth.blockNumber

12



7) 송금 테스트를 위하여 새로운 계정 생성
> personal.newAccount("Bob")

"0xa05a9541b72f4eb37cdfeba4d24ead785a66ff04"



8) Alice가 Bob으로 10이더 송금
한가지 주의할 사항은 최소 가스는 21,000 입니다.

> eth.sendTransaction({from: eth.coinbase, to: "0xa05a9541b72f4eb37cdfeba4d24ead785a66ff04", value: web3.toWei(10, "ether")})

또는

> from = web3.eth.accounts[0]

> to = web3.eth.accounts[1]

> web3.eth.sendTransaction({from: from, to: to, value: web3.toWei(10, 'ether'), gasLimit: 21000, gasPrice: 20000000000}) 



위 송금 명령어를 실행하면 Alice 계정에서 Bob의 계정으로 돈을 옮겨야 하는데 계정이 LOCK 되어 있으니 Unlock 시키라는 에러 메시지가 보일 것입니다.

Error: authentication needed: password or unlock

    at web3.js:3143:20

    at web3.js:6347:15

    at web3.js:5081:36

    at <anonymous>:1:1



9) Alice 계정을 UNLOCK 시킴
> personal.listWallets[0].status  // 계정의 상태 확인

> web3.personal.unlockAccount(eth.coinbase) // 계정 락 해제

또는

> web3.personal.unlockAccount(eth.coinbase, "Alice")



만약 패스워드를 입력하라고 하면 계정명과 동일한 "Alice" 를 입력. (대소문자 구분)

계정 락이 해제 되었으므로 8)에서 수행한 송금 명령어를 다시 수행합니다.

정상적으로 수행되었다면 트랜잭션이 바로 수행되지 않고, 수행 대기 상태가 됩니다. (pending status)

수행 대기 상태에서 정상적으로 송금을 완료 하려면 마이닝 작업을 수행해야 합니다.



10) 수행대기중인 트랜잭션 확인
> eth.pendingTransactions

eth.pendingTransactions

[{

blockHash: null,

blockNumber: null,

from: "0xeb54fc1e2e4a0df9ace10d8b11deee4601b90fc0",

gas: 90000,

gasPrice: 20000000000,

hash: "0x9a327d3897fc16234d77ae1c4ef3f2b1acdbce84d8ea9625329c1cee7eff928f",

input: "0x",

nonce: 0,

r: "0x1034352cc1ed4affc814555d9cf408fcd8111119c6978f8c8d994b09da62b504",

s: "0x58c765d7ea7f76fddf938fbb8d81488d0d37b9632c1c8d3197f3dbda8c0ce904",

to: "0x041445881b3caf96c43f989f351c67282af2509f",

transactionIndex: 0,

v: "0xa95",

value: 10000000000000000000

}]

11) 마이닝
> miner.start()



블록이 생성되면 마이닝을 정지하고 다시 한번 수행 대기중인 트랜잭션을 확인합니다.

> eth.pendingTransactions

[]



12) Bob 계정 잔액 조회
Bob이 정상적으로 Alice 로부터 이더를 받았는지 확인하기 위하여 잔액을 조회해봅니다.

> eth.getBalance(eth.accounts[1])

10000000000000000000



Wei 단위이므로 위와같이 출력되며 정상적으로 10 이더 잔액을 확인 할 수 있습니다.

마치며...

geth가 어떻게 동작되는지 엔진을 설치하고 CLI를 통하여 다양한 명령어를 살펴보았습니다. 물론 본 포스팅에서 다룬 명령어는 빙산의 일각에 불가하지만 성공적으로 엔진을 설치하고 명령어를 수행 해본데에 큰 의의를 두었으면 합니다. 나머지 다양한 명령어들은 직접 이더리움 문서를 통하여 살펴보시길 바랍니다. CLI를 통하여 MIST 지갑과 연동 테스트도 할수 있고, smart contract를 작성하여 테스트도 할수 있습니다. 또한 JSON RPC를 통한 web3.js 기반의 프론트 엔드 페이지도 작성할수 있으니 geth 엔진 구동을 시작으로 좀 더 깊이있는 이더리움 학습을 해보려 합니다.

출처: http://softwaree.tistory.com/18

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Hi! I am a robot. I just upvoted you! I found similar content that readers might be interested in:
http://softwaree.tistory.com/rss

Congratulations @miraclecoin! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Are you a DrugWars early adopter? Benvenuto in famiglia!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Congratulations @miraclecoin! You received a personal award!

Happy Steem Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Downvote challenge - Add up to 3 funny badges to your board
Vote for @Steemitboard as a witness to get one more award and increased upvotes!