솔리디티를 이용한 이더리움 스마트 컨트랙트 개발 강좌를 써오면서 저도 몇 번 새롭게 개발환경을 구축 할 필요가 있었습니다. 그런데 제일 중요한 초기 geth 설치 및 geth 실행에 대한 부분을 안 써놔서 제 글들을 한 참 찾아 헤맸었습니다. 그래서 오늘 간략히 정리해서 필요하신 분들도 보고, 저도 또 개발환경 구축할 때 참고하려고 합니다v
!주의: 개발환경은 Ubuntu 16.04 (리눅스)입니다.
Blockchain 선택
이더리움을 포함해서 블락체인 개발환경은 어떤 블락체인을 사용하느냐에 따라 달라집니다.
- Main Net: Public blockchain으로 누구나 접근 가능. 한 개만 존재.
- Test Nets: 자체 Ether를 발행하여, 테스트 용도로만 사용. 복수의 테스트넷 존재.
- Local Net: 자신의 PC에 온전한 blockchain을 올려서 개발. 복수개를 만들어서 하는 것도 가능.
Metamask를 설치하고 Signup을 하면 아래와 같이 다양한 블락체인 네트워크를 선택할 수 있습니다.
다 아시다시피 각 블락체인 네크워크마다 자체 코인이 있습니다. 즉 테스트 넷의 ether를 Main net에서 사용할 수 없죠. 그런데 한가지 모르실 수도 있는 점은 Metamask에서 메인넷에서 주소를 하나 생성하면 테스트넷에서도 동일한 주소를 사용할 수 있다는 것입니다. 즉, 네트워크 별로 따로 주소를 만들지 않아도 된다는 것이죠.
개발시 Blockchain별 장단점
개발시에 어떤 blockchain을 사용하는지에 따라 장단점이 있습니다. 간략히 요약만 해보겠습니다.
Main Net. 메인넷
- 내가 발행한 스마트 컨트랙트가 모두에게 Open되어 누구나 접근가능.
- 실제 서비스할 때는 메인넷에 올려야 함.
- 개발시 트랜잭션이 발생하면 실제 Ether가 소모됨(엄밀히는 gas가 소모).
즉 메인넷 사용 비용을 개발자(엄밀히는 트랜잭션 발생자)가 지불해야 함. - 트랜잭션 처리 시간이 오래 걸림. 실제 채굴자들이 채굴해 줘야 거래가 진행됨.
- 그래서 개발시에는 사용하지 말아야 함.
Test Nets. 테스트넷
- 위 Metamask 그림에 나타났듯이 다수의 테스트넷이 존재. Ropspen, Kovan, Rinkeby,
- 각 테스트넷 별로 사용하기 위한 Ether를 획득해야 함. 테스트넷이지만 개발자들이 증가함에 따라 이곳에 사용되는 Ether 구하는 것도 점점 까다로와 짐. 그나마 Rinkeby가 간단함.
- 테스트넷에서도 트랜잭션 발생시 테스트넷용 Ether가 필요함.
- 사용자가 많아짐에 따라 트랜잭션 처리 속도 느려지고 있음.
Local Net. 로컬넷
- 자신의 Local PC 또는 클라우스 서버에 직접 독자적인 블락체인을 만들 수 있음.
- Public/Private 블락체인 개념으로 흔히들 Private 블락체인이라고들 하는데, 엄밀히 로컬넷은 Private하기보다는 개인 개발용으로 만들어 사용하는 것을 의미.
- 채굴도 로컬 PC에서 함(자신의 PC에서 개발하면서 채굴도 같이 함)
- Ether는 채굴함에 따라 자동으로 생성. 테스트할 Ether 걱정 필요없음.
- 트랜잭션이 거의 바로 채굴되어 처리됨. 채굴 난이도 조절도 직접 할 수 있음.
- 개인적으로 스마트 컨트랙트 개발하기엔 최적의 네트워크임.
결론적으로, 개인 개발시에는 로컬넷을 사용하는 것이 가장 좋습니다. 로컬넷에서 어느 정도 감을 익히고, 동작 확인 되면 그 때부터 테스트넷에서 테스트 하고, 문제가 없다면 메인넷에 진짜로 등록시키게 되는 거죠. 저도 아직 로컬넷에서만 작업하고 있습니다~
Geth
이더리움 블락체인에 연결하는 노드들을 이더리움 클라이언트라고 합니다. 좀더 단순히는 블락체인에 참여하는 노드입니다. 블락체인에 연결되어 트랜잭션을 발생시키고, 검증하는 역할을 담당합니다.
클라이언트 기능을 하기 위해 프로그램이 필요한데, 가장 많이 사용하는 프로그램이 go-ethereum (Geth)입니다. Go언어로 만들어진 이더리움 클라이언트 입니다. 이 프로그램을 사용하기 위해서는 몇가지 의존 패키지를 설치해야 합니다.
의존 패키지 설치
$ sudo apt-get install build-essential libgmp3-dev golang git tree
geth 소스 설치
geth를 바이너리 형태(실행파일 형태)로 받을 수도 있지만 여기서는 소스를 받아서 빌드하는 방법을 설명합니다.
$ git clone https://github.com/ethereum/go-ethereum.git
$ cd go-ethereum
geth는 업데이트가 빠르게 되고 있어서 최신 버전은 다른 의존 패키지와 의존성 문제를 일으킬 수 있습니다. 이럴 때 geth를 최신 버전으로 사용하지 않고, 비교적 안정적이고 이전 버전을 선택해서 소스 빌드 하여 사용합니다.
<블락체인, 애플리케이션 개발 실전 입문> 책 내용대로 아래와 같은 버전을 선택하여 빌드합니다.
$ git checkout refs/tags/v1.5.5
$ make geth
빌드가 제대로 되면 현재위치에서 build/bin 디렉터리 밑에 geth라는 바이너리 파일이 생성됩니다. 이것은 아래와 같이 시스템 디렉터리에 복사합니다.
$ sudo cp build/bin/geth /usr/local/bin
geth를 그냥 실행하게 되면 메인넷의 노드로 동작하려고 할 것입니다. 즉, 메인넷의 모든 블락 데이터를 다운로드 받으려고 할 것입니다. 바로 geth를 실행하지 마시고, 아래와 같이 로컬넷의 블락체인 생성 및 초기화 합니다.
블락체인 생성
로컬넷에서 geth 프로그램을 실행시키려면 블락이 저장될 위치를 지정해야 하고, 최초의 블락에 대한 정보 파일인 genesis.json 파일을 만들어야 합니다. 난이도인 difficulty는 적절히 설정합니다.
$ mkdir -p ~/Blockchain/data_testnet
$ cd ~/Blockchain/data_testnet
$ cat > genesis.json
{
"config": {},
"nonce": "0x0000000000000042",
"timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x0",
"gasLimit": "0x8000000",
"difficulty": "0x4000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333",
"alloc": {}
}
블락이 저장될 디렉터리와 genesis.json 파일이 준비되었기 때문에 이제 geth를 초기화하여 로컬넷 블락체인을 생성합니다.
$ geth --datadir ~/Blockchain/data_testnet init ~/Blockchain/data_testnet/genesis.json
--datadir
옵션에 블락이 저장될 디렉터리를 넣어주고, init
옵션에 genesis.json 파일을 경로포함해서 넣어줍니다.
이렇게 하면 자신의 PC에서 독자적인 블락체인이 생성되게 됩니다. 해당 블락체인은 geth 프로그램을 이용해서 접근할 수 있게 됩니다.
geth 기동
그럼 한 번 geth를 기동해보겠습니다.
$ geth --networkid 4649 --nodiscover --maxpeers 0 --datadir ~/Blockchain/data_testnet console 2>> ~/Blockchain/data_testnet/geth.log
위 명령에서 사용된 옵션의 간략한 내용은 다음과 같습니다.
- --networkid 4649: 네트워크 식별자
- --nodiscover: 생성자의 노드를 다른 노드에서 검색할 수 없게 하는 옵션
- --maxpeers 0: 생성자의 노드에 연결할 수 있는 노드의 수를 지정. 0을 지정하면 다른 노드와 연결하지 않음.
- console: 대화형 콘솔을 띄움.
- 2>> ~/Blockchain/data_testnet/geth.log: 로그 파일을 없다면 만들고 거기에 에러 내용을 기록함.
문제가 없다면 위 그림의 마지막처럼 콘솔의 입력 프롬트프인 >
이 나타납니다.
geth 기본 명령
geth를 이용하여 계정 생성, 채굴 설정 등의 명령을 알아보겠습니다.
계정(주소) 생성
위와 같이 geth를 기동한 후에 geth 콘솔에서 아래와 같이 계정을 생성할 수 있습니다.
> personal.newAccount("pass0")
"0x47F46482ED22F168CC7C7fFBf176d3a88766917f"
콘솔에서 존재하는 계정 확인은 아래와 같이 합니다.
> eth.accounts
"0x47F46482ED22F168CC7C7fFBf176d3a88766917f"
특정 계정의 잔고를 아래와 같이 콘솔에서 확인할 수 있습니다.
> eth.getBalance( eth.accounts[0] )
0
채굴. Mining 설정
먼저 채굴이 되고 있는지 안되고 있는지 아래와 같이 콘솔에서 확인합니다.
> eth.mining
false
지금은 채굴이 안되고 있는 상태입니다. 그러면 채굴을 시작해 보겠습니다.
> miner.start(1)
true
그러면 반대로 채굴을 중지해 보겠습니다.
> miner.stop()
true
채굴관련 정보를 아래와 같은 명령으로 확인할 수 있습니다.
> eth.hashrate
0
> eth.blockNumber
62
geth의 다양한 명령에 대해서는 검색 후 사용하시면 되겠습니다.
geth 원격 접속을 허용하는 기동
이전의 geth 기동 옵션은 로컬에서만 사용할 때 사용하는 옵션이고 만약 web에서의 접속을 허용하고 싶을 때, 특히 오프라인으로 remix를 사용하고 싶을 때는 web 관련 옵션을 추가해야 합니다.
$ nohup geth --networkid 4649 --nodiscover --maxpeers 0 --datadir ~/Blockchain/data_testnet --mine --minerthreads 1 --rpc --rpcaddr "0.0.0.0" --rpcport 8545 --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --unlock 0,1 --password ~/Blockchain/data_testnet/passwd --verbosity 6 2>> ~/Blockchain/data_testnet/geth.log &
주요 옵션은 다음과 같습니다.
- nohup: geth옵션이 아니라 리눅스 옵션임. SIGHUP을 무시한 상태로 프로세스를 기동함. 쉘로부터 SIGHUP이 전송돼도 무시하기 때문에 로그아웃 후에도 프로세스가 종료되지 않음. 중지하기 위해 kill 명령 사용.
- --mine: 채굴을 활성화
- --rpc: HTTP-RPC 서버를 활성화
- --rpcaddr "0.0.0.0": HTTP-RPC 서버에 접속할 IP를 지정. "0.0.0.0"값은 모든 IP가 접속가능하게 함.
- --rpcport 8545: HTTP-RPC 서버가 요청을 받기 위해 사용하는 포트 지정.
- --rpccorsdomain "": 자신의 노드에 RPC로 접속할 IP를 지정. ""값은 모든 IP가 접속가능.
- --rpcapi "admin, db, eth, debug, miner, net, shh, txpool, personal, web3": RPC에서 사용이 허가되는 기능 모듈의 지정.
- --unlock 0, 1: 계정 0과 계정 1을 다음의 --password 옵션으로 풀어 놓는다. geth에서 암호입력없이 해당 계정 접근 가능.
- --password: password가 저장되어 있는 경로명 포함한 파일 이름
- &: geth를 백그라운드에서 실행하라는 명령.
그럼 다른 터미널에서 위 geth에 접속해 보겠습니다.
$ geth attach rpc:http://localhost:8545`
Welcome to the Geth JavaScript console!
instance: Geth/v1.5.5-stable-ff07d548/linux/go1.6.2
coinbase: 0x9751574414138b22986eb80ce2713cd2f5508c5c
at block: 4481 (Sun, 25 Mar 2018 13:26:31 KST)
datadir: ~/Blockchain/data_testnet
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.mining
true
오늘의 실습: 자신만의 로컬넷을 만들고 채굴을 통해서 1M Ether를 모아보세요. 얼마나 시간이 걸리는지 체크해보세요.