• 본 게시글은 K-MOOC 묶음강좌 '블록체인 암호화폐:입문부터 심화까지' 강의를 수강하고 공부하며 정리한 내용입니다.
이더리움은 블록체인 기술을 기반으로 설계된 스마트 컨트랙트를 실행시키는 분산 컴퓨팅 플랫폼입니다. 오픈 소스 프로젝트로 2013년 비탈릭 부테린이 백서를 작성하고, 2014년 ICO를 진행한 후, 2015년 7월 런칭되었습니다.
비트코인의 핵심 기술 블록체인에 계약서 등의 추가 정보를 기록할 수 있는 점을 더하여, 전세계의 사용자들의 컴퓨팅 자원을 활용하여 분산 네트워크를 구성하고 이 플랫폼을 이용하여 SNS, Email, 전자 투표 등 다양한 정보를 기록하는 시스템을 창안하였습니다.
C++, Java, Python, Go 등 주요 프로그래밍 언어를 지원합니다.
이더리움의 로드맵은 다음과 같습니다.
이더리움은 2세대 블록체인으로 1세대 블록체인과 다음과 같은 차이점을 가지고 있습니다.
이더리움 클라이언트에서 어카운트 생성 명령어를 통해 계정 생성시 20Byte의 Hex값이 생성됩니다.
한 외부 소유 어카운트에서 다른 어카운트나 스마트 컨트랙트의 함수를 호출할 때 트랜잭션을 사용합니다. 또한, 외부 소유 어카운트가 스마트 컨트랙트를 생성하여 이더리움에 브로드캐스팅할 때도 트랜잭션을 사용합니다. 이렇게 트랜잭션을 사용할 때, 발신자가 해당 트랜잭션이 다른 노드들에게 검증될 때 정당하다는 것을 입증하기 위해 전자서명이 필요합니다.
트랜잭션을 실행할 때, 실행 비용은 Price*GasLimit으로 결정됩니다.
Recipt는 트랜잭션 실행의 결과입니다. 트랜잭션을 처리하며 발생하는 로그를 리시트에 저장하며, 블록 내에 정상적으로 포함된 모든 트랜잭션에 대한 정보들이 저장됩니다.
이더리움 블록은 블록 헤더, 엉클 블록, 트랜잭션, 난이도 총합 등으로 구성되어 있으며, 주요 정보들은 헤더에 저장되어 있습니다.
제네시스 블록
제네시스 블록은 최초 블록으로서 이전 블록이 없어 이를 참조할 수 없고 블록의 번호 또한 초기값인 0을 가집니다. 처음에는 트랜잭션이 생성되지 않았기 때문에 트랜잭션이 없습니다.
또한, 같은 제네시스 블록을 갖고 있을 때만 같은 이더리움 네트워크에 연결되어 있다는 것을 인지하고 블록들을 싱크합니다. 제네시스 블록이 다르면 다른 블록체인이라고 할 수 있으며, 이를 프라이빗 네트워크를 생성할 때 사용합니다.
작업 증명하여 블록 생성에 성공하였지만 메인 블록체인에 포함되지 못한 블록을 엉클 블록이라고 합니다. 비트코인에서는 고아 혹은 스테일 블록이라 부르며 아무런 보상을 받지 못합니다.
엉클 블록이 많아지면 트랜잭션 처리를 지연시키고, 해시 계산을 위한 컴퓨팅 자원이 낭비되며, 이더리움의 보안성을 약화시키는 문제가 발생합니다.
고스트 알고리즘은 이더리움의 엉클 블록 문제를 해결하기 위한 솔루션입니다. 블록 생성시 마이너가 정상 블록에 대해 최대 2개의 엉클 블록을 추가하고 이에 따른 보상을 엉클 블록을 생성한 마이너에게 이더로 지급하여 엉클 블록의 문제를 해결합니다. 엉클 블록에 있는 트랜잭션과 컨트랙트는 블록체인에 포함되지 못하지만, 사용한 컴퓨팅 파워에 대해 보상해주는 것 입니다.
상태전이함수를 통해 트랜잭션이 블록에 포함되어 블록체인에 저장됩니다. S[0]에서 Tx[0]~Tx[n-1]을 적용하여 S[n]이 되고, 블록의 마이너에게 base 보상 및 수수료 보상을 완료하고 마지막 상태(S_FINAL)로 전이됩니다.
비트코인에서는 모든 유저들이 데이터를 공유할 때, 데이터의 크기 증가하여 블록체인 참여자들에게 주는 부담을 줄이기 위해 머클 트리를 사용하여 처리하였습니다. 이더리움에서는 트랜잭션과 리시트를 블록에 포함하여 저장하는데 더 이상 변경되지 않는 데이터이므로 머클 트리를 사용할 수 있지만 데이터의 낭비가 되며 해시함수를 SHA256이 아닌 Keccak256을 사용합니다.
머클 패트리샤 트리는 머클 트리를 개선한 해시 기반 트리 자료구조입니다. 트랜잭션과 리시트는 변하지 않지만, 이더리움에는 어카운트 정보를 포함하고 있는 상태(key와 value로 이루어진 map 구조)는 어카운트가 생성되거나 변경될 수 있고 잔액이나 스토리지가 트랜잭션이 적용될 때마다 동적으로 변경됩니다. 상태의 특징으로 인하여 상태의 트리는 머클 트리에 패트리샤 트리의 특징을 결합한 머클 패트리샤 트리를 사용하고, 모든 데이터를 LevelDB에 저장합니다. 공통의 키값을 따라 저장하여 중복 저장을 하지 않아 공간이 절약됩니다. 또한, 트리 전체 정보를 뒤질 필요 없이 연결된 키 값들을 path를 따라가는 것처럼 수정, 삭제, 검색하여 처리속도가 빠릅니다. 트리의 깊이를 한정지어 디도스 공격으로 트리의 깊이를 무한정 깊게 만들어 성능 저하를 일으키는 것을 방지할 수 있도록 만들어졌습니다.
1 Eth = 10^18 Wei
이더리움 컨버터를 이용하여 단위를 변환할 수 있음
이더리움은 이더의 가격 변동성이 크기 때문에 변동성이 적은 운영 토큰인 가스를 도입하였습니다. 이더리움 시스템에서의 운영 토큰이며 이더리움 플랫폼을 이용한 대가를 지급하는데 사용합니다. 트랜잭션을 만들어서 보내는 계정이 그에 대한 대가를 지급할 때 가스로 트랜잭션 처리비용을 지급해야 트랜잭션이 처리됩니다. 또한, 단위 트랜잭션이 너무 많은 리소스를 소모한다면 블록체인에 악영향을 미칠 수 있기 때문에 트랜잭션의 남용을 막기 위해서 사용되기도 합니다.
이더리움에서 트랜잭션을 처리하기 위한 비용은 (Gas Price: 1 가스당 지급할 가격)*(Gas Limit: 트랜잭션 수행에 소비될 총 가스에 대한 예상치)으로 계산하고, Gas Price가 높을수록 마이너에 의해 빨리 처리됩니다.
실행계층은 스마트 컨트랙트 실행을 위한 계층입니다.
닉 자보가 고안한 스마트 컨트랙트의 개념을 채용하여 이더리움에서는 다양한 형태의 응용 컨트랙트를 개발할 수 있도록 발전하였습니다. 이더리움에서 스마트 컨트랙트는 이더리움 어카운트의 상태를 변경할 수 있는 프로그램 코드로 이더리움 네트워크 상에 배포되어 블록체인 내에 상태정보로 존재하고, EVM(이더리움 가상 머신)에서 작동되어 상태전이를 유발합니다. 언어 중 Solidity가 가장많이 사용되며 이를 통해 스마트컨트랙트 코드를 작성합니다.
EVM은 이더리움 스마트 컨트랙트의 바이트 코드를 실행하는 32바이트 스택 기반의 실행환경입니다. 이더리움의 각 노드는 EVM을 포함하고 있고, 이 EVM을 통해서 컨트랙트의 바이트코드를 Op code로 변환 후 내부에서 실행합니다. 내부에 휘발성 메모리와 비휘발성 메모리로 구성되어 바이트 배열 형태로 스택의 항목들을 저장합니다. 카운터를 0부터 증가시키면서 반복적으로 op 코드에 대한 연산을 실행하며 가스를 소비하고 종료 조건(오류, STOP 명령어, RETURN 명령어)을 만족했을 때 코드 실행을 종료합니다. 스택, 무한대로 확장 가능한 바이트 배열을 담을 수 있는 메모리, 영속적으로 값을 저장하기 위한 저장소에 접근 가능해야 합니다.
공통계층은 전체 아키텍처에서 공통으로 사용하는 기능을 포함합니다.
이더리움 네트워크는 네트워크에 참여하는 노드들이 존재하며, 노드(클라이언트)들은 서로 p2p 네트워크를 형성하고 이를 위해 RLPx 프로토콜을 사용하고 있습니다. 또한 서비스들간의 통신을 위해서 eth 프로토콜을 사용합니다.
클라이언트를 구동시키면 노드가 JSON-RPC server를 실행하고 노출시킵니다. 네트워크 외부의 웹 앱, 네이티브 앱 등은 JSON-RPC server에 요청하여 이더리움 네트워크 안의 데이터를 얻을 수 있습니다.
p2p네트워크 상에서 일반 전송과 애플리케이션 간의 통신을 위한 RLPx라는 암호화된 네트워크 프로토콜을 사용합니다.
RLPx
RLPx는 peer 간 노드를 탐색하기 위한 기능(노드 디스커버리 프로토콜), ECDSA로 서명된 UDP 프로토콜, 암호화된 TCP 프로토콜 등 이더리움 전반에 걸쳐 사용되는 P2P 네트워크 기능이 포함되어 있습니다.
노드 디스커버리 프로토콜은 네트워크에 연결된 RLPx 노드를 탐지하는데 사용되는 UDP 기반의 RPC 프로토콜입니다.
이더리움 네트워크에서 한 노드가 네트워크에 참여하기 위해서는 네트워크 상의 다른 노드들과 서로 연결되어야 합니다. 노드 디스커버리 프로토콜은 분산 해시 테이블인 카데리마 프로토콜을 기반으로 네트워크 상의 노드를 탐지하는 프로토콜입니다.
노드 디스커버리 프로토콜의 작동 절차
1. 부트스트랩 노드를 통해 초기 연결할 노드의 목록을 전달받음
2. 프로토콜을 사용하여 노드드로가 연결 시작
3. 노드들과 연결되면 부트스트랩 노드와 접속 중단
노드 디스커버리 프로토콜의 4가지 패킷
노드 디스커버리 프로토콜에서 이더리움의 각 노드는 enode라는 url로 표현되며 노드 주소의 역할을 합니다.
enode 예시
enode://~~~@10.5.57.7:30303?discport=30301 enode url + @(구분자) + Host IP + : + TCP port 번호 + UDP port 번호
이더리움은 처음 시작시 부트스트랩 노드와 연결하여야 하는데, 이 때 여러가지 방법이 있습니다.
이더리움은 기본 저장소로 내부에 ethdb 패키지를 통해 key value 저장소인 레벨DB를 사용하고 있습니다. ethdb 패키지로 레벨DB를 래핑하여 사용하고 있는데, 이를 통해 나중에 코드의 변경 없이 다른 dbms로 손쉽게 교체할 수 있습니다.
머클트리의 트랜잭션, 리시트, 머클 패트리샤 트리 내의 모든 상태 정보, EVM의 비휘발성 저장소 등 스토리지에 저장될 필요가 있는 모든 정보를 레벨 DB에 저장합니다.
레벨 db는 사용하기 쉽지만 데이터의 조회 기능이 너무 단순하고 인덱스를 지원하지 않아, 데이터 용량이 커지면 탐색 시간이 많이 소요되고 복잡한 질의가 불가능합니다. 이러한 문제 해결을 위해 mongo DB 등으로 변환하는 프로젝트를 진행 중입니다.
RLP인코딩은 내부에서 임의로 중첩된 바이너리 배열을 인코딩하기 위해 만들어졌습니다. RLP 인코딩은 이더리움에 있는 객체들을 직렬화 하는데 사용되는 메인 인코딩 방법입니다. 다양한 인코딩 방법이 있지만 단순한 과정으로 인코딩하여 크기를 줄이고, 바이트 단위의 일관성을 확보하기 위하여 직접 고안된 인코딩 방법 입니다. 하나의 item을 취하며, item은 string과 item들의 list로 정의됩니다.
응용 계층은 이더리움은 다양한 문제를 해결하는 서비스를 개발하고 운영할 수 있는 플랫폼을 목표로 하고, 이러한 서비스들을 DApp이라 부릅니다.
이더리움은 DApp 개발을 위해 이더리움은 web3.js라는 JS 라이브러리를 제공합니다. web3.js는 JSON-RPC를 사용하여 블록체인의 데이터와 스마트 컨트랙트의 바이트 코드를 JS로 다룰 수 있게 하는 라이브러리입니다.
Swarm은 인센티브 방식으로 운영되는 p2p 파일 시스템으로 Content Delivery Network와 유사한 콘텐츠 전달 채널입니다. 블록체인의 데이터와 DApp의 코드와 데이터 등을 탈중앙화된 분산 형태로 저장하고 해당 콘텐츠를 전달하기 위해 사용됩니다. 콘텐츠를 다운 받으면 이를 제공한 노드에게 대가를 지급하고, 인기 있는 콘텐츠를 제공하면 해당 콘텐츠를 다움 받아 사용한 피어들로부터 대가를 받을 수 있는 인센티브 시스템입니다.
스웜 네트워크 참여자들은 각자 역할에 따라 보상을 받아 자체적으로 유지되고 성장할 수 있습니다.
PoC(Proof of Concept)로 구현중에 있으며, 최종 목표는 디도스 공격의 무력화, 무정지 운영, 인센티브 기반 하 자생적으로 운영하는 것 입니다.
Whisper는 Dapp들이 서로 통신하기 위한 통신 프로토콜으로, geth와 C++ 클라이언트에 포함되어 배포가 될 것 같습니다. 또한, 추적 불가능한 P2P 메세징 프로토콜입니다. Multi-casting, broadcasting, M-to-M과 같은 다양한 노드 간 메세징을 지원합니다. 또한 암호화 알고리즘 사용하였으며, 구동하기 위해서 geth 구동시 ?shh 옵션을 사용합니다.
탈중앙 P2P 네트워크에서는 네트워크 지연, 중복 수신, 의도적 변조 등 정보 전달 과정에 문제가 발생할 수 있습니다. 이는 Consensus Mechanism을 통해 해결합니다.
Consensus Mechanism의 조건
1. 특정 노드가 임의로 블록체인 조작 불가능
2. 블록과 트랜잭션의 유효성 여부를 검증할 수 있는 방법 필요
3. 블록을 체인에 연결시, 동시에 두개 이상의 유효한 블록체인 존재시 하나를 선택하는 규칙 필요
작업증명(Proof of Work)
복잡한 계산의 해답을 가장 빨리 찾은 마이너의 블록을 블록체인에 연결하고 이러한 작업에 대해 보상해주는 방식
분기(포크)는 블록체인 시스템 업그레이드를 말하며 소프트웨어의 버전 업그레이드 또는 현재 블록체인을 기반으로 새로운 블록체인을 만드는데 사용됩니다.
1. 하드포크
하드포크는 실제 소프트웨어의 데이터 구조 등이 변경되어 이전 버전과 호환되지 않아 모든 사용자와 마이너가 모두 업그레이드 해야합니다. 이더리움 또한 DAO 해킹 이후 하드포크를 진행하였고 기존 블록체인을 이더리움 클래식으로 운영하게 되었습니다.
2. 소프트포크
이전 버전과 신규 버전의 블록체인이 호환되어 사용자는 반드시 업그레이드할 필요가 없지만 마이너는 업그레이드 해야합니다. 마이닝 컴퓨팅 파워의 50% 이상이 업그레이드해야 새로운 블록체인 구조로 변경되고 그 유효성을 유지할 수 있습니다.
3. 레귤러포크
동시에 두개의 블록이 생성되었을 때 나타나는 일시적 충돌로, 긴 블록체인을 선택하여 해결합니다.
비트코인의 합의 알고리즘은 해시 결과가 미리 지정된 숫자보다 작은 Nonce 값을 가장 먼저 찾아야하는 알고리즘입니다. 이는 강력한 해시 연산이 필요하고 마이너들은 해시연산에 특화된 ASIC 기반의 마이닝 전용 하드웨어를 확보하여 파워를 늘렸습니다. 하지만 이로 인하여 해시연산력의 중앙집중화 문제가 발생하였습니다.
하지만 이더리움의 합의 엔진 Ethash는 비트코인 합의 알고리즘의 해시연산력 중앙집중화 문제가 발생하지 않습니다. 이더리움의 메모리 기반의 PoW 합의 엔진으로 메모리 상의 일정량의 데이터를 읽은 후 이것을 Nonce와 함께 해시 계산을 반복하는 방식을 사용합니다. 메모리 계산에 DAG 파일이 사용되며 매 3만 블록 마다 수GB 용량을 가진 DAG 파일이 생성됩니다.
이러한 방식은 메모리를 읽고 복제하는 속도가 해시 계산보다 느려 해시 연산력을 높이는 것이 큰 의미가 없습니다. 10~15초마다 새로운 블록을 생성하도록 설계되어 있습니다.
DAG 파일
시드 해시로 생성된 약 2GB의 캐시 데이터 집합으로, 블록의 번호를 스캔하여 시드 해시값 추출한 파일
1. 첫번째 이포치(30000블록 단위)에서 시드해시는 0으로 이루어진 32바이트 hash값
2. 이전 시드의 해시의 hash값이 다시 새로운 시드의 해시로 사용
3. 해당 시드를 통해 16MB의 수도 랜덤 캐시를 계싼
4. 해당 캐시를 통해 1GB 이상의 Full Dataset 생성
5. Full Dataset이 DAG 파일이며, 데이터셋의 랜덤한 부분을 마이닝의 해싱 부분에 포함시키는것이 Ethash의 핵심
Ethash에서는 DAG를 통해 미리 알 수 없는 메모리 읽기 연산을 요구하여 ASIC 제작이 어렵습니다. Ethash는 정확한 nonce와 mixDigest를 찾는것이 목적으로 합니다.
Ethash는 다음과 같은 과정을 통해 진행됩니다.
이 때 목표값 수식은 Target = 2^256/Difficulty 입니다.
PoW는 불필요한 해싱 연산을 통한 에너지 소비 증가, 블록 생성 주기를 PoW의 Difficulty로 유지하는데 한계가 있는 등 문제점이 있습니다. 따라서 이러한 문제점들을 보완하기 위하여 PoS 합의 알고리즘이 개발되었습니다. PoS에서는 마이너는 없고 검증자(Validator)가 존재하며, 자신이 가진 지분에 비례한 확률로 블록을 생성할 권한을 갖고, 블록을 생성한 이후 자신이 원하는 체인에 블록 연결 후 그에 대한 보상을 받는 방식 입니다. PoS 합의 알고리즘은 에너지 비용 절감 및 중앙화 위험 감소, 악의적 행동에 패널티 부여 가능 등의 장점을 가지고 있습니다.
이더를 스마트 컨트랙트에 예치하면 해당 어카운트는 검증자가 될 수 있고 예치금은 한동안 사용할 수 없게 묶입니다. 지분 비율을 고려하여 검증자가 되면 새로운 블록을 메인체인에 추가할지 여부를 투표할 권한이 부여됩니다. 검증자가 컨센서스 규칙을 따르지 않으면 불이익이 발생하며, 100번째 블록마다 checkpoint를 도입하여 finality를 부여하는 것은 고려 중입니다.