[Ethereum] Part 1 : 이더리움 소개 및 private network 구축

고려대학교 정보통신대학원 인호 교수님 수업 내용을 복습 차원에서 정리한 포스트입니다. 실습 환경은 Ubuntu 16.04입니다.



이더리움이란?

비트코인은 최초의 블록체인을 사용한 가상화폐(cryptocurrency) 이더리움은 최초의 블록체인을 사용한 탈중앙화 응용프로그램(Dapp) 플랫폼.

블록체인을 활용한 프로그래밍

Smart Contract는 (제3자 없이) 신뢰가 없는 사람간의 계약을 가능하게 해준다. 이더리움은 Smart Contract를 최초로 구현한 프로그램이다. 이더리움 실습을 한다는 것은 Smart Contract를 구현해보는 것(블록체인을 활용한 프로그래밍을 하는것).

  • 이더리움 Smart Contract의 한계
    • 구현할 수 있는 것이 많지 않다. (현실세계와 연동이 어렵다.) 예를 들어, 축구 경기의 결과에 대해 voting해여 배당금을 가져가는 (제 3자를 배제한) smart contract를 짠다고 하더라도, 현실세계에서의 축구결과를 smart contract에 넣어주는 oracle이 필요하다.
    • 기술이 발전하면서 Smart Contract를 적용할 수 있는 범위가 확장될 것이다.

이더리움 클라이언트

이더리움은 분산 네트워크 기반의 플랫폼으로서 중앙 집중형 서버 프로그램이 따로 존재하지 않고 오로지 클라이언트 프로그램만 존재한다. 클라이언트 프로그램은 다양한 프로그래밍 언어로 개발되고 있으나, Ethereum Foundation에서는 구글에서 만든 프로그래밍 언어 Go 언어로 개발된 Go Ethereum과 Rust로 개발된 Parity를 이더리움의 메인 클라이언트로 개발하고 있다.

Go Ethereum

이더리움 클라이언트 중에 Go Ethereum를 다룰 것이다. Go Ethereum은 Google에서 만든 Go 언어를 기반으로 개발되었으며, GNU LGPL v3 라이선스를 따르고 있는 오픈소스이기 때문에 누구나 소스 코드를 살펴보고 개발에 기여할 수 있다. Github

Node js

우선 node.js를 설치한다. 여기에서 설치할 수도 있고, 우분투 사용자라면 아래와 같이 손쉽게 설치할 수 있다. npm은 nodejs 패키지 매니져인데, 설치하는김에 같이 했다. 2018-10-29기준 v4.2.6 버젼이 설치되었다.

1
2
3
sudo apt-get update
sudo apt-get install nodejs
sudo apt-get install npm

설치확인

1
nodejs -v

Geth

여기에서 Geth를 설치한다. Geth 1.8.17를 설치하였다.

우분투 환경이라면 아래와 같이 stable버젼을 설치할 수 있다.

1
2
3
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

개발 버젼은

1
2
3
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum-unstable

설치확인

1
geth version

eth-01-01

사설 이더리움 네트워크 구축하기

본인이 만든 smart contract를 공용 이더리움 네트워크에 바로 배포하고 테스트 한다면 실제 이더리움을 배포비용으로 사용하기 때문에 수정배포를 반복 할 때 비용이 계속 든다. 따라서 개발자가 사설 네트워크를 구축하여 여기서 배포 테스트를 하는 것이 효율적이다. 사설공간에서는 개발자나 사용자가 원하는 만큼 이더를 채굴할 수 있기 때문이다.

사설 네트워크를 구축하기 위해서 우리가 새롭게 생성하거나 설정해야 할 요소들은 아래와 같다.

  • Genesis 블록 파일 생성 : 이더리움 네트워크에서 사용되는 블록체인의 최초 시작 블록을 생성한다.
  • Data 디렉토리 설정 : 계좌나 블록 정보들이 저장될 디렉토리를 설정한다.(–datadir “C:\ethereum\data”)
  • 네트워크 ID 설정 : 사설 이더리움 네트워크의 ID를 정의한다. (–networkid id_number)
  • Node Discovery 비활성화 : 이더리움 네트워크에 있는 모든 노드들은 끊임없이 다른 노드를 찾아 자신의 peer로 등록하게 되는데 테스트의 용도로 구성된 사설 네트워크에서는 이러한 과정이 필요하지 않으므로 비활성화한다. (–nodiscover)
1
2
mkdir ~/ethereum/data
geth --datadir "~/ethereum/data" account new

eth-01-02

Geth 클라이언트는 새롭게 개설된 20바이트 크기의 16진수 형태를 가진 공개 계좌주소를 출력한다. 67eb80f126b75f8ea6a6c741a5be62ac40bde647가 계좌의 주소다. 계좌와 관련된 데이터는 ~/ethereum/data/keystore 에 저장된다.

1
geth --datadir "~/ethereum/data" account list

eth-01-03

