Genesis 정보까지 모두 준비되었다. 이제 Node 를 실행하면 된다.
그런데 옵션으로 주어야 할게 쫌 있다. 좀 자질구레한것들이지만 Shell Script 로 만들어놓으면 편하기 때문에 MinGW 의 bash shell script 로 만들어놓는다.

▌실행 Script

내가 사용중인 Shell Script 는 다음과 같다. Wallet 의 Master Password 는 1111 이고 JSON-RPC 를 사용하기 위한 Session-Key 로는 0000 을 지정해주었다. 

그리고 연결되는 Node 간의 시간차는 +- 13분 이내 이어야 한다. 시간을 잘 맞추고 시작하자.

[Linux]
./eth --config $ETH_HOME/res/config.json --master 1111 --json-rpc
--json-admin 0000 --admin-via-http --no-bootstrap --listen 30301
--remote "192.168.0.122" --port 30301 --db-path $ETH_HOME/db_goodjoon 
--mining on --address "0047d27a61e384403d875239cbc462896044213e" 
--verbosity 99 --json-rpc-port 8545 --ipc --upnp off  $@

[Windows]
.\eth.exe --config d:\ethereum\res\config.json --master 1111 
--json-rpc --json-rpc-port 8545 --json-admin 0000 --admin-via-http 
--listen 30301 --remote "192.168.0.60" --port 30301 
--db-path d:\ethereum\db_goodjoon --verbosity 9 
--admin-via-http -o full  --upnp off  %*

--admin-via-http 옵션은 1.2.0 에서 새로생긴 옵션인데, JSON-RPC 를 통해 admin 기능을 실행할 수 있게 허용하겠단 이야기이다. 
--no-bootstrap 으로, Peer Server 에 연결하지 않도록 하였으며
--remote 옵션으로 직접 연결할 Node 를 지정해주었다.
--db-path 로 기본 DB PATH 를 사용하지 않고 db_goodjoon 을 사용하도록 설정하였다. 
console 옵션은 어차피 1.2.1 버전의 C++ eth 는 동작하지 않는다. 나중에 process 를 하나 더 띄워서 attach 해서 사용할것이기 때문에 console 옵션은 주지 않았다.

뒤에서 언급하겠지만, 1.2.1 버전 오면서 Windows 의 버그와 Default 값의 동작이 더 심각해졌다. coinbase address 도 기본으로 안넣어주고, JSONRPC 포트도 지정해주지 않으면 -1 값이다. 그러나 아직도 --help 에는 8545 기본값으로 나온다. Geth 의 jsonrpcapi 옵션에서 볼수있었던 JSON RPC admin 기능을 위해 --admin-via-http 옵션도 생겨나고 했는데 그러면서 좀더 꼬이고있기도 하다. (새로 팀장 오고나서 팀을 "REBOOT" 하겠다고 했는데, 좀 잘 되었으면 좋겠다. Go 팀을 좀 봐라 쫌..)

▌실행 확인
(++)Ethereum 이 출력되고 이후 뭔가 좌르륵~ 나오고 있다면 일단 동작하는 것이다. 

Ubuntu에서 실행중인 모습
korean44@ubuntu-svr:~/project/blockchain/webthree-umbrella/build/webthree/eth$ ./ethGoodJoon.sh 
(++)Ethereum
...  00:36:07.628|eth  Reading /home/korean44/.web3/keys/152d7983-ac83-b2f9-159c-18ab7106fd83.json
⧎ ℹ  00:36:07.649|eth  Id: ##e808dba2…...  00:36:07.684|eth  Opened blockchain DB. Latest: #5df28093… (rebuild not needed)...  00:36:07.700|eth  Opened state DB.
⧫ ◎  00:36:07.702|eth  startedWorking()
cpp-ethereum 1.2.1
  By cpp-ethereum contributors, (c) 2013-2016.
  See the README for contributors and credits.
