C++ 이더리움으로 Private/Local Network 을 구성해보도록 하겠다.
Frontier 나 testnet 이 아닌, 두 개 혹은 그 이상의 peer 간에 상호 통신이 가능한 환경을 만들어 보도록 한다.

Windows 버전과 Mac OS X, Linux 버전을 사용하도록 하겠다. 
Windows 버전의 빌드는 지난번 블로그로 올렸고, Mac 과 Linux (Ubuntu) 버전은 Ethereum 의 가이드 대로 소스빌드를 하면 별 어려움 없이 빌드 가능하다.

▌Mac OS X 소스빌드 전 필요사항

  1. Mac OS X Yosemite 또는 El Capitan
  2. Home Brew
  3. git

▌Mac OS X 소스 빌드 방법

아래 커맨드 들을 순차적으로 입력하자
brew install boost --c++11
brew install cmake cryptopp miniupnpc leveldb gmp jsoncpp libmicrohttpd libjson-rpc-cpp
brew install homebrew/versions/v8-315
brew install llvm --HEAD --with-clang
brew install qt5 --with-d-bus

시간이 꽤나 걸리기때문에 인내심이 필요하다
다음으로는 소스코드를 Clone 하고 cmake 로 XCode 용 프로젝트를 생성한다
git clone --recursive https://github.com/ethereum/webthree-umbrella.git
cd webthree-umbrella

XCode 용 프로젝트를 생성한다
mkdir build_xc
cd build_xc
LLVM_DIR=/usr/local/Cellar/llvm/HEAD/lib/cmake cmake -G Xcode ..

XCode 를 띄우고 프로젝트를 Build 한다. Windows 와 다르게 매우 매끄럽게 빌드된다는 점에 놀라지 않을 수 없다

만약 빌드시에 LLVM 관련한 오류가 발생한다면, LLVM Library 의 버전을 체크하기 바란다. LLVM 라이브러리 버전은 3.7.0 이상이면 되고, 현재 Release 된 최신 LLVM Library 버전은 3.7.1 이다.
El Capitan OS X 이 내 Mac 은 이상하게 LLVM 3.9.0 이 설치되어있었다 (뭐하다가 이게 설치되어있었는지는 모른다). 그런데 3.9.0 은 Develop 버전이며, 빌드 시 오류가 생긴다. 3.7.1 버전으로 재설치 해주도록 한다.

▌Linux 소스 빌드 방법 (ubuntu 14.04 이후)

리눅스 빌드 방법도 거침 없이 진행된다. 사실 이 블로그를 쓰는 이유는 Windows 버전 때문이다. 아무리 생각해도 C++ Ethereum 은 Windows 버전은 빌드 되는지 정도만 테스트 하는것 같다. 개발은 Mac 과 Linux 로 하고있지않나 싶을정도이다. 

나는 Ubuntu 15.10 으로 apt-get 으로 upgrade 한 후 아래 가이드를 따라 소스빌드 했다.

나의 경우 오류 없이 잘 빌드되었다. 또한 console 모드로 실행해도 console 도 잘 실행된다.
(별 문제없는 과정들은 다음부터는 간단히 간단히~)

▌UPNP 코드 수정 (옵션)

eth 는 NAT 환경의 지원을 위해 upnp 기능을 제공하고있다. upnp 를 지원하는 공유기나 라우터 안에 node 가 있다면, upnp 기능으로 자동으로 포트 포워딩을 설정하도록 하는 것이다.
그러나 우리는 외부와 연결 없이 내부 node 끼리 테스트하고 싶으므로 upnp 기능까지는 필요 없다.

eth 간에 상호 peer 와 연결하기 위해 Node 간 통신 시에 자신의 IP 를 상대방에게 알려주도록 되어있는데, 이때 약간의 문제가 발생한다.
IPV4 는 Public IP 와 함께 주소 부족과 보안등의 이유로 주로 NAT 내에서 Private IP 를 사용하도록 되어있는데, 
Class A (10.*), Class B 172.(16 ~ 31).* Class C 192.168.* 는 모두 Private IP 로 분류된다.

