4. Ethereum(이더리움)
"Ethereum is decentralized platform that run smart contract applications that run
exactly as programmed without any possibility of downtime, censorship, fraud or third
party interference."
- 이더리움은 스마트 계약(고장, 검열, 부정이나 제3자에 의한 방해가 전혀없이 프로그래밍된 대
로 동작하는 app)을 수행할 수 있는 분산형 플랫폼
5. 클라이언트 언어
go-ethereum Go
Parity Rust
cpp-ethereum C++
pyethapp Python
ethereumjs-lib Javascript
Ethereum(J) Java
ruby-ethereum Ruby
ethereumH Haskell
6. 네트워크
* 라이브 네트워크
공개된 네트워크(공개 블록체인). 실제 이더리움을 이용해 Transaction 할 수 있다.
채굴도 가능하지만, 개인 PC로 채굴하는 것은 극히 힘들다.
* 테스트 네트워크
테스트용 네트워크.
1) [Morden 테스트넷] : 라이브 네트워크 처럼 전 세계의 노드가 참가할 수 있다.
2) [사설 테스트넷] : 혼자 또는 한정된 노드만 참가
테스트넷에서 채굴된 이더리움은 테스트넷에서만 사용이 가능하다. 실제 라이브 네트워크에
는 공유가 되지 않는다.
7. Ether
* 이더리움은 "ether" 라는 단위를 사용한다. 물론 더 작은 단위로 나눌 수 있다.
* 가장 작은 단위는 "wei" 이며, 1 ether는 10 wei 이다.
18
1 ether
10 wei
18
1,000,000,000,000,000,000 wei
8. Gas
Ether 송금과 계약을 실행하기 위해서는 수수료로 이더리움을 지불해야한다.
이를 'Gas’라고 부른다.
1 Ether 전송
21,000 Gas
Gas Price : 2.2 X 10 wei
14
=> 1 ether - 4.62 X 10 wei
14
=> 1 ether
10. Geth 설치
Geth 는 go-ethereum 이라는 이름에서도 알 수 있듯이, Go 언어로 만들어진 클라이언트.
1) Mac
Homebrew를 통해서 쉽게 설치 할 수 있다.
$ brew tap ethereum/ethereum
$ brew install ethereum
2) 윈도우
https://geth.ethereum.org/downloads/ 에서 받으면 된다.
zip 파일을 다운받아 설치하면 자동으로 PATH 환경 변수가 추가된다.
11. 설치가 완료되면, 터미널(CMD)에서 다음 명령어를 통해 확인 할 수 있다.
1) Mac
$ geth version
2) 윈도우
geth.exe 를 실행 후, CMD에서 version을 확인하면 된다.
Geth 확인
12. 로컬 테스트넷에서 Geth를 가동해봅시다.
1) 데이터 디렉토리
송수신한 블록 데이터와 계정 정보를 저장할 폴더를 말한다.
데이터 디렉토리를 별도 지정하지 않으면 ~/.ethereum 이 기본 폴더로 지정된다.
우선 바탕화면에 test_data 폴더를 만든다.
2) Genesis 파일
앞서 설명했듯이 Genesis 블록에 대한 정보가 저장된 JSON 형식의 텍스트 파일이다.
사설 테스트넷을 구축할 경우 0 부터 블록 체인을 만들기 때문에 Genesis 파일을 만들어준
다.
Geth
14. 바탕화면에 test_data 폴더에 genesis.json 이라고 저장한다.
그리고 터미널에 다음 명령어를 입력한다.
$ geth --datadir /PATH_TO/test_data init /PATH_TO/genesis.json
Genesis
15. 오류 없이 설정이 완료되면, test_data 폴더에 새로운 폴더들이 생성되었다.
Genesis
genesis.json geth keystore
1) geth 폴더에는 최초 생성된 블록에 대한 정보가 저장되어있다.
2) keystore 폴더에는 앞으로 저장될 키값들이 저장된다.
16. 다음 명령어를 통해 geth를 실행시켜본다.
$ geth --networkid 4649 --nodiscover --maxpeers 0 --dataidr /PATH_TO/test_data
console 2>> /PATH_TO/test_data/geth.log
다음 장에서 각 명령어에 대한 설명과 옵션에 대해 설명하겠습니다.
Geth 실행
17. $ geth --networkid 4649 --nodiscover --maxpeers 0 --dataidr /PATH_TO/test_data
console 2>> /PATH_TO/test_data/geth.log
Geth 명령어
* networkid 4649
네트워크 식별자(정수), 0~3은 예약된 숫자이다. 0~3을 제외한 숫자를 작성하면 된다.
* nodiscover
생성자의 노드를 다른 노드에서 검색할 수 없게 하는 옵션이다.
현재로써는 노드를 추가하는 것은 수동으로 해야한다.
이 옵션을 하지 않으면 동일한 Genesis 파일과 네트워크 ID를 가진 블록체인 네트워크에
생성자의 노드가 연결 될 수 있다.
18. $ geth --networkid 4649 --nodiscover --maxpeers 0 --dataidr /PATH_TO/test_data
console 2>> /PATH_TO/test_data/geth.log
Geth 명령어
* maxpeers 0
생성자의 노드에 연결할 수 있는 노드의 수를 지정. 0을 지정하면 다른 노드와 연결 X
* datadir /PATH_TO/test_data
방금 우리가 생성한 데이터 폴더를 지정한다.
미지정 시, 기본 디렉토리를 사용한다.
19. $ geth --networkid 4649 --nodiscover --maxpeers 0 --dataidr /PATH_TO/test_data
console 2>> /PATH_TO/test_data/geth.log
Geth 명령어
* console
대화형 자바스크립트 콘솔을 가동한다.
* 2>> /PATH_TO/test_data/geth.log
로그 파일을 만들 때 사용하는 옵션. 에러를 해당 경로의 파일에 저장한다.
(참고, 리눅스 쉘 명령어이다.)
20. 1) 계정 생성
* EOA(Externally Owned Account)
- EOA는 일반 사용자가 사용하는 계정으로, 비밀키로 관리됨
- Ether를 송금하거나 계약을 실행 할 수 있다.
* Contract
- 계약용 계정으로, 계약을 블록체인에 배포할 때 만들어짐(블록체인에 존재)
- 다른 계정으로부터 메시지를 수신해 코드를 싱핼하고 계정에 메시지를 보낼수 있다.
2) 생성 코드
> personal.newAccount("pw1")
"g4dfgajasdk23cdjxzcmq9r32"
테스트 넷 Ethereum
21. 1) 계정 확인
> eth.accounts
["as23nvgieqaw3jidweo23fsd"]
2) 추가 계정 생성 & 계정 확인
> personal.newAccount("pw2")
"afwgfw2312vfsdxzscsdfafsd"
> eth.accounts
["as23nvgieqaw3jidweo23fsd","afwgfw2312vfsdxzscsdfafsd"]
> eth.accounts[0]
"as23nvgieqaw3jidweo23fsd"
테스트 넷 Ethereum
22. 1) 채굴 준비
> eth.coinbase
"as23nvgieqaw3jidweo23fsd"
2) 채굴자 변경하기
> miner.setEtherbase(eth.accounts[1])
true
> eth.coinbase
"afwgfw2312vfsdxzscsdfafsd"
테스트 넷 Ethereum
23. 1) 잔고 확인
> eth.getBalance(eth.accounts[0])
0
2) 블록체인 수 확인 & 채굴시작 & 채굴 종료
> eth.blockNumber
0
> miner.start()
> miner.stop()
테스트 넷 Ethereum
24. 1) 채굴 로그 파일 확인
2) 블록체인 수 확인 & 잔고 확인
> eth.getBalance(eth.accounts[0])
8500000000000000
> eth.blockNumber
17
테스트 넷 Ethereum
INFO [03-27|12:46:25] 🔨 mined potential block number=1 hash=161fb7…785fd0
INFO [03-27|12:46:25] Commit new mining work number=2 txs=0 uncles=0 elapsed=146.212µs
INFO [03-27|12:46:26] Successfully sealed new block number=2 hash=7a1976…ef1355
INFO [03-27|12:46:26] 🔨 mined potential block number=2 hash=7a1976…ef1355
INFO [03-27|12:46:26] Commit new mining work number=3 txs=0 uncles=0 elapsed=161.31µs
INFO [03-27|12:46:26] Successfully sealed new block number=3 hash=d8a249…490949
INFO [03-27|12:46:26] 🔨 mined potential block number=3 hash=d8a249…490949
25. 1) 로그 분석
* DAG(Directed Asyclic Graph)가 생성됨
- 채굴이 완료되기까지 약간 시간이 걸림
- DAG는 채굴의 ASIC내성을 위해 만들어지는 약 1GB 크기의 파일
30,000블록마다 다시 만들어진다.
2) wei -> ether 변환
채굴해서 나온 이더리움은 wei 단위로 표기된다.
ether로 변환시켜서 표시하기 위해,
> web3.fromWei(eth.getBalance(eth.coinbase),"ether")
85
테스트 넷 Ethereum
26. 1) Ether 송금
이더리움을 채굴했으니, eth.accounts[0] 에서 eth.accounts[1]로 1 ether를 보내봅시다.
송금은 sendTransaction 명령어를 입력한다.
eth.sendTransaction( { from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(1, "ether")})
2) Error 발생
송금을 실행하면 오류가 발생한다.
Transaction은 수수료가 들기 때문에 잘못 실행하는 것을 방지하고자, 잠금 상태이다.
테스트 넷 Ethereum
27. 1) 잠금해제
보내는 사람의 잠금 상태를 해제하기 위해 다음 명령어를 입력한다.(기본 5분)
> personal.unlockAccount(eth.accounts[0])
passphrase: (계정 암호)
2) 다시 송금해보기
> eth.sendTransaction( { from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(1, "ether")})
"sar23g2fsyjrhtgqg4whyfg34tgdfgdsg345yhshs"
테스트 넷 Ethereum
28. 1) 송금 후 잔고확인
eth.accounts[1]의 잔고를 확인해보자.
> eth.getBalance(eth.accounts[1])
0
2) Transaction을 실행해도 바로 처리 X
왜냐함녀, 블록체인에서는 블록 안에 해당 트랜잭션이 포함될 때,
트랜잭션 내용이 실행되기 때문이다. 즉, 채굴을 통한 블록 생성이 필요하다.
테스트 넷 Ethereum
29. 1) 트랜잭션 확인하기
앞서 트랜잭션으로 나온 ID값을 확인해보자.
> eth.getTransaction("sar23g2fsyjrhtgqg4whyfg34tgdfgdsg345yhshs")
{
blockhash:"0x000000000000000000000000",
blockNumber:"null"
…
}
2) blockNumber == null
아직 트랜잭션이 처리가 된게 아니다. 즉, 앞서 채굴했던 블록 넘버 이후에 생성된
트랜잭션이기 때문에 이후에 생성되는 블록에 해당 트랜잭션이 포함될 것이다.
테스트 넷 Ethereum
30. 1) 미처리된 트랜잭션 처리
미처리된 트랜잭션을 처리하기 위해, 채굴을 재개하자.
> miner.start()
조금 기다린 뒤, 미처리된 항목이 있는지 확인해보자.
> eth.pendingTransactions
[]
> miner.stop()
true
> eth.getTransaction("sar23g2fsyjrhtgqg4whyfg34tgdfgdsg345yhshs")
{
blockNumber : 18
}
테스트 넷 Ethereum
31. 1) 트랜잭션이 포함된 블록
앞서 트랜잭션을 처리한 블록을 보자.
> eth.getBlock(18)
{
difficulty: 131072,
hash: "0x0239fsjgeaklg0wse234kmfgsdkgjdfgsdgsdfgdfg",
miner: "sgdrgf324hsdfggfag4tsdfsfwef",
number: 18,
…
transactions: ["sgfv43ytgadrghgaw4tyawfrsaefasdf"]
…
}
테스트 넷 Ethereum
32. 1) 트랜잭션 여러번 하기
이제 트랜잭션을 여러번 실행해보자.
이번에는 eth.accounts[1] 에서 eth.accounts[0] 으로 이더리움을 보내보자.
트랜잭션 후, eth.accounts[1]의 잔고와 eth.accounts[0] 잔고를 확인해보자.
2) 소수점이 나왔어요!
실제 보낸 값보다 덜 들어왔다면, Gas 가 소비되었다고 생각하면 된다.
그런데, eth.accounts[0]에서 보낼 때는 Gas가 소비되지 않았다.
왜냐하면 eth.accounts[0]이 채굴자이기 때문이다. Gas는 채굴자에게 보상으로 주어지는
데, 채굴자가 송금을 하기 때문이다.
테스트 넷 Ethereum
33. 1) Gas
트랜잭션 정보를 조회하면, gas와 gasPrice 부분이 있다.
* gasPrice : 1 Gas 당 가격을 의미한다. (단위는 wei)
* gas : 지불 가능한 최대 Gas를 의미하며, 실제 해당 트랜잭션을 처리하는데
지불된 Gas는 아니다.
(실제 지불된 Gas는 gas 값보다 작을 것이다.)
예를들면, 0.000378 수수료이고 gasPricer 18,000,000,000 wei 라면,
0.000378 ether = 378,000,000,000,000 wei 를 대입하면,
378,000,000,000,000 / 18,000,000,000 = 21,000 Gas 이다.
따라서 최대 gas 90,000 사용가능 중, 21,000 Gas를 소비한 것이다.
테스트 넷 Ethereum