Transaction Signer: XE50000000000000000000000000000000 (00000000-0000-0000-0000-000000000000 - 00000000)
Mining Beneficiary: XE8916H0DGVW3SIMF6X9AWCB8J6ZV5PWE6 (152d7983-ac83-b2f9-159c-18ab7106fd83 - 0047d27a)
Foundation: XE55PXQKKK4B9BYPBGT1XCYW6R5ELFAT6EM (00000000-0000-0000-0000-000000000000 - de0b2956)
  ℹ  00:36:13.611|p2p  UPnP device: http://192.168.0.1:3274/etc/linuxigd/gatedesc.xml [st: urn:schemas-upnp-org:device:InternetGatewayDevice:1 ]
⧎ ℹ  00:36:13.684|p2p  Punched through NAT and mapped local port 30301 onto external port 15725 .
⧎ ℹ  00:36:13.684|p2p  External addr: 211.222.99.134
⧎ ℹ  00:36:13.686|p2p  p2p.started id: ##e808dba2…
 ⚡   00:36:13.695|eth  void dev::p2p::Host::start() 2091 ms
Node ID: enode://e808dba2f0d7eb464656e01be81317386af18b8a0c554c7f9fd78fcd0f1a008a584891aed201018444af50ede46faf6884750baa1f06eca9e9c706d827b931a3@211.222.99.134:15725
JSONRPC Admin Session Key: 0000
⧫ ℹ  00:36:13.738|eth  Mining Beneficiary: @0047d27a
⧫ ◎  00:36:13.739|eth  Rejigging seal engine......  00:36:13.741|eth  Generating seal on #ab31b73b… # 1
  ℹ  00:36:13.743|miner0  Loading full DAG of seedhash: #00000000…
DAG  00:36:19.606|miner0  Generating DAG file. Progress: 0 %
⧫ ◎  00:36:22.718|eth  Since 2016-03-04 15:36:07.686Z (15): 15ticks
DAG  00:36:25.842|miner0  Generating DAG file. Progress: 1 %
DAG  00:36:32.097|miner0  Generating DAG file. Progress: 2 %



아마 Windows 에서는 아예 Console 에서 JavaScript Console 기능이 동작하지 않을 것이다. 버그이다. 이건 Frontier Release 이전부터 계속되어오는 문제이다.
수정하고싶은 생각도 없는듯 하고 암튼 Windows 는 C++ Ethereum의 대상이 아닌게 날이갈수록 확신이 든다.

Miner는 DAG 파일을 만드는데에 상당한 시간이 소요된다. 처음 1회만 실행되므로 참고 기다린다.


▌Console Attach

그래도 JavaScript Console 을 띄워서 보는게 가장 빠른 방법이므로 한번 해보도록 한다.

Linux 에서는 
$ eth --session-key 0000 attach
만으로도 현재 실행중인 eth 에 attach 를 한다. Linux 에서는 console 이 잘 동작하므로 처음 실행할 때 마지막에 console 이라고 치면 되긴 하지만, 로그가 수없이 지나가므로 JavaScript API 를 실행시켜도 결과가 로그에 파묻힌다. 그래서 난 그냥 터미널 하나 더 띄워서 attach 시킨다.

Windows 는 1.2.1 버전 오더니 더 심각한 버그들이 발생한다.
$ eth --session-key 0000 attach --url "http://localhost:8545"
이렇게 url 까지 적어줘야 한다. default 가 먹히질 않는다.

암튼 Console 이 attach 되고나면 ">" 가 보인다. JavaScript Console 이다.

1.2.0 까지만 해도 안그랬던것 같은데, JavaScript API 를 Geth 와 I/F 를 맞추고있는 과정이라서 그런지 web3 만 치면 전체 object 들이 나와야 하지만 에러가 난다. 이건 Linux 나 Windows 나 모두 마찬가지이다.

