[루디움 렉쳐] 이더리움 베이직_kingyoungdae 학습 내용 정리 (블록과 체인)

블록과 체인

블록은 블록 체인에 추가된 새로운 거래의 기록이다. 새로운 트랜잭션(기록)을 블록(장부)에 담는다고 표현할 수 있다. 각 블록에는 다른 블록과 구별할 수 있는 고유한 코드와 이전 블록의 해시가 포함되어 블록을 연결한다. 이렇게 서로 연결되어 위변조 할 수 없는 안전한 체인이 형성되는 것이다. 네트워크가 온라인 상태가 된 후 채굴 된 첫 번째 블록을 제네시스 블록(genesis block)이라 하고 이를 포함하여 함께 연결된 모든 블록들을 일컬어 블록 체인 이라고 부른다. 체인은 네트워크 내 모든 트랜잭션을 포함해 모든 계정의 잔고를 기록하는 장부, 즉 원장이라고 할 수 있다.

블록과 블록의 작동방식

이더리움 네트워크의 모든 참가자가 동기화 된 상태를 유지하고 정확한 트랜잭션 내역에 동의하도록 하기 위해, 트랜잭션을 블록에 담아 일괄처리 한다. 수십 또는 수백개의 트랜잭션이 한 번에 커밋되고, 합의되고,동기화 된다는 것을 의미한다. 또한 트랜잭션의 크기는 제각각이고, 블록은 트랜잭션의 수가 아니라 블록에 포함될 트랜잭션이 소비할 수 있는 최대 가스량에 의해 정해진다. 다시 말해, 블록 당 저장되는 데이터의 최대량은 정해져 있다.

출처 : https://ethereum.org/ko/developers/docs/blocks/

사용자가 트랜잭션을 요청하면 트랜잭션을 받은 노드들은 자신에게 설치된 클라이언트를 통해 유효성을 확인한다. 해당 트랜잭션이 유효하면 멤풀(Mempool, Memory pool)이란 보류중인 트랜잭션이 모인 공간에 추가되고 검증자들은 해당 트랜잭션들 중 수수료가 높은 것을 먼저 선택해 블록에 포함시킨다. 간단하게 트랜잭션과 블록 생성 과정을 알아보았다.

네트워크 상의 거래 내역을 보존하기 위해서 블록은 상위 블록에 대한 참조가 필요하게끔 정렬되어 결합한다고 앞서 언급했다. 그렇다면 블록은 어떤 방식으로 결합되는 것일까? 새로운 트랜잭션은 블록체인에서 나온 새로운 기록이라고 할 수 있다. 검증자들은 무작위로 트랜잭션을 블록에 담을 수 있는 권한을 부여받는데 이를 블록 제안자(proposer)라고 하고, 트랜잭션을 블록에 담아 공유하면 수많은 검증자(validator)들은 블록 안의 트랜잭션을 검증하고 새로운 블록을 기존의 블록에 추가하여 저장한다. 그 후 다음 블록을 생성할 새로운 검증자가 선택되어 새 블록을 생성한다. 정확한 블록 결합의 과정과 합의 프로세스는 현재 이더리움의 지분증명 프로토콜에 따라 지정된다.

블록의 구성

기본적으로 이더리움 블록은 아래와 같이 구성되어 있습니다.

  • slot: 블록이 속한 슬롯의 번호.
  • proposer_index: 블록을 제안한 검증자의 ID
  • parent_root: 이전 블록의 해시. 블록체인에서 각 블록이 연결되는 구조를 제공한다.
  • state_root: 이 블록의 상태 객체의 루트 해시. 블록에 반영된 전역 상태의 최신 버전을 나타낸다.
  • body: 아래의 여러 세부 필드를 포함하는 객체.

블록 바디의 구성 요소

  • randao_reveal: 다음 블록 제안자를 선택하는 데 사용되는 값.
  • eth1_data: 예치 계약에 대한 정보를 포함한다.
  • graffiti: 블록에 부여된 임의의 데이터로, 블록을 식별하거나 태그하는 데 사용된다.
  • proposer_slashings: 검증자에 벌금을 적용할 목록.
  • attester_slashings: 증인에 대한 벌금을 적용할 목록.
  • attestations: 현재 블록에 대한 모든 증명 목록. 각 증명은 여러 구성 요소를 포함한다.
    • aggregation_bits: 해당 증명에 참여한 검증자들의 목록.
    • data: 여러 하위 필드를 포함하는 컨테이너.
      • slot: 증명과 관련된 슬롯 번호.
      • index: 증명에 참여한 검증자의 인덱스.
      • beacon_block_root: 이 객체를 포함하는 비콘(Beacon)블록의 루트 해시값.
      • source: 최근 정당화된 체크포인트.
      • target: 최신 에포크(epoch)경계 블록.
    • signature: 모든 증명 검증자의 집계 서명
  • deposits: 예치 계약에 새로 추가된 예치 목록.
  • voluntary_exits: 네트워크를 나가는 검증자들의 목록.
  • sync_aggregate: 경량 클라이언트를 서비스하는 데 사용되는 검증자의 부분 집합.
  • execution_payload: 실행 클라이언트에서 전달된 트랜잭션 목록. 이는 글로벌 상태를 업데이트하는 데 사용된다.