그런데 만약 upnp 를 지원하지 않는 라우터 내에 있는 Node 간에 연결해야 하는 경우, --upnp off 옵션을 주도록 하는데, 이렇게 되면 Node 의 IP 가 public IP 를 사용하는것으로 간주한다.
하지만 public IP 가 아니므로 Exception 이 발생하고 eth 가 죽고만다.

그래서, 해당 코드를 수정해서 Private IP 를 public 으로 간주하도록 해주어야 한다.

<프로젝트 루트>\libweb3core\libp2p\common.cpp 을 열고 84 라인 부터 보면 (1.1.3 기준) 아래와 같은 코드가 있다.
bool p2p::isPrivateAddress(bi::address const& _addressToCheck)
{
    if (_addressToCheck.is_v4())
    {
        bi::address_v4 v4Address = _addressToCheck.to_v4();
        bi::address_v4::bytes_type bytesToCheck = v4Address.to_bytes();
        if (bytesToCheck[0] == 10 || bytesToCheck[0] == 127)
            return true;
        if (bytesToCheck[0] == 172 && (bytesToCheck[1] >= 16 && bytesToCheck[1] <= 31))
            return true;
        if (bytesToCheck[0] == 192 && bytesToCheck[1] == 168)
            return true;
    }
    else if (_addressToCheck.is_v6())

위 부분에서, 자신이 속하는 class 를 체크하는 로직을 // 로 comment 처리 하거나 삭제한다.
예를들어 Class A 체크하는 부분을 삭제하면 아래와 같다.
bool p2p::isPrivateAddress(bi::address const& _addressToCheck)
{
    if (_addressToCheck.is_v4())
    {
        bi::address_v4 v4Address = _addressToCheck.to_v4();
        bi::address_v4::bytes_type bytesToCheck = v4Address.to_bytes();

        if (bytesToCheck[0] == 127)
            return true;
        if (bytesToCheck[0] == 172 && (bytesToCheck[1] >= 16 && bytesToCheck[1] <= 31))
            return true;
        if (bytesToCheck[0] == 192 && bytesToCheck[1] == 168)
            return true;
    }

위 과정은 upnp 를 지원하지 않는 라우터나 네트워크 내에 있을 때 활용할 수 있는 방법이며, 그 외의 경우는 그냥 그대로 사용하도록 한다.

이제 Account 를 만들고 나만의 genesis 를 만들어서 ether 도 충분히 넣은 후 Java Script Console, JSON-RPC 를 사용하여 Smart Contract 를 만들고 실행해보면 된다.

▌Account 만들기

Account 를 만드는 방법은 2가지가 있다. 

  1. 자동생성 방법
  2. 직접 만들기

※ 자동생성 방법
자동 생성 방법은 일단 eth 를 실행시키면 된다. eth 를 그냥 실행만 시켜도 최초 실행시에 master password 를 물어보고, master password 를 입력하면 그 즉시 Account 를 하나 생성해주고 address 를 콘솔에 출력해준다.

만약 그냥 지나갔다면, JS console 에서 web3.eth.accounts 를 쳐보면 생성된 Account 의 주소를 볼 수 있다.

※ 수동생성 방법
C++ Ethereum 팀은 Account 와 Key 를 관리하기 위한 도구를 별도로 개발했다. ethkey 가 그것이며, 프로젝트 전체를 빌드했다면 (ALL_BUILD), 
<빌드디렉토리>/libethereum/ethkey/Debug
안에 ethkey 실행파일이 있을것이다.

C++ Ethereum 과 Go-Ethereum (Geth) 는 이 키를 관리하는 디렉토리의 위치가 약간 다르다.
eth 는 Windows 의 경우 %APPDATA%\web3\keys 안에 키를 저장하도록 되어있다
geth 는 Windows 의 경우 Ethereum 의 <datadir>\keyfiles 안에 저장한다

ethkey 는 Cygwin 이나 MinGW 의 Bash 에서 실행하면 Master Password 를 물어보는 과정에서 Exception 이 발생하고 죽는다. Windows 의 Command Prompt 를 통해 실행하도록 한다.

ethkey 로 새로운 key 를 생성해본다
ethkey new <Account 이름> 을 입력하면 아래와 같은 과정이 실행된다.
> ethkey new myname
Please enter your MASTER passphrase: 
Enter a passphrase with which to secure this account (or nothing to use the master passphrase):
Please confirm the passphrase by entering it again: 
Created key 6ecc980b-2f99-013d-167e-0ea9caffde4e
  Name: myname
  Password hint:
  ICAP: XE561WBEXUY46M6G05SDKF5P9C334V3JT6
  Raw hex: 007386abec97fc9f994abafa85b1b42dd97f860a
myname 이라는 이름으로 대표할 수 있는 007386abec97fc9f994abafa85b1b42dd97f860a 주소의 Account 가 생성되었다.
처음 물어보는것은 MASTER 패스워드이며, 모든 Account 와 관련한 동작을 할 때 이 Master Password 를 입력해야 한다. eth 를 실행할때에도 마찬가지이다.
귀챦다면, --master 옵션으로 Command Line 에서 미리 주어 물어보지 않게 할 수도 있다.

ICAP (Inter-exchange Client Address Protocol)는 IBAN 의 국제 공용 계좌번호의 형식이다. 향후에 좀더 소개할 기회가 있을지 모르겠으나, Ethereum 은 향후 Ethereum과 직접적인 국제계좌 연계를 염두에 두고 이런 무리한(?) 사상을 추가도입하였다. 물론 현재 실제 ether 가 IBAN 계좌로 이체되지는 않지만 이러한 주소체계를 기본적인 20바이트 Address 외에도 추가로 표시해주고있다.

추가적으로, registrar 라는 기본 Smart Contract 를 통해 20바이트 주소 대신 Alias Name 을 통해 거래나 Smart Contract Call 도 가능하다. Frontier 이후 부터 해당 Contract 가 기본적으로 들어갔다.

말이 옆으로 샜는데, 다시 돌아와서..
위에 추가한 Account 가 잘 보이는지 확인해 본다.
>ethkey list

Please enter your MASTER passphrase: 1a7e55b0-3eb7-05ec-248e-8d901e268d76 0096bb98??XE602H4XB00HUY08LU416SCBGO3CS63H66  Default key
6ecc980b-2f99-013d-167e-0ea9caffde4e 007386ab??XE561WBEXUY46M6G05SDKF5P9C334V3JT6  myname
처음 보이는게 자동으로 만들어졌던 Account Address 이고, 두번째 것이 myname 이라는 이름으로 만든 Account Address 이다.

MASTER 패스워드라는 개념은 현재 C++ Ethereum 에서만 도입되었다. Geth 의 경우, Account 별 패스워드를 넣지만 C++ 은 Account 패스워드 외에도 MASTER 패스워드가 있다. 마치 Mac 이나 Windows 의 keystore 와 같은 개념이다. Keystore 자체에 접근하기 위한 패스워드와 서비스를 사용하기 위한 패스워드가 다르듯이 말이다.

C++ Ethereum 은 Account 별 패스워드를 지정하지 않을 수 있다. 기본으로 생성된 Account 가 그렇다. MASTER 패스워드만 사용하려면 Account 를 만들 때 그냥 Enter 만 쳐주면 된다.

-----

술먹고 들어와서 쓰려니 눈이 스르르 감긴다. 체력이 바닥나고있는 관계로 나머지는 또 다음으로..^^




반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,