# 1. Geth로 프라이빗 네트워크 구축하기
- 먼저, Geth 의 Linux binary 버전을 설치했고, Geth 명령어들을 통해서 이더리움 노드를 수행시킬 수 있었다.
초기화 하기
---
```csh
geth init genesis.json
```
- genesis.json 파일은 노드를 시작할 때 사용하는 초기 설정값이다. 예를 들면 아래와 같이 설정할 수 있다.
```json
{
"config": {
"chainId": 0,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x20000",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00",
"alloc" : {},
}
```
- `geth init`을 사용할 때 한 가지 아쉬웠던 것은, 메시지가 출력되어서 stdout 과 stderr 로 구분하여 에러 핸들링을 하려고 했지만, '*Successfully wrote*' 이나 '*Maximum peer count*' 메시지가 포함된 stdout과 같은 에러들이 stderr로 튀어나와서 예외처리를 해줘야 했다.
[자세히](https://gist.github.com/0mkara/b953cc2585b18ee098cd)
계정 생성하기
---
```csh
geth account new --datadir {데이터베이스와 keystore가 저장될 위치}
```
- 노드를 처음 활성화하는 경우가 있거나 노드를 잠시 껐다가 다시 활성화시키는 경우가 있다. 이 점을 고려하여, 노드를 완전히 새로 활성화하는 경우와 기존에 활성화했던 경우로 구분했다.
- **신규 노드 활성화**: 완전히 처음 생성한 노드의 경우 계정이 없다. 그렇기 때문에 `geth account new` 명령어로 새로운 계정을 생성해줘야 한다. 이 경우에는 초기 비밀번호 설정을 해줘야 하고, 비밀번호는 절대! 까먹으면 안된다.*
- **기존 노드 활성화**: 노드를 기존에 켠 적 있는 경우: 이 경우에는 특정 디렉토리 위치 (datadir 로 설정된 위치. 다음 <노드 설정하기>에서 자세히 다룸.) 에 계정 정보가 남아있다. 그렇기 때문에 계정 정보를 가져와서 사용할 수 있다.
> \**이 비밀번호가 mnemonic 이랑 같은 역할을 하는지는 좀 더 알아봐야 할 듯 하다*
노드 설정하기
---
- **부트스트랩 노드**는 제네시스 노드와 같은 것이다. 이더리움 메인넷에서도 이 부트스트랩 노드는 하드코딩 되어 있다고 한다.
- **일반 노드**는 부트스트랩이 아닌 노드를 일반 노드라고 부른다. 일반 노드는 검증 노드로만 머물러 있을 수 있고, 또는 채굴 노드 기능까지 포함시킬 수 있다.
- 먼저, 부트스트랩 노드를 수행시켜서 enode라는 주소를 얻고, 일반 노드를 활성화시키는 순서로 수행하였다.
##### 부트스트랩 노드
```csh
geth
--ws
--ws.api web3,eth,debug,personal,net,miner
--ws.addr 0.0.0.0
--ws.port {외부로 공개된 포트}
--ws.origins='*'
--datadir {datadir 위치}
--nat extip:{외부로 공개된 IP}
--networkid {네트워크 id}
--http.vhosts '*'
--http.corsdomain '*'
--allow-insecure-unlock
--mine
```
##### 일반 노드
```csh
geth
--ws
--ws.api web3,eth,debug,personal,net,miner
--ws.addr 0.0.0.0
--ws.port {외부로 공개된 포트}
--ws.origins='*'
--datadir {datadir 위치}
--nat extip:{외부로 공개된 IP}
--networkid {네트워크 id}
--http.corsdomain '*'
--bootnodes {}
--allow-insecure-unlock
--mine
```
*주의) 다양한 옵션들을 테스트하다보니 꼭 필요하지 않아도 되거나 빠져있는 옵션이 있을 수 있음*
- ws: `Enable the WS-RPC server`. web socket을 사용한다는 의미다. web socket 연결 외에 http 연결도 있는데 http 보다 web socket이 실시간 처리가 더 좋다.[web socket vs http 차이](https://mangkyu.tistory.com/48)
- ws.api: `API's offered over the WS-RPC interface`. ???
- ws.addr: `WS-RPC server listening interface (default: "localhost")`. 외부 네트워크와 인터페이스하기 위해서 공개된 IP 주소를 의미한다.
- ws.port: `WS-RPC server listening port (default: 8546)`. 외부 네트워크와 인터페이스하기 위해서 공개된 Port 주소를 의미한다.
- ws.origins: `Origins from which to accept websockets requests`. '*'로 설정했다는 것은 외부의 모든 IP와의 연결을 허용하겠다는 의미다. 방화벽으로 따지면, 방화벽 설정이 없는 것이다.
- datadir: `Data directory for the databases and keystore (default: "~/.ethereum")`. 데이터가 저장되는 공간으로 블록체인 데이터를 포함한 노드를 구동하기 위해 사용되는 다양한 데이터가 저장된다. 대표적으로 pending Transaction 이 들어있는 transaction.rlp 파일도 이 아래에 있고, 보안을 위한 keystore 파일도 이 아래 저장된다.
- nat: `NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>) (default: "any")`. ???
- networkid: `Explicitly set network id (integer)(For testnets: use --ropsten, --rinkeby, --goerli instead) (default: 1)`. 이더리움 메인넷과 테스트넷의 차이는 네트워크 id에 있다. 프라이빗 네트워크를 구축하면 어떤 network id를 사용해야할지 결정해야하고, 퍼블릭 네트워크를 사용하면, 기존에 정의되어 있는 값을 사용하면 된다.
- http.corsdomain: `Comma separated list of domains from which to accept cross origin requests (browser enforced)`. 이건 맨 처음에 http 옵션으로 설정했을 때, 사용했던 옵션인데, web socket으로 변경한 다음에 사용하진 않을 것 같다.
- allow-insecure-unlock: `Allow insecure account unlocking when account-related RPCs are exposed by http
`. 사용자의 지갑을 unlock 하고 송금할 때, 이 옵션이 정의되지 않으면 에러가 뜬다. 이걸 꼭 사용하지 않는 방법이 있을까 하는데, 일단 내가 네트워크를 구축할 때는 이 옵션을 사용하지 않으면 에러가 발생했다.
- mine: `Enable mining`. 채굴을 시작할 것임을 의미한다. 초기에 이 옵션을 주면 자동으로 채굴을 할 줄 알았는데, 다시 채굴을 enable 해야지 '*Generate DAG*'이라는 메시지를 띄우면서 별도의 채굴을 수행한다.
- bootnodes: `Comma separated enode URLs for P2P discovery bootstrap`. 부트스트랩 노드를 생성하면 '*enode:xxx*' 라며 enode 값이 나온다. 일반 노드의 경우 이 enode 값을 입력해야지 같은 네트워크 안에 포함되게 된다.
[더 많은 옵션에 대해서...](https://geth.ethereum.org/docs/interface/command-line-options)
채굴 시작하기
---
```python
# web3.py 기능 사용.
# client가 뭔지 자세한 내용은 web3.py 정리한 내용에서 다룸.
# 나 같은 경우에는 --mine 옵션을 geth 수행할 때 줬지만, 잘 먹히지 않는 것도 있고, mine 에 대한 여부를 결정할 수 있도록 따로 뺀 것도 있다.
DEFAULT_MINER_CNT = 3
client.geth.miner.start(DEFAULT_MINER_CNT)
```
- 위 명령어를 web3.py 에서 사용하면 '*Geneate DAG*'과 같은 메시지가 출력된다.
## 그 다음은?
- [2. ERC20 토큰 개발 및 배포하기 (web3.py)](/Gg6oOnYxSyWE3vKQgcrx9Q)