실행 페이로드(execution_payload) 구성 요소
실행 페이로드는 두가지 요소, execution_payload_header와 execution_payload로 나뉜다. 블록 내에서 트랜잭션과 관련된 데이터를 처리하고 검증하는데 필요한 정보를 포함하며, 이를 통해 네트워크의 글로벌 상태를 업데이트 한다. 클라이언트는 실행 페이로드의 트랜잭션을 재실행하여 ‘state_root’와 일치하는지 확인함으로써 블록의 유효성을 검증한다.

  • execution_payload_header: 실행 데이터에 대한 중요한 요약 정보를 포함한다.
    • parent_hash: 부모 블록의 해시. 이전 블록과의 연결성을 제공한다.
    • fee_recipient: 트랜잭션 수수료를 받을 계정의 주소.
    • state_root: 이 블록에서 변경된 글로벌 상태의 루트 해시. 이 해시는 모든 클라이언트가 동일한 최신 상태를 유지할 수 있게 한다.
    • receipts_root: 트랜잭션 영수증 트리의 해시. 트랜잭션 처리 결과를 검증하는 데 사용된다.
    • logs_bloom: 이벤트 로그를 포함하는 데이터 구조. 특정 이벤트의 검색과 필터링에 사용된다.
    • prev_randao: 랜덤 검증자 선택에 사용된 값.
    • block_number: 현재 블록의 번호.
    • gas_limit: 블록에서 허용된 최대 가스 양.
    • gas_used: 실제로 사용된 가스 양.
    • timestamp: 블록이 생성된 시각.
    • extra_data: 추가적인 임의 데이터. 주로 블록의 부가적인 설명이나 식별 정보를 포함한다.
    • base_fee_per_gas: 기본 가스 요금 값.
    • block_hash: 실행 블록의 해시.
    • transactions_root: 페이로드의 트랜잭션의 루트 해시.
    • withdrawal_root: 페이로드의 인출에 대한 루트 해시.
  • execution_payload: 트랜잭션 및 인출 정보를 실제로 포함한다는 것을 제외하면 헤더와 동일하다.
    • parent_hash: 부모 블록의 해시.
    • fee_recipient: 트랜잭션 수수료를 받는 계정의 주소.
    • state_root: 이 블록에서 변경된 글로벌 상태의 루트 해시.
    • receipts_root: 트랜잭션 영수증 트리의 해시.
    • logs_bloom: 이벤트 로그를 포함하는 데이터 구조.
    • prev_randao: 랜덤 검증자 선택에 사용된 값.
    • block_number: 현재 블록의 번호.
    • gas_limit: 블록에서 허용된 최대 가스 양.
    • gas_used: 실제로 사용된 가스 양.
    • timestamp: 블록이 생성된 시각.
    • extra_data: 추가적인 임의 데이터.
    • base_fee_per_gas: 기본 가스 요금 값.
    • block_hash: 실행 블록의 해시.
    • transactions: 실행할 트랜잭션 목록. 이 목록은 블록에 포함된 모든 트랜잭션을 실행하여 글로벌 상태를 업데이트한다.
    • withdrawals: 인출 객체 목록. 아래의 요소를 포함한다.
      • address: 인출한 계정 주소입니다.
      • amount: 인출 금액입니다.
      • validatorIndex: 검증자 인덱스 값.
      • index: 인출 인덱스 값.

블록 시간(Block time)

블록 시간은 새로운 블록이 생성되는데 걸리는 시간을 말한다. 이더리움 네트워크에 ‘슬롯’이란 시간을 나타내는 단위가 있는데, 1슬롯은 12초를 나타내고 각 슬롯마다 한명의 검증자가 블록을 제안할 기회를 갖는다. 검증자가 오프라인 상태일 경우 슬롯에 블록이 생성되지 않을 수도 있지만 대부분 생성된다.

블록 크기(Block size)

블록 하나에 담을 수 있는 데이터의 양은 제한이 있다. 앞서 언급했듯이 블록 크기는 트랜잭션이 소비할 수 있는 가스의 양, 즉 가스 한도(Gas limit)로 정해지고 가스는 계산 자원의 양을 측정할 수 있는 단위이다. 가스 한도는 네트워크의 상태에 따라 증가하거나 감소할 수 있는데, 네트워크가 안정적일때 목표는 1500만 가스이다. 네트워크의 트랜잭션의 수요가 증가하면 최대 3000만 가스까지 증가할 수 있다. 가스 한도는 이전 블록 한도를 기준으로 최대 1/1024만큼 증감할 수 있다. 블록에 포함되는 모든 트랜잭션의 가스 소비량이 가스 한도를 초과해선 안된다. 이는 블록의 크기가 임의로 커지는 것을 막기 위함이다. 블록의 크기가 너무 커지면 다음 슬롯에 맞춰 처리하기 위해 더 많은 컴퓨팅 파워가 요구되는데 네트워크의 성능이 낮은 노드가 이를 처리하기 어려워지고, 이는 네트워크의 중앙화로 이어질 수 있다. 결론적으로 이를 통해 네트워크의 효율과 안정성을 유지할 수 있다.

느낀점

블록과 체인의 작동 방식에 대한 설명이 매우 명확하고 흥미로웠습니다. 블록이 서로 연결되어 위변조를 방지하는 구조와, 블록 생성 과정에서 검증자들이 어떻게 트랜잭션을 처리하는지에 대한 이해가 깊어졌습니다. 또한, 가스 한도를 통해 블록 크기를 조절하여 네트워크의 효율성과 안정성을 유지하는 방식이 이더리움의 뛰어난 설계임을 느꼈습니다.