අද වන විට, අනුමැතිය පාරිභෝගිකයන් පහසුවෙන් BeaconState සිට පෞද්ගලික දත්ත කොටස් සහ ඒවා තහවුරු කිරීමට අවශ්ය සාක්ෂි සපයන්නේ නැත.Ethereum හි Light Client පද්ධතිය සමහර සාක්ෂි මාර්ග සකස් කරයි, නමුත් පාරිභෝගිකයන් විසින් මෙම සාක්ෂි නිර්මාණය කිරීමට හෝ සේවය කිරීමට විශ්වීය හෝ ස්ථාවර ක්රමයක් නැත. එය සැබෑ නොවේ - රටට වටේ , එය ඉක්මනින් ජාලය හරහා යැවීමට විශාල වන අතර නඩත්තු සහ පරිශීලකයා දෙස අනවශ්ය ප්රමාණයට පත් කරයි.The specs even warns that the debug endpoints used for picking full states are meant only for diagnostics, not real-world use. Beaconකරණය තැපැල් 12,145,344 271 MB වඩා හොඳ විසඳුමක් තමයි භාවිතය. එය විශේෂයෙන් ප්රයෝජනවත් වන අතර, රාජ්ය ප්රමාණය බොහෝ විට විනිවිදකයින් (~232 MB) සහ විනිවිදකයින් (~15 MB) සිට පැමිණෙන අතර, ඉතිරි ක්ෂේත්රයේ ප්රමාණය ~24 MB පමණ වේ.විශේෂ වශයෙන්, පරිශීලකයාට එක් කුඩා ක්ෂේත්රයක් පමණක් අවශ්ය නම්, මුළු 271 MB රාජ්යයයයය බාගත කිරීම අහිමි වේ. Merkle proofs or multiproofs මෙම හේතුව නිසා, අපි පාරිභෝගිකයන් ඉල්ලීමට සාමාන්ය හා ස්ථාවර ක්රමයක් අවශ්ය එය තහවුරු කිරීම සඳහා අවශ්ය සාක්ෂි සහිතව.This reduces bandwidth, reduces CPU load, and replaces today's scattered and custom implementations (for example, විශේෂ ක් රියාකාරකම් ) අවශ් ය දත්ත පමණක්, Nimbus හි historical_summaries මෙම වැඩ Ethereum අනාගතය සඳහාත් වැදගත් වේ.SSZ ප්රොටෝලට් වඩාත් මධ්යම බවට පත් වේ: RLP වෙනුවට SSZ වෙනුවට RLP වෙනුවට RLP වෙනුවට SSZ වෙනුවට (එහෙත් කියනවා නම් Will එබැවින් සාක්ෂි මත පදනම්ව දත්ත ප්රවේශය සඳහා පිරිසිදු, ඵලදායී සහ සම්මත ක්රමයක් ගොඩනැගීම අනාගත ප්රොටෝලට් යාවත්කාලීන කිරීම සඳහා ප්රධාන පියවරක් වේ. කුසලාන (EIP-7919) beam chain lean chain ඵලදායී Proposed Solution: Introducing the SSZ Query Language (SSZ-QL) යෝජිත විසඳුම: SSZ Query Language (SSZ-QL) SSZ-QL හි අදහස මුලින්ම යෝජනා කලේ ඔහුගේ ප්රධාන ප් රශ්නය සරල නමුත් බලවත් විය: ඉන්ටන් Kissling “What if we had a standard way to request SSZ field — together with a Merkle proof — directly from any consensus client?” any ඕනෑම අද වන විට, අනුමැතිය පාරිභෝගිකයන් සාක්ෂි සහිතව විශේෂිත SSZ දත්ත ඉල්ලීම සඳහා සාමාන්ය හෝ ස්ථාවර ක්රමයක් ඉදිරිපත් නොකරයි. ), නමුත් නිවැරදි, විශ්වීය SSZ ප්රශ්න භාෂාව ලබා ගත නොහැක - සහ සමහර විට මෙම අදහසක් ලියන විට කිසිවක් සූදානම් නැත. Web3 සංකේත Etan ගේ යෝජනාව SSZ Query Language මගින් ලබා ගත හැකි දේ විස්තර කරයි: SSZ මාතෘකාව තුළ ඕනෑම subtree ඉල්ලීම ක්ෂේත් රයක් සම්පූර්ණයෙන්ම පුළුල් කළ යුතුද හෝ hash_tree_root ලෙස පමණක් ආපසු ලබා ගත යුතුද යන්න තෝරා ගැනීම ෆිල්ටර කිරීම (උදාහරණයක් ලෙස, නිශ්චිත මූලාශ්රය සහිත ව්යාපාරයක් සොයා ගැනීම) Back-references භාවිතා කිරීම (උදාහරණයක් ලෙස, ගැලපෙන ව්යාපාරයක් ලෙස එකම ඉංජිනේරු මත ප්රතික්ෂේප කිරීම) සාක්ෂි ඇන්කර් කළ යුත්තේ කොහේද යන්න නිශ්චිත කිරීම පරිශීලකයින් නොදන්නා අනාගත ක්ෂේත්ර ආරක්ෂිතව නොසලකා බැලිය හැක මෙම වර්ගයේ API එකතුව සහ ක්රියාත්මක කිරීමේ සේවාදායකයන් විසින් භාවිතා කළ හැකිය.Forward-compatible SSZ types (like those from ප්රශ්න සහ ප්රතිචාර ව්යුහයන් පවා ස්වයංක්රීයව නිර්මාණය කළ හැකිය. ඇපල්-7495 මෙම අදහස මත පදනම්ව, EPF ව්යාපෘතියේ කොටසක් ලෙස මෙම ව්යාපෘතිය සංවර්ධනය කරන අය, SSZ Query Language (SSZ-QL) සහාය දක්වන නව Beacon API අවසාන ස්ථානය එකතු කිරීමයි. මෙම අවසාන ස්ථානය භාවිතා කරන්නන් අවශ්ය වන SSZ දත්ත නිවැරදිව ලබා ගත හැකිය - කිසිවක් වඩා, කිසිවක් අඩු නොවේ - එය නිවැරදි බව තහවුරු වන Merkle සාක්ෂි සමග. the proposed solution by and ජූනි ෆ්රැන්ඩෝ ජූනි ෆ්රැන්ඩෝ මෙම අවම අනුවාදයට අමතරව, සම්පූර්ණ SSZ-QL විශේෂාංගයක් නිර්මාණය කිරීමට සැලසුම් කර ඇත. මෙම පුළුල් කරන ලද අනුවාදයේ ප්රතිරෝධය, දත්ත ප්රමාණ ඉල්ලීම සහ Custom Anchor Points තෝරා ගැනීම වැනි උසස් හැකියාවන් සහාය වේ.Merkel සාක්ෂි ඇතුළත් කර ඇත. SSZ-QL වෙත පිවිසීමට පෙර Generalized Indexes (GI) තේරුම් ගැනීම SSZ හි, සෑම ඔක්කොම ඔක්කොම - මුළු එය A ලෙස නියෝජනය කරයි. . A එකිනෙකා හඳුනාගත හැකි සංඛ් යාව මේ ගහේ ඇතුළේ BeaconState binary Merkle tree generalized index (GI) any node නීති ඉතා සරල ය: Root node එකේ generalized index :GI = 1 අංකය i:left child = 2*i, right child = 2*i + 1 එබැවින් මුළු ගස අංකය වන්නේ: GI:1 / \ GI:2 GI:3 / \ / \ GI:4 GI:5 GI:6 GI:7 ... මෙම අංකය Merkle සාක්ෂි පහසු කරයි. , ඔබ හරියටම දන්නේ එය ගස තුළ වාඩි වී ඇති ස්ථානය සහ එය තහවුරු කිරීම සඳහා සහෝදර හෙෂයන් ඇතුළත් කළ යුතුය. 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 ඉහළ මට්ටමේ ක්ෂේත් ර 21 ක් ඇත (0.20). මේ ක්ෂේත් රයන් Merkle ගස් වෙත ස්ථාපනය කිරීම සඳහා, SSZ ඔවුන් ඊළඟ බලශක්ති දෙකක් දක්වා පඩිපෙට් කරයි (32). 32 අකුරු → ගැඹුර = 5. ඉහළ මට්ටමේ ලුහුබැඳියන් GI ප්රමාණය රැස් කරයි: 32 ... 63 අපි ඉහළ මට්ටමේ ක්ෂේත්ර සඳහා GI ගණනය කරන්නේ: Formula එක : GI_top = 2^depth + field_index සඳහා field index = ක්ෂේත් රය .validators 11 ඒ අනුව : GI_validators = 2^5 + 11 = 32 + 11 = 43. මෙය ( ) is the leaf commitment of the entire inside the global ගස් 43 validator’s subtree BeaconState Multi-Level Proof: Example With validators[42].withdrawal_credentials දැන්, අපි සඳහා සාක්ෂි අවශ්ය බව අනුමාන කරමු: BeaconState.validators[42].withdrawal_credentials මෙය අවශ් ය : 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 Generalized Indices පරිගණකයට පෙර SSZ Serialization තේරුම් ගැනීම නිවැරදිව ගණනය කිරීම ඔබ මුලින්ම තේරුම් ගත යුතු වන්නේ SSZ සහ විවිධ දත්ත වර්ග Generalized indexes don’t exist in isolation – they are derived from the , සහ ගස් හැඩය සම්පූර්ණයෙන්ම SSZ පදනම Go struct ක්ෂේත්ර පරිවර්තනය කරන්නේ කෙසේද යන්න මත රඳා පවතී. generalized index සැරසිලි වෙළෙඳපොළ Merkle ගහගේ හැඩය SSZ තුළ, සෑම ක්ෂේත්රයක්ම ප්රවර්ග දෙකෙන් එකක් පමණක් විය හැක: 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 ඕනෑම ක්ෂේත් රයක් සඳහා පොදු ඉංජිනේරු ගණනය කිරීම සඳහා, අපි මුලින්ම තේරුම් ගත යුතුය මාතෘකාව ගැන : SSZ structure මොන ක්ෂේත් රයක් තියෙනවද, සෑම ක්ෂේත් රයක්ම ලැයිස්තුවක් හෝ වික්රමයක් වන අතර, සෑම ක්ෂේත් රයකම කොපමණ කොටස් රැඳී සිටිනවද, කොයිතරම් අලංකාර වුණත් අලංකාර ගමනක් ගත යුතුයි. මේ තමයි හරියටම මොනවද මේ ක්රියාකාරීත්වය Prysm හි, ස්ථාපිත වේ 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 ඒකයි මේ Function දර්ශන එළියට ඒකයි, ඒකයි A - එය කරයි එය සැබෑ runtime අගය මත රඳා පවතී, Go වර්ගය සහ struct ටැග් මත පමණි. analyzeType examines a Go value using reflection what kind of SSZ type පිරිසිදු වර්ගය විශ්ලේෂණය පියවර not ඔබ එය ක්ෂේත්රයක් හෝ struct ලබා දෙන්නේ නම්, එය: Go වර්ග (uint, struct, slice, pointer ආදිය) පරීක්ෂා කරයි ssz-size සහ ssz-max වැනි SSZ සම්බන්ධ struktur tags කියවන්න 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 හිතන්න එවැනි කාර්යයක් ලෙස නිෂ්පාදනය A මේ මනුස්සයාට analyzeType scans the type definition static SSZ layout blueprint What PopulateVariableLengthInfo Does කොහොමත් අධ්යයනය The , some SSZ objects cannot be fully described without the . analyzeType වර්ගය සැබෑ වටිනාකම උදාහරණ : ලැයිස්තු ([]T) ඔවුන්ගේ වර්තමාන දිග දැන ගැනීමට අවශ්ය ප් රමාණවත් ප් රමාණවත් ප් රමාණවත් ප් රමාණවත් ප් රමාණවත් ප් රමාණවත් ප් රමාණවත් ප් රමාණය සෑම ලැයිස්තුවක්ම සෑම අංගයකම සැබෑ ප් රමාණය අවශ් ය වේ. මේ අතුරුදහන් වන තොරතුරු සම්පූර්ණ කරන්න. PopulateVariableLengthInfo එය : analyzeType විසින් නිර්මාණය කරන ලද SszInfo blueprint බලන්න අතහැර ගිය අංගයේ සැබෑ වටිනාකම දෙස බැලීම 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 සෑම දෙයක්ම පාවිච්චි කරනවා උදාහරණයක් ලෙස, ලැයිස්තු සහිත ව්යුහයන් ඇති ලැයිස්තු සහිත ලැයිස්තු සහිත ලැයිස්තු සහිත ලැයිස්තු සහිත කොන්ත් රාත් සියල්ල සම්පූර්ණ කරනු ඇත. recursively හිතන්න එවැනි කාර්යයක් ලෙස ඔබ පාවිච්චි කරන සැබෑ වටිනාකම මත පදනම්ව සැබෑ ප්රමාණයන් සම්පූර්ණ කරයි. PopulateVariableLengthInfo takes the blueprint from analyzeType Example: අපි මෙම ක්රියාකාරිත්වය පරීක්ෂා කරමු BeaconState struct සමග 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()) } ප් රතිඵල : 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) SSZ analyzer වලදී, shown for each field represents the exact byte position where that field begins when the entire struct is serialized according to SSZ rules. SSZ serialization lays out all , tightly packed one after another, and the offset tells you where each of these fields starts within that packed byte stream. For example, in the line ක්ෂේත් රය එය 32-බයිට් ස්ථාවර ප්රමාණයේ අගය වන අතර, එහි serialized bytes ස්ථානයේ ආරම්භ වේ. SSZ-coded byte array - සංකේතය ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමාණයේ ප්රමා 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 උදාහරණයක්: Offset භාවිතයෙන් ක්ෂේත්රයක් සඳහා Merkle පිටුව සොයා ගැනීම SSZ Analyzer Output හි සැබෑ ක්ෂේත් රයක් ගන්න: ├─ 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) අපි මේ ක්ෂේත් රයට සාක්ෂි දෙනවා: fork.epoch “Fork” ක්ෂේත් රයේ starts at Serial Byte Stream එකෙන්. BeaconState offset 48 ඇතුලේ The ක්ෂේත් රයේ ආරම්භය (සංස්කරණයේ ආරම්භය ගැන කතා කරමු) fork epoch offset 8 ඒ අනුව : absolute_offset = base_offset_of_fork + offset_of_epoch_inside_fork absolute_offset = 48 + 8 = 56 bytes begins at byte 56 of the full serialized BeaconState. fork.epoch SSZ සාරාංශය බෙදා හැරීම : 32-byte chunks Chunk 0 → බයිට් 0–31 Chunk 1 → bytes 32–63 Chunk 2 → බයිට් 64–95 … දැන් හොයන්න මොන chunk contains byte : 56 chunk_index = floor(56 / 32) = 1 ඒ අනුව : ඇතුළත් කරන ලද්දේ මාලිගාව / Chunk 1 fork.epoch එකයි සම්පූර්ණ fork.epoch 8-byte කොටුව 1 තුළ (බයිට් 32-63): local_offset = 56 - 32 = 24 එබැවින් 32-බයිට් පිටුව ඇතුළත, බයිට් පෙනේ: [ 0 … 23 ] → unrelated fields [ 24 … 31 ] → fork.epoch (8 bytes) To prove this value, you: අංක 1 - මේක ඔයාගේ පින්තූරයක්. 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. ඔබ ඉහළම Merkle root වෙත ළඟා වන තුරු දිගටම කරන්න. සොහොයුරන් හෙක්සි එකතු කර ඔබේ: SSZ Merkle proof branch for fork.epoch Anyone can verify this by recomputing: hash_tree_root(leaf + all_siblings) == state_root මෙම ප්රතිඵල ප්රතිඵල ප්රතිඵල ප්රතිඵල ප්රතිඵල ප්රතිඵල ප්රතිඵල ප්රතිඵල ප්රතිඵල ප්රතිඵල ප් රසිද්ධියේ : SSZ Query Language (SSZ-QL) /prysm/v1/beacon/states/{state_id}/query /prysm/v1/beacon/blocks/{block_id}/query මෙම අවසාන අංග දෙකම SSZ-QL අවසාන අංග විශේෂාංගය අනුගමනය කරන අතර, BeaconState හෝ BeaconBlock ඇතුළේ විශේෂිත ක්ෂේත්ර ඉල්ලීම සඳහා ප්රශ්න සංකේතයක් භාවිතා කිරීමට පාරිභෝගිකයින්ට ඉඩ සලසයි. සේවාදායකයා ඉල්ලන SSZ ක්ෂේත් රයක් අමු SSZ බයිට් ලෙස සකස් කරයි. ප් රවෘත්ති සෑම විටම Merkle සාක්ෂි නොමැතිව ප්රතිචාර ලබා දෙයි. include_proof ඉල්ලුම ව්යුහය වන්නේ: type SSZQueryRequest struct { Query string `json:"query"` IncludeProof bool `json:"include_proof,omitempty"` } මෙම ප්රතිඵල දෙකම SSZ කේතය සහිත ප්රතිඵලයක් ලබා දෙයි: 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 } සම්පූර්ණ විශේෂාංග සහ උදාහරණ සඳහා, ඔබ මෙහි සඳහන් කළ හැකිය ලින්ක් සහ SSZ විශ්ලේෂකයාගේ තොරතුරු, පොදු ඉංජිනේරු භාවිතා කිරීම වෙනුවට. For now, the implementation locates the requested field using the computed offset size වැඩි විස්තර සඳහා, ඔබට Jun Song ගේ වැඩ බලන්න පුළුවන් - ඔවුන්ගේ EPF ව්යාපෘතියේ කොටසක් ලෙස Fernando සමඟ අනුගමනය කරන ලද prysm. For more information, you can check out ’s work — implemented together with as part of their EPF project in prysm. Jun Song Fernando ජෝන් සින්දු ෆ්රැන්ඩෝ