로컬 테스트넷에서 Geth 실행하는 방법
Geth를 로컬 테스트넷에서 실행하기 위해서는 먼저 데이터 디렉토리 + genesis.json 파일이 준비되어야 합니다. 데이터 디렉토리에서는 송수신한 블록 데이터 및 계정 정보를 저장하게 됩니다. genesis.json 파일은 블록체인의 Genesis 블록 정보가 저장됩니다.
git에서 Clone한 go-ethereum 프로젝트 내에 test_data 디렉토리를 생성하고, genesis.json 파일을 생성합니다.
정상적으로 이더리움 블록체인에 접속 가능한지 확인합니다.
$ geth
이더리움 테스트넷에서 사용할 계정 생성
다음 명령을 입력한 후 2번의 password를 입력하면 정상적으로 account가 생성됩니다. Public Key가 생성되는데, 이 키는 genesis.json 파일에서 사용하게 되므로 복사해둬야 합니다.
$ geth --datadir test_data account new
Password:
Repeat password:
Your new key was generated
Public address of the key: [계정 공개키]
Path of the secret key file: test_data/keystore/UTC--2022-07-05T09-31-52.070080860Z--4d3ef63064ccc938a80791a0d80df671aceae315
- You can share your public address with anyone. Others need it to interact with you.
- You must NEVER share the secret key with anyone! The key controls access to your funds!
- You must BACKUP your key file! Without the key, it's impossible to access account funds!
- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!
계정을 생성한 후 생성된 계정 목록을 다음 명령으로 확인할 수 있습니다.
$ geth --datadir test_data account list
INFO [07-05|18:33:42.793] Maximum peer count ETH=50 LES=0 total=50
INFO [07-05|18:33:42.793] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [07-05|18:33:42.794] Set global gas cap cap=50,000,000
Account #0: {4d3ef63064ccc938a80791a0d80df671aceae315} keystore:///root/go-ethereum/test_data/test_data/keystore/UTC--2022-07-05T09-31-52.070080860Z--4d3ef63064ccc938a80791a0d80df671aceae315
Genesis Block 생성하는 방법
블록체인을 시작하기 위해서는 genesis Block을 생성해야 합니다. 앞에서 생성했던 genesis.json 파일에 아래 내용을 입력합니다. 계정을 생성할 때 반환된 공개주소를 계정 주소값으로 입력합니다.
$ vim genesis.json
{
"config":{
"chainId" : 8484,
"homesteadBlock" : 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0
},
"difficulty" : "20",
"gasLimit" : "2100000",
"alloc" : {
"계정 주소값": {"balance" : "300000"}
}
}
- config : 이더리움 관련 설정을 포함합니다.
- config.chainId : 현재 chain을 구별하는 값입니다. 유효한 데이터 전송을 악의적으로 반복시켜 공격하는 replay attack을 방지합니다.
- config.homesteadBlock : 이더리움은 <프론티어><홈스테드><메트로폴리스><세레니티> 4단계 로드맵을 가지고 있습니다. 속성값 0은 true를 의미합니다.
- config.eip155Block : EIP(Ethereum Improvement Proposal)은 개발자들이 이더리움을 발전시키기 위해 아이디어를 제안하는 것을 의미합니다. EIP155는 replay attack을 방지하기 위한 아이디어입니다.
- config.eip150Block : EIP150은 IO가 많이 발생하는 작업에 대한 가스 변경 비용을 위한 설정.
- config.eip158Block : EIP158은 계정의 상태가 변경되고, 변경된 결과값에 의해 계정의 논스와 밸런스가 0이 되고 code / storage가 빈값이 되는 경우 계정을 삭제하자는 아이디어 입니다.
- difficulty : 채굴 난이도를 의미합니다. 높은 값일 수록 난이도가 올라갑니다. 테스트넷에서는 높은 난이도가 불필요하므로 낮은 값을 할당합니다.
- gasLimit : 블록마다 담을 수 있는 가스 한도를 설정합니다. 즉, 하나의 블록에 담을 수 있는 트랜잭션의 량을 설정합니다. 값이 클 수록 많은 트랜잭션을 블록에 담을 수 있습니다.
- alloc : genesis block이 생성되면서 동시에 할당된 주소로 밸런스가 할당됩니다. alloc에서 사용하는 값의 단위는 wei 입니다.
- parentHash : 부모 블록의 해시값 / genesis block은 부모 블록이 존재하지 않습니다.
- coinbase : genesis block 채굴시 주어지는 보상.
- nounce, mixhash : 블록이 정당하게 채굴되었는지 증명. mixhash는 nounce 값을 찾기 위한 중간 계산값으로 공격자가 부당한 nounce값으로 블록을 생성하는 경우를 적발합니다. 단 genesis block은 채굴을 통해 생성하지 않고 json 파일로 생성하기 때문에 mixhash 및 nounce 값이 필요하지 않습니다.
- timestamp : 블록이 생성된 시점을 나타냅니다. 블록간 생성 간격이 짧다면 난이도가 쉽다는 뜻이므로 난이도가 조절됩니다.
Genesis Block 생성 및 초기화
아래 명령어로 위에서 작성한 genesis.json 파일을 실행해 제네시스 블록을 생성하고 초기화 합니다.
$ geth --datadir test_data init test_data/genesis.json
root@8a8da77d4483:~/go-ethereum/test_data# geth --datadir test_data init ./genesis.json
INFO [07-05|21:56:15.789] Maximum peer count ETH=50 LES=0 total=50
INFO [07-05|21:56:15.791] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [07-05|21:56:15.797] Set global gas cap cap=50,000,000
INFO [07-05|21:56:15.800] Allocated cache and file handles database=/root/go-ethereum/test_data/test_data/geth/chaindata cache=16.00MiB handles=16
INFO [07-05|21:56:15.831] Opened ancient database database=/root/go-ethereum/test_data/test_data/geth/chaindata/ancient readonly=false
INFO [07-05|21:56:15.831] Writing custom genesis block
INFO [07-05|21:56:15.833] Persisted trie from memory database nodes=1 size=142.00B time="834.046µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [07-05|21:56:15.834] Successfully wrote genesis state database=chaindata hash=9a4612..be0494
INFO [07-05|21:56:15.834] Allocated cache and file handles database=/root/go-ethereum/test_data/test_data/geth/lightchaindata cache=16.00MiB handles=16
INFO [07-05|21:56:15.864] Opened ancient database database=/root/go-ethereum/test_data/test_data/geth/lightchaindata/ancient readonly=false
INFO [07-05|21:56:15.864] Writing custom genesis block
INFO [07-05|21:56:15.868] Persisted trie from memory database nodes=1 size=142.00B time="524.732µs" gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [07-05|21:56:15.870] Successfully wrote genesis state database=lightchaindata hash=9a4612..be0494
현재 생성된 test_data 디렉토리의 구조는 다음과 같습니다.
root@8a8da77d4483:~/go-ethereum/test_data# tree ./
./
|-- genesis.json
`-- test_data
|-- geth
| |-- LOCK
| |-- chaindata
| | |-- 000001.log
| | |-- CURRENT
| | |-- LOCK
| | |-- LOG
| | |-- MANIFEST-000000
| | `-- ancient
| | |-- FLOCK
| | |-- bodies.0000.cdat
| | |-- bodies.cidx
| | |-- bodies.meta
| | |-- diffs.0000.rdat
| | |-- diffs.meta
| | |-- diffs.ridx
| | |-- hashes.0000.rdat
| | |-- hashes.meta
| | |-- hashes.ridx
| | |-- headers.0000.cdat
| | |-- headers.cidx
| | |-- headers.meta
| | |-- receipts.0000.cdat
| | |-- receipts.cidx
| | `-- receipts.meta
| |-- lightchaindata
| | |-- 000001.log
| | |-- CURRENT
| | |-- LOCK
| | |-- LOG
| | |-- MANIFEST-000000
| | `-- ancient
| | |-- FLOCK
| | |-- bodies.0000.cdat
| | |-- bodies.cidx
| | |-- bodies.meta
| | |-- diffs.0000.rdat
| | |-- diffs.meta
| | |-- diffs.ridx
| | |-- hashes.0000.rdat
| | |-- hashes.meta
| | |-- hashes.ridx
| | |-- headers.0000.cdat
| | |-- headers.cidx
| | |-- headers.meta
| | |-- receipts.0000.cdat
| | |-- receipts.cidx
| | `-- receipts.meta
| `-- nodekey
`-- keystore
`-- UTC--2022-07-05T09-31-52.070080860Z--4d3ef63064ccc938a80791a0d80df671aceae315
7 directories, 46 files
Geth 실행하기
genesis block을 생성했다면 geth를 실행합니다.
$ geth --networkid 8484 --nodiscover --datadir test_data -allow-insecure-unlock --http.addr 0.0.0.0 --http --http.port 8545 --http.corsdomain "*" --http.api="db,eth,net,web3,personal,web3,miner,admin" --miner.threads 1 console 2>> test_data/geth.log
- --datadir test_data : 데이터 디렉토리 지정
- networkid 8484 : 네트워크 식별자
- http :과거 rpc에서 http로 변경됨
- http.addr "ip" : 현재 사용중인 IP를 입력합니다.
- http.port "port" : 사용하고자 하는 port 번호를 입력합니다.
- http.corsdomain "*" : 접속 가능한 RPC 클라이언트 URL을 지정합니다. "*"(와일드카드)는 전체 허용을 의미합니다.
- -nodiscover : 생성자 노드를 다른 노드에서 검색 못하게 막는 옵션입니다. 제네시스 블록과 네트워크 ID의 블록들이 연결되는 것을 방지합니다.
- http.api "db,eth,net,web3,personal" : RPC에 접근 가능한 API 들을 지정합니다. geth 내에서 사용가능한 명령어들입니다.
- -maxpeers 0 : 생성자 노드에 연결 가능한 노드의 수를 지정합니다. 0이면 다른 노드들과 연결하지 않습니다.
- console : 대화형 자바스크립트 콘솔
- 2>> /home/ngle/data_testnet/geth.log : 에러를 해당 경로의 파일에 저장합니다. 로그 옵션입니다.
정상적으로 실행되었다면 Geth Javascript console 화면을 확인할 수 있습니다.
Welcome to the Geth JavaScript console!
instance: Geth/v1.10.20-stable-8f2416a8/linux-amd64/go1.18.1
coinbase: 0x4d3ef63064ccc938a80791a0d80df671aceae315
at block: 0 (Thu Jan 01 1970 09:00:00 GMT+0900 (KST))
datadir: /root/go-ethereum/test_data/test_data
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
To exit, press ctrl-d or type exit
>
Etherbase 설정하는 방법
이더리움에는 2가지 계정이 존재합니다. EOA(Externally Owned Account)는 일반 사용자가 사용하는 계정입니다. 비밀키로 관리되며 이더를 송금하거나 컨트랙트를 실행할 수 있습니다. Contract 계정은 컨트랙트를 블록체인에 배포할 때 생성됩니다.
새로운 EOA 계정 추가하는 방법
geth console에서 EOA를 생성하는 명령입니다.
> personal.newAccount('password')
"0x1a9d8ca79769da4e7fd27e94f688e6438761f14a"
기존 계정 확인
> eth.accounts
["0x4d3ef63064ccc938a80791a0d80df671aceae315", "0x1a9d8ca79769da4e7fd27e94f688e6438761f14a"]
채굴 보상 계정 선택하기(Etherbase)
이더리움에서 채굴시 보상받는 계정은 Etherbase입니다. Etherbase를 설정하기 위해서는 eth.coinbase 변수에 저장해야 합니다. 디폴트 값은 eth.accounts[0]이 지정됩니다. 새로 생성한 계정을 Etherbase로 설정합니다.
> miner.setEtherbase(personal.listAccounts[1]);
true
계정 잔고 확인하기
잔액 단위는 wei입니다.
> eth.getBalance(eth.accounts[0])
300000
잔액 단위를 변경할 수 있습니다.
> web3.fromWei(eth.getBalance(eth.accounts[0]), 'ether')
3e-13
생성된 블록 개수 조회
> eth.blockNumber
0
N 번째 블록 조회
0번째 블록은 제네시스 블록입니다.
> eth.getBlock(0)
{
difficulty: 20,
extraData: "0x",
gasLimit: 2100000,
gasUsed: 0,
hash: "0x9a4612f7ee07f0769f9b976ce5fccff2ffa09207a97a17cb9d008f170bbe0494",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x0000000000000000000000000000000000000000",
mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
nonce: "0x0000000000000000",
number: 0,
parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 504,
stateRoot: "0xa5a0b65df588b85b9c6ac613e01ffaf793715180082300ee6a1a00958cae0916",
timestamp: 0,
totalDifficulty: 20,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
계정 상태 조회
계정의 잠김 상태를 확인할 수 있습니다.
> personal.listWallets[0].status
"Locked"
계정 해제하는 방법
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x4d3ef63064ccc938a80791a0d80df671aceae315
Passphrase:
true
personal.unlockAccount('주소', '비밀번호', '유효기간) // 0은 geth 종료시 까지 unlock 유지
> personal.unlockAccount(eth.accounts[1], 'password', 0)
true
이더리움 채굴하는 방법
위에서 이더리움 채굴 보상 계정을 선택했습니다. 채굴을 진행하면 해당 계정으로 시작합니다. miner.start(N)으로 채굴을 시작합니다. N은 스레드 개수입니다.
> miner.setEtherbase(eth.accounts[1])
true
> miner.start(10)
null
채굴을 시작하면 이더리움 테스트 네트워크 내 블록개수가 증가하는 것을 확인할 수 있습니다.
> eth.blockNumber
5
> eth.blockNumber
6
> eth.blockNumber
7
채굴 종료는 miner.stop()을 사용합니다.
> miner.stop()
null
'Blockchain' 카테고리의 다른 글
[Blockchain] 이더리움 머클 패트리시아 트리(MPT)란? (0) | 2022.07.06 |
---|---|
[Blockchain] 이더리움 Geth 사용 방법 2 (이더 송금하기) (0) | 2022.07.05 |
[Blockchain] 이더리움 Geth 설치 방법(Ubuntu Docker) (0) | 2022.07.05 |
[Blockchain] 클레이튼(Klaytn) 블록체인 이란? (0) | 2022.07.04 |
[Blockchain] 작업증명(PoW) vs 지분증명(PoS) vs 위임지분증명(DPoS) 차이점 (1) | 2022.07.04 |
댓글