account list 명령어를 통해 우리가 개설한 계좌의 정보를 조회할 수 있다. --datadir 옵션을 통해 계좌의 정보가 저장된 경로를 지정해주어야 한다.

  • Genesis 블록은 이더리움의 기반인 블록체인의 가장 첫 번째 블록(block0)으로서 이전 블록에 대한 정보를 갖고 있지 않는 유일한 블록이다.
  • 이더리움은 이 블록체인의 내용을 유연하게 변경할 수 있는 많은 옵션들을 지원하며, 이 옵션을 Genesis 블록에 정의함으로써 원하는 목적에 부합하는 이더리움 사설 네트워크를 구축할 수 있다.
  • 해당 이더리움 네트워크에 접속하는 모든 클라이언트 노드들은 동일한 Genesis 블록을 소유하고 있어야 블록체인의 합의 과정에 참여할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  "config": {
        "chainId": 0,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
  "alloc"      : {
	"67eb80f126b75f8ea6a6c741a5be62ac40bde647": { "balance": "300000" }
	},
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x2000",
  "extraData"  : "",
  "gasLimit"   : "0x2100000",
  "nonce"      : "0x0000000000000042",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00"
}

위 내용을 ~/ethereum/CustomGenesis.json로 생성한다. 이때 alloc은 주소에 이더를 생성해주는 코드이다. 아까 생성한 주소67eb80f126b75f8ea6a6c741a5be62ac40bde647에 300000만큼의 balance를 넣어주자. (각자 생성된 주소로 넣어주면 된다.) 위 내용을 바탕으로 genesis block을 생성하려면 아래의 명령어를 사용하면 된다.

1
geth init "~/ethereum/CustomGenesis.json"

eth-01-04

  • console 옵션: 대화형 자바스크립트 콘솔 환경으로 접근하는 모드로
    • 다양한 API를 이용하여 실시간으로 새로운 계좌를 생성하거나,
    • Ether를 전송하고,
    • 채굴과 같은 기능 등을 활성화 또는 비활성화할 때 사용한다.
1
geth --identity "PrivateNetwork" --datadir "~/ethereum/data" --port "30303" --rpc --rpcaddr 0.0.0.0 --rpcport "8123" --rpccorsdomain "*" --rpcapi "db,eth,net,web3,miner" --nodiscover --networkid 1900  console

지금까지의 과정을 올바르게 수행하였다면 다음과 같이 이더리움 클라이언트가 실행이 되고 대화형 자바스크립트 콘솔 환경에 접속할 수 있다.

eth-01-05

아래와 같이 계좌를 조회할 수도 있다. 아까 생성했던 계좌의 주소를 확인할 수 있다. eth-01-06

  • 잔고 조회: eth.getBalance(eth.accounts[0]) 명령어나 eth.getBalace(eth.coinbase) 명령어로 계좌의 잔고를 확인할 수 있다. 이때 잔고는 eth단위가 아닌 wei단위로 출력된다. eth 단위로 출력하기 위해서는 web3.fromWei(eth.getBalance(eth.coinbase), "ether") 명령어를 사용하면 된다.
  • 채굴기능 활성화: Geth 실행시 --mine 옵션을 넣거나 자바스크립트 콘솔 환경에서 miner.start()명령어를 사용해서 채굴을 실행한다. 채굴 중단은 miner.stop()이다. 채굴 실행시 DAG process를 100%까지 수행한 뒤 채굴이 실행된다. 사설 네트워크에서는 난이도가 상당히 낮게 설정되어 있어 빠른 속도로 채굴이 가능하다.

Mist 브라우저

이더리움에서 이더를 사용하거나 스마트 컨트랙트를 실행하기 위해서는 반드시 지갑(wallet)이 있어야 한다. 콘솔 환경에서도 이더를 주고받거나 스마트 컨트랙트를 배포 및 실행할 수 있으나 일반 사용자의 입장에서는 그래픽 유저 인터페이스 기반의 지갑 프로그램이 더 사용하기 편리할 것이다. 이러한 그래픽 유저 인터페이스(GUI) 기반 이더리움 지갑 프로그램이 Mist 브라우저이다. 여기에서 Mist를 받을 수 있다. 사이트에서 두 종류의 프로그램을 다운로드 받을 수 있는데 ‘Ethereum Wallet’과 ‘Mist’이다. ‘Ethereum Wallet’은 이더리움 지갑의 기능을 기본 모드로 수행하는 프로그램이며, ‘Mist’는다른 Dapp을 사용할 수 있게 해주는 기능을 기본 모드로 수행하는 프로그램으로 기본 모드가 다를 뿐 기반은 같다.

Mist 브라우저가 사설 네트워크에 바로 접속하기 위해서는 Geth를 이용하여 미리 이더리움 사설 네트워크를 구축해 놓아야 한다. 그렇지 않은 경우, Mist 브라우저는 공용 이더리움 네트워크에 접속하게 된다. 만약 성공적으로 사설 네트워크에 접속되었다면 왼쪽 빨간 동그라미에 마우스를 올리거나 클릭했을 때 ‘Private’ 이라는 표시가 출력될 것이다. 이는 공용 네트워크에 접속했을 때는 볼 수 없는 메시지이다. eth-01-07