그래서, web3.eth 객체를 살펴보면, 아래처럼 출력이 될 것이다.
> web3.eth
{
  _requestManager: {
    provider: {
      send: [Function],
      sendAsync: [Function]
    },
    polls: {
    },
    timeout: null,
    send: [Function],
    sendAsync: [Function],
    sendBatch: [Function],
    setProvider: [Function],
    startPolling: [Function],
    stopPolling: [Function],
    reset: [Function],
    poll: [Function]
  },
  getBalance: [Function],
  getStorageAt: [Function],
  getCode: [Function],
  getBlock: [Function],
  getUncle: [Function],
  getCompilers: [Function],
  getBlockTransactionCount: [Function],
  getBlockUncleCount: [Function],
  getTransaction: [Function],
  getTransactionFromBlock: [Function],
  getTransactionReceipt: [Function],
  getTransactionCount: [Function],
  call: [Function],
  estimateGas: [Function],
  sendRawTransaction: [Function],
  sendTransaction: [Function],
  sign: [Function],
  compile: {
    solidity: [Function],
    lll: [Function],
    serpent: [Function]
  },
  submitWork: [Function],
  getWork: [Function],
  coinbase: '0x0047d27a61e384403d875239cbc462896044213e',
  getCoinbase: [Function],
  mining: false,
  getMining: [Function],
  hashrate: 0,
  getHashrate: [Function],
  syncing: false,
  getSyncing: [Function],
  gasPrice: 50000000000',
  getGasPrice: [Function],
  accounts: ['
0x0047d27a61e384403d875239cbc462896044213e'],
  getAccounts: [Function],
  blockNumber: 0,
  getBlockNumber: [Function],
  iban: [Function],
  sendIBANTransaction: [Function],
  defaultBlock: '
latest',
  defaultAccount: undefined,
  contract: [Function],
  filter: [Function],
  namereg: [Function],
  icapNamereg: [Function],
  isSyncing: [Function]
}

▌Block Sync 확인
현재 Difficulty 도 낮춰놓고, 블록 생성 간격도 13분에서 1분으로 맞추도록 조정하였다. 


▌Windows 버전 => Linux / Mac OS X 으로 갈아타자
여태 Windows 버전을 Build 하고 소스 수정하고 해왔다. 그런데 Homestead 겨냥중인 1.2.1 버전 릴리즈 되면서 더이상 Windows 를 안쓰고싶게 만든다.
Frontier (1.0.1) 까지는 그나마 참고 쓸 수 있었으나 1.1.3 버전 부터였나 점점 되야하는 기능들이 Windows 에서 안돌더니 이제 Geth 와 I/F 맞춘다는 명목등을 이유로 작업을 하고있으면서 Windows 는 안그래도 뒷전인데 더 뒷전이 되어버렸다.

Windows 에서 못써먹겠다는 이유는 대략 이러하다.
1.0.1 => Contract 를 Create 하고 배포한 후 JSONRPC 건 JavaScript 건 call 을 2회 하면 그 다음부터는 무조건 0을 리턴한다. 재기동만이 정상화 방법이다. 그래서 Windows 에서는 Mining 시키고 Mac 이나 Linux 에 Contract call 을 해왔다.

1.1.3 => Windows 버전이 다른 Peer 와 Connect 할때 RLPx Handshake 시에 괜히 auth fail 이 난다. 그리고 이 시점 부터 다른 Platform 의 Miner 가 멈추고 아예 동작을 안한다. Windows 를 먼저 띄워놓고 다른 Platform 의 Peer 가 connect 을 하면 괜챦다. 

1.2.0/1.2.1 => Windows 가 붙으면 auth fail 은 또 계속 난다. Miner 죽는 문제는 해결한듯 하다. 그런데 Geth 와 CLI 나 JS Console 이 아직 맞춰지지도 않았고 API 가 동작하지 않는것들도 있다. 

그리고, DAG 도 버그가 있다. 어떤때는 hashrate 가 3,4 H/s 가 나온다. 계속 재실행 하다보면 언젠다 다시 정상 hashrate 가 나온다. 문제다.

위 이유로, 이후 진행은 Linux 로만 한다. Mac OS X 도 잘 지원되는 편이나 블로그 쓰는데 맥북까지 켜서 2대에서 끄적거리기가 싫다 ^^;; 그냥 VirtualBox 로 Linux 2대 켜놓고, shared folder 하나 만들어서 소스는 한군데에서 수정하고 빌드한 후 양쪽 VBox Guest (Ubuntu 15.10) 에서 실행시켜 테스트 하는 방향으로 가겠다. 뭐 필요하면 3대 4대 하거나 Instance 를 더 늘리던가 하겠다.





반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
Ubuntu 를 15.10 으로 업그레이드한 후 Shared Folder 를 설정했는데 먹히질 않는다.
이전 VirtualBox 의 Guest Addition 이 오류가 생긴듯 하다. 그래서 다시 Guest Addition 을 설치해보도록 한다.

1. VirtualBox 에서 GuestAddition CD 를 삽입한 후
$ sudo mount /dev/cdrom /media/cdrom

2. Guest Addition 을 빌드하기 위한 필요 패키지들을 받는다.
※ 설치 전에 apt-get update 는 필수이다
$ sudo apt-get install -y dkms build-essential linux-headers-generic linux-headers-$(uname -r)

3. VBoxLinuxAdditions.run 을 실행한다
$ sudo /media/cdrom/VBoxLinuxAdditions.run

4. Reboot 한다

5. 공유폴더를 Mount 해본다 
$ sudo mount -t vboxsf <공유이름> <마운트할폴더>

잘 되면 그냥 쓰면된다. 그런데 No Such Device 라고 나올 수 있다. 이럴때는

6. vboxadd 설정을 다시 해본다
$ cd /opt/VBoxGuestAdditions-*/init 
$ sudo ./vboxadd setup

7. 다시한번 리부팅 하고 마운트 해보면 잘 될것이다



반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,
Account 까지 만들었으므로 이제 Account 의 address 에 이더가 충만한 나만의 genesis 를 만들어서 간단한 Transfer Transaction 을 실행해보겠다.

참고로, 그간 golang 강좌 초반부를 쓰느라 신경을 좀 못쓴 동안에 1.2.0 버전이 바로 어제 릴리즈 되었다 (2016.02.29 에).
git pull 하고 submodule 을 update 한 후 1.2.0 버전으로 소스를 업데이트 하고서 다시 빌드를 하였으며, 이후 설명은 eth 1.2.0 기준으로 해 가도록 하겠다.

1.1.4 버전으로 Private Network 을 구성하고 나서 좀 당황스러운 점들이 있었다. 일단, Node 간에 RLPx handshake 가 auth 를 검증하는 동안 실패하는 상황이 발생하며 Handshake가 실패하면 아예 Miner 가 Mining 을 멈추는 상황으로 가는 버그이다. 이게 수정되었는지 궁굼한데 Release Note 를 보니 Mining 쪽 버그 픽스가 되었다고 하는데 1.2.0 에서 확인해봐야 하겠다.

그리고, Geth 의 Attach 가 eth 에 가능하게 되었다. geth 에는 --session-key 옵션이 없는데 이게 어떻게 동작할라나 모르겠다. 암튼 된다고 하니 이 두녀석들을 갖고 또 테스트 해봐야 하겠다. eth 1.2.0 과 geth 1.3.4 가 거의 동시에 릴리즈 되었으니, geth 설명할 때에도 최신버전 (아예 1.3.4의 코드네임이 Homestead 이다)으로 해야 하겠다.

[goodjoon Debug]$  ./eth --version
eth version 1.2.0
eth network protocol version: 63
Client database version: 12041
Build: Windows/msvc/int/Debug
[goodjoon Debug]$

일단은 Private Network 상에서 PoW 로 Consensus 를 하는, Public 형태와 동일한 Ethereum Local Network 을 구성 해보도록 한다.

▌config.json (genesis.json) 만들기

genesis.json 이 Frontier Release 버전인 eth 1.0.0 과 달라졌다. Geth 와도 호환이 안되는 JSON 포맷으로 바뀌었다 (config.json). 그나마 좀 Simple 한 포맷이었는데, 좀더 복잡하게 바뀌었다.
create-genesis.py 스크립트로 만들어져 나오는 json 은 동작하지 않으므로, 수동으로 작업해보도록 하겠다.

1.2.0 부터는 genesis.json 으로 부르지 않고, config.json 으로 부른다. 옵션도 --config 로 바뀌었다. --genesis 옵션도 코드 내에서는 아직 살아있지만 --help 로 볼때는 나오지 않는다.

우선 내 Account 중에 억만장자를 만들고 싶은 Account 의 Address 를 결정해야 한다.
eth 가 잘 빌드되었다면

$WEBTHREE/build/libethereum/ethkey/Debug
밑에 ethkey.exe 파일이 있다

[goodjoon Debug]$  ethkey.exe list --master 1111
1a7e55b0-3eb7-05ec-248e-8d901e268d76 0096bb98… XE602H4XB00HUY08LU416SCBGO3CS63H66  Default key
6ecc980b-2f99-013d-167e-0ea9caffde4e 007386ab… XE561WBEXUY46M6G05SDKF5P9C334V3JT6  myname
31ae0923-14da-a1a9-85ba-ab9563c5da4b 005bfaf9… XE241IE5KGWVRVYD6B5H8ZHMXNMP57Q4KM  joooooon
[goodjoon Debug]$
위 처럼 Wallet 의 Key 들이 보인다면 이중에서 사용할 Key 를 선택한다. 난 "Default key" 로 자동생성되었던 Account 를 선택한다.

Genesis 에는 Account 의 Balance 를 지정해주려면 Address 가 필요한데, 위 ethkey list 명령으로 출력된 결과에는 address 가 FULL 로 표시되지 않는다. ethkey 를 다시 사용하여 Full Address 를 표시해본다.
[goodjoon Debug]$  ethkey.exe inspect "Default key" --master 1111
Default key (0096bb98…)
  ICAP: XE602H4XB00HUY08LU416SCBGO3CS63H66
  Raw hex: 0096bb9802b14f72ba4cdbd105127fe57a1dafae
[goodjoon Debug]$

옵션에 계속 --master 1111 을 넣는 이유는, 현재 MinGW/MSYS 를 사용하고있는데 eth 가 이 환경에서는 key store 의 master 패스워드 입력하라는 Prompt 가 나올 때 Exception 이 발생하므로 master 패스워드를 바로 지정해주어야 한다. (Windows Command Prompt 환경에서는 문제가 없다)

위 Raw hex : 부분이 사용할 Account 의 address 이다.

이렇게 Linux 나 Mac 버전 또는 다른 Windows 에서도 Wallet 을 만들고 (keys.info, keys.salt), Key 를 생성한다 (Wallet (keys.info) 에 key 추가, .web3/keys 디렉토리에 추가된 key 의 정보(json) 추가).
Account 의 Address 를 모두 파악했다면, 이제 Genesis 정보를 만들어준다

{
    "sealEngine""Ethash",
    "params": {
        "accountStartNonce""0x00",
        "maximumExtraDataSize""0xFF",
        "tieBreakingGas"false,
        "minGasLimit""0x1388",
        "gasLimitBoundDivisor""0x0400",
        "minimumDifficulty""0x020000",
        "difficultyBoundDivisor""0x0800",
        "durationLimit""0x0d",
        "blockReward""0x4563918244F40000",
        "registrar" : "",
        "networkID" : "0xA1"
    },
    "genesis": {
        "nonce""0x0000000000000000",
        "difficulty""0x020000",
        "mixHash""0x0000000000000000000000000000000000000000000000000000000000000000",
        "author""0x0000000000000000000000000000000000000000",
        "timestamp""0x00",
        "parentHash""0x0000000000000000000000000000000000000000000000000000000000000000",
        "extraData""0x",
        "gasLimit""0x1388"
    },
    "accounts": {
        "0096bb9802b14f72ba4cdbd105127fe57a1dafae": { "wei""10000000000000000000000000000000000"},
        "0047d27a61e384403d875239cbc462896044213e": { "wei""20000000000000000000000000000000000"}
    }
}

위 처럼 genesis 정보를 만들어 준다. 가장 아래의 "accounts" 내의 정보가 주소와 Balance 이다.

아래는 "파악된" json 파라미터 정보들이다. Ethereum 의 가장 큰 문제가 바로 "체계 없는 문서화" 라고 생각한다. 어떤것은 Github Wiki 에 있고 어떤건 Gitbook 에, 또 어떤건 readthedocs 에.. 또 어떤건 각 Repository 의 wiki 에.. 또 어떤건 Repository 내의 프로젝트에 있는 .md 파일에.. 뭐 난리다.. 그래서 더 접근하기가 쉽지 않다.

위 config.json 의 경우도 제대로 된 문서 하나를 찾지 못했다. 개념적인 부분과 소스코드를 분석했던 기억을 더듬어 다시 써보니 혹시 틀린 부분이 있다면 그저 그러려니 하자.

[SealEngine]
Block 생성을 위한 Consensus 메커니즘을 어떤걸 사용할것인지를 지정한다.
현재 SealEngineBase Class 를 상속받는 Class 들에는 Ethash, BasicAuthority, NoProof 가 있다. 

Ethash 는 DAG 나 General Hashing 을 통해 PoW 를 하는 엔진이고, BasicAuthority 는 PoA 를 위해 실험적으로 Ethereum 에서 만들어놓은 Consensus 메커니즘으로, 현재 flu core 를 통해 사용할 수도 있으며, web3 에 통합되어있다. NoProof 는 Consensus 를 위한 증명작업을 하지 않는 Sealer 이다.

[Params]
"AccountStartNonce" : Account 의 최초 시작 Nonce 값을 지정한다. 기본적으로는 당연히 0 부터 시작하면 된다.
"maximumExtraDataSize" : 블럭의 Extra Data 의 최대 크기를 지정한다. 
"tieBreakingGas" : 
"minGasLimit" : 블럭의 최소 Gas 제한량이다. Block 의 GasLimit 값은 이 minGasLimit 보다 커야한다.
"gasLimitBoundDivisor" : 현재 블럭의 GasLimit 값은 parent block 의 gaslimit 대비 +- (parent block 의 GasLimit / gasLimitBoundDivisor)이내에 있어야 한다.
"minimumDifficulty" : 블럭의 최소 Difficulty 이다. 아무리 시간이 오래걸려도 PoW 는 이 Difficulty 이상을 유지해야 한다.
"difficultyBoundDivisor" : Frontier 까지 유효하며, 이전 Block 생성시간 대비 현재 Block 생성 시간이 durationLimit 보다 작으면 parent 의 difficulty 에 parent 의 difficulty / difficultyBoundDivisor 값을 더하고, 크면 같은값을 빼서 블럭 생성 시간을 조정한다
"blockReward" : Miner 의 Codebase 에 챙겨줄 reward wei 이다
"registrar" : Olympic 부터 Frontier, Homestead 등에서 기본적으로 존재하는 registrar Smart Contract 의 Address 이다. Name Register 서비스를 해주는 Contract 로 보면 된다.
"networkID" : 피어간의 통신 시 논리적으로 네트웍을 구분짓는 ID 이다. 피어간에 통신을 위해서는 이 networkID 값이 같아야 한다. Olympic 은 0, Frontier 는 1, Morden Testnet 은 2를 쓴다.

[Genesis]
"nonce" : 블럭의 nonce 값
"difficulty" : Block 의 Difficulty
"mixhash" : Block 의 hash 값
"author" : Block Author 정보, 필요하면 넣고..
"timestamp" : 블럭 생성 시각
"parentHash" : Genesis 이므로 0
"extraData" : 넣고싶은 Extra Data
"gasLimit" : Block 의 Gas Limit

[Accounts]
"<Account Address>": {"wei":<Balance>} 와 같은 형식은 UCA/UOA Account 의 Balance 를 적는 형식이고,
"0000000000000000000000000000000000000001": { "wei": "1", "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } } 와 같은 형식은 Precompiled Contract 를 표시하는 형식이다. Precompiled Contract 사용에 대해서는 향후에 알아보자.


이렇게 하면 일단 Private Network 에서 동작하는 Ethereum 을 위한 기본적인 Genesis 정보를 정의할 수 있다. 원래는 Genesis 만 지정하였는데, C++ Ethereum 은 좀더 유연성을 부여하기 위해 
  1. sealEngine
  2. options
  3. params
  4. genesis
  5. accounts
  6. network
로 구성된 config 정보를 입력할 수 있도록 하였다. 일단 목적은 private blockchain 을 염두에 둔것 같다.

다음은 이 Genesis 정보 기반으로 두 노드간에 실제적으로 통신을 해보자 (졸려졸려..)

반응형
블로그 이미지

Good Joon

IT Professionalist Since 1999

,