타입별 인코딩/디코딩
Header
인코딩 (EncodeRLP)
> 리스트 시작
> 헤더 1바이트 (0x80 + 0x20) + 부모 해시 32바이트
> 헤더 1바이트 (0x80 + 0x20) + 엉클 해시 32바이트
> 헤더 1바이트 (0x80 + 0x14) + 코인베이스 20바이트
> 헤더 1바이트 (0x80 + 0x20) + 상태 루트 32바이트
> 헤더 1바이트 (0x80 + 0x20) + 트랜잭션 루트 32바이트
> 헤더 1바이트 (0x80 + 0x20) + 영수증 루트 32바이트
> 헤더 3바이트 (0xb8 + 0x02 /0x01/0x00) + 로그 블룸 256바이트
> 난이도 동적 처리 (big.Int)
> 블록 번호 동적 처리 (big.Int)
> 가스 한도 동적 처리 (uint64)
> 가스 사용량 동적 처리 (uint64)
> 타임스탬프 동적 처리 (uint64)
> 추가 데이터 동적 처리 ([]byte)
> 헤더 1바이트 (0x80 + 0x20) + 혼합 다이제스트 32바이트
> 헤더 1바이트 (0x80 + 0x08) + 논스 8바이트
> (이하 필드 중 하나라도 nil이 아니면) 기본 비용 동적 처리 (big.Int) || 0x80
> (이하 필드 중 하나라도 nil이 아니면) 헤더 1바이트 (0x80 + 0x20) + 출금 해시 32바이트 || 0x80
> (이하 필드 중 하나라도 nil이 아니면) 블롭 가스 사용량 동적 처리 (uint64) || 0x80
> (이하 필드 중 하나라도 nil이 아니면) 블롭 가스 초과량 동적 처리 (uint64) || 0x80
> (nil이 아니면) 헤더 1바이트 (0x80 + 0x20) + 부모 비콘 루트 32바이트 || 0x80
> 리스트 끝
Log
인코딩 (EncodeRLP)
> 리스트1 시작
> 헤더 1바이트 (0x80 + 0x20) + 주소 20바이트
> 리스트2 시작
> 헤더 1바이트 (0x80 + 0x20) + 토픽 0 32바이트
...
> 헤더 1바이트 (0x80 + 0x20) + 토픽 n-1 32바이트
> 리스트2 끝
> 데이터 동적 처리 ([]byte)
> 리스트1 끝
StateAccount
인코딩 (EncodeRLP)
> 리스트 시작
> 논스 동적 처리 (uint64)
> 잔액 동적 처리 (big.Int)
> 헤더 1바이트 (0x80 + 0x20) + 상태 루트 32바이트
> 헤더 1바이트 (0x80 + 0x20) + 코드 해시 32바이트
> 리스트 끝
Receipt
type receiptRLP struct {
PostStateOrStatus []byte
CumulativeGasUsed uint64
Bloom Bloom
Logs []*Log
}
인코딩 (EncodeRLP)
Legacy
> 리스트1 시작
> 영수증 상태 1 바이트 (failed: 0x80, success: 0x01)
> 누적 가스 사용량 동적 처리 (uint64)
> 헤더 3바이트 (0xb8 + 0x02 /0x01/0x00) + 로그 블룸 256바이트
> 리스트2 시작
> 로그0 동적 처리
...
> 로그n-1 동적 처리
> 리스트2 끝
> 리스트1 끝
EIP-2718
> 리스트1 시작
> 트랜잭션 유형 1 바이트
> 리스트2 시작
> 영수증 상태 1 바이트 (failed: 0x80, success: 0x01)
> 누적 가스 사용량 동적 처리 (uint64)
> 헤더 3바이트 (0xb8 + 0x02 /0x01/0x00) + 로그 블룸 256바이트
> 리스트3 시작
> 로그0 동적 처리
...
> 로그n-1 동적 처리
> 리스트3 끝
> 리스트2 끝
> 리스트1 끝
Transaction
Legacy
panic!!
Access List
> 리스트1 시작
> 체인 ID 동적 처리 (big.Int)
> 헤더 1바이트 (0x80 + 바이트 길이) + uint64 논스를 바이트로 인코딩
> 가스 비용 동적 처리 (big.Int)
> 헤더 1바이트 (0x80 + 바이트 길이) + 가스량을 바이트로 인코딩
> 헤더 1바이트 (0x80 + 0x14) + 수신자 20바이트
> 이더 금액 동적 처리 (big.Int)
> 데이터 동적 처리 ([]byte)
> 리스트2 시작: 접근 목록
> 헤더 1바이트 (0x80 + 0x14) + 접근 목록 주소1 20바이트
> 리스트3 시작: 접근 목록 저장 위치
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치1 32바이트
...
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치n-1 32바이트
> 리스트3 끝
...
> 헤더 1바이트 (0x80 + 0x14) + 접근 목록 주소n 20바이트
> 리스트m+2 시작: 접근 목록 저장 위치
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치1 32바이트
...
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치n-1 32바이트
> 리스트m+2 끝
> 리스트2 끝
> V 동적 처리 (big.Int)
> R 동적 처리 (big.Int)
> S 동적 처리 (big.Int)
> 리스트1 끝
Dynamic Fee
> 리스트1 시작
> 체인 ID 동적 처리 (big.Int)
> 헤더 1바이트 (0x80 + 바이트 길이) + uint64 논스를 바이트로 인코딩
> 가스 팁 캡 동적 처리 (big.Int)
> 가스 비용 캡 동적 처리 (big.Int)
> 헤더 1바이트 (0x80 + 바이트 길이) + 가스량을 바이트로 인코딩
> 헤더 1바이트 (0x80 + 0x14) + 수신자 20바이트
> 이더 금액 동적 처리 (big.Int)
> 데이터 동적 처리 ([]byte)
> 리스트2 시작: 접근 목록
> 헤더 1바이트 (0x80 + 0x14) + 접근 목록 주소1 20바이트
> 리스트3 시작: 접근 목록 저장 위치
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치1 32바이트
...
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치n-1 32바이트
> 리스트3 끝
...
> 헤더 1바이트 (0x80 + 0x14) + 접근 목록 주소n 20바이트
> 리스트3 시작: 접근 목록 저장 위치
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치1 32바이트
...
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치n-1 32바이트
> 리스트3 끝
> 리스트2 끝
> V 동적 처리 (big.Int)
> R 동적 처리 (big.Int)
> S 동적 처리 (big.Int)
> 리스트1 끝
Blob
type blobTxWithBlobs struct {
BlobTx *BlobTx
Blobs []kzg4844.Blob
Commitments []kzg4844.Commitment
Proofs []kzg4844.Proof
}
> 리스트1 시작
> 체인 ID 동적 처리 (big.Int)
> 헤더 1바이트 (0x80 + 바이트 길이) + uint64 논스를 바이트로 인코딩
> 가스 팁 캡 동적 처리 (big.Int)
> 가스 비용 캡 동적 처리 (big.Int)
> 헤더 1바이트 (0x80 + 바이트 길이) + 가스량을 바이트로 인코딩
> 헤더 1바이트 (0x80 + 0x14) + 수신자 20바이트
> 이더 금액 동적 처리 (big.Int)
> 데이터 동적 처리 ([]byte)
> 리스트2 시작: 접근 목록
> 헤더 1바이트 (0x80 + 0x14) + 접근 목록 주소1 20바이트
> 리스트3 시작: 접근 목록 저장 위치
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치1 32바이트
...
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치n-1 32바이트
> 리스트3 끝
...
> 헤더 1바이트 (0x80 + 0x14) + 접근 목록 주소n 20바이트
> 리스트3 시작: 접근 목록 저장 위치
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치1 32바이트
...
> 헤더 1바이트 (0x80 + 0x20) + 저장 위치n-1 32바이트
> 리스트3 끝
> 리스트2 끝
> 블롭 비용 캡 동적 처리 (uint256.Int)
> 리스트4 시작: 블룸 해시
> 헤더 1바이트 (0x80 + 0x20) + 블룸 해시1 32바이트
...
> 헤더 1바이트 (0x80 + 0x20) + 블룸 해시n-1 32바이트
> 리스트4 끝
> V 동적 처리 (big.Int)
> R 동적 처리 (big.Int)
> S 동적 처리 (big.Int)
(optional - 사이드카가 nil이 아닌 경우)
> 리스트5 시작: 블롭
> 헤더 4바이트 (0xb8 + 0x03 /0x02/0x00/0x00) + 블롭 131072바이트
...
> 헤더 4바이트 (0xb8 + 0x03 /0x02/0x00/0x00) + 블롭 131072바이트
> 리스트5 끝
> 리스트6 시작: 커밋먼트
> 헤더 1바이트 (0x80 + 0x30) + 커밋먼트1 48바이트
...
> 헤더 1바이트 (0x80 + 0x30) + 커밋먼트n-1 48바이트
> 리스트6 끝
> 리스트7 시작: 프루프
> 헤더 1바이트 (0x80 + 0x30) + 프루프1 48바이트
...
> 헤더 1바이트 (0x80 + 0x30) + 프루프n-1 48바이트
> 리스트7 끝
> 리스트1 끝
블롭을 사용하면 블록의 크기가 굉장히 커질 수도 있을 것 같은데 무슨 용도이고 어떻게 사용하는지 궁금하다. 덴쿤 업그레이드에 대해 더 알아봐야겠다.
Withdrawal
인코딩 (EncodeRLP)
> 리스트 시작
> 헤더 1바이트 (0x80 + 바이트 길이) + uint64 인덱스를 바이트로 인코딩
> 헤더 1바이트 (0x80 + 바이트 길이) + uint64 검증자 인덱스를 바이트로 인코딩
> 헤더 1바이트 (0x80 + 0x14) + 출금 주소 20바이트
> 헤더 1바이트 (0x80 + 바이트 길이) + uint64 출금 금액을 바이트로 인코딩
> 리스트 끝
Block
type extblock struct {
Header *Header
Txs []*Transaction
Uncles []*Header
Withdrawals []*Withdrawal `rlp:"optional"`
}
인코딩 (EncodeRLP)
> 리스트1 시작
> 헤더 인코딩
> 리스트2 시작
> 트랜잭션 인코딩
...
> 트랜잭션 인코딩
> 리스트2 끝
> 리스트3 시작
> 엉클 인코딩
...
> 엉클 인코딩
> 리스트3 끝
(optional)
> 리스트4 시작
> 출금 인코딩
...
> 출금 인코딩
> 리스트4 끝
> 리스트1 끝