블록체인 이론 및 응용 - (3) 이더리움

BLANC·2022년 1월 12일
0

블록체인

목록 보기
7/11
post-thumbnail

• 본 게시글은 K-MOOC 묶음강좌 '블록체인 암호화폐:입문부터 심화까지' 강의를 수강하고 공부하며 정리한 내용입니다.

이더리움

이더리움은 블록체인 기술을 기반으로 설계된 스마트 컨트랙트를 실행시키는 분산 컴퓨팅 플랫폼입니다. 오픈 소스 프로젝트로 2013년 비탈릭 부테린이 백서를 작성하고, 2014년 ICO를 진행한 후, 2015년 7월 런칭되었습니다.

비트코인의 핵심 기술 블록체인에 계약서 등의 추가 정보를 기록할 수 있는 점을 더하여, 전세계의 사용자들의 컴퓨팅 자원을 활용하여 분산 네트워크를 구성하고 이 플랫폼을 이용하여 SNS, Email, 전자 투표 등 다양한 정보를 기록하는 시스템을 창안하였습니다.

C++, Java, Python, Go 등 주요 프로그래밍 언어를 지원합니다.

이더리움 로드맵

이더리움의 로드맵은 다음과 같습니다.

  • 1단계 (Frontier)
    암호화폐 이더리움을 개발하여, 이더리움 블록을 채굴하여 네트워크를 형성함으로써 이더리움 블록체인을 생성하는 단계
  • 2단계 (Homestead)
    이더리움에 참가하는 노드들이 생겨 생태계가 구축되는 초기 단계
    이더리움 성장을 위하여 여러 기능을 업데이트하여 보완함
    2016년 7월 8일 DAO 공격 발생으로 1,920,000번째 블록에서 하드포크가 진행되어 이더리움 클래식이 생겨남
  • 3단계 (Metropolis)
    이더리움의 대중화를 위한 인프라가 형성되는 단계
    이더리움의 인프라가 형성되어 성장이 본격적으로 가속화되는 시기
    비잔티움과 콘스탄티노플 두 단계로 이루어짐
    비잔티움 하드포크는 2017년 10월 16일 437만번째 블록을 기점으로 실행되었음
    PoW에서 PoS의 방식으로 서서히 바뀌게 됨
  • 4단계 (Serenity)
    모든 변화 후 평정을 찾는 마지막 단계
    PoS로 합의 알고리즘의 전환을 완료하고, DApp이 어려움 없이 작동 가능한 블록체인 플랫폼이 형성되는 단계

2세대 블록체인

이더리움은 2세대 블록체인으로 1세대 블록체인과 다음과 같은 차이점을 가지고 있습니다.

  • 스마트컨트랙트 지원
  • 튜링 완전성
    비트코인의 경우 거래의 유효성 검증을 위해 튜링 불완전한 스크립트 언어 사용
    도적으로 반복문을 제거하여 무한 루프에 빠지는 것으로부터 보호하며 if문만 지원
    이더리움의 경우 튜링 완전한 언어를 사용하여 if문 뿐만 아닌 반복문과 다른 조건문도 지원
  • Account의 유무

이더리움 플랫폼 레퍼런스 모델

  • 데이터 계층
    이더리움에서 다루는 각종 데이터 구조를 정의하고, 관련 데이터를 관리합니다. 데이터 모델은 하부에 ethdb 패키지를 통해 구글이 만든 빠르고 가벼운 키/값 데이터베이스인 레벨 DB에 바이너리 형태로 저장됩니다.
  • 동의 계층 (합의 계층)
    계정에 의해 생성된 트랜잭션과, 블록의 유효성을 검증하는 합의엔진, 마이닝과 마이닝의 난이도, Gas, Ether 등의 처리를 담당합니다.
  • 실행 계층
    이더리움 블록체인 네트워크에서 구동 가능한 스마트 컨트랙트와 스마트 컨트랙트를 이더리움 노드에서 수행시켜 줄 EVM의 처리를 담당합니다.
  • 공통 계층
    공통적으로 사용하는 기능들을 제공합니다. 노드 간의 연결과 동기화를 위한 P2P 네트워크 프로토콜을 비롯하여 암호 해시, 전자 서명, 각종 인코딩, 공통 저장소 등 모든 계층에서 공통적으로 이용할 기능들을 담당합니다.
  • 응용 계층
    이더리움은 프로그래밍 가능한 플랫폼으로서 다양한 응용 서비스와 디앱을 개발할 수 있습니다. DApp과 더불어 블록체인에서 구동 가능한 스마트 컨트랙트, 그리고 분산 파일 시스템 스웜, 분산 메시징 시스템 휘스퍼 등을 제공합니다.

