SSZ 란?
SSZ 는 비콘 체인에서 사용하는 직렬화 방법으로 Merklization 을 하기 위한 데이터 정렬 작업이다.
실행 레이어에서 RLP 직렬화 작업이 이루어졌다면, 합의 레이어에서는 SSZ 로 직렬화 작업이 이루어진다.
그러면 직렬화란 무엇인가?
데이터 구조를 저장 또는 다른 노드와 데이터 통신할 경우, 파싱할 수 있는 형태로 만들기 위해서 변환하는 작업을 말한다.
예를 들어 참조형 데이터를 통신하는 경우, 메모리 주소에 있는 값을 참조하게 되는데
이때, 데이터를 받은 노드의 메모리 주소에는 다른 값이 존재할 수 있기 때문에
참조형 데이터의 주소값에 대한 데이터를 값 타입 데이터로 변환하는 작업을 거쳐야 한다.
이더리움에서의 직렬화는 unsigned int 와 boolean 의 기본 타입 변수로 변환하는 것이다.
SSZ 의 offset 과 바이트 스트림 형태
위 타입의 변수는 고정 길이로 little-endian 바이트로 변환하는 작업만 하면 되지만
Struct 타입과 같은 가변 길이의 데이터는 offset 이 적용된 값으로 처리된다.
아래는 Struct -> unsigned int 로 offset 을 적용한 직렬화 예시이다.
struct Dummy {
number1: u64,
number2: u64,
vector: Vec<u8>,
number3: u64
}
dummy = Dummy {
number1: 37,
number2: 55,
vector: vec![1, 2, 3, 4],
number3: 22,
}
serialized = ssz.serialized(dummy)
serialized 에 담기는 값은 다음과 같다.
[37, 0, 0, 0, 55, 0, 0, 0, 16, 0, 0, 0, 22, 0, 0, 0, 1, 2, 3, 4]
이때, 벡터 위치에는 offset 값이 들어가고 벡터 값은 number 3 의 값 뒤에 위치한다.
여기서, 16의 의미는 벡터에 대한 값이 어느 위치에서 시작하는지 나타내는 값이다!!
(벡터값 1, 2, 3, 4 가 인덱스 16 에서 시작하므로 해당 값을 넣어준 것이며,
가변 길이 타입의 실제 값은 직렬화 데이터 끝에 있는 힙에 저장된다.)
그리고 number 1 변수를 little-endian 바이트로 인코딩한 것은 실제로 32비트의 값을 가지지만,
예시에서는 u64 변수와 벡터 변수의 위치 관계를 명시하기 위해서[37, 0, 0, 0, ...] 의 4비트 자리로 표현하였다!
실제 인코딩된 바이트 스트림 형태는 다음과 같다.
[
10100101000000000000000000000000 # little-endian encoding of `number1`
10110111000000000000000000000000 # little-endian encoding of `number2`.
10010000000000000000000000000000 # The "offset" that indicates where the value of `vector` starts (little-endian 16).
10010110000000000000000000000000 # little-endian encoding of `number3`.
10000001100000101000001110000100 # The actual value of the `bytes` field.
]
Merklization
SSZ 직렬화 과정을 거치면 머클 루트 계산 가능하다!
위에서 계산한 SSZ 값에 대한 머클 루트를 계산하는데
이때, 각 leaf 에 대한 일반화 지수에 대한 계산 식은 다음과 같다. (결국에는 노드 인덱스)
2 ** 요소의 depth + 해당 열에서 요소의 index
MultiProof
Merklization 는 proof (아마 트랜잭션 결과에 대한 proof 말하는 듯?) 루트값에 대한 검증이 가능하다.
예를 들어 아래와 같은 트리 형태인 경우,
9번 값을 검증하기 위해 먼저, 해시(8, 9) 와 해시(4) 가 같은지 확인해야 하고
해당 값에 5를 해시하고(=> 해시 2) 또, 해당 값에 3을 해시하여 (=> 해시 루트 1)
1번 인덱스의 해시 루트 값을 생성하는 식이다.
따라서, 이 과정에서 데이터가 잘못되었을 경우, 루트값이 바뀌므로 다중 증명 검증이 가능하다.
위 직렬화는 노드의 트랜잭션 처리를 위한 개념이지만, 데이터가 어떻게 직렬화된 것인지 알아보는 것은
곧 인코딩이 어떻게 처리되었는지 이해하는 것이기 때문에 필요한 개념이라고 생각한다.
각 네트워크의 주소 유효성 검사, 니모닉 유효성 검사를 무지성 처리하기 전에
어떤 인코딩 방식으로 데이터가 처리되었는지 확인해봐야겠다~!~!
참고문서링크
https://ethereum.org/en/developers/docs/data-structures-and-encoding/ssz/
'이더리움' 카테고리의 다른 글
23.03.12 EIP-1559 가스비 메커니즘 (0) | 2023.03.13 |
---|---|
22.01.05 이더리움 주소 체계 (0) | 2022.01.05 |
21.09.15 이더리움 2.0 [정리 중!] (0) | 2021.09.16 |
21.05.27 이더리움에 대한 첫 관심 (1) | 2021.05.28 |