블록은 이전블록의 해시(prevHash라고 부르도록 하겠다.)와 트랜잭션의 묶음이라고 생각할 수 있다. 해시는 블록의 데이터를 통해 계산되기 때문에 체인의 형태로 구성될 수 있다. 만약, 블록이 생성된 이후에 블록의 데이터를 변경하게 되면, 해당 블록의 블록해시(block hash)가 바뀌고, 이는 이후 생성된 다른 블록들에 영향을 주어 모든 검증자들이 알아차릴 수 있기 때문에, 다음 블록이 모두 무효화되어 임의 변조를 막을 수 있다.
네트워크의 모든 참가자들이 동기화된(Syncronized) 상태(State)를 유지하고, 모든 트랜잭션에 동의를 하기 쉽게 하기 위해 다수의 트랜잭션들을 한 개의 블록으로 묶어서 Commit, agree, Syncronize를 한 번에 처리한다.
모든 블록들이 적절하게 검증을 받을 수 있도록, 네트워크는 참여자들에게 검증을 할 수 있는 충분한 시간을 부여한다. 트랜잭션은 초당 수십~수백개씩 발생할 수 있지만, 블록은 12초에 한 번 이더리움에서 생성되고 commite된다.
즉, 블록이 없다면, 모든 validator(트랜잭션(혹은 블록)을 검증하는 객체)는 매 초 모든 트랜잭션을 검증해야하며, 네트워크 상태에 따라 트랜잭션이 누락되는 경우에도 이를 검증하고, 블록을 네트워크에 추가해야하기 때문에, 블록을 사용할 때에 비해 Fork의 수가 수없이 많아지게 될 것이다.
(이정도면 블록이 있는 이유에 대해 충분히 알아본 것 같다…!)
블록의 작동 방식
transaction history를 보존하기 위해 블록은 상위 블록에 대한 참조를 가지고있어야 하며(prevHash에 대한 정보가 기록되어야 함), 블록 내에 있는 트랜잭션 또한 엄밀한 과정을 거쳐 블록에 정렬된다.
→ 추후에 더 알아볼 예정
PoS시스템에서, 네트워크에서 무작위로 선택된 검증자(PoS에서는, Proposer라고 부른다.)가 블록을 빌드하면, 이를 전체 네트워크에 Broadcast하게 되고, 합의의 과정 이후에 모든 노드는 이 블록을 블록체인의 끝에 추가하고 새로운 Proposer가 선출되어 다음 블록이 생성되는 과정을 통해 블록 추가해 대한 commitment와 consensus 프로세스를 명시하고 있다.
블록의 구조
slot 블록이 속한 슬롯
proposer_index | Proposer의 ID |
parent_root | prevHash |
state_root | state root hash |
body | 블록 데이터를 담고있는 객체 (바로 아래에서 설명) |
Body
randao_reveal 다음 block의 Proposer를 선택하기 위한 값(RANDAO seed)
eth1_data | deposit contract에 대한 정보 |
graffiti | 블록 태그를 위한 임의의 데이터 |
proposer_slashings | slash당할 validator의 리스트 |
attester_slashings | slash당할 attestor의 리스트 |
attestations | 이 블록에 대한 attestation 리스트 (바로 아래에서 설명) |
deposits | list of new deposits to the deposit contract |
voluntary_exits | 네트워크를 떠난 validator 리스트 |
sync_aggregate | light client에게 serve하는 validator subset |
execution_payload | execution client에서부터 넘어온 정보(트랜잭션 데이터 등) (아래에서 설명) |
Attestations
→ list of attestations
aggregation_bits 어느 validator가 이 attesttation에 참여했는지에 대한 목록
data | a container with multiple subfields (아래에서 설명) |
signature | 모든 attester들의 aggregate signature |
- data (in attestation)slot attestation이 실행된 slot
index validator의 ID beacon_block_root 이 object를 포함하는 비콘블록의 루트해시 source the last justified checkpoint target the latest epoch boundary block
Execution Payload header
parent_hash parent block의 hash
fee_recipient | 트랜잭션 수수료를 받는 주소 |
state_root | 이 블록으로 인한 state 변화를 적용한 global state의 root hash |
receipts_root | tx_receipt trie의 root hash |
logs_bloom | 이벤트로그를 포함하는 데이터 구조 |
prev_randao | random validator selection에 사용된 value (RANDAO seed) |
block_number | 블록 번호 |
gas_limit | 이 블록에 allow된 최대 gas |
gas_used | 이 블록에서 사용된 실제 가스 |
timestamp | block time |
extra_data | arbitrary additional data as raw bytes |
base_fee_per_gas | base fee value |
block_hash | Hash of execution block |
transactions_root | 트랜잭션들의 root hash |
withdrawal_root | withdrawal 데이터의 root hash |
Execution payload
parent_hash parent block의 hash
fee_recipient | 트랜잭션 수수료를 받는 주소 |
state_root | 이 블록으로 인한 state 변화를 적용한 global state의 root hash |
receipts_root | tx_receipt trie의 root hash |
logs_bloom | 이벤트로그를 포함하는 데이터 구조 |
prev_randao | random validator selection에 사용된 value (RANDAO seed) |
block_number | 블록 번호 |
gas_limit | 이 블록에 allow된 최대 gas |
gas_used | 이 블록에서 사용된 실제 가스 |
timestamp | block time |
extra_data | arbitrary additional data as raw bytes |
base_fee_per_gas | base fee value |
block_hash | Hash of execution block |
transactions | 실행될 트랜잭션들의 리스트 |
withdrawals | withdrawal 객체의 리스트 |
- withdrawalsaddress withdraw한 객체의 주소
amount withdraw한 ETH총량 index withdrawal index value validatorIndex validator index value - 스테이킹된 이더를 인출하는것과 관련된 데이터 필드
Blocktime
블록타임(Blocktime)은 블록을 나누는 시간 단위. 이더리움에서는 12초 단위로 시간이 쪼개지며, 이를 slot(슬롯)이라는 시간 단위로 사용한다. 각 slot에서, 랜덤한 프로세스를 거쳐(RANDAO) single validator가 선출되어 블록을 propose한다. 모든 validator가 온라인 상태이고 문제없이 작동한다고 가정했을 때의 blocktime이 12초가 된다. 그러나, 종종 validator가 오프라인상태라면, 해당 검증자의 슬롯은 비워질 수 있다.
Blocksize
블록은 블록 사이즈에 의해 나눠지기도 한다. (Blocktime에서는 한 블록이 몇 초에 한 번 생성되는지를 이야기했다면, 이 말은 한 블록의 사이즈가 얼마나 되는냐는 말이다.) 각 블록의 일반적인 크기는 1500만 gas이며, 네트워크 상태에 따라 증가, 감소가 가능하여 최대 3000만 gas까지 늘어날 수 있다.
Blocksize가 늘어나는 매커니즘
블록의 크기는 한번에 확 증가하는 것이 아닌, 점진적으로 증가/감소하는 방식을 가지고 있다. 그 증가/감소 비율을 최대 $\frac{1}{1024}$의 비율만큼 늘어날 수 있는 것인데, 예를 들어 현재 블록의 크기가 1500만 gas라면, 다음 블록의 최대 크기는 $15,000,000 + (15,000,000/1024==14,648)=15,014,648$ 만큼의 크기를 가질 수 있게 된다는 말이며, 이러한 블록 크기 증가가 여러번 반복되어 최대 30,000,000 gas 크기까지 도달할 수 있다는 말이다.
결과적으로, validator는 합의를 통해 블록의 gas limit을 변경할 수 있으며, 블록의 모든 트랜잭션의 gas 소비량이 블록의 gas limit보다 작을 수 있도록 이를 조절하여야 한다. 블록의 사이즈가 임의대로 커질 수 있다면, 성능이 떨어지는 Full node는 공간 및 속도 요구사항을 충족시키지 못하여 네트워크의 속도를 따라잡을 수 없을 것이다. 블록이 클수록 다음 슬롯에 맞춰 처리하는 데 필요한 컴퓨팅 성능을 더 많이 요구하기 떄문에, 이는 적절히 조절되어야 할 것이다.
'web3 > web3 research' 카테고리의 다른 글
Virtuals Protocol 1편 (0) | 2025.01.03 |
---|---|
Gasper(Casper + LMD GHOST)에 대해 공부해보자! (2) | 2024.07.15 |
[Bitcoin] 블록체인 기술공부 / 비트코인 백서 공부 (5. 네트워크) (0) | 2024.04.09 |
[Bitcoin] 블록체인 기술공부 / 비트코인 백서 공부 (3. 타임스탬프) / 이중지불 문제 (0) | 2024.04.07 |
[Bitcoin] 블록체인 기술공부 / 비트코인 백서 공부 (2. 거래) / 트랜잭션(Transaction) (1) | 2024.04.07 |