Hari ini, pelanggan konsensus tidak boleh dengan mudah menyediakan keping data individu daripada BeaconState bersama-sama dengan bukti yang diperlukan untuk mengesahkan mereka. sistem Light Client Ethereum mendefinisikan beberapa laluan bukti, tetapi tidak ada cara universal atau standard bagi pelanggan untuk menghasilkan atau berkhidmat bukti ini. tidak realistis - negara untuk ialah sekitar , yang terlalu besar untuk menghantar melalui rangkaian dengan cepat dan meletakkan beban yang tidak perlu pada kedua-dua nod dan pengguna. spesifikasi juga memberi amaran bahawa titik akhir debug yang digunakan untuk mengambil keadaan penuh hanya bertujuan untuk diagnostik, bukan penggunaan dunia sebenar. BeaconPerkh Perbincangan 12.145.344 271 MB Cara yang lebih baik ialah menggunakan , yang membolehkan pembekal untuk menghantar hanya sebahagian yang sangat kecil, yang boleh disahkan daripada keadaan.Ini sangat berguna kerana kebanyakan saiz keadaan datang daripada validator (~232 MB) dan keseimbangan (~15 MB); sisa medan kira-kira ~24 MB.Jika pengguna hanya memerlukan satu medan kecil, ia membuang-buang untuk memuat turun keseluruhan 271 MB keadaan.Sebaliknya, bukti Merkle boleh menyampaikan hanya lembaran yang diminta ditambah laluan pengesahan - biasanya hanya beberapa kilobyte. Merkle proofs or multiproofs Oleh kerana ini, kami memerlukan cara yang umum dan standard untuk pelanggan untuk meminta Ini mengurangkan lebar band, mengurangkan beban CPU, dan menggantikan pelaksanaan tersebar dan tersuai hari ini (contohnya, Tindakan khas daripada ) daripada hanya data yang mereka perlukan, daripada Nimbus historical_summaries Kerja ini juga penting untuk masa depan Ethereum. SSZ menjadi lebih pusat kepada protokol: menggantikan RLP dengan SSZ, dan (juga dikenali sebagai (Dia akan Oleh itu, membina kaedah yang bersih, cekap dan standard untuk capaian data berasaskan bukti adalah langkah utama ke arah kemas kini protokol masa depan. Putih (EIP-7919) beam chain lean chain Leverage yang Proposed Solution: Introducing the SSZ Query Language (SSZ-QL) Penyelesaian yang disyorkan: Memperkenalkan bahasa pertanyaan SSZ (SSZ-QL) Idea SSZ-QL pada mulanya telah dicadangkan oleh Soalan utama beliau adalah mudah tetapi kuat: Kisah Kissling “What if we had a standard way to request SSZ field — together with a Merkle proof — directly from any consensus client?” any mana-mana Hari ini, pelanggan konsensus tidak menawarkan kaedah umum atau standard untuk meminta data SSZ tertentu dengan bukti. sesetengah penyelesaian ad-hoc wujud (contohnya, pertanyaan asas Nimbus yang digunakan oleh pengesahan ), tetapi tidak ada bahasa pertanyaan SSZ yang betul dan universal yang tersedia - dan mungkin tiada yang siap pada masa idea ini ditulis. Web3Sejarah Rancangan Etan menggambarkan apa yang bahasa query SSZ perlu membenarkan: Meminta sebarang subtree di dalam objek SSZ Memilih sama ada medan perlu diperluaskan sepenuhnya atau dikembalikan hanya sebagai hash_tree_root Penapisan (contohnya, mencari transaksi dengan akar tertentu) Menggunakan rujukan balik (contohnya, mendapatkan kuis pada indeks yang sama sebagai transaksi yang sesuai) Menentukan di mana bukti perlu diikat Menyokong keserasian ke hadapan supaya pelanggan boleh mengabaikan bidang masa depan yang tidak diketahui dengan selamat Jenis API ini boleh digunakan oleh kedua-dua pelanggan konsensus dan eksekusi. Dengan jenis SSZ yang bersesuaian ke hadapan (seperti yang Struktur permintaan dan tindak balas juga boleh dihasilkan secara automatik. Perkhidmatan EIP7495 Berdasarkan idea ini, , yang sedang membangunkan ini sebagai sebahagian daripada projek EPF mereka di prysm, adalah untuk menambah titik akhir API Beacon baru yang menyokong SSZ Query Language (SSZ-QL). Endpoint ini membolehkan pengguna mengambil data SSZ yang mereka perlukan - tidak lebih, tidak kurang - bersama dengan bukti Merkle yang mengesahkan ketepatannya. Versi awal akan menawarkan set ciri minimum tetapi praktikal, yang sudah meliputi kebanyakan kes penggunaan sebenar. (Specifikasi rancangan API tersedia untuk disemak semula.) the proposed solution by and Jun yang FERNANDO Jun yang FERNANDO Selain daripada versi minimum ini, mereka juga merancang untuk mencipta spesifikasi SSZ-QL yang lengkap. Versi yang diperluaskan ini akan menyokong ciri-ciri lanjutan seperti penapis, meminta julat data, dan memilih titik ancor tersuai, semua dengan bukti Merkle termasuk. Memahami indeks umum (GI) sebelum menyelam ke dalam SSZ-QL Dalam SSZ, setiap objek – termasuk keseluruhan Ia diwakili sebagai a . A ialah nombor yang secara unik mengidentifikasi di dalam pokok ini. BeaconState binary Merkle tree generalized index (GI) any node Syarat-syarat ini sangat mudah: Node akar mempunyai indeks umum:GI = 1 Untuk mana-mana nod dengan indeks i:anak kiri = 2*i,anak kanan = 2*i + 1 Oleh itu, pokok-pokok tersebut dijumlahkan sebagai berikut: GI:1 / \ GI:2 GI:3 / \ / \ GI:4 GI:5 GI:6 GI:7 ... Maklumat ini akan memudahkan pengesahan Merkle. jika anda tahu , anda tahu persis di mana ia duduk di dalam pokok dan hash bersaudara mana yang mesti dimasukkan untuk mengesahkan ia. generalized index of a leaf Example with Beacon State: 0 GenesisTime string 1 GenesisValidatorsRoot string 2 Slot string 3 Fork *Fork 4 LatestBlockHeader *BeaconBlockHeader 5 BlockRoots []string 6 StateRoots []string 7 HistoricalRoots []string 8 Eth1Data *Eth1Data 9 Eth1DataVotes []*Eth1Data 10 Eth1DepositIndex string 11 Validators []*Validator ← (p = 11) 12 Balances []string 13 RandaoMixes []string 14 Slashings []string 15 PreviousEpochAttestations []*pendingAttestation 16 CurrentEpochAttestations []*pedningAttestation 17 JustificationBits string 18 PreviousJustifiedCheckpoint *Checkpoint 19 CurrentJustifiedCheckpoint *Checkpoint 20 FinalizedCheckpoint *Checkpoint Terdapat 21 medan peringkat atas (diindeks 0..20). untuk meletakkan ini dalam pokok Merkle, SSZ pads mereka sehingga kuasa seterusnya dua (32). 32 daun → kedalaman = 5. Lapisan peringkat atas menduduki julat GI: 32 ... 63 Kami mengira GI untuk medan peringkat atas menggunakan: Formula : GI_top = 2^depth + field_index untuk , indeks medan = .validators 11 daripada : GI_validators = 2^5 + 11 = 32 + 11 = 43. Perkara ini ( ) ialah komitmen lembaran keseluruhan Di dalam dunia global pokok yang 43 validator’s subtree BeaconState Multi-Level Proof: Example With validators[42].withdrawal_credentials Sekarang, katakan kita mahu bukti untuk: BeaconState.validators[42].withdrawal_credentials Ini memerlukan : two levels of proof Prove that the entire validator’s subtree is included in the BeaconState root We already know: Top-level GI for validators = 43 Using GI 43, the consensus client collects the sibling hashes on the path from leaf 43 up to root (e.g., ). GI 43 → 21 → 10 → 5 → 2 → 1 This gives the proof: validators_root ---> BeaconState_root Prove that is inside the validator’s subtree validator[42].withdrawal_credentials Now treat the . validators list as its own Merkle tree Inside this subtree: Validator is the 42-nd element → it maps to some leaf index (e.g. chunk ) inside this subtree. 42 k Withdrawal credentials lives inside one of the 32-byte SSZ chunks of validator #42 (for example chunk — number doesn’t matter, just concept). k = 128 We now generate: leaf (withdrawal_credentials chunk) ---> validators_root by collecting sibling hashes inside the local validator-subtree. Final Combined Proof You end up with: 1. Local Level Proof Proves withdrawal_credentials --> validator_root 2. Top-level branch proof Proves validator_root --> BeaconState_root A verifier can now reconstruct the BeaconState root from only: the requested leaf the two lists of sibling nodes the known BeaconState root No full state download needed. ┌───────────────────────────────┐ │ BeaconState Root │ └───────────────────────────────┘ ▲ │ (Top-level Merkle Proof) │ Sibling hashes for GI = 43 │ ┌─────────────────────────────────────────┐ │ validators_root (GI = 43) │ └─────────────────────────────────────────┘ ▲ │ (Local Subtree Proof) │ Proof inside validators list │ for index = 42 │ ┌─────────────────────────────────────────────────────────┐ │ Validator[42] Subtree (list element #42) │ └─────────────────────────────────────────────────────────┘ ▲ │ (Field-level Merkle Proof) │ Sibling hashes inside the │ validator struct │ ┌──────────────────────────────────────────┐ │ validator[42].withdrawal_credentials │ ← requested field └──────────────────────────────────────────┘ Understanding SSZ Serialization Before Computing Generalized Indices Memahami serialisasi SSZ sebelum mengkomputerkan indeks generalis Untuk mengira yang betul Pertama, anda perlu memahami bagaimana SSH dan jenis data yang berbeza. Indeks-indeks umum tidak wujud secara berasingan - mereka berasal daripada , dan bentuk pokok bergantung sepenuhnya kepada bagaimana SSZ menafsirkan medan struktur Go yang mendasari. generalized index Serialisasi Merklise Bentuk pokok Merkle Dalam SSZ, setiap medan hanya boleh menjadi salah satu daripada dua kategori: Base Types (fixed-size values) , , , etc. These are straightforward — they always serialize into a fixed number of bytes. uint64 Bytes32 Bytes20 uint256 Composite Types (like BeaconState), (fixed length), (variable length), , And each of them is serialized in a slightly different way. Container Vector[T, N] List[T, N] Bitvector[N] Bitlist[N] To compute a for any field inside a state, the SSZ tree must first know . This is why the generated files include tags such as: generalized index (g-index) how that field is serialized *.pb.go ssz-size:"8192,32" → Vector ssz-max:"16" → List ssz-size:"?,32" → List of Vector Untuk mengira indeks umum untuk mana-mana medan, kita mesti terlebih dahulu memahami daripada objek : SSZ structure kawasan yang wujud, sama ada setiap medan ialah senarai atau vektor, Berapa banyak bahagian-bahagian yang ditempati oleh setiap bidang, dan bagaimana jenis-jenis nested perlu dilalui. Inilah yang tepatnya yang berfungsi di Prysm, yang terletak di AnalyzeObject encoding/ssz/query/analyzer.go // AnalyzeObject analyzes given object and returns its SSZ information. func AnalyzeObject(obj SSZObject) (*SszInfo, error) { value := reflect.ValueOf(obj) info, err := analyzeType(value, nil) if err != nil { return nil, fmt.Errorf("could not analyze type %s: %w", value.Type().Name(), err) } // Populate variable-length information using the actual value. err = PopulateVariableLengthInfo(info, value) if err != nil { return nil, fmt.Errorf("could not populate variable length info for type %s: %w", value.Type().Name(), err) } return info, nil } What analyzeType Does Apakah fungsi yang dan bilangan keluar A. Ia adalah a - Ia melakukan bergantung kepada nilai runtime sebenar, hanya pada jenis Go dan tag struktur. analyzeType examines a Go value using reflection what kind of SSZ type Tahap Analisis Tipe Bersih not Apabila anda memberikannya medan atau struktur, ia: Memeriksa jenis Go (uint, struct, slice, pointer, dan lain-lain) Membaca tag struktur berkaitan SSZ seperti ssz-size dan ssz-max Decides : whether this field is a basic SSZ type ( , , ) uint64 uint32 bool a Vector ( ) ssz-size:"N" a List ( ) ssz-max:"N" a Bitvector / Bitlist a Container (struct) Builds an that describes: SszInfo record the SSZ type (List, Vector, Container...) whether it is fixed-sized or variable-sized offsets of fields (for Containers) nested SSZ information for child fields Pikirkan tentang Sebagai fungsi yang dan menghasilkan a untuk jenis ini. analyzeType scans the type definition static SSZ layout blueprint What PopulateVariableLengthInfo Does manakala kajian yang , sesetengah objek SSZ tidak boleh digambarkan sepenuhnya tanpa . analyzeType type Nilai sebenar Contoh : Senarai ([]T) perlu tahu panjang semasa mereka Bidang-bidang kontena saiz yang berubah-ubah memerlukan kompensasi sebenar mereka Senarai yang dibina memerlukan saiz sebenar setiap elemen mengisi maklumat runtime yang hilang ini. PopulateVariableLengthInfo Ia : Lihat blueprint SszInfo yang dicipta oleh analyzeType Lihat kepada nilai sebenar objek yang telah berlalu Computes values that can only be known at runtime: length of Lists sizes of nested variable elements offsets of variable-sized fields inside Containers bitlist length from bytes Ia memproses segala Contohnya, Kontena dengan Senarai yang mengandungi struktur dengan Senarai semua akan diisi. recursively Pikirkan tentang Sebagai fungsi yang and fills in the real measurements based on the actual value you pass. PopulateVariableLengthInfo takes the blueprint from analyzeType Example: Mari kita menguji fungsi ini dengan struktur BeaconState yang lewat type BeaconState struct { state protoimpl.MessageState `protogen:"open.v1"` GenesisTime uint64 `protobuf:"varint,1001,opt,name=genesis_time,json=genesisTime,proto3" json:"genesis_time,omitempty"` GenesisValidatorsRoot []byte `protobuf:"bytes,1002,opt,name=genesis_validators_root,json=genesisValidatorsRoot,proto3" json:"genesis_validators_root,omitempty" ssz-size:"32"` Slot github_com_OffchainLabs_prysm_v7_consensus_types_primitives.Slot `protobuf:"varint,1003,opt,name=slot,proto3" json:"slot,omitempty" cast-type:"github.com/OffchainLabs/prysm/v7/consensus-types/primitives.Slot"` Fork *Fork `protobuf:"bytes,1004,opt,name=fork,proto3" json:"fork,omitempty"` LatestBlockHeader *BeaconBlockHeader `protobuf:"bytes,2001,opt,name=latest_block_header,json=latestBlockHeader,proto3" json:"latest_block_header,omitempty"` BlockRoots [][]byte `protobuf:"bytes,2002,rep,name=block_roots,json=blockRoots,proto3" json:"block_roots,omitempty" ssz-size:"8192,32"` StateRoots [][]byte `protobuf:"bytes,2003,rep,name=state_roots,json=stateRoots,proto3" json:"state_roots,omitempty" ssz-size:"8192,32"` HistoricalRoots [][]byte `protobuf:"bytes,2004,rep,name=historical_roots,json=historicalRoots,proto3" json:"historical_roots,omitempty" ssz-max:"16777216" ssz-size:"?,32"` Eth1Data *Eth1Data `protobuf:"bytes,3001,opt,name=eth1_data,json=eth1Data,proto3" json:"eth1_data,omitempty"` Eth1DataVotes []*Eth1Data `protobuf:"bytes,3002,rep,name=eth1_data_votes,json=eth1DataVotes,proto3" json:"eth1_data_votes,omitempty" ssz-max:"2048"` Eth1DepositIndex uint64 `protobuf:"varint,3003,opt,name=eth1_deposit_index,json=eth1DepositIndex,proto3" json:"eth1_deposit_index,omitempty"` Validators []*Validator `protobuf:"bytes,4001,rep,name=validators,proto3" json:"validators,omitempty" ssz-max:"1099511627776"` Balances []uint64 `protobuf:"varint,4002,rep,packed,name=balances,proto3" json:"balances,omitempty" ssz-max:"1099511627776"` RandaoMixes [][]byte `protobuf:"bytes,5001,rep,name=randao_mixes,json=randaoMixes,proto3" json:"randao_mixes,omitempty" ssz-size:"65536,32"` Slashings []uint64 `protobuf:"varint,6001,rep,packed,name=slashings,proto3" json:"slashings,omitempty" ssz-size:"8192"` PreviousEpochAttestations []*PendingAttestation `protobuf:"bytes,7001,rep,name=previous_epoch_attestations,json=previousEpochAttestations,proto3" json:"previous_epoch_attestations,omitempty" ssz-max:"4096"` CurrentEpochAttestations []*PendingAttestation `protobuf:"bytes,7002,rep,name=current_epoch_attestations,json=currentEpochAttestations,proto3" json:"current_epoch_attestations,omitempty" ssz-max:"4096"` JustificationBits github_com_OffchainLabs_go_bitfield.Bitvector4 `protobuf:"bytes,8001,opt,name=justification_bits,json=justificationBits,proto3" json:"justification_bits,omitempty" cast-type:"github.com/OffchainLabs/go-bitfield.Bitvector4" ssz-size:"1"` PreviousJustifiedCheckpoint *Checkpoint `protobuf:"bytes,8002,opt,name=previous_justified_checkpoint,json=previousJustifiedCheckpoint,proto3" json:"previous_justified_checkpoint,omitempty"` CurrentJustifiedCheckpoint *Checkpoint `protobuf:"bytes,8003,opt,name=current_justified_checkpoint,json=currentJustifiedCheckpoint,proto3" json:"current_justified_checkpoint,omitempty"` FinalizedCheckpoint *Checkpoint `protobuf:"bytes,8004,opt,name=finalized_checkpoint,json=finalizedCheckpoint,proto3" json:"finalized_checkpoint,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } package main import ( "fmt" "github.com/OffchainLabs/prysm/v7/encoding/ssz/query" eth "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1" ) func main() { v := &eth.BeaconState{} // Analyze it with Prysm’s existing SSZ analyzer info, _ := query.AnalyzeObject(v) fmt.Println(info.Print()) } Pengeluaran : BeaconState (Variable-size / size: 2687377) ├─ genesis_time (offset: 0) uint64 (Fixed-size / size: 8) ├─ genesis_validators_root (offset: 8) Bytes32 (Fixed-size / size: 32) ├─ slot (offset: 40) Slot (Fixed-size / size: 8) ├─ fork (offset: 48) Fork (Fixed-size / size: 16) │ ├─ previous_version (offset: 0) Bytes4 (Fixed-size / size: 4) │ ├─ current_version (offset: 4) Bytes4 (Fixed-size / size: 4) │ └─ epoch (offset: 8) Epoch (Fixed-size / size: 8) ├─ latest_block_header (offset: 64) BeaconBlockHeader (Fixed-size / size: 112) │ ├─ slot (offset: 0) Slot (Fixed-size / size: 8) │ ├─ proposer_index (offset: 8) ValidatorIndex (Fixed-size / size: 8) │ ├─ parent_root (offset: 16) Bytes32 (Fixed-size / size: 32) │ ├─ state_root (offset: 48) Bytes32 (Fixed-size / size: 32) │ └─ body_root (offset: 80) Bytes32 (Fixed-size / size: 32) ├─ block_roots (offset: 176) Vector[Bytes32, 8192] (Fixed-size / size: 262144) ├─ state_roots (offset: 262320) Vector[Bytes32, 8192] (Fixed-size / size: 262144) ├─ historical_roots (offset: 2687377) List[Bytes32, 16777216] (Variable-size / length: 0, size: 0) ├─ eth1_data (offset: 524468) Eth1Data (Fixed-size / size: 72) │ ├─ deposit_root (offset: 0) Bytes32 (Fixed-size / size: 32) │ ├─ deposit_count (offset: 32) uint64 (Fixed-size / size: 8) │ └─ block_hash (offset: 40) Bytes32 (Fixed-size / size: 32) ├─ eth1_data_votes (offset: 2687377) List[Eth1Data, 2048] (Variable-size / length: 0, size: 0) ├─ eth1_deposit_index (offset: 524544) uint64 (Fixed-size / size: 8) ├─ validators (offset: 2687377) List[Validator, 1099511627776] (Variable-size / length: 0, size: 0) ├─ balances (offset: 2687377) List[uint64, 1099511627776] (Variable-size / length: 0, size: 0) ├─ randao_mixes (offset: 524560) Vector[Bytes32, 65536] (Fixed-size / size: 2097152) ├─ slashings (offset: 2621712) Vector[uint64, 8192] (Fixed-size / size: 65536) ├─ previous_epoch_attestations (offset: 2687377) List[PendingAttestation, 4096] (Variable-size / length: 0, size: 0) ├─ current_epoch_attestations (offset: 2687377) List[PendingAttestation, 4096] (Variable-size / length: 0, size: 0) ├─ justification_bits (offset: 2687256) Bitvector[8] (Fixed-size / size: 1) ├─ previous_justified_checkpoint (offset: 2687257) Checkpoint (Fixed-size / size: 40) │ ├─ epoch (offset: 0) Epoch (Fixed-size / size: 8) │ └─ root (offset: 8) Bytes32 (Fixed-size / size: 32) ├─ current_justified_checkpoint (offset: 2687297) Checkpoint (Fixed-size / size: 40) │ ├─ epoch (offset: 0) Epoch (Fixed-size / size: 8) │ └─ root (offset: 8) Bytes32 (Fixed-size / size: 32) └─ finalized_checkpoint (offset: 2687337) Checkpoint (Fixed-size / size: 40) ├─ epoch (offset: 0) Epoch (Fixed-size / size: 8) └─ root (offset: 8) Bytes32 (Fixed-size / size: 32) Dalam kaedah analisis SSZ, yang ditunjukkan untuk setiap medan mewakili kedudukan byte yang tepat di mana medan itu bermula apabila seluruh struktur diserialisasi mengikut peraturan SSZ. , dikemas dengan ketat satu selepas yang lain, dan offset memberitahu anda di mana setiap bidang ini bermula dalam aliran byte yang dikemas itu. dan medan ialah 32-byte nilai saiz tetap, dan bajet seri bermula di kedudukan dalam SSZ-coded byte array. menunjukkan berapa banyak byte medan menyumbang kepada output serialis (32 byte dalam kes ini). Untuk jenis saiz tetap, saiz ditentukan terlebih dahulu, manakala untuk jenis saiz variabel, analis mengira saiz berdasarkan nilai sebenar. Bersama-sama, offset dan saiz menunjukkan dengan tepat bagaimana susunan SSZ disusun dalam memori apabila struktur disusun secara seri. offset fixed-size fields first root (offset: 8) Bytes32 (Fixed-size / size: 32) root 8 size Example: Finding the Merkle Leaf for a Field Using the Offset Contoh: Mencari lembaran Merkle untuk medan menggunakan offset Mari kita ambil medan sebenar daripada output SSZ Analyzer: ├─ fork (offset: 48) Fork (Fixed-size / size: 16) │ ├─ previous_version (offset: 0) Bytes4 (Fixed-size / size: 4) │ ├─ current_version (offset: 4) Bytes4 (Fixed-size / size: 4) │ └─ epoch (offset: 8) Epoch (Fixed-size / size: 8) We want to prove the field: fork.epoch Kawasan “fork” dalam bermula di dalam aliran byte seri. BeaconState offset 48 dalam , yang Lapangan bermula di (Berdasarkan permulaan daripada Fork) fork epoch offset 8 daripada : absolute_offset = base_offset_of_fork + offset_of_epoch_inside_fork absolute_offset = 48 + 8 = 56 bytes bermula pada bajet 56 daripada BeaconState yang sepenuhnya serialis. fork.epoch SSZ membahagikan serialisasi kepada : 32-byte chunks Chunk 0 → byte 0–31 Chunk 1 → byte 32–63 Chunk 2 → byte 64–95 … Sekarang cari chunk yang mengandungi byte : 56 chunk_index = floor(56 / 32) = 1 daripada : Lapisan yang mengandungi ialah Leaf / Chunk 1. fork.epoch is an Integra fork.epoch 8-byte Dalam bahagian 1 (byte 32–63) : local_offset = 56 - 32 = 24 So inside the 32-byte leaf, the bytes look like: [ 0 … 23 ] → unrelated fields [ 24 … 31 ] → fork.epoch (8 bytes) To prove this value, you: Langkah 1 – Ini Adalah Rujukan Anda When hashing up the tree, at each level: If chunk is a left child → record the right sibling hash. If chunk is a right child → record the left sibling hash. Teruskan sehingga anda mencapai akar Merkle atas. Hashing bersaudara yang dikumpulkan membentuk anda: ☀️ SSZ Merkle proof branch for fork.epoch Anyone can verify this by recomputing: hash_tree_root(leaf + all_siblings) == state_root Ini memperkenalkan dua titik akhir baru yang mendedahkan versi asal in Prysm: SSZ Query Language (SSZ-QL) /prysm/v1/beacon/states/{state_id}/query /prysm/v1/beacon/blocks/{block_id}/query Both endpoints follow the SSZ-QL endpoint specification and allow clients to request specific fields inside a BeaconState or BeaconBlock using a query string. The server returns the requested SSZ field encoded as raw SSZ bytes. For now, at the time of writing this, the feature supports only a single query per request, and the bendera diabaikan - PR sentiasa mengembalikan jawapan tanpa bukti Merkle. include_proof Struktur permintaan ialah: type SSZQueryRequest struct { Query string `json:"query"` IncludeProof bool `json:"include_proof,omitempty"` } Dan kedua-dua titik akhir mengembalikan jawapan yang dikodkan SSZ dalam bentuk ini: type SSZQueryResponse struct { state protoimpl.MessageState `protogen:"open.v1"` Root []byte `protobuf:"bytes,1,opt,name=root,proto3" json:"root,omitempty" ssz-size:"32"` Result []byte `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty" ssz-max:"1073741824"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } Untuk spesifikasi lengkap dan contoh, anda boleh merujuk kepada ini LINK dan maklumat daripada analis SSZ, dan bukannya menggunakan indeks umum. For now, the implementation locates the requested field using the computed offset size Untuk maklumat lanjut, anda boleh melihat kerja Jun Song – yang dijalankan bersama Fernando sebagai sebahagian daripada projek EPF mereka di prysm. For more information, you can check out ’s work — implemented together with as part of their EPF project in prysm. Jun Song Fernando Lagu Jun FERNANDO