데이터 계층

Account

이더리움 클라이언트에서 어카운트 생성 명령어를 통해 계정 생성시 20Byte의 Hex값이 생성됩니다.

  • 주소 생성과정
    1. 랜덤으로 32byte의 개인키 생성
    2. 개인키를 ECDSA를 통해 64byte의 공개키 생성
    3. 공개키를 Keccak256 해시함수를 실행하여 32byte의 해시값 생성
    4. 생성된 해시값에서 뒤의 20byte를 추출한 것이 Account의 주소

Transaction

한 외부 소유 어카운트에서 다른 어카운트나 스마트 컨트랙트의 함수를 호출할 때 트랜잭션을 사용합니다. 또한, 외부 소유 어카운트가 스마트 컨트랙트를 생성하여 이더리움에 브로드캐스팅할 때도 트랜잭션을 사용합니다. 이렇게 트랜잭션을 사용할 때, 발신자가 해당 트랜잭션이 다른 노드들에게 검증될 때 정당하다는 것을 입증하기 위해 전자서명이 필요합니다.

  • 트랜잭션 데이터 Field
    AccountNonce : 발신자로부터 보내진 트랜잭션의 수(0부터 시작)
    Price : 발신자가 실행단계마다 마이너(실행자)에게 지급할 비용(일종의 수수료)
    GasLimit : 발신자가 자신이 보내는 트랜잭션이 처리되기 위해서 지급가능한 최대 범위
    Recipient : 트랜잭션의 수신자의 주소
    Amount : 발신자가 수신자에게 전송할 이더 금액 양
    Payload : 스마트 컨트랙트의 함수 호출시 함께 전송되는 파마리터가 될 수 있고, 컨트랙트 생성을 위한 트랜잭션에서 실제 컨트랙트 바이트 코드가 담기는 필드
    V, R, S : 트랜잭션 발신자의 ECDSA 전자서명과 관련된 값

트랜잭션을 실행할 때, 실행 비용은 Price*GasLimit으로 결정됩니다.

Receipt

Recipt는 트랜잭션 실행의 결과입니다. 트랜잭션을 처리하며 발생하는 로그를 리시트에 저장하며, 블록 내에 정상적으로 포함된 모든 트랜잭션에 대한 정보들이 저장됩니다.

  • 리시트 데이터 Field
    PostState : 트랜잭션 처리 후 상태 정보
    Failed : 트랜잭션 처리 후 실패 여부, 0x01 → 이상 없음 / 0x00 → 이상 있음
    CumulativeGasUsed : 해당 리시트와 상응하는 트랜잭션을 포함하는 블록에서 현재까지 사용한 누적 가스 비용
    Bloom : Logs에 저장된 로그들을 빠르게 검색하기 위한 블룸 필터
    Logs : 트랜잭션을 실행하면서 생성된 각종 로그들
    TxHash : 해당 리시트를 발생시킨 트랜잭션의 해시값, 트랜잭션을 식별하기 위해 사용
    ContractAddress : 트랜잭션이 스마트 컨트랙트로부터 생성되었을 경우 해당 스마트 컨트랙트의 주소를 의미
    GasUsed : 해당 트랜잭션을 처리하기 위해서 사용된 가스 비용

이더리움 블록

이더리움 블록은 블록 헤더, 엉클 블록, 트랜잭션, 난이도 총합 등으로 구성되어 있으며, 주요 정보들은 헤더에 저장되어 있습니다.

