Nykyään konsensus-asiakkaat eivät voi helposti tarjota yksittäisiä tietoja BeaconStateista sekä todisteita, joita tarvitaan niiden todentamiseen. Ethereumin Light Client -järjestelmä määrittelee joitakin todisteiden polkuja, mutta asiakkaille ei ole yleistä tai vakiomuotoista tapaa tuottaa tai palvella näitä todisteita. ei ole realistista - valtio on on ympärillä , joka on liian suuri lähettämään verkkoon nopeasti ja aiheuttaa tarpeetonta kuormitusta sekä solmulle että käyttäjälle. spec jopa varoittaa, että täyden tilan hankkimiseen käytettävät vianmäärityspäätteet on tarkoitettu vain diagnostiikkaan, ei todelliseen käyttöön. Beacon mukaan Vapaaehtoinen 12,145,344 271 MB Parempi ratkaisu on käyttää Tämä on erityisen hyödyllistä, koska suurin osa tilan koosta tulee validoijista (~232 MB) ja tasapainoista (~15 MB); loput kentät ovat noin ~24 MB. Jos käyttäjä tarvitsee vain yhden pienen kentän, koko 271 MB: n tilan lataaminen on tuhlaavaa. Merkle proofs or multiproofs Tästä syystä tarvitsemme yleisen ja standardoidun tavan, jolla asiakkaat voivat pyytää Tämä vähentää kaistanleveyttä, vähentää prosessorin kuormitusta ja korvaa nykyiset hajanaiset ja mukautetut toteutukset (esim. Erityinen käsittely ) on Vain tarvittavat tiedot, Nimbuksen historical_summaries Tämä työ on tärkeää myös Ethereumin tulevaisuudelle. SSZ on yhä keskeisempi protokolla: ehdottaa RLP: n korvaamista SSZ: llä ja tulevan (kutsutaan myös nimellä tahto Näin ollen puhtaan, tehokkaan ja vakiomenetelmän rakentaminen todistepohjaiselle tietojen saatavuudelle on keskeinen askel kohti tulevia protokollan päivityksiä. Pähkinä (EIP-7919) beam chain lean chain Levittäminen Proposed Solution: Introducing the SSZ Query Language (SSZ-QL) Ehdotettu ratkaisu: SSZ Query Language (SSZ-QL) käyttöönotto SSZ-QL:n idea esitettiin alun perin Hänen tärkein kysymyksensä oli yksinkertainen, mutta voimakas: Pääosat Kissling “What if we had a standard way to request SSZ field — together with a Merkle proof — directly from any consensus client?” any Mikä tahansa Nykyään konsensus-asiakkaat eivät tarjoa yleistä tai standardoitua menetelmää pyytää tiettyjä SSZ-tietoja todisteilla. ), mutta ei ole olemassa asianmukaista, yleismaailmallista SSZ-kyselykieltä saatavilla - ja ehkä mitään valmis, kun tämä ajatus kirjoitettiin. WEB3 allekirjoittaja Etanin ehdotuksessa kuvataan, mitä SSZ Query -kielen pitäisi sallia: SSZ-objektin sisällä olevan alapuun pyytäminen Valitse, laajennetaanko kenttää kokonaan vai palautetaanko se vain hash_tree_root-kenttänä Suodatus (esimerkiksi transaktioiden löytäminen tietyllä juurella) Takaisinviittausten käyttäminen (esim. saat kuitin samasta indeksistä kuin vastaava transaktio) Määritä, mihin todistusaineistoa olisi kiinnitettävä Tuki tulevaisuuden yhteensopivuudelle, jotta asiakkaat voivat ohittaa tuntemattomat tulevat kentät turvallisesti Tämäntyyppisiä API-sovelluksia voivat käyttää sekä konsensus- että täytäntöönpanokäyttäjät.Edelleen yhteensopivilla SSZ-tyypeillä (kuten Pyyntö- ja vastausrakenteet voidaan jopa luoda automaattisesti. Vapaaehtoinen 7495 Tämän idean pohjalta, , jotka kehittävät tätä osana EPF-hankettaan prysm: ssä, on lisätä uusi Beacon API -päätepiste, joka tukee SSZ Query Language (SSZ-QL). Tämän päätepisteen avulla käyttäjät voivat hakea tarkalleen tarvitsemansa SSZ-tiedot - ei enempää, ei vähempää - yhdessä Merkle-todistuksen kanssa, joka tarkistaa sen oikeellisuuden. the proposed solution by and Junia FernandoMuokkaa Junia FernandoMuokkaa Tämän vähäisen version lisäksi suunnitelmissa on myös luoda täydellinen SSZ-QL-eritelmä. Tämä laajennettu versio tukee kehittyneitä ominaisuuksia, kuten suodatusta, tietojen pyytämistä ja mukautettujen ankkuripisteiden valitsemista, kaikki Merkle-todisteet mukaan lukien. Ymmärtää yleistettyjä indeksejä (GI) ennen sukellusta SSZ-QL: hen SSZ:ssä jokainen objekti – mukaan lukien koko Se on edustettuna a . A on vain numero, joka yksilöi Tämän puun sisällä. BeaconState binary Merkle tree generalized index (GI) any node Säännöt ovat hyvin yksinkertaisia: Root node on yleistetty indeksi:GI = 1 Mikä tahansa solmu, jossa indeksi i:vasen lapsi = 2*i, oikea lapsi = 2*i + 1 Koko puu on siis numeroitu näin: GI:1 / \ GI:2 GI:3 / \ / \ GI:4 GI:5 GI:6 GI:7 ... Tämä numerointi tekee Merkle-todisteista helppoja. , tiedät tarkalleen, missä se istuu puussa ja mitkä sisarukset on sisällytettävä sen todentamiseen. 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 On 21 ylimmän tason kenttiä (indeksoitu 0..20). Jos haluat sijoittaa nämä Merkle-puuhun, SSZ laittaa ne seuraavaan voimaan kaksi (32). 32 lehdet → syvyys = 5. Korkean tason lehdet miehittävät GI-alueen: 32 ... 63 Laskemme ylimmän tason kentän GI: n käyttämällä: Tässä kaava: GI_top = 2^depth + field_index puolesta , field index = .validators 11 Näin siis: GI_validators = 2^5 + 11 = 32 + 11 = 43. Tähän mennessä ( ) on koko ryhmän sitoutuminen Globaalin sisällä Puun kanssa. 43 validator’s subtree BeaconState Multi-Level Proof: Example With validators[42].withdrawal_credentials Oletetaan, että haluamme todisteita: BeaconState.validators[42].withdrawal_credentials This requires : 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 SSZ: n serialisoinnin ymmärtäminen ennen yleistettyjen indeksien laskemista Lasketaan oikea Ensinnäkin sinun on ymmärrettävä, miten SSZ ja Erilaisia tietotyyppejä Yleisiä indeksejä ei ole olemassa erillään – ne ovat peräisin , ja puun muoto riippuu täysin siitä, miten SSZ tulkitsee taustalla olevia Go struct -kenttiä. generalized index sarjakuvat Merkkiä Merkle-puun muoto SSZ:ssä jokainen kenttä voi olla vain yksi kahdesta kategoriasta: 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 Jotta voidaan laskea yleistetty indeksi mihin tahansa kenttään, meidän on ensin ymmärrettävä of the object: SSZ structure Mitkä alueet ovat olemassa, whether each field is a List or Vector, kuinka monta ruutua kukin kenttä miehittää, ja miten nestemäisiä tyyppejä tulisi ylittää. Tämä on juuri sitä, mitä Toiminto toimii Prysmissä, joka sijaitsee 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 Se on toiminto, joka Numerot ulos Se on, se on a - Se tekee riippuu todellisista suoritusajan arvoista, vain Go-tyypistä ja struktur-tunnisteista. analyzeType examines a Go value using reflection what kind of SSZ type Puhdas tyyppianalyysivaihe not Kun annat sille kentän tai rakenteen, se: Tarkistaa Go-tyypin (uint, struct, slice, pointer jne.) Lukee SSZ:hen liittyviä struktur-tunnisteita, kuten ssz-size ja 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 Ajattele Toiminto, joka ja tuottaa a tälle tyypille analyzeType scans the type definition static SSZ layout blueprint What PopulateVariableLengthInfo Does Vaikka Tutkimukset The , some SSZ objects cannot be fully described without the . analyzeType tyyppi Todellinen arvo Esimerkkejä tästä: Luettelot ([]T) tarvitsevat nykyisen pituutensa Vaihtelevan kokoiset konttikentät tarvitsevat todellisen kompensoinnin Nestettyjen luetteloiden on oltava kunkin elementin todellisen koon Täytä tämä puuttuva runtime-tieto. PopulateVariableLengthInfo It: Katso analyzeTypen luoma SszInfo-suunnitelma Näyttää kuluneen kohteen todellisen arvon 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 Se käsittelee kaiken — Esimerkiksi säiliö, jossa on luettelo, joka sisältää luetteloita sisältäviä rakenteita, täytetään kaikki. recursively Ajattele Toiminto, joka ja täyttää todelliset mittaukset siirtämäsi todellisen arvon perusteella. PopulateVariableLengthInfo takes the blueprint from analyzeType Example: Testaa tämä toiminto kulkevalla BeaconState-rakenteella 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()) } Tuotantoa : 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-analysaattorin tulostuksessa on jokaiselle kentälle näytetty edustaa täsmällistä byte-asemaa, jossa kenttä alkaa, kun koko struktur on serialisoitu SSZ-sääntöjen mukaisesti. , tiukasti pakattu yksi toisensa jälkeen, ja offset kertoo, mistä kukin näistä kentistä alkaa kyseisen pakatun byte-virran sisällä. ja kenttä on 32-byteinen kiinteä koko-arvo, ja sen sarjakuvat alkavat sijainnista SSZ-koodattu byte-array, jossa on osoittaa, kuinka monta baittia kenttä edistää sarjatuotantoa (32 baittia tässä tapauksessa). Kiinteän koon tyyppien osalta koko on ennalta määritetty, kun taas muuttujan koon tyyppien osalta analysaattori laskee koon todellisen arvon perusteella. Yhdessä kompensointi ja koko osoittavat tarkalleen, miten SSZ-asettelu on järjestetty muistiin, kun rakenne sarjataan. 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 Example: Finding the Merkle Leaf for a Field Using the Offset Otetaan todellinen kenttä 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) Haluamme todistaa kentän: fork.epoch ”Fork” kenttä aloittaa Serioituneen byte-virran avulla BeaconState offset 48 Sisällä Se on Kenttä alkaa (relative to the start of Fork). fork epoch offset 8 Näin siis: absolute_offset = base_offset_of_fork + offset_of_epoch_inside_fork absolute_offset = 48 + 8 = 56 bytes aloitetaan täydellä serialisoidulla BeaconState 56 -byteillä. fork.epoch SSZ jakaa serialisoinnin : 32-byte chunks Chunk 0 → bytes 0–31 Chunk 1 → bytejä 32–63 Chunk 2 → bytejä 64–95 … Nyt selvitetään, mikä kappale sisältää bytejä : 56 chunk_index = floor(56 / 32) = 1 Näin siis: Lehti, joka sisältää Leaf ja Chunk 1 fork.epoch Se on integroitua fork.epoch 8-byte Osan 1 sisällä (bytejä 32–63): local_offset = 56 - 32 = 24 Joten 32-byte-lehden sisällä bytit näyttävät tältä: [ 0 … 23 ] → unrelated fields [ 24 … 31 ] → fork.epoch (8 bytes) To prove this value, you: 1. Tämä on sinun lehdesi. 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. Jatka, kunnes saavutat Merkle-juuren. Kerätyt sisarukset muodostavat sinut: Tää SSZ Merkle proof branch for fork.epoch Anyone can verify this by recomputing: hash_tree_root(leaf + all_siblings) == state_root Tämä tuo kaksi uutta päätepistettä, jotka paljastavat alkuperäisen version Käytössä Prysm: SSZ Query Language (SSZ-QL) /prysm/v1/beacon/states/{state_id}/query /prysm/v1/beacon/blocks/{block_id}/query Molemmat päätepisteet noudattavat SSZ-QL-päätepisteen eritelmää ja antavat asiakkaille mahdollisuuden pyytää tietyt kentät BeaconStaten tai BeaconBlockin sisällä kyselylomakkeella. Palvelin palauttaa pyydetyn SSZ-kentän, joka on koodattu raaka-SSZ-byteinä. lippu jätetään huomiotta – PR palauttaa aina vastauksia ilman Merkle-todisteita. include_proof Pyynnön rakenne on: type SSZQueryRequest struct { Query string `json:"query"` IncludeProof bool `json:"include_proof,omitempty"` } Ja molemmat päätepisteet palauttavat tämän lomakkeen SSZ-koodatun vastauksen: 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 } For the full specification and examples, you can refer to this linkki ja tietoja SSZ-analysaattorista yleisen indeksin sijaan. For now, the implementation locates the requested field using the computed offset size Lisätietoja saat Jun Songin työstä, joka toteutettiin yhdessä Fernando Fernandoin kanssa osana EPF-hanketta prysmissa. For more information, you can check out ’s work — implemented together with as part of their EPF project in prysm. Jun Song Fernando Jun laulu FernandoMuokkaa