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

,