제네시스 블록
제네시스 블록은 최초 블록으로서 이전 블록이 없어 이를 참조할 수 없고 블록의 번호 또한 초기값인 0을 가집니다. 처음에는 트랜잭션이 생성되지 않았기 때문에 트랜잭션이 없습니다.
또한, 같은 제네시스 블록을 갖고 있을 때만 같은 이더리움 네트워크에 연결되어 있다는 것을 인지하고 블록들을 싱크합니다. 제네시스 블록이 다르면 다른 블록체인이라고 할 수 있으며, 이를 프라이빗 네트워크를 생성할 때 사용합니다.

  • 블록의 Field
    Alloc : 이더를 특정 어카운트에 미리 할당하는 기능으로 마이닝 없이 명시한 어카운트에 이더 할당 가능
    코인base : 마이너가 보상과 수행 대가를 전송받은 어카운트 주소
    Difficulty : Nonce값을 찾기 위해 수행하는 계산에서 사용되는 목표값
    ParentHash : 부모 블록 헤더의 해시값으로, 제네시스 블록은 부모블록이 없어 0임
    Tiemstamp : 해당 블록의 생성 시간으로, 유닉스 time()함수의 값

엉클 블록

작업 증명하여 블록 생성에 성공하였지만 메인 블록체인에 포함되지 못한 블록을 엉클 블록이라고 합니다. 비트코인에서는 고아 혹은 스테일 블록이라 부르며 아무런 보상을 받지 못합니다.

엉클 블록이 많아지면 트랜잭션 처리를 지연시키고, 해시 계산을 위한 컴퓨팅 자원이 낭비되며, 이더리움의 보안성을 약화시키는 문제가 발생합니다.

고스트 알고리즘

고스트 알고리즘은 이더리움의 엉클 블록 문제를 해결하기 위한 솔루션입니다. 블록 생성시 마이너가 정상 블록에 대해 최대 2개의 엉클 블록을 추가하고 이에 따른 보상을 엉클 블록을 생성한 마이너에게 이더로 지급하여 엉클 블록의 문제를 해결합니다. 엉클 블록에 있는 트랜잭션과 컨트랙트는 블록체인에 포함되지 못하지만, 사용한 컴퓨팅 파워에 대해 보상해주는 것 입니다.

  • 정상 블록 B에 포함된 엉클 블록의 특징
    블록 B의 k번째 조상의 직접적인 자손(k는 2~7)이며, 블록 B의 조상이어서는 안됩니다.
    유효한 블록 헤더를 가져야하지만 유효한 블록을 가질 필요는 없으며 다른 정상 블록에 중복해서 포함되면 안됩니다.

이더리움 상태 전이함수 APPLY(S,TX) -> S’

상태전이함수를 통해 트랜잭션이 블록에 포함되어 블록체인에 저장됩니다. S[0]에서 Tx[0]~Tx[n-1]을 적용하여 S[n]이 되고, 블록의 마이너에게 base 보상 및 수수료 보상을 완료하고 마지막 상태(S_FINAL)로 전이됩니다.

머클 패트리샤 트리 (Merkle Patricia Tree)

비트코인에서는 모든 유저들이 데이터를 공유할 때, 데이터의 크기 증가하여 블록체인 참여자들에게 주는 부담을 줄이기 위해 머클 트리를 사용하여 처리하였습니다. 이더리움에서는 트랜잭션과 리시트를 블록에 포함하여 저장하는데 더 이상 변경되지 않는 데이터이므로 머클 트리를 사용할 수 있지만 데이터의 낭비가 되며 해시함수를 SHA256이 아닌 Keccak256을 사용합니다.

머클 패트리샤 트리는 머클 트리를 개선한 해시 기반 트리 자료구조입니다. 트랜잭션과 리시트는 변하지 않지만, 이더리움에는 어카운트 정보를 포함하고 있는 상태(key와 value로 이루어진 map 구조)는 어카운트가 생성되거나 변경될 수 있고 잔액이나 스토리지가 트랜잭션이 적용될 때마다 동적으로 변경됩니다. 상태의 특징으로 인하여 상태의 트리는 머클 트리에 패트리샤 트리의 특징을 결합한 머클 패트리샤 트리를 사용하고, 모든 데이터를 LevelDB에 저장합니다. 공통의 키값을 따라 저장하여 중복 저장을 하지 않아 공간이 절약됩니다. 또한, 트리 전체 정보를 뒤질 필요 없이 연결된 키 값들을 path를 따라가는 것처럼 수정, 삭제, 검색하여 처리속도가 빠릅니다. 트리의 깊이를 한정지어 디도스 공격으로 트리의 깊이를 무한정 깊게 만들어 성능 저하를 일으키는 것을 방지할 수 있도록 만들어졌습니다.

  • 머클 패트리샤 트리의 주요 특징
    Recursive Length Prefix(RLP)로 인코딩됨
    머클 패트리샤 트리에 있는 모든 노드에 대한 경로는 RLP인코딩과 Keccak256 해싱을 거쳐 LevelDB에 저장됨
    트리의 노드는 성능향상을 위해 공백 노드, 리프 노드, 확장 노드, 브랜치 노드 4가지 타입으로 이루어짐
    리프 노드와 확장 노드를 구별하기 위해 prefix를 사용함

Ether

1 Eth = 10^18 Wei
이더리움 컨버터를 이용하여 단위를 변환할 수 있음

Gas

이더리움은 이더의 가격 변동성이 크기 때문에 변동성이 적은 운영 토큰인 가스를 도입하였습니다. 이더리움 시스템에서의 운영 토큰이며 이더리움 플랫폼을 이용한 대가를 지급하는데 사용합니다. 트랜잭션을 만들어서 보내는 계정이 그에 대한 대가를 지급할 때 가스로 트랜잭션 처리비용을 지급해야 트랜잭션이 처리됩니다. 또한, 단위 트랜잭션이 너무 많은 리소스를 소모한다면 블록체인에 악영향을 미칠 수 있기 때문에 트랜잭션의 남용을 막기 위해서 사용되기도 합니다.

이더리움에서 트랜잭션을 처리하기 위한 비용은 (Gas Price: 1 가스당 지급할 가격)*(Gas Limit: 트랜잭션 수행에 소비될 총 가스에 대한 예상치)으로 계산하고, Gas Price가 높을수록 마이너에 의해 빨리 처리됩니다.

트랜잭션의 처리과정 (사용자A → 사용자B 송금)

  1. 사용자A가 사용자B에게 ETH를 보내는 트랜잭션을 자신의 개인키로 ECDSA 전자서명
  2. 이더리움 클라이언트는 해당 트랜잭션을 네트워크에 연결되어 있는 근처 peer 노드에게 브로드캐스팅하여 이더리움 네트워크에 전파
  3. 마이너가 해당 트랜잭션을 전달받으면 트랜잭션의 유효성 검증을 수행하고 처리비용을 계산하여 트랜잭션 풀에 해당 트랜잭션을 등록
  4. 트랜잭션이 선택되면 송금값을 A 어카운트에서 B 어카운트로 옮기고 트랜잭션을 처리할 때 사용자 A에게 충분한 이더가 없거나 가스가 모두 소비되는 등 코드 실행이 불가능하다는 이유로 중간에 송금이 실패한다면 실행비용을 제외하고 모든 상태를 초기 상태로 복구하고 트랜잭션 처리 비용을 마이너 어카운트에 전송
  5. 트랜잭션이 성공하면 결과를 상태 DB에 반영 후 남아있는 모든 가스를 이더로 환산하여 사용자 A에게 반환하고 트랜잭션 처리 비용을 마이너에게 전송
  6. 모든 트랜잭션 처리 후, 마이닝에 성공한 블록은 블록체인에 연결

실행 계층

실행계층은 스마트 컨트랙트 실행을 위한 계층입니다.

스마트 컨트랙트

닉 자보가 고안한 스마트 컨트랙트의 개념을 채용하여 이더리움에서는 다양한 형태의 응용 컨트랙트를 개발할 수 있도록 발전하였습니다. 이더리움에서 스마트 컨트랙트는 이더리움 어카운트의 상태를 변경할 수 있는 프로그램 코드로 이더리움 네트워크 상에 배포되어 블록체인 내에 상태정보로 존재하고, EVM(이더리움 가상 머신)에서 작동되어 상태전이를 유발합니다. 언어 중 Solidity가 가장많이 사용되며 이를 통해 스마트컨트랙트 코드를 작성합니다.

스마트 컨트랙트 작동 프로세스

  1. 솔리디티 등의 언어로 스마트 컨트랙트 작성
  2. 컴파일러를 통해 컴파일 되어 EVM에서 사용할 수 있는 바이트 코드로 컴파일
  3. 이더리움 클라이언트(geth)를 이용하여 블록체인에 배포
  4. 해당 트랜잭션이 블록에 포함되면 컨트랙트 주소를 갖는 컨트랙트 계정과 다른 어플리케이션에서 이 컨트랙트의 바이트 코드에 접근할 수 잇는 ABI 생성
  5. 컨트랙트의 주소와 ABI를 이용하여 외부에서 스마트 컨트랙트 활용

EVM

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가지 패킷

  • ping
    노드가 온라인 상태인지 확인하는 패킷
    연결되어 있는 피어 노드 중 첫번째 노드에 ping을 보내고 ping을 받은 노트는 pong 패킷을 보내 응답합니다.
  • pong
    ping 패킷에 대한 응답 패킷
  • findnode
    목표노드 주변에 위치한 peer 노드들에 전달되어 findnode 패킷의 수신자는 해당 목표 노드 주변에 위치한 노드를 안다면 해당 노드들의 목록을 neighbors 패킷에 포함하여 반환합니다.
  • neighbors
    findnode 패킷에 대한 응답 패킷이고, 요청된 목표 노드 인접 노드들이 포함되어 있습니다.

노드 디스커버리 프로토콜에서 이더리움의 각 노드는 enode라는 url로 표현되며 노드 주소의 역할을 합니다.

enode 예시
enode://~~~@10.5.57.7:30303?discport=30301
enode url + @(구분자) + Host IP + : + TCP port 번호 + UDP port 번호

부트스트랩 노드와 연결하는 방법

이더리움은 처음 시작시 부트스트랩 노드와 연결하여야 하는데, 이 때 여러가지 방법이 있습니다.

  1. default로서 geth 클라이언트를 구동하면 go-ethereum 프로그램에 하드코딩된 부트스트랩 노드 목록을 참조하여 연결시도
  2. geth 클라이언트를 구동할 때, --bootnodes 옵션을 사용하여 부트스트랩 노드 직접 지정
    (geth -bootnodes “enode URL”)
  3. geth 클라이언트 콘솔 상에서 addmin.addPeer()를 사용하여 연결하고자 하는 노드 지정
    (admin.addPeer(“enode url + @(구분자) + Host IP + : + TCP port 번호”//))
  4. geth가 구동할 때, 항상 특정 노드와 연결하게 해주는 정적 노드 기능을 활용
geth data directory 아래에 static-nodes.json 파일 생성 후 파일 안에 “enode://공개키@IP주소:포트”형태로 연결할 노드를 명시하면 geth 실행과 동시에 해당 enode에 연결됨

이더리움 데이터 베이스

이더리움은 기본 저장소로 내부에 ethdb 패키지를 통해 key value 저장소인 레벨DB를 사용하고 있습니다. ethdb 패키지로 레벨DB를 래핑하여 사용하고 있는데, 이를 통해 나중에 코드의 변경 없이 다른 dbms로 손쉽게 교체할 수 있습니다.

머클트리의 트랜잭션, 리시트, 머클 패트리샤 트리 내의 모든 상태 정보, EVM의 비휘발성 저장소 등 스토리지에 저장될 필요가 있는 모든 정보를 레벨 DB에 저장합니다.

레벨 db는 사용하기 쉽지만 데이터의 조회 기능이 너무 단순하고 인덱스를 지원하지 않아, 데이터 용량이 커지면 탐색 시간이 많이 소요되고 복잡한 질의가 불가능합니다. 이러한 문제 해결을 위해 mongo DB 등으로 변환하는 프로젝트를 진행 중입니다.

RLP 인코딩

RLP인코딩은 내부에서 임의로 중첩된 바이너리 배열을 인코딩하기 위해 만들어졌습니다. RLP 인코딩은 이더리움에 있는 객체들을 직렬화 하는데 사용되는 메인 인코딩 방법입니다. 다양한 인코딩 방법이 있지만 단순한 과정으로 인코딩하여 크기를 줄이고, 바이트 단위의 일관성을 확보하기 위하여 직접 고안된 인코딩 방법 입니다. 하나의 item을 취하며, item은 string과 item들의 list로 정의됩니다.

응용 계층

응용 계층은 이더리움은 다양한 문제를 해결하는 서비스를 개발하고 운영할 수 있는 플랫폼을 목표로 하고, 이러한 서비스들을 DApp이라 부릅니다.

DApp의 특징

  • 특정 주체를 신뢰할 필요 없음
  • 투명한 운영 원칙
  • 향상된 보안
  • 개인정보 보호
  • 글로벌 서비스의 용이함

이더리움은 DApp 개발을 위해 이더리움은 web3.js라는 JS 라이브러리를 제공합니다. web3.js는 JSON-RPC를 사용하여 블록체인의 데이터와 스마트 컨트랙트의 바이트 코드를 JS로 다룰 수 있게 하는 라이브러리입니다.

Swarm

Swarm은 인센티브 방식으로 운영되는 p2p 파일 시스템으로 Content Delivery Network와 유사한 콘텐츠 전달 채널입니다. 블록체인의 데이터와 DApp의 코드와 데이터 등을 탈중앙화된 분산 형태로 저장하고 해당 콘텐츠를 전달하기 위해 사용됩니다. 콘텐츠를 다운 받으면 이를 제공한 노드에게 대가를 지급하고, 인기 있는 콘텐츠를 제공하면 해당 콘텐츠를 다움 받아 사용한 피어들로부터 대가를 받을 수 있는 인센티브 시스템입니다.
스웜 네트워크 참여자들은 각자 역할에 따라 보상을 받아 자체적으로 유지되고 성장할 수 있습니다.
PoC(Proof of Concept)로 구현중에 있으며, 최종 목표는 디도스 공격의 무력화, 무정지 운영, 인센티브 기반 하 자생적으로 운영하는 것 입니다.

Whisper

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. 레귤러포크
동시에 두개의 블록이 생성되었을 때 나타나는 일시적 충돌로, 긴 블록체인을 선택하여 해결합니다.

이더리움의 합의엔진 Ethash

비트코인의 합의 알고리즘은 해시 결과가 미리 지정된 숫자보다 작은 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 Hashing Algorithm

Ethash는 다음과 같은 과정을 통해 진행됩니다.

  1. 입력받은 새로운 블록 헤더와 임의로 추정한 nonce값을 Keccak256 해시를 통해 첫번째 믹스 해시 구성
  2. 첫번째 믹스 해시를 사용하여 DAG로 부터 임의의 페이지 2개 추출
  3. 이더리움의 믹싱함수를 사용하여 추출된 페이지들과 첫번째 믹스해시로부터 다음번 믹스해시 생성
  4. 2,3 과정을 64번 반복하여 64번째 믹스 해시 생성
  5. 믹스 해시에 후처리 함수를 적용하여 32바이트의 mixDigest를 만듦
  6. MixDigest와 미리 정의된 마이닝 목푯값을 비교하여 마이닝 성공 여부 판단
  7. 실패시 1 과정부터 다시 시작

이 때 목표값 수식은 Target = 2^256/Difficulty 입니다.

PoS 합의 알고리즘

PoW는 불필요한 해싱 연산을 통한 에너지 소비 증가, 블록 생성 주기를 PoW의 Difficulty로 유지하는데 한계가 있는 등 문제점이 있습니다. 따라서 이러한 문제점들을 보완하기 위하여 PoS 합의 알고리즘이 개발되었습니다. PoS에서는 마이너는 없고 검증자(Validator)가 존재하며, 자신이 가진 지분에 비례한 확률로 블록을 생성할 권한을 갖고, 블록을 생성한 이후 자신이 원하는 체인에 블록 연결 후 그에 대한 보상을 받는 방식 입니다. PoS 합의 알고리즘은 에너지 비용 절감 및 중앙화 위험 감소, 악의적 행동에 패널티 부여 가능 등의 장점을 가지고 있습니다.

이더리움 PoS의 기본 컨셉(추후 변경될 것)

이더를 스마트 컨트랙트에 예치하면 해당 어카운트는 검증자가 될 수 있고 예치금은 한동안 사용할 수 없게 묶입니다. 지분 비율을 고려하여 검증자가 되면 새로운 블록을 메인체인에 추가할지 여부를 투표할 권한이 부여됩니다. 검증자가 컨센서스 규칙을 따르지 않으면 불이익이 발생하며, 100번째 블록마다 checkpoint를 도입하여 finality를 부여하는 것은 고려 중입니다.

profile
Frontend Engineer

0개의 댓글