diff --git a/ethereum/Cargo.lock b/ethereum/Cargo.lock index 0ae5bc98..bf1c6db0 100644 --- a/ethereum/Cargo.lock +++ b/ethereum/Cargo.lock @@ -1434,6 +1434,8 @@ dependencies = [ "anyhow", "bls12_381 0.8.0", "ethereum-types", + "ethereum_ssz", + "ethereum_ssz_derive", "ethers-core", "getset", "hex", @@ -1506,6 +1508,18 @@ dependencies = [ "smallvec", ] +[[package]] +name = "ethereum_ssz_derive" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eccd5378ec34a07edd3d9b48088cbc63309d0367d14ba10b0cdb1d1791080ea" +dependencies = [ + "darling 0.13.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ethers" version = "2.0.14" diff --git a/ethereum/Cargo.toml b/ethereum/Cargo.toml index b1de0104..e945d0a4 100644 --- a/ethereum/Cargo.toml +++ b/ethereum/Cargo.toml @@ -12,6 +12,8 @@ repository = "https://github.com/lurk-lab/zk-light-clients" anyhow = "1.0.86" clap = "4.5.8" env_logger = "0.11.3" +ethereum_ssz = "0.5.4" +ethereum_ssz_derive = "0.5.4" ethereum-types = "0.14.1" ethers-core = "2.0.14" glob = "0.3.1" diff --git a/ethereum/core/Cargo.toml b/ethereum/core/Cargo.toml index da39ba10..2b86c447 100644 --- a/ethereum/core/Cargo.toml +++ b/ethereum/core/Cargo.toml @@ -18,6 +18,8 @@ thiserror = { workspace = true } tiny-keccak = { workspace = true, features = ["keccak"] } [dev-dependencies] +ethereum_ssz_derive = { workspace = true } +ethereum_ssz = { workspace = true } ethereum-types = { workspace = true } ssz_types = { workspace = true, features = ["arbitrary"] } tree_hash = { workspace = true } diff --git a/ethereum/core/src/crypto/sig.rs b/ethereum/core/src/crypto/sig.rs index 5b5c6f68..b7c0f486 100644 --- a/ethereum/core/src/crypto/sig.rs +++ b/ethereum/core/src/crypto/sig.rs @@ -356,7 +356,7 @@ mod test { fn test_ssz_serde_sync_aggregate() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/SyncAggregateDeneb.ssz"); + .join("../test-assets/committee-change/SyncAggregateDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/core/src/merkle/storage_proofs.rs b/ethereum/core/src/merkle/storage_proofs.rs index 4e30bec4..483e6a7f 100644 --- a/ethereum/core/src/merkle/storage_proofs.rs +++ b/ethereum/core/src/merkle/storage_proofs.rs @@ -9,16 +9,26 @@ //! //! This module only handles inclusion proofs from the EIP1186. -use crate::crypto::hash::{keccak256_hash, HashValue}; +use crate::crypto::error::CryptoError; +use crate::crypto::hash::{keccak256_hash, HashValue, HASH_LENGTH}; +use crate::deserialization_error; use crate::merkle::error::MerkleError; use crate::merkle::utils::rlp::{decode_list, paths_match, shared_prefix_length, skip_length}; use crate::merkle::utils::{get_nibble, rlp::rlp_encode_account}; use crate::types::error::TypesError; -use crate::types::{Address, Bytes32}; +use crate::types::utils::{ + extract_fixed_bytes, extract_u32, ssz_decode_list_bytes, ssz_encode_list_bytes, + OFFSET_BYTE_LENGTH, +}; +use crate::types::{Address, Bytes32, ADDRESS_BYTES_LEN}; use ethers_core::abi::AbiEncode; use ethers_core::types::EIP1186ProofResponse; use ethers_core::utils::rlp::encode; +/// Bse byte length for the SSZ serialized `EIP1186Proof`. +pub const EIP1186_PROOF_BASE_BYTE_LENGTH: usize = + OFFSET_BYTE_LENGTH * 3 + ADDRESS_BYTES_LEN + HASH_LENGTH; + /// Data structure the data received from the `eth_getProof` RPC call. #[derive(Debug, Clone, PartialEq, Eq)] pub struct EIP1186Proof { @@ -93,8 +103,146 @@ impl EIP1186Proof { Ok(true) } + + pub fn to_ssz_bytes(&self) -> Vec { + let mut final_bytes = vec![]; + + // Serialize encoded account + final_bytes.extend_from_slice(&(EIP1186_PROOF_BASE_BYTE_LENGTH as u32).to_le_bytes()); + let encoded_account_bytes = &self.encoded_account; + + // Serialize address + final_bytes.extend_from_slice(&self.address); + + // Serialize storage hash + final_bytes.extend_from_slice(self.storage_hash.as_ref()); + + // Account proof serialization + let account_proof_offset = EIP1186_PROOF_BASE_BYTE_LENGTH + encoded_account_bytes.len(); + final_bytes.extend_from_slice(&(account_proof_offset as u32).to_le_bytes()); + + let account_proof_bytes = ssz_encode_list_bytes(&self.account_proof); + + // Storage proof serialization + let storage_proof_offset = account_proof_offset + account_proof_bytes.len(); + final_bytes.extend_from_slice(&(storage_proof_offset as u32).to_le_bytes()); + + let proof_as_list_bytes = self + .storage_proof + .iter() + .map(|proof| proof.to_ssz_bytes()) + .collect::>(); + let storage_proof_bytes = ssz_encode_list_bytes(&proof_as_list_bytes); + + // Extend final bytes + final_bytes.extend_from_slice(encoded_account_bytes); + final_bytes.extend_from_slice(&account_proof_bytes); + final_bytes.extend_from_slice(&storage_proof_bytes); + + final_bytes + } + + pub fn from_ssz_bytes(bytes: &[u8]) -> Result { + let cursor = 0; + + // Retrieve encoded account offset + let (cursor, account_offset) = extract_u32("EIP1186Proof", bytes, cursor)?; + + // Retrieve address bytes + let (cursor, address) = + extract_fixed_bytes::("EIP1186Proof", bytes, cursor)?; + + // Retrieve storage hash bytes + let (cursor, storage_hash) = + extract_fixed_bytes::("EIP1186Proof", bytes, cursor)?; + + // Retrieve account proof offset + let (cursor, account_proof_offset) = extract_u32("EIP1186Proof", bytes, cursor)?; + + // Retrieve storage proof offset + let (cursor, storage_proof_offset) = extract_u32("EIP1186Proof", bytes, cursor)?; + + // Retrieve encoded account + if cursor != account_offset as usize { + return Err(deserialization_error!( + "EIP1186Proof", + "Invalid offset for encoded account" + )); + } + let encoded_account = bytes + .get(cursor..account_proof_offset as usize) + .ok_or_else(|| TypesError::OutOfBounds { + structure: "EIP1186Proof".into(), + offset: account_proof_offset as usize, + length: bytes.len(), + })? + .to_vec(); + + // Retrieve account proof + let cursor = cursor + encoded_account.len(); + if cursor != account_proof_offset as usize { + return Err(deserialization_error!( + "EIP1186Proof", + "Invalid offset for account proof" + )); + } + let account_proof_bytes = bytes + .get(cursor..storage_proof_offset as usize) + .ok_or_else(|| TypesError::OutOfBounds { + structure: "EIP1186Proof".into(), + offset: storage_proof_offset as usize, + length: bytes.len(), + })?; + let account_proof = ssz_decode_list_bytes(account_proof_bytes)?; + + // Retrieve storage proof + let cursor = cursor + account_proof_bytes.len(); + if cursor != storage_proof_offset as usize { + return Err(deserialization_error!( + "EIP1186Proof", + "Invalid offset for storage proof" + )); + } + let storage_proof_bytes = bytes.get(cursor..).ok_or_else(|| TypesError::OutOfBounds { + structure: "EIP1186Proof".into(), + offset: cursor, + length: bytes.len(), + })?; + let storage_proof = ssz_decode_list_bytes(storage_proof_bytes)? + .iter() + .map(|v| StorageProof::from_ssz_bytes(v)) + .collect::, _>>()?; + + Ok(Self { + encoded_account, + address, + storage_hash: HashValue::new(storage_hash), + account_proof, + storage_proof, + }) + } + + /// Computes a hash for the EIP1186 proof based on the account and storage keys used + /// to query the data. + /// + /// # Returns + /// + /// A `HashValue` representing the hash of the EIP1186 proof. + pub fn key_hash(&self) -> Result { + let mut message = vec![]; + + message.extend_from_slice(&self.address); + for storage_proof in &self.storage_proof { + message.extend_from_slice(&storage_proof.key); + } + + keccak256_hash(&message) + } } +/// Offset for the key in a SSZ serialized `StorageProof`. +pub const STORAGE_PROOF_KEY_OFFSET: usize = OFFSET_BYTE_LENGTH * 3; + /// Data structure representing a storage proof. #[derive(Debug, Default, Clone, PartialEq, Eq)] pub struct StorageProof { @@ -121,6 +269,112 @@ impl TryFrom for StorageProof { }) } } + +impl StorageProof { + /// SSZ serialization method for the `StorageProof` data structure. + /// + /// # Returns + /// + /// A `Vec` containing the SSZ serialized `StorageProof` data structure. + pub fn to_ssz_bytes(&self) -> Vec { + let mut final_bytes = vec![]; + + // Key serialization + final_bytes.extend_from_slice(&(STORAGE_PROOF_KEY_OFFSET as u32).to_le_bytes()); + let key_bytes = &self.key; + + // Proof serialization + let proof_offset = STORAGE_PROOF_KEY_OFFSET + key_bytes.len(); + final_bytes.extend_from_slice(&(proof_offset as u32).to_le_bytes()); + + let proof_bytes = ssz_encode_list_bytes(&self.proof); + + // Value serialization + let value_offset = proof_offset + proof_bytes.len(); + final_bytes.extend_from_slice(&(value_offset as u32).to_le_bytes()); + + // Extend with all values + final_bytes.extend_from_slice(key_bytes); + final_bytes.extend_from_slice(&proof_bytes); + final_bytes.extend_from_slice(&self.value); + + final_bytes + } + + /// SSZ deserialization method for the `StorageProof` data structure. + /// + /// # Arguments + /// + /// * `bytes` - The SSZ formatted bytes to deserialize the `StorageProof` data structure from. + /// + /// # Returns + /// + /// A `Result` containing the deserialized `StorageProof` data structure or a `TypesError`. + pub fn from_ssz_bytes(bytes: &[u8]) -> Result { + let cursor = 0; + let (cursor, key_offset) = extract_u32("StorageProof", bytes, cursor)?; + let (cursor, proof_offset) = extract_u32("StorageProof", bytes, cursor)?; + let (cursor, value_offset) = extract_u32("StorageProof", bytes, cursor)?; + + // Retrieve key + if cursor != key_offset as usize { + return Err(deserialization_error!( + "StorageProof", + "Invalid offset for key" + )); + } + + let key = bytes + .get(cursor..proof_offset as usize) + .ok_or_else(|| TypesError::OutOfBounds { + structure: "StorageProof".into(), + offset: proof_offset as usize, + length: bytes.len(), + })? + .to_vec(); + + // Retrieve proof + let cursor = cursor + key.len(); + if cursor != proof_offset as usize { + return Err(deserialization_error!( + "StorageProof", + "Invalid offset for proof" + )); + } + + let proof_bytes = + bytes + .get(cursor..value_offset as usize) + .ok_or_else(|| TypesError::OutOfBounds { + structure: "StorageProof".into(), + offset: value_offset as usize, + length: bytes.len(), + })?; + + let proof = ssz_decode_list_bytes(proof_bytes)?; + + // Retrieve value + let cursor = cursor + proof_bytes.len(); + if cursor != value_offset as usize { + return Err(deserialization_error!( + "StorageProof", + "Invalid offset for value" + )); + } + + let value = bytes + .get(cursor..) + .ok_or_else(|| TypesError::OutOfBounds { + structure: "StorageProof".into(), + offset: cursor, + length: bytes.len(), + })? + .to_vec(); + + Ok(Self { key, proof, value }) + } +} + /// Verifies a proof against a root hash. /// /// # Arguments @@ -182,3 +436,132 @@ fn verify_proof( Ok(false) } + +#[cfg(test)] +mod test { + use crate::merkle::storage_proofs::{EIP1186Proof, StorageProof}; + use serde::{Deserialize, Serialize}; + use ssz::Encode; + use ssz_derive::{Decode, Encode}; + use ssz_types::typenum::{U10, U20, U3, U32, U6, U8, U9}; + use ssz_types::{FixedVector, VariableList}; + + #[derive(Debug, Clone, PartialEq, Encode, Decode, Serialize, Deserialize)] + struct EIP1186ProofTest { + encoded_account: VariableList, + address: FixedVector, + storage_hash: FixedVector, + account_proof: VariableList, U3>, + storage_proof: VariableList, + } + + #[derive(Debug, Clone, PartialEq, Encode, Decode, Serialize, Deserialize)] + struct StorageProofTest { + key: VariableList, + proof: VariableList, U3>, + value: VariableList, + } + + fn assert_storage_proof_equality( + storage_proof: &StorageProof, + storage_proof_test: &StorageProofTest, + ) { + assert_eq!(storage_proof.key, storage_proof_test.key.to_vec()); + assert_eq!( + storage_proof.proof.len(), + storage_proof_test.proof.to_vec().len() + ); + for (i, proof) in storage_proof.proof.iter().enumerate() { + assert_eq!(proof, &storage_proof_test.proof.to_vec()[i].to_vec()); + } + assert_eq!(storage_proof.value, storage_proof_test.value.to_vec()); + + let storage_proof_bytes = storage_proof.to_ssz_bytes(); + let serialized_storage_proof_test = storage_proof_test.as_ssz_bytes(); + + assert_eq!(storage_proof_bytes, serialized_storage_proof_test); + } + + #[test] + fn test_ssz_serde_storage_proof() { + let storage_proof_test = StorageProofTest { + key: VariableList::from(vec![1, 2, 3, 4, 5, 6, 7, 8]), + proof: VariableList::from(vec![ + VariableList::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + VariableList::from(vec![11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), + VariableList::from(vec![21, 22, 23, 24, 25, 26, 27, 28, 29, 30]), + ]), + value: VariableList::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]), + }; + + let serialized_storage_proof_test = storage_proof_test.as_ssz_bytes(); + + let storage_proof = StorageProof::from_ssz_bytes(&serialized_storage_proof_test).unwrap(); + + assert_storage_proof_equality(&storage_proof, &storage_proof_test); + } + + #[test] + fn test_ssz_serde_eip1186_response() { + let storage_proof_test = StorageProofTest { + key: VariableList::from(vec![1, 2, 3, 4, 5, 6, 7, 8]), + proof: VariableList::from(vec![ + VariableList::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + VariableList::from(vec![11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), + VariableList::from(vec![21, 22, 23, 24, 25, 26, 27, 28, 29, 30]), + ]), + value: VariableList::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]), + }; + + let eip1186_proof_test = EIP1186ProofTest { + encoded_account: VariableList::from(vec![1, 2, 3, 4, 5, 6, 7, 8]), + address: FixedVector::from(vec![1; 20]), + storage_hash: FixedVector::from(vec![1; 32]), + account_proof: VariableList::from(vec![ + VariableList::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), + VariableList::from(vec![11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), + VariableList::from(vec![21, 22, 23, 24, 25, 26, 27, 28, 29, 30]), + ]), + storage_proof: VariableList::from(vec![storage_proof_test]), + }; + + let serialized_eip1186_proof_test = eip1186_proof_test.as_ssz_bytes(); + + let eip1186_proof = EIP1186Proof::from_ssz_bytes(&serialized_eip1186_proof_test).unwrap(); + + assert_eq!( + eip1186_proof.encoded_account, + eip1186_proof_test.encoded_account.to_vec() + ); + assert_eq!( + eip1186_proof.address.to_vec(), + eip1186_proof_test.address.to_vec() + ); + assert_eq!( + eip1186_proof.storage_hash.to_vec(), + eip1186_proof_test.storage_hash.to_vec() + ); + assert_eq!( + eip1186_proof.account_proof.len(), + eip1186_proof_test.account_proof.to_vec().len() + ); + for (i, proof) in eip1186_proof.account_proof.iter().enumerate() { + assert_eq!( + proof, + &eip1186_proof_test.account_proof.to_vec()[i].to_vec() + ); + } + assert_eq!( + eip1186_proof.storage_proof.len(), + eip1186_proof_test.storage_proof.to_vec().len() + ); + + for (i, proof) in eip1186_proof.storage_proof.iter().enumerate() { + assert_storage_proof_equality(proof, &eip1186_proof_test.storage_proof.to_vec()[i]); + } + + let eip1186_proof_bytes = eip1186_proof.to_ssz_bytes(); + + assert_eq!(eip1186_proof_bytes, serialized_eip1186_proof_test); + } +} diff --git a/ethereum/core/src/types/block/consensus.rs b/ethereum/core/src/types/block/consensus.rs index ea74c566..516042ba 100644 --- a/ethereum/core/src/types/block/consensus.rs +++ b/ethereum/core/src/types/block/consensus.rs @@ -168,7 +168,7 @@ pub(crate) mod test { fn test_ssz_serde() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/BeaconBlockHeaderDeneb.ssz"); + .join("../test-assets/committee-change/BeaconBlockHeaderDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -183,7 +183,7 @@ pub(crate) mod test { fn test_beacon_block_hash_tree_root() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/BeaconBlockHeaderDeneb.ssz"); + .join("../test-assets/committee-change/BeaconBlockHeaderDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/core/src/types/block/execution.rs b/ethereum/core/src/types/block/execution.rs index 8b0c8065..5e690289 100644 --- a/ethereum/core/src/types/block/execution.rs +++ b/ethereum/core/src/types/block/execution.rs @@ -324,7 +324,7 @@ pub(crate) mod test { fn test_ssz_serde() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/ExecutionPayloadHeaderDeneb.ssz"); + .join("../test-assets/committee-change/ExecutionPayloadHeaderDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -339,7 +339,7 @@ pub(crate) mod test { fn test_execution_block_hash_tree_root() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/ExecutionPayloadHeaderDeneb.ssz"); + .join("../test-assets/committee-change/ExecutionPayloadHeaderDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/core/src/types/block/mod.rs b/ethereum/core/src/types/block/mod.rs index 7d111b52..44789221 100644 --- a/ethereum/core/src/types/block/mod.rs +++ b/ethereum/core/src/types/block/mod.rs @@ -215,7 +215,7 @@ pub(crate) mod test { fn test_ssz_serde() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientHeaderDeneb.ssz"); + .join("../test-assets/committee-change/LightClientHeaderDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -230,7 +230,7 @@ pub(crate) mod test { fn test_light_client_header_hash_tree_root() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientHeaderDeneb.ssz"); + .join("../test-assets/committee-change/LightClientHeaderDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/core/src/types/bootstrap.rs b/ethereum/core/src/types/bootstrap.rs index b23eb08f..131b03e2 100644 --- a/ethereum/core/src/types/bootstrap.rs +++ b/ethereum/core/src/types/bootstrap.rs @@ -165,7 +165,7 @@ mod test { fn test_ssz_serde() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientBootstrapDeneb.ssz"); + .join("../test-assets/committee-change/LightClientBootstrapDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/core/src/types/committee.rs b/ethereum/core/src/types/committee.rs index 8cf1920e..c624dcaf 100644 --- a/ethereum/core/src/types/committee.rs +++ b/ethereum/core/src/types/committee.rs @@ -226,7 +226,7 @@ pub(crate) mod test { fn test_ssz_serde_sync_committee() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/SyncCommitteeDeneb.ssz"); + .join("../test-assets/committee-change/SyncCommitteeDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -241,7 +241,7 @@ pub(crate) mod test { fn test_sync_committee_hash_tree_root() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/SyncCommitteeDeneb.ssz"); + .join("../test-assets/committee-change/SyncCommitteeDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/core/src/types/error.rs b/ethereum/core/src/types/error.rs index b1751761..7d69ace8 100644 --- a/ethereum/core/src/types/error.rs +++ b/ethereum/core/src/types/error.rs @@ -38,6 +38,12 @@ pub enum TypesError { minimum: usize, actual: usize, }, + #[error("Received data out of bounds for {structure}. Offset: {offset}, Length: {length}.")] + OutOfBounds { + structure: String, + offset: usize, + length: usize, + }, #[error("Error while converting hexadecimal value to a fixed-size array")] InvalidHexadecimal, } diff --git a/ethereum/core/src/types/store.rs b/ethereum/core/src/types/store.rs index 4e615bb2..e8a56638 100644 --- a/ethereum/core/src/types/store.rs +++ b/ethereum/core/src/types/store.rs @@ -174,7 +174,7 @@ impl LightClientStore { /// # Notes /// /// From [the Altaïr specifications](https://github.com/ethereum/consensus-specs/blob/5cce790decfb362bef300a4ca9f8075b1699ccb1/specs/altair/light-client/sync-protocol.md#validate_light_client_update). - fn validate_light_client_update(&self, update: &Update) -> Result<(), ConsensusError> { + pub fn validate_light_client_update(&self, update: &Update) -> Result<(), ConsensusError> { // Ensure we at least have 1 signer if update .sync_aggregate() @@ -496,7 +496,7 @@ mod test { // Instantiate bootstrap data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientBootstrapDeneb.ssz"); + .join("../test-assets/committee-change/LightClientBootstrapDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -505,7 +505,7 @@ mod test { // Instantiate Update data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -514,7 +514,7 @@ mod test { // Instantiate new period Update data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateNewPeriodDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateNewPeriodDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/core/src/types/update.rs b/ethereum/core/src/types/update.rs index 543a6635..df9ab372 100644 --- a/ethereum/core/src/types/update.rs +++ b/ethereum/core/src/types/update.rs @@ -379,7 +379,7 @@ mod test { fn test_ssz_serde_update() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -394,7 +394,7 @@ mod test { fn test_update_proof() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -423,7 +423,7 @@ mod test { fn test_ssz_serde_finality_update() { let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/core/src/types/utils.rs b/ethereum/core/src/types/utils.rs index 463f86f9..0a01daa3 100644 --- a/ethereum/core/src/types/utils.rs +++ b/ethereum/core/src/types/utils.rs @@ -159,6 +159,101 @@ pub fn unpack_bits(bytes: &[u8], num_bits: usize) -> Vec { .collect() } +/// Utility to convert a list of bytes slice to an SSZ encoded object. +/// +/// # Arguments +/// +/// * `list` - The list of bytes to convert. +/// +/// # Returns +/// +/// A vector of bytes. +pub fn ssz_encode_list_bytes(list: &[Vec]) -> Vec { + let mut bytes: Vec = vec![]; + + if list.is_empty() { + return bytes; + } + + // First element offset + let mut element_offset = list.len() * OFFSET_BYTE_LENGTH; + bytes.extend_from_slice(&(element_offset as u32).to_le_bytes()); + + // Grow with offset and create the serialized element slice + let mut serialized_elements = vec![]; + + for (i, element) in list.iter().enumerate() { + if i < list.len() - 1 { + element_offset += element.len(); + bytes.extend_from_slice(&(element_offset as u32).to_le_bytes()); + } + + serialized_elements.extend_from_slice(element); + } + + // Finalize list bytes and extend final bytes + bytes.extend_from_slice(&serialized_elements); + + bytes +} + +/// Utility to convert a slice of bytes into a list of bytes. +/// +/// # Arguments +/// +/// * `bytes` - The slice of bytes to convert. +/// +/// # Returns +/// +/// A vector of bytes. +pub fn ssz_decode_list_bytes(bytes: &[u8]) -> Result>, TypesError> { + let mut list_bytes = vec![]; + if bytes.len() > OFFSET_BYTE_LENGTH { + let (mut cursor, mut offset) = extract_u32("StorageProof", bytes, 0)?; + let first_offset = offset as usize; + + loop { + if cursor == first_offset { + break; + } + + let (next_cursor, next_offset) = extract_u32("StorageProof", bytes, cursor)?; + list_bytes.push( + bytes + .get(offset as usize..next_offset as usize) + .ok_or_else(|| TypesError::OutOfBounds { + structure: "StorageProof".into(), + offset: next_offset as usize, + length: bytes.len(), + })? + .to_vec(), + ); + + cursor = next_cursor; + offset = next_offset; + } + + list_bytes.push( + bytes + .get(offset as usize..) + .ok_or_else(|| TypesError::OutOfBounds { + structure: "StorageProof".into(), + offset: offset as usize, + length: bytes.len(), + })? + .to_vec(), + ); + } else if !bytes.is_empty() { + return Err(TypesError::UnderLength { + structure: "StorageProof".into(), + minimum: OFFSET_BYTE_LENGTH, + actual: bytes.len(), + }); + } + + Ok(list_bytes) +} + /// Utility to convert a slice of bytes into an array of 32 bytes. /// /// # Arguments diff --git a/ethereum/docs/src/benchmark/configuration.md b/ethereum/docs/src/benchmark/configuration.md index e59d844f..b649ebc7 100644 --- a/ethereum/docs/src/benchmark/configuration.md +++ b/ethereum/docs/src/benchmark/configuration.md @@ -1 +1,56 @@ -# Configuration for the benchmarks \ No newline at end of file +# Configuration for the benchmarks + +In this section we will cover the configuration that should be set to run the benchmarks. It is also +important to run the benchmarks on proper machines, such as the one described for the Proof Server in +the [Run the Light Client](../run/overview.md) section. + +## Requirements + +The requirements to run the benchmarks are the same as the ones for the client. You will need to follow +the instructions listed [here](../run/configuration.md). + +## Other settings + +Here are the standard config variables that are worth setting for any benchmark: + +- `RUSTFLAGS="-C target-cpu=native -C opt-level=3"` + + This can also be configured in `~/.cargo/config.toml` by adding: + ```toml + [target.'cfg(all())'] + rustflags = ["--cfg", "tokio_unstable", "-C", "target-cpu=native", "-C", "opt-level=3"] + ``` + +- `SHARD_SIZE=4194304` + + The highest possible setting, giving the fewest shards. Because the compression phase dominates the timing of the + SNARK proofs, we need as few shards as possible. + +- `SHARD_BATCH_SIZE=0` + + This disables checkpointing making proving faster at the expense of higher memory usage + +- `cargo +nightly-2024-05-31` + + This ensures you are on a nightly toolchain. Nightly allows usage of AVX512 instructions which is crucial for + performance. + This is the same version set on `rust-toolchain.toml`. It's pinned to a specific release (`v1.80.0-nightly`) to + prevent + unexpected issues caused by newer Rust versions. + +- `cargo bench --release <...>` + + Make sure to always run in release mode with `--release`. Alternatively, specify the proper compiler options via + `RUSTFLAGS="-C opt-level=3 <...>"`, `~/.cargo/config.toml` or Cargo profiles + +- `RUST_LOG=debug` _(optional)_ + + This prints out useful Sphinx metrics, such as cycle counts, iteration speed, proof size, etc. + +## SNARK proofs + +When running any tests or benchmarks that makes Plonk proofs over BN254, the prover leverages some pre-built circuits +artifacts. Those circuits artifacts are generated when we release new versions of Sphinx and are automatically +downloaded on first use. The current address for downloading the artifacts can be found +[here](https://github.com/lurk-lab/sphinx/blob/dev/prover/src/install.rs), but it should not be necessary to download +them manually. diff --git a/ethereum/docs/src/benchmark/proof.md b/ethereum/docs/src/benchmark/proof.md index 91bb6817..49362d56 100644 --- a/ethereum/docs/src/benchmark/proof.md +++ b/ethereum/docs/src/benchmark/proof.md @@ -4,7 +4,7 @@ In this section we will cover how to run the benchmarks for the individual proof the `light-client` crate folder. Those benchmarks are associated with programs that are meant to reproduce a production environment settings. They are meant to measure performance for a complete end-to-end flow. -# Sync committee change +## Sync committee change Benchmark that will run a proof generation for the sync committee change program. This program will execute a hash for the received `LightClientStore::current_sync_committee` to ensure that the signature is from the previous sync committee @@ -22,7 +22,28 @@ this benchmark: } ``` -### Running the benchmarks +## Storage inclusion + +Benchmark that will run a proof generation for the storage inclusion program. This program will execute a hash for the +received `LightClientStore::current_sync_committee` to ensure that the signature is from the current known sync +committee +set, execute a `LightClientStore::validate_light_client_update` to confirm that the received block information is one +signed +by the committee, and finally run an `EIP1186Proof::verify` against the state root of the finalized execution block +header. + +On our [production configuration](../run/overview.md), we currently get the following results for SNARK generation for +this benchmark: + +```json +{ + // Time in milliseconds, 7~ minutes + "proving_time": 441123, + "verification_time": 2 +} +``` + +## Running the benchmarks **Using Makefile** diff --git a/ethereum/docs/src/run/setup_proof_server.md b/ethereum/docs/src/run/setup_proof_server.md index 99fbdb7e..0d1d5322 100644 --- a/ethereum/docs/src/run/setup_proof_server.md +++ b/ethereum/docs/src/run/setup_proof_server.md @@ -31,6 +31,16 @@ Make sure to launch the proof servers with `cargo +nightly-2024-05-31`. > One can also set the `RUST_LOG` environment variable to `debug` to get more information > about the execution of the server. +## Deploy the secondary server + +Now that our deployment machine is properly configured, we can run the secondary server. + +```bash +git clone git@github.com:lurk-lab/zk-light-clients.git && \ + cd zk-light-clients/aptos/proof-server && \ + SHARD_SIZE=4194304 SHARD_BATCH_SIZE=0 RUSTFLAGS="-C target-cpu=native --cfg tokio_unstable -C opt-level=3" cargo +nightly-2024-05-31 run --release --bin server_secondary -- -a +``` + ## Deploy the primary server Finally, once the primary server is configured in the same fashion, run it: @@ -38,5 +48,5 @@ Finally, once the primary server is configured in the same fashion, run it: ```bash git clone git@github.com:lurk-lab/zk-light-clients.git && \ cd zk-light-clients/ethereum/light-client && \ - SHARD_BATCH_SIZE=0 RUSTFLAGS="-C target-cpu=native -C opt-level=3" cargo +nightly-2024-05-31 run --release --bin server_primary -- -a --snd-addr + SHARD_SIZE=4194304 SHARD_BATCH_SIZE=0 RUSTFLAGS="-C target-cpu=native -C opt-level=3" cargo +nightly-2024-05-31 run --release --bin server_primary -- -a --snd-addr ``` diff --git a/ethereum/ethereum-programs/artifacts/committee-change-program b/ethereum/ethereum-programs/artifacts/committee-change-program index af1ab096..9f437cfe 100755 Binary files a/ethereum/ethereum-programs/artifacts/committee-change-program and b/ethereum/ethereum-programs/artifacts/committee-change-program differ diff --git a/ethereum/light-client/benches/committee_change.rs b/ethereum/light-client/benches/committee_change.rs index f1611f0e..5ab52f53 100644 --- a/ethereum/light-client/benches/committee_change.rs +++ b/ethereum/light-client/benches/committee_change.rs @@ -23,7 +23,7 @@ impl BenchmarkAssets { // Instantiate bootstrap data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientBootstrapDeneb.ssz"); + .join("../test-assets/committee-change/LightClientBootstrapDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -32,7 +32,7 @@ impl BenchmarkAssets { // Instantiate Update data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -41,7 +41,7 @@ impl BenchmarkAssets { // Instantiate new period Update data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateNewPeriodDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateNewPeriodDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/light-client/benches/inclusion.rs b/ethereum/light-client/benches/inclusion.rs new file mode 100644 index 00000000..5176611d --- /dev/null +++ b/ethereum/light-client/benches/inclusion.rs @@ -0,0 +1,126 @@ +// Copyright (c) Yatima, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use ethereum_lc::proofs::inclusion::{StorageInclusionIn, StorageInclusionProver}; +use ethereum_lc::proofs::{Prover, ProvingMode}; +use ethereum_lc::types::storage::GetProofResponse; +use ethereum_lc_core::merkle::storage_proofs::EIP1186Proof; +use ethereum_lc_core::types::bootstrap::Bootstrap; +use ethereum_lc_core::types::store::LightClientStore; +use ethereum_lc_core::types::update::{FinalityUpdate, Update}; +use serde::Serialize; +use std::env::current_dir; +use std::time::Instant; +use std::{env, fs}; + +struct BenchmarkAssets { + prover: StorageInclusionProver, + store: LightClientStore, + finality_update: FinalityUpdate, + eip1186_proof: EIP1186Proof, +} + +impl BenchmarkAssets { + fn generate() -> BenchmarkAssets { + // Instantiate bootstrap data + let test_asset_path = current_dir() + .unwrap() + .join("../test-assets/inclusion/LightClientBootstrapDeneb.ssz"); + + let test_bytes = fs::read(test_asset_path).unwrap(); + + let bootstrap = Bootstrap::from_ssz_bytes(&test_bytes).unwrap(); + + // Instantiate Update data + let test_asset_path = current_dir() + .unwrap() + .join("../test-assets/inclusion/LightClientUpdateDeneb.ssz"); + + let test_bytes = fs::read(test_asset_path).unwrap(); + + let update = Update::from_ssz_bytes(&test_bytes).unwrap(); + + // Instantiate finality update data + let test_asset_path = current_dir() + .unwrap() + .join("../test-assets/inclusion/LightClientFinalityUpdateDeneb.ssz"); + + let test_bytes = fs::read(test_asset_path).unwrap(); + + let finality_update = FinalityUpdate::from_ssz_bytes(&test_bytes).unwrap(); + + // Instantiate EIP1186 proof data + let test_asset_path = current_dir() + .unwrap() + .join("../test-assets/inclusion/base-data/EthGetProof.json"); + + let test_bytes = fs::read(test_asset_path).unwrap(); + + let ethers_eip1186_proof: GetProofResponse = serde_json::from_slice(&test_bytes).unwrap(); + + // Initialize the LightClientStore + let checkpoint = "0xf783c545d2dd90cee6c4cb92a9324323ef397f6ec85e1a3d61c48cf6cfc979e2"; + let trusted_block_root = hex::decode(checkpoint.strip_prefix("0x").unwrap()) + .unwrap() + .try_into() + .unwrap(); + + let mut store = LightClientStore::initialize(trusted_block_root, &bootstrap).unwrap(); + + store.process_light_client_update(&update).unwrap(); + + let prover = StorageInclusionProver::new(); + + BenchmarkAssets { + prover, + store, + finality_update, + eip1186_proof: EIP1186Proof::try_from(ethers_eip1186_proof.result().clone()).unwrap(), + } + } +} + +#[derive(Debug, Clone, Serialize)] +struct BenchResults { + proving_time: u128, + verification_time: u128, +} + +fn main() { + let mode_str: String = env::var("MODE").unwrap_or_else(|_| "STARK".into()); + let mode = ProvingMode::try_from(mode_str.as_str()).expect("MODE should be STARK or SNARK"); + + // Instantiate BenchmarkAssets + let benchmark_assets = BenchmarkAssets::generate(); + + // Prove storage inclusion + let inputs = StorageInclusionIn::new( + benchmark_assets.store.clone(), + benchmark_assets.finality_update.clone().into(), + benchmark_assets.eip1186_proof.clone(), + ); + + let start_proving = Instant::now(); + let proof = benchmark_assets + .prover + .prove(inputs, mode) + .expect("Failed to prove storage inclusion"); + let proving_time = start_proving.elapsed(); + + // Verify proof + let start_verifying = Instant::now(); + benchmark_assets + .prover + .verify(&proof) + .expect("Failed to verify storage inclusion proof"); + let verifying_time = start_verifying.elapsed(); + + // Print results + let results = BenchResults { + proving_time: proving_time.as_millis(), + verification_time: verifying_time.as_millis(), + }; + + let json_output = serde_json::to_string(&results).unwrap(); + println!("{}", json_output); +} diff --git a/ethereum/light-client/src/bin/client.rs b/ethereum/light-client/src/bin/client.rs index 30282cfb..385a5fbb 100644 --- a/ethereum/light-client/src/bin/client.rs +++ b/ethereum/light-client/src/bin/client.rs @@ -7,6 +7,7 @@ use ethereum_lc::client::Client; use ethereum_lc::proofs::ProvingMode; use ethereum_lc_core::merkle::storage_proofs::EIP1186Proof; use ethereum_lc_core::types::store::LightClientStore; +use ethereum_lc_core::types::update::Update; use ethereum_lc_core::types::utils::calc_sync_period; use log::info; use std::sync::Arc; @@ -96,8 +97,6 @@ async fn main() { .await .expect("Failed to fetch finality update"); - println!("Finality update: {:?}", finality_update); - let inclusion_merkle_proof = state .client .get_proof( @@ -120,11 +119,27 @@ async fn main() { let light_client_internal = EIP1186Proof::try_from(inclusion_merkle_proof).expect("Failed to convert to EIP1186Proof"); - println!("Proof of storage inclusion: {:?}", &light_client_internal); + info!("Generating proof of inclusion..."); + let proof = state + .client + .prove_storage_inclusion( + ProvingMode::STARK, + &state.store, + &Update::from(finality_update), + &light_client_internal, + ) + .await + .expect("Failed to prove storage inclusion"); + info!("Proof of storage inclusion generated successfully"); - light_client_internal - .verify(finality_update.finalized_header().execution().state_root()) - .expect("Failed to verify proof"); + // Verify the proof of storage inclusion + info!("Verifying proof of storage inclusion..."); + state + .client + .verify_storage_inclusion(proof) + .await + .expect("Failed to verify storage inclusion proof"); + info!("Proof of storage inclusion verified successfully"); } async fn initialize_light_client( diff --git a/ethereum/light-client/src/bin/server_primary.rs b/ethereum/light-client/src/bin/server_primary.rs index 293619ce..343d56dd 100644 --- a/ethereum/light-client/src/bin/server_primary.rs +++ b/ethereum/light-client/src/bin/server_primary.rs @@ -9,7 +9,7 @@ use ethereum_lc::types::network::Request; use ethereum_lc::utils::{read_bytes, write_bytes}; use log::{error, info}; use std::sync::Arc; -use tokio::net::TcpListener; +use tokio::net::{TcpListener, TcpStream}; use tokio::task::spawn_blocking; #[derive(Parser)] @@ -25,13 +25,14 @@ struct Cli { #[tokio::main] async fn main() -> Result<()> { - let Cli { addr, .. } = Cli::parse(); + let Cli { addr, snd_addr } = Cli::parse(); env_logger::init(); let listener = TcpListener::bind(addr).await?; info!("Server is running on {}", listener.local_addr()?); + let snd_addr = Arc::new(snd_addr); let committee_prover = Arc::new(CommitteeChangeProver::new()); loop { @@ -39,6 +40,7 @@ async fn main() -> Result<()> { info!("Received a connection"); let committee_prover = committee_prover.clone(); + let snd_addr = snd_addr.clone(); tokio::spawn(async move { info!("Awaiting request"); @@ -68,6 +70,17 @@ async fn main() -> Result<()> { ) .await?; } + Request::ProveInclusion(_) | Request::VerifyInclusion(_) => { + info!("Connecting to the secondary server"); + let mut secondary_stream = TcpStream::connect(&*snd_addr).await?; + info!("Sending secondary request"); + write_bytes(&mut secondary_stream, &request_bytes).await?; + info!("Awaiting response from secondary server"); + let response = read_bytes(&mut secondary_stream).await?; + info!("Received response from the secondary server. Sending result"); + write_bytes(&mut client_stream, &response).await?; + info!("Response forwarded"); + } }, Err(err) => error!("Failed to deserialize request object: {err}"), } diff --git a/ethereum/light-client/src/bin/server_secondary.rs b/ethereum/light-client/src/bin/server_secondary.rs index 331f974e..16757d97 100644 --- a/ethereum/light-client/src/bin/server_secondary.rs +++ b/ethereum/light-client/src/bin/server_secondary.rs @@ -1,5 +1,77 @@ // Copyright (c) Yatima, Inc. // SPDX-License-Identifier: Apache-2.0 -#[allow(clippy::missing_const_for_fn)] -fn main() {} +use anyhow::{Error, Result}; +use clap::Parser; +use ethereum_lc::proofs::inclusion::StorageInclusionProver; +use ethereum_lc::proofs::Prover; +use ethereum_lc::types::network::Request; +use ethereum_lc::utils::{read_bytes, write_bytes}; +use log::{error, info}; +use std::sync::Arc; +use tokio::net::TcpListener; +use tokio::task::spawn_blocking; + +#[derive(Parser)] +struct Cli { + /// Address of this server. E.g. 127.0.0.1:4321 + #[arg(short, long)] + addr: String, +} + +#[tokio::main] +async fn main() -> Result<()> { + let Cli { addr } = Cli::parse(); + + env_logger::init(); + + let listener = TcpListener::bind(addr).await?; + + info!("Server is running on {}", listener.local_addr()?); + + let inclusion_prover = Arc::new(StorageInclusionProver::new()); + + loop { + let (mut client_stream, _) = listener.accept().await?; + info!("Received a connection"); + + let inclusion_prover = inclusion_prover.clone(); + + tokio::spawn(async move { + info!("Awaiting request"); + let request_bytes = read_bytes(&mut client_stream).await?; + info!("Request received"); + + info!("Deserializing request"); + match Request::from_bytes(&request_bytes) { + Ok(request) => match request { + Request::ProveInclusion(boxed) => { + info!("Start proving"); + let proof_handle = spawn_blocking(move || { + let (proving_mode, inputs) = boxed.as_ref(); + inclusion_prover.prove(inputs.clone(), proving_mode.clone()) + }); + let proof = proof_handle.await??; + info!("Proof generated. Serializing"); + let proof_bytes = proof.to_bytes()?; + info!("Sending proof"); + write_bytes(&mut client_stream, &proof_bytes).await?; + info!("Proof sent"); + } + Request::VerifyInclusion(proof) => { + write_bytes( + &mut client_stream, + &[u8::from(inclusion_prover.verify(&proof).is_ok())], + ) + .await?; + } + _ => { + error!("Received unexpected request object, secondary server only handles inclusion proofs") + } + }, + Err(err) => error!("Failed to deserialize request object: {err}"), + } + Ok::<(), Error>(()) + }); + } +} diff --git a/ethereum/light-client/src/client/mod.rs b/ethereum/light-client/src/client/mod.rs index 8f892b48..8909e085 100644 --- a/ethereum/light-client/src/client/mod.rs +++ b/ethereum/light-client/src/client/mod.rs @@ -20,6 +20,7 @@ use crate::client::storage::StorageClient; use crate::proofs::{ProofType, ProvingMode}; use crate::types::beacon::update::UpdateResponse; use crate::types::checkpoint::Checkpoint; +use ethereum_lc_core::merkle::storage_proofs::EIP1186Proof; use ethereum_lc_core::types::bootstrap::Bootstrap; use ethereum_lc_core::types::store::LightClientStore; use ethereum_lc_core::types::update::{FinalityUpdate, Update}; @@ -28,8 +29,8 @@ use ethers_core::types::EIP1186ProofResponse; pub(crate) mod beacon; pub(crate) mod checkpoint; pub mod error; -mod proof_server; -mod storage; +pub(crate) mod proof_server; +pub mod storage; /// The client for the light client. It is the entrypoint for any needed remote call. #[derive(Debug, Clone)] @@ -207,4 +208,51 @@ impl Client { .get_proof(address, storage_keys, block_hash) .await } + + /// `prove_storage_inclusion` makes a request to the Proof Server API to generate the proof of a storage inclusion. + /// + /// # Arguments + /// + /// * `proving_mode` - The proving mode, either STARK or SNARK. + /// * `store` - The light client store. + /// * `update` - The update data. + /// * `eip1186_proof` - The EIP1186 proof. + /// + /// # Returns + /// + /// The proof of the storage inclusion. + /// + /// # Errors + /// + /// Returns an error if the request fails or the response is not successful or properly formatted. + pub async fn prove_storage_inclusion( + &self, + proving_mode: ProvingMode, + store: &LightClientStore, + update: &Update, + eip1186_proof: &EIP1186Proof, + ) -> Result { + self.proof_server_client + .prove_storage_inclusion(proving_mode, store, update, eip1186_proof) + .await + } + + /// `verify_storage_inclusion` makes a request to the Proof Server API to verify the proof of a storage inclusion. + /// + /// # Arguments + /// + /// * `proof` - The proof of the storage inclusion. + /// + /// # Returns + /// + /// A boolean indicating whether the proof is valid. + /// + /// # Errors + /// + /// Returns an error if the request fails or the response is not successful or properly formatted. + pub async fn verify_storage_inclusion(&self, proof: ProofType) -> Result { + self.proof_server_client + .verify_storage_inclusion(proof) + .await + } } diff --git a/ethereum/light-client/src/client/proof_server.rs b/ethereum/light-client/src/client/proof_server.rs index 7202b2a5..c2505233 100644 --- a/ethereum/light-client/src/client/proof_server.rs +++ b/ethereum/light-client/src/client/proof_server.rs @@ -8,9 +8,11 @@ use crate::client::error::ClientError; use crate::proofs::committee_change::CommitteeChangeIn; +use crate::proofs::inclusion::StorageInclusionIn; use crate::proofs::{ProofType, ProvingMode}; use crate::types::network::Request; use crate::utils::{read_bytes, write_bytes}; +use ethereum_lc_core::merkle::storage_proofs::EIP1186Proof; use ethereum_lc_core::types::store::LightClientStore; use ethereum_lc_core::types::update::Update; use tokio::net::TcpStream; @@ -144,4 +146,113 @@ impl ProofServerClient { Ok(res[0] == 1) } + + /// Prove the inclusion of a given value in the chain storage by executing [`EIP1186Proof::verify`] + /// and proving its correct execution. + /// + /// # Arguments + /// + /// * `proving_mode` - The proving mode to use, either STARK or SNARK. + /// * `store` - The light client store. + /// * `update` - The update to process. + /// * `eip1186_proof` - The EIP1186 proof to verify. + /// + /// # Returns + /// + /// A proof of the storage inclusion. + pub(crate) async fn prove_storage_inclusion( + &self, + proving_mode: ProvingMode, + store: &LightClientStore, + update: &Update, + eip1186_proof: &EIP1186Proof, + ) -> Result { + let mut stream = + TcpStream::connect(&self.address) + .await + .map_err(|err| ClientError::Request { + endpoint: "ProofServer::ProveInclusion".into(), + source: err.into(), + })?; + let inputs = StorageInclusionIn::new(store.clone(), update.clone(), eip1186_proof.clone()); + let request = Request::ProveInclusion(Box::new((proving_mode, inputs))); + + write_bytes( + &mut stream, + &request.to_bytes().map_err(|err| ClientError::Request { + endpoint: "ProofServer::ProveInclusion".into(), + source: err.into(), + })?, + ) + .await + .map_err(|err| ClientError::Request { + endpoint: "prover".into(), + source: err.into(), + })?; + + let res = read_bytes(&mut stream) + .await + .map_err(|err| ClientError::Response { + endpoint: "ProofServer::ProveInclusion".into(), + source: err.into(), + })?; + + ProofType::from_bytes(&res).map_err(|err| ClientError::Response { + endpoint: "ProofServer::ProveInclusion".into(), + source: err.into(), + }) + } + + /// Verify a proof for storage inclusion. + /// + /// # Arguments + /// + /// * `proof` - The proof to verify. + /// + /// # Returns + /// + /// A boolean indicating whether the proof is valid. + pub(crate) async fn verify_storage_inclusion( + &self, + proof: ProofType, + ) -> Result { + let mut stream = + TcpStream::connect(&self.address) + .await + .map_err(|err| ClientError::Request { + endpoint: "ProofServer::VerifyInclusiona".into(), + source: err.into(), + })?; + + let request = Request::VerifyInclusion(proof); + + write_bytes( + &mut stream, + &request.to_bytes().map_err(|err| ClientError::Request { + endpoint: "ProofServer::VerifyInclusiona".into(), + source: err.into(), + })?, + ) + .await + .map_err(|err| ClientError::Request { + endpoint: "prover".into(), + source: err.into(), + })?; + + let res = read_bytes(&mut stream) + .await + .map_err(|err| ClientError::Response { + endpoint: "ProofServer::VerifyInclusiona".into(), + source: err.into(), + })?; + + if res.len() != 1 { + return Err(ClientError::Response { + endpoint: "ProofServer::VerifyInclusiona".into(), + source: "Invalid response length".into(), + }); + } + + Ok(res[0] == 1) + } } diff --git a/ethereum/light-client/src/client/storage.rs b/ethereum/light-client/src/client/storage.rs index 6c4ca15e..95c054a5 100644 --- a/ethereum/light-client/src/client/storage.rs +++ b/ethereum/light-client/src/client/storage.rs @@ -15,18 +15,11 @@ //! authenticate the client with the RPC provider. use crate::client::error::ClientError; +use crate::types::storage::GetProofResponse; use ethers_core::types::EIP1186ProofResponse; use getset::Getters; use reqwest::header::CONTENT_TYPE; use reqwest::Client; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)] -struct GetProofResponse { - id: u64, - jsonrpc: String, - result: EIP1186ProofResponse, -} /// An internal client to handle communication with the RPC Provider. #[derive(Debug, Clone, Getters)] @@ -120,6 +113,6 @@ impl StorageClient { source: err.into(), })?; - Ok(deserialized.result) + Ok(deserialized.result().clone()) } } diff --git a/ethereum/light-client/src/proofs/committee_change.rs b/ethereum/light-client/src/proofs/committee_change.rs index 3318c4e7..e143dc67 100644 --- a/ethereum/light-client/src/proofs/committee_change.rs +++ b/ethereum/light-client/src/proofs/committee_change.rs @@ -227,7 +227,7 @@ mod test { // Instantiate bootstrap data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientBootstrapDeneb.ssz"); + .join("../test-assets/committee-change/LightClientBootstrapDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -236,7 +236,7 @@ mod test { // Instantiate Update data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); @@ -245,7 +245,7 @@ mod test { // Instantiate new period Update data let test_asset_path = current_dir() .unwrap() - .join("../test-assets/LightClientUpdateNewPeriodDeneb.ssz"); + .join("../test-assets/committee-change/LightClientUpdateNewPeriodDeneb.ssz"); let test_bytes = fs::read(test_asset_path).unwrap(); diff --git a/ethereum/light-client/src/proofs/inclusion.rs b/ethereum/light-client/src/proofs/inclusion.rs new file mode 100644 index 00000000..f8d28653 --- /dev/null +++ b/ethereum/light-client/src/proofs/inclusion.rs @@ -0,0 +1,398 @@ +// Copyright (c) Yatima, Inc. +// SPDX-License-Identifier: Apache-2.0 + +//! # Inclusion Prover module +//! +//! This module provides the prover implementation for the storage inclusion proof. The prover +//! is responsible for generating, executing, proving, and verifying proofs for the light client. + +use crate::proofs::error::ProverError; +use crate::proofs::{ProofType, Prover, ProvingMode}; +use anyhow::Result; +use ethereum_lc_core::crypto::hash::HashValue; +use ethereum_lc_core::deserialization_error; +use ethereum_lc_core::merkle::storage_proofs::EIP1186Proof; +use ethereum_lc_core::types::error::TypesError; +use ethereum_lc_core::types::store::LightClientStore; +use ethereum_lc_core::types::update::Update; +use ethereum_lc_core::types::utils::{extract_u32, OFFSET_BYTE_LENGTH}; +use ethereum_programs::INCLUSION_PROGRAM; +use sphinx_sdk::{ProverClient, SphinxProvingKey, SphinxStdin, SphinxVerifyingKey}; + +/// The prover for the storage inclusion proof. +pub struct StorageInclusionProver { + client: ProverClient, + keys: (SphinxProvingKey, SphinxVerifyingKey), +} + +impl Default for StorageInclusionProver { + fn default() -> Self { + Self::new() + } +} + +impl StorageInclusionProver { + /// Create a new `StorageInclusionProver`. + /// + /// # Returns + /// + /// A new `StorageInclusionProver`. + pub fn new() -> Self { + let client = ProverClient::new(); + let keys = client.setup(INCLUSION_PROGRAM); + + Self { client, keys } + } +} + +/// The input for the storage inclusion proof. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct StorageInclusionIn { + store: LightClientStore, + update: Update, + eip1186_proof: EIP1186Proof, +} + +impl StorageInclusionIn { + /// Create a new `StorageInclusionIn`. + /// + /// # Arguments + /// + /// * `store` - The `LightClientStore` that wil be passed to the program. + /// * `update` - The `Update` that will be passed to the program. + /// * `eip1186_proof` - The `EIP1186Proof` that will be passed to the program. + /// + /// # Returns + /// + /// A new `StorageInclusionIn`. + pub const fn new(store: LightClientStore, update: Update, eip1186_proof: EIP1186Proof) -> Self { + Self { + store, + update, + eip1186_proof, + } + } + + /// Serialize the `StorageInclusionIn` struct to SSZ bytes. + /// + /// # Returns + /// + /// A `Vec` containing the SSZ serialized `StorageInclusionIn` struct. + pub fn to_ssz_bytes(&self) -> Result, TypesError> { + let mut bytes = vec![]; + + let store_offset: u32 = (OFFSET_BYTE_LENGTH * 3) as u32; + let store_bytes = self.store.to_ssz_bytes()?; + bytes.extend_from_slice(&store_offset.to_le_bytes()); + + let update_offset = store_offset + store_bytes.len() as u32; + let update_bytes = self.update.to_ssz_bytes()?; + bytes.extend_from_slice(&update_offset.to_le_bytes()); + + let eip1186_proof_offset = update_offset + update_bytes.len() as u32; + let eip1186_proof_bytes = self.eip1186_proof.to_ssz_bytes(); + bytes.extend_from_slice(&eip1186_proof_offset.to_le_bytes()); + + bytes.extend_from_slice(&store_bytes); + bytes.extend_from_slice(&update_bytes); + bytes.extend_from_slice(&eip1186_proof_bytes); + + Ok(bytes) + } + + /// Deserialize a `StorageInclusionIn` struct from SSZ bytes. + /// + /// # Arguments + /// + /// * `bytes` - The SSZ encoded bytes. + /// + /// # Returns + /// + /// A `Result` containing either the deserialized `StorageInclusionIn` struct or a `TypesError`. + pub fn from_ssz_bytes(bytes: &[u8]) -> Result { + let cursor = 0; + let (cursor, store_offset) = extract_u32("CommmitteeChangeIn", bytes, cursor)?; + let (cursor, update_offset) = extract_u32("CommmitteeChangeIn", bytes, cursor)?; + let (cursor, eip1186_proof_offset) = extract_u32("CommmitteeChangeIn", bytes, cursor)?; + + // Deserialize the Light Client store + if cursor != store_offset as usize { + return Err(deserialization_error!( + "CommmitteeChangeIn", + "Invalid offset for store" + )); + } + let store = LightClientStore::from_ssz_bytes(&bytes[cursor..update_offset as usize])?; + + // Deserialize the Update + let update = + Update::from_ssz_bytes(&bytes[update_offset as usize..eip1186_proof_offset as usize])?; + + // Deserialize the EIP1186Proof + let eip1186_proof = EIP1186Proof::from_ssz_bytes(&bytes[eip1186_proof_offset as usize..])?; + + Ok(Self { + store, + update, + eip1186_proof, + }) + } +} + +/// The output for the sync committee change proof. +#[derive(Debug, Clone)] +#[allow(dead_code)] +pub struct StorageInclusionOut { + sync_committee_hash: HashValue, + beacon_attested_slot: u64, + eip1186_key_hash: HashValue, +} + +impl Prover for StorageInclusionProver { + const PROGRAM: &'static [u8] = INCLUSION_PROGRAM; + type Error = ProverError; + type StdIn = StorageInclusionIn; + type StdOut = StorageInclusionOut; + + fn generate_sphinx_stdin(&self, inputs: Self::StdIn) -> Result { + let mut stdin = SphinxStdin::new(); + stdin.write( + &inputs + .store + .to_ssz_bytes() + .map_err(|err| ProverError::SphinxInput { source: err.into() })?, + ); + stdin.write( + &inputs + .update + .to_ssz_bytes() + .map_err(|err| ProverError::SphinxInput { source: err.into() })?, + ); + Ok(stdin) + } + + fn execute(&self, inputs: Self::StdIn) -> Result { + sphinx_sdk::utils::setup_logger(); + + let stdin = self.generate_sphinx_stdin(inputs)?; + + let (mut public_values, _) = self + .client + .execute(Self::PROGRAM, &stdin) + .map_err(|err| ProverError::Execution { source: err.into() })?; + + let sync_committee_hash = HashValue::new(public_values.read::<[u8; 32]>()); + let beacon_attested_slot = public_values.read::(); + let eip1186_key_hash = HashValue::new(public_values.read::<[u8; 32]>()); + + Ok(StorageInclusionOut { + sync_committee_hash, + beacon_attested_slot, + eip1186_key_hash, + }) + } + + fn prove(&self, inputs: Self::StdIn, mode: ProvingMode) -> Result { + let stdin = self.generate_sphinx_stdin(inputs)?; + + match mode { + ProvingMode::STARK => self + .client + .prove(&self.keys.0, stdin) + .map_err(|err| ProverError::Proving { + proof_type: mode.into(), + source: err.into(), + }) + .map(ProofType::STARK), + ProvingMode::SNARK => self + .client + .prove_plonk(&self.keys.0, stdin) + .map_err(|err| ProverError::Proving { + proof_type: mode.into(), + source: err.into(), + }) + .map(ProofType::SNARK), + } + } + + fn verify(&self, proof: &ProofType) -> Result<(), Self::Error> { + let vk = &self.keys.1; + + match proof { + ProofType::STARK(proof) => self + .client + .verify(proof, vk) + .map_err(|err| ProverError::Verification { source: err.into() }), + ProofType::SNARK(proof) => self + .client + .verify_plonk(proof, vk) + .map_err(|err| ProverError::Verification { source: err.into() }), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::types::storage::GetProofResponse; + use ethereum_lc_core::crypto::hash::keccak256_hash; + use ethereum_lc_core::types::bootstrap::Bootstrap; + use ethereum_lc_core::types::store::LightClientStore; + use ethereum_lc_core::types::update::{FinalityUpdate, Update}; + use std::env::current_dir; + use std::fs; + + struct TestAssets { + store: LightClientStore, + finality_update: FinalityUpdate, + eip1186_proof: EIP1186Proof, + } + + fn generate_test_assets() -> TestAssets { + // Instantiate bootstrap data + let test_asset_path = current_dir() + .unwrap() + .join("../test-assets/inclusion/LightClientBootstrapDeneb.ssz"); + + let test_bytes = fs::read(test_asset_path).unwrap(); + + let bootstrap = Bootstrap::from_ssz_bytes(&test_bytes).unwrap(); + + // Instantiate Update data + let test_asset_path = current_dir() + .unwrap() + .join("../test-assets/inclusion/LightClientUpdateDeneb.ssz"); + + let test_bytes = fs::read(test_asset_path).unwrap(); + + let update = Update::from_ssz_bytes(&test_bytes).unwrap(); + + // Instantiate finality update data + let test_asset_path = current_dir() + .unwrap() + .join("../test-assets/inclusion/LightClientFinalityUpdateDeneb.ssz"); + + let test_bytes = fs::read(test_asset_path).unwrap(); + + let finality_update = FinalityUpdate::from_ssz_bytes(&test_bytes).unwrap(); + + // Instantiate EIP1186 proof data + let test_asset_path = current_dir() + .unwrap() + .join("../test-assets/inclusion/base-data/EthGetProof.json"); + + let test_bytes = fs::read(test_asset_path).unwrap(); + + let ethers_eip1186_proof: GetProofResponse = serde_json::from_slice(&test_bytes).unwrap(); + + // Initialize the LightClientStore + let checkpoint = "0xf783c545d2dd90cee6c4cb92a9324323ef397f6ec85e1a3d61c48cf6cfc979e2"; + let trusted_block_root = hex::decode(checkpoint.strip_prefix("0x").unwrap()) + .unwrap() + .try_into() + .unwrap(); + + let mut store = LightClientStore::initialize(trusted_block_root, &bootstrap).unwrap(); + + store.process_light_client_update(&update).unwrap(); + + TestAssets { + store, + finality_update, + eip1186_proof: EIP1186Proof::try_from(ethers_eip1186_proof.result().clone()).unwrap(), + } + } + + #[test] + fn test_execute_inclusion() { + let test_assets = generate_test_assets(); + + let prover = StorageInclusionProver::new(); + + let inclusion_input = StorageInclusionIn { + store: test_assets.store.clone(), + update: Update::from(test_assets.finality_update.clone()), + eip1186_proof: test_assets.eip1186_proof.clone(), + }; + + let inclusion_output = prover.execute(inclusion_input).unwrap(); + + assert_eq!( + inclusion_output.sync_committee_hash, + keccak256_hash(&test_assets.store.current_sync_committee().to_ssz_bytes()).unwrap() + ); + assert_eq!( + &inclusion_output.beacon_attested_slot, + test_assets + .finality_update + .attested_header() + .beacon() + .slot() + ); + assert_eq!( + inclusion_output.eip1186_key_hash, + test_assets.eip1186_proof.key_hash().unwrap() + ); + } + + #[test] + #[ignore = "This test is too slow for CI"] + fn test_prove_stark_storage_inclusion() { + use std::time::Instant; + + let test_assets = generate_test_assets(); + + let prover = StorageInclusionProver::new(); + + let inclusion_inputs = StorageInclusionIn { + store: test_assets.store.clone(), + update: Update::from(test_assets.finality_update.clone()), + eip1186_proof: test_assets.eip1186_proof.clone(), + }; + + println!("Starting STARK proving for sync committee change..."); + let start = Instant::now(); + + let _ = prover.prove(inclusion_inputs, ProvingMode::STARK).unwrap(); + println!("Proving took {:?}", start.elapsed()); + } + + #[test] + #[ignore = "This test is too slow for CI"] + fn test_prove_snark_storage_inclusion() { + use std::time::Instant; + + let test_assets = generate_test_assets(); + + let prover = StorageInclusionProver::new(); + + let inclusion_inputs = StorageInclusionIn { + store: test_assets.store.clone(), + update: Update::from(test_assets.finality_update.clone()), + eip1186_proof: test_assets.eip1186_proof.clone(), + }; + + println!("Starting SNARK proving for sync committee change..."); + let start = Instant::now(); + + let _ = prover.prove(inclusion_inputs, ProvingMode::SNARK).unwrap(); + println!("Proving took {:?}", start.elapsed()); + } + + #[test] + fn test_ssz_serde_inputs() { + let test_assets = generate_test_assets(); + + let inclusion_inputs = StorageInclusionIn { + store: test_assets.store.clone(), + update: Update::from(test_assets.finality_update.clone()), + eip1186_proof: test_assets.eip1186_proof.clone(), + }; + + let ssz_bytes = inclusion_inputs.to_ssz_bytes().unwrap(); + + let deserialized_inclusion_inputs = StorageInclusionIn::from_ssz_bytes(&ssz_bytes).unwrap(); + + assert_eq!(inclusion_inputs, deserialized_inclusion_inputs); + } +} diff --git a/ethereum/light-client/src/proofs/mod.rs b/ethereum/light-client/src/proofs/mod.rs index 23b9025e..e409f669 100644 --- a/ethereum/light-client/src/proofs/mod.rs +++ b/ethereum/light-client/src/proofs/mod.rs @@ -24,7 +24,8 @@ use serde::{Deserialize, Serialize}; use sphinx_sdk::{SphinxPlonkBn254Proof, SphinxProof, SphinxProofWithPublicValues, SphinxStdin}; pub mod committee_change; -mod error; +pub mod error; +pub mod inclusion; /// The proving mode for the prover. #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] diff --git a/ethereum/light-client/src/types/mod.rs b/ethereum/light-client/src/types/mod.rs index c63ca171..ccd9c291 100644 --- a/ethereum/light-client/src/types/mod.rs +++ b/ethereum/light-client/src/types/mod.rs @@ -15,9 +15,11 @@ //! - `beacon`: This sub-module contains the data structures used by the Beacon Node. //! - `checkpoint`: This sub-module contains the data structures used by the Checkpoint service. //! - `network`: This sub-module contains the data structures that serves as payload for the Proof Server. +//! - `storage`: This sub-module contains the data structures used by the RPC Provider. //! //! For more detailed information, users should refer to the specific documentation for each sub-module. pub mod beacon; pub mod checkpoint; pub mod network; +pub mod storage; diff --git a/ethereum/light-client/src/types/network.rs b/ethereum/light-client/src/types/network.rs index 984b10e6..4f31d3fb 100644 --- a/ethereum/light-client/src/types/network.rs +++ b/ethereum/light-client/src/types/network.rs @@ -1,4 +1,5 @@ use crate::proofs::committee_change::CommitteeChangeIn; +use crate::proofs::inclusion::StorageInclusionIn; use crate::proofs::{ProofType, ProvingMode}; use anyhow::{anyhow, Error}; @@ -8,6 +9,10 @@ pub enum Request { ProveCommitteeChange(Box<(ProvingMode, CommitteeChangeIn)>), /// Request to verify the validity of a proof for a sync committee change. VerifyCommitteeChange(ProofType), + /// Request to prove the inclusion of value in the chain storage. + ProveInclusion(Box<(ProvingMode, StorageInclusionIn)>), + /// Request to verify the validity of a proof for the inclusion of value in the chain storage. + VerifyInclusion(ProofType), } impl Request { @@ -34,6 +39,24 @@ impl Request { bytes.extend_from_slice(&proof_type.to_bytes().map_err(|e| anyhow!(e))?); Ok(bytes) } + Request::ProveInclusion(boxed) => { + let mut bytes = vec![2]; + + let (proving_mode, storage_inclusion_in) = boxed.as_ref(); + + bytes.push(proving_mode.to_bytes()); + bytes.extend_from_slice( + &storage_inclusion_in + .to_ssz_bytes() + .map_err(|e| anyhow!(e))?, + ); + Ok(bytes) + } + Request::VerifyInclusion(proof_type) => { + let mut bytes = vec![3]; + bytes.extend_from_slice(&proof_type.to_bytes().map_err(|e| anyhow!(e))?); + Ok(bytes) + } } } @@ -62,6 +85,20 @@ impl Request { let proof_type = ProofType::from_bytes(&bytes[1..])?; Ok(Request::VerifyCommitteeChange(proof_type)) } + 2 => { + let proving_mode = ProvingMode::from_bytes(&bytes[1..2])?; + + let storage_inclusion_in = StorageInclusionIn::from_ssz_bytes(&bytes[2..])?; + + Ok(Request::ProveInclusion(Box::new(( + proving_mode, + storage_inclusion_in, + )))) + } + 3 => { + let proof_type = ProofType::from_bytes(&bytes[1..])?; + Ok(Request::VerifyInclusion(proof_type)) + } _ => Err(anyhow!("Invalid request")), } } diff --git a/ethereum/light-client/src/types/storage.rs b/ethereum/light-client/src/types/storage.rs new file mode 100644 index 00000000..68d642d8 --- /dev/null +++ b/ethereum/light-client/src/types/storage.rs @@ -0,0 +1,12 @@ +use ethers_core::types::EIP1186ProofResponse; +use getset::Getters; +use serde::{Deserialize, Serialize}; + +/// The response from the `eth_getProof` RPC method. +#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize, Getters)] +pub struct GetProofResponse { + id: u64, + jsonrpc: String, + #[getset(get = "pub")] + result: EIP1186ProofResponse, +} diff --git a/ethereum/programs/inclusion/Cargo.lock b/ethereum/programs/inclusion/Cargo.lock index 3af8f118..1eb5327c 100644 --- a/ethereum/programs/inclusion/Cargo.lock +++ b/ethereum/programs/inclusion/Cargo.lock @@ -2,12 +2,44 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "anyhow" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + [[package]] name = "base16ct" version = "0.2.0" @@ -29,6 +61,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "bitvec" version = "1.0.1" @@ -73,12 +111,55 @@ dependencies = [ "subtle", ] +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +dependencies = [ + "serde", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "num-traits", +] + +[[package]] +name = "const-hex" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -132,6 +213,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + [[package]] name = "digest" version = "0.9.0" @@ -187,12 +279,61 @@ dependencies = [ "zeroize", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + [[package]] name = "ethereum-lc-core" version = "0.1.0" dependencies = [ "anyhow", "bls12_381", + "ethers-core", "getset", "hex", "serde", @@ -201,6 +342,55 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers-core" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" +dependencies = [ + "arrayvec", + "bytes", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array", + "k256", + "num_enum", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + [[package]] name = "ff" version = "0.13.0" @@ -212,6 +402,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + [[package]] name = "funty" version = "2.0.0" @@ -263,6 +465,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hex" version = "0.4.3" @@ -287,6 +501,44 @@ dependencies = [ "typenum", ] +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "inclusion-program" version = "0.1.0" @@ -295,6 +547,22 @@ dependencies = [ "sphinx-zkvm", ] +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "k256" version = "0.13.3" @@ -309,12 +577,76 @@ dependencies = [ "signature", ] +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.68", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -327,6 +659,31 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "pairing" version = "0.23.0" @@ -336,6 +693,32 @@ dependencies = [ "group", ] +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -352,6 +735,29 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -385,6 +791,22 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bitflags", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "unarray", +] + [[package]] name = "quote" version = "1.0.36" @@ -430,6 +852,44 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + [[package]] name = "rfc6979" version = "0.4.0" @@ -440,6 +900,83 @@ dependencies = [ "subtle", ] +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scale-info" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "sec1" version = "0.7.3" @@ -474,6 +1011,17 @@ dependencies = [ "syn 2.0.68", ] +[[package]] +name = "serde_json" +version = "1.0.120" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha2" version = "0.9.9" @@ -497,6 +1045,16 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "signature" version = "2.2.0" @@ -547,6 +1105,34 @@ dependencies = [ "der", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.68", +] + [[package]] name = "subtle" version = "2.6.1" @@ -581,6 +1167,18 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + [[package]] name = "thiserror" version = "1.0.61" @@ -610,18 +1208,59 @@ dependencies = [ "crunchy", ] +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "version_check" version = "0.9.4" @@ -634,6 +1273,88 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/ethereum/programs/inclusion/src/main.rs b/ethereum/programs/inclusion/src/main.rs index 3b29eefa..18db14ca 100644 --- a/ethereum/programs/inclusion/src/main.rs +++ b/ethereum/programs/inclusion/src/main.rs @@ -3,6 +3,73 @@ #![no_main] +use ethereum_lc_core::crypto::hash::keccak256_hash; +use ethereum_lc_core::merkle::storage_proofs::EIP1186Proof; +use ethereum_lc_core::types::store::LightClientStore; +use ethereum_lc_core::types::update::Update; + sphinx_zkvm::entrypoint!(main); -pub fn main() {} +pub fn main() { + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-start: read_inputs"); + } + let store_bytes = sphinx_zkvm::io::read::>(); + let update_bytes = sphinx_zkvm::io::read::>(); + let eip1186_proof_bytes = sphinx_zkvm::io::read::>(); + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-end: read_inputs"); + } + + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-start: deserialize_inputs"); + } + let store = LightClientStore::from_ssz_bytes(&store_bytes) + .expect("LightClientStore::from_ssz_bytes: could not create store"); + let update = Update::from_ssz_bytes(&update_bytes) + .expect("Update::from_ssz_bytes: could not create update"); + let eip1186_proof = EIP1186Proof::from_ssz_bytes(&eip1186_proof_bytes) + .expect("EIP1186Proof::from_ssz_bytes: could not create proof"); + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-end: deserialize_inputs"); + } + + // Validate the received update + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-start: validate_update"); + } + store + .validate_light_client_update(&update) + .expect("validate_light_client_update: could not validate update"); + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-end: validate_update"); + } + + // Verify proof against finalized state root + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-start: verify_proof"); + } + eip1186_proof + .verify(update.finalized_header().execution().state_root()) + .expect("verify: could not verify proof"); + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-end: verify_proof"); + } + + // Output the signers sync committee hash, the attested block number, the hash of address + storage keys + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-start: output"); + } + let sync_committee_hash = keccak256_hash(&store.current_sync_committee().as_ref().expect("Store should have a sync committee").to_ssz_bytes()) + .expect("LightClientStore::current_sync_committee: could not hash committee after inclusion proving"); + sphinx_zkvm::io::commit(sync_committee_hash.as_ref()); + sphinx_zkvm::io::commit(update.attested_header().beacon().slot()); + sphinx_zkvm::io::commit( + eip1186_proof + .key_hash() + .expect("EIP1186Proof::key_hash: could not get key hash"), + ); + sphinx_zkvm::precompiles::unconstrained! { + println!("cycle-tracker-end: output"); + } +} diff --git a/ethereum/test-assets/LightClientFinalityUpdateDeneb.ssz b/ethereum/test-assets/LightClientFinalityUpdateDeneb.ssz deleted file mode 100644 index 190f623d..00000000 Binary files a/ethereum/test-assets/LightClientFinalityUpdateDeneb.ssz and /dev/null differ diff --git a/ethereum/test-assets/base-data/FinalityUpdateDeneb.json b/ethereum/test-assets/base-data/FinalityUpdateDeneb.json deleted file mode 100644 index 4209ebec..00000000 --- a/ethereum/test-assets/base-data/FinalityUpdateDeneb.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "version": "deneb", - "data": { - "attested_header": { - "beacon": { - "slot": "9540379", - "proposer_index": "1030861", - "parent_root": "0xf798244689e678cf424f8288661089325ec5c7c326ef97fb9d49889d56933559", - "state_root": "0x1082e5af54efe468445b715403446e54fb926592dac1cda1118ac798811fad3a", - "body_root": "0xcf3d3ef61c322d0b17dea752d2262141d5b224f92b8f1a2e161c65b487259466" - }, - "execution": { - "parent_hash": "0x399e2ef6f18eae519307a252dbf92f8557675df167746fb794ae13f8dac2db68", - "fee_recipient": "0x1f9090aae28b8a3dceadf281b0f12828e676c326", - "state_root": "0x7ae8a9bcbef490b8a07b24604ec142d5cca83f8fbcb6d68b55816693e395d04c", - "receipts_root": "0x3977e8a7d846f6efd2387ffbff542a8a94737d8ba09e7ecaee1f43067d1c1575", - "logs_bloom": "0x1025e403c1446145104502e0f281066a11102103184108c16109c0871422b488d051cda291228a366600b004414701004363a2599e4a39203df0b7d1c8ae8ac0e894658d911b288b794e6c2c996806681909003311545933390614418c6e145e887a08de4260002020584018c4053e116284044b108094e86484429f02484c821f10e2d0c921a200204921513321860d1c62269d895684487721a0f26698321a770840421922a0221a0514e4888114082631854171e61a61042b3610111080241395281a01181f600146147a5021198788b451a31e024895ad08227ac810e117807ca043cda8a06243840d80191d0422802d10c3c20dacc4020b847031c9b454", - "prev_randao": "0x585045159e8df327f4c645a413a37f01a18a74535bda0ec2fa348cdf6b533935", - "block_number": "20333644", - "gas_limit": "30000000", - "gas_used": "12839308", - "timestamp": "1721308571", - "extra_data": "0x7273796e632d6275696c6465722e78797a", - "base_fee_per_gas": "13438429010", - "block_hash": "0x3cd5f91351a7442322504afbefc8c7153a97e0324a2877864c5dd320dd691803", - "transactions_root": "0x8adc6b673b77b9764bc247b81442e17e361de8662d4a9447e283458f47160638", - "withdrawals_root": "0xf93a9cd23df0fdde3f5abaca7ea5aa95f352153e1c562dcfb0f18b59b11a3334", - "blob_gas_used": "0", - "excess_blob_gas": "524288" - }, - "execution_branch": [ - "0x51077c50674f5b874829289bfbb20ebfbe4360719e5da4372a644b1d65db1534", - "0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb", - "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x4dd83b28b616da7b8e62e1d11354f08b7deb27a367181eec9f1727c9dd41324c" - ] - }, - "finalized_header": { - "beacon": { - "slot": "9540288", - "proposer_index": "464177", - "parent_root": "0xc59d5f837314f77bdb8dc4b27d6e471114fc1992fd6c0aff665237e17dfde6ae", - "state_root": "0x2dfcc738931e9b5d637c5a70c7a9ed89ebfcf8feda50ded9f3bb4d09b711f347", - "body_root": "0x314263dcd1388c65250f53189566550d115d11fadfbc7398a30c27813a9ddbfe" - }, - "execution": { - "parent_hash": "0x8d71137605f82546fe06bd0b3687ccc1e83b3f56ff902323e85bdeeb913defaa", - "fee_recipient": "0x388c818ca8b9251b393131c08a736a67ccb19297", - "state_root": "0x0d336c739b98287ce3ea167afaf707f7b51be0ee21d99908ff613cec660b3be4", - "receipts_root": "0xe7af8561f69c7967451df7baefd141d126a5e880e39ee29e0d8b5d793ad45475", - "logs_bloom": "0x802100828481190221088840c219080810030091000011800451081a940080c002828000a0802c280600285101400504a200c0a18800221604015026002e228e06048009222018290c24530a801440f83053001101489c02270291009aa2c1000581841e030000a00008f21420916d51220101253203042200035af891084b421108004a8002495891480e6301310c27002020010140040a4494215464108870020002480000b106000010f2ec0824a000214281102004000be0248104008041082546e28f0d397449080005821988814003400f402008bc158103020423a050407328469918100040048183a0009ad30003d0000a2054c40008923050724005", - "prev_randao": "0x9c5fad8734c5398a657e98cf4ed35c0a507d382962888cb9116ba14b0e2d6a06", - "block_number": "20333553", - "gas_limit": "30000000", - "gas_used": "5227479", - "timestamp": "1721307479", - "extra_data": "0x4e65746865726d696e64", - "base_fee_per_gas": "8049624358", - "block_hash": "0xfe187994b93cf6933ff5c6d303d31e793327be421f849107d252bc2b1f53c72a", - "transactions_root": "0xe6f5e0bfe69d649e1a404cd441f022da50573ba52c47aa6aa90c9a1886270363", - "withdrawals_root": "0xe3c12ad9bded2e7b82055debf8393ae896ac74e98c8558291644332a6b951a16", - "blob_gas_used": "786432", - "excess_blob_gas": "393216" - }, - "execution_branch": [ - "0x4c0371ead9c69762f7b92c2ebaaa6ae76649f61b17c15a67a7beff695e082011", - "0x8fdc5e72d0611568b4a150d1ff4d6e0238618c34f38c4babf18bd089aeeb297c", - "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x656e5dd6facd02d0863394028d8479a181e292f74415540fe3688491ce1ef6c5" - ] - }, - "finality_branch": [ - "0x968c040000000000000000000000000000000000000000000000000000000000", - "0xef6be8da8680f021248447fbfb10280650641ba5859061badf1373d8dd833b31", - "0x97c9cc0bdcc3d1407dcbfc521bc98888a3dc0b854b7df5540004c54cadd66465", - "0xe61c68acd7207431ef86c67bbb1cfe84e91415454d75e8bb09e9b4f86dd72a7c", - "0xc4179e512f8ee500f12a80a46089bc7917b5165649813b7843d4272bddad0786", - "0x80c2fbd4d0767161528730756882e40aaf519e3192765e98c5911cdf5c8d080a" - ], - "sync_aggregate": { - "sync_committee_bits": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffffffdffffffffffffffffffffffffffffffffdfff7ffffffffffffffffffffff", - "sync_committee_signature": "0x95cc6649d547b24f6a7b52ac16e3b483ebc94e80b0ea9806e92cbd30b7365f64c3f7320f5698f7786bc952943712cb9d10052c0b0e243b68b0b20ebc8c3097192def9154e351380c783d94aaf700d03aa7283503d3f28d9881aee3603467e6e3" - }, - "signature_slot": "9540380" - } -} \ No newline at end of file diff --git a/ethereum/test-assets/BeaconBlockHeaderDeneb.ssz b/ethereum/test-assets/committee-change/BeaconBlockHeaderDeneb.ssz similarity index 100% rename from ethereum/test-assets/BeaconBlockHeaderDeneb.ssz rename to ethereum/test-assets/committee-change/BeaconBlockHeaderDeneb.ssz diff --git a/ethereum/test-assets/ExecutionPayloadHeaderDeneb.ssz b/ethereum/test-assets/committee-change/ExecutionPayloadHeaderDeneb.ssz similarity index 100% rename from ethereum/test-assets/ExecutionPayloadHeaderDeneb.ssz rename to ethereum/test-assets/committee-change/ExecutionPayloadHeaderDeneb.ssz diff --git a/ethereum/test-assets/LightClientBootstrapDeneb.ssz b/ethereum/test-assets/committee-change/LightClientBootstrapDeneb.ssz similarity index 100% rename from ethereum/test-assets/LightClientBootstrapDeneb.ssz rename to ethereum/test-assets/committee-change/LightClientBootstrapDeneb.ssz diff --git a/ethereum/test-assets/LightClientHeaderDeneb.ssz b/ethereum/test-assets/committee-change/LightClientHeaderDeneb.ssz similarity index 100% rename from ethereum/test-assets/LightClientHeaderDeneb.ssz rename to ethereum/test-assets/committee-change/LightClientHeaderDeneb.ssz diff --git a/ethereum/test-assets/LightClientUpdateDeneb.ssz b/ethereum/test-assets/committee-change/LightClientUpdateDeneb.ssz similarity index 100% rename from ethereum/test-assets/LightClientUpdateDeneb.ssz rename to ethereum/test-assets/committee-change/LightClientUpdateDeneb.ssz diff --git a/ethereum/test-assets/LightClientUpdateNewPeriodDeneb.ssz b/ethereum/test-assets/committee-change/LightClientUpdateNewPeriodDeneb.ssz similarity index 100% rename from ethereum/test-assets/LightClientUpdateNewPeriodDeneb.ssz rename to ethereum/test-assets/committee-change/LightClientUpdateNewPeriodDeneb.ssz diff --git a/ethereum/test-assets/SyncAggregateDeneb.ssz b/ethereum/test-assets/committee-change/SyncAggregateDeneb.ssz similarity index 100% rename from ethereum/test-assets/SyncAggregateDeneb.ssz rename to ethereum/test-assets/committee-change/SyncAggregateDeneb.ssz diff --git a/ethereum/test-assets/SyncCommitteeDeneb.ssz b/ethereum/test-assets/committee-change/SyncCommitteeDeneb.ssz similarity index 100% rename from ethereum/test-assets/SyncCommitteeDeneb.ssz rename to ethereum/test-assets/committee-change/SyncCommitteeDeneb.ssz diff --git a/ethereum/test-assets/base-data/BootstrapDeneb.json b/ethereum/test-assets/committee-change/base-data/BootstrapDeneb.json similarity index 100% rename from ethereum/test-assets/base-data/BootstrapDeneb.json rename to ethereum/test-assets/committee-change/base-data/BootstrapDeneb.json diff --git a/ethereum/test-assets/base-data/UpdateDeneb.json b/ethereum/test-assets/committee-change/base-data/UpdateDeneb.json similarity index 100% rename from ethereum/test-assets/base-data/UpdateDeneb.json rename to ethereum/test-assets/committee-change/base-data/UpdateDeneb.json diff --git a/ethereum/test-assets/base-data/UpdateNewPeriodDeneb.json b/ethereum/test-assets/committee-change/base-data/UpdateNewPeriodDeneb.json similarity index 100% rename from ethereum/test-assets/base-data/UpdateNewPeriodDeneb.json rename to ethereum/test-assets/committee-change/base-data/UpdateNewPeriodDeneb.json diff --git a/ethereum/test-assets/inclusion/LightClientBootstrapDeneb.ssz b/ethereum/test-assets/inclusion/LightClientBootstrapDeneb.ssz new file mode 100644 index 00000000..6a55781c Binary files /dev/null and b/ethereum/test-assets/inclusion/LightClientBootstrapDeneb.ssz differ diff --git a/ethereum/test-assets/inclusion/LightClientFinalityUpdateDeneb.ssz b/ethereum/test-assets/inclusion/LightClientFinalityUpdateDeneb.ssz new file mode 100644 index 00000000..58a55079 Binary files /dev/null and b/ethereum/test-assets/inclusion/LightClientFinalityUpdateDeneb.ssz differ diff --git a/ethereum/test-assets/inclusion/LightClientUpdateDeneb.ssz b/ethereum/test-assets/inclusion/LightClientUpdateDeneb.ssz new file mode 100644 index 00000000..975e70f4 Binary files /dev/null and b/ethereum/test-assets/inclusion/LightClientUpdateDeneb.ssz differ diff --git a/ethereum/test-assets/inclusion/base-data/BootstrapDeneb.json b/ethereum/test-assets/inclusion/base-data/BootstrapDeneb.json new file mode 100644 index 00000000..695d177d --- /dev/null +++ b/ethereum/test-assets/inclusion/base-data/BootstrapDeneb.json @@ -0,0 +1,563 @@ +{ + "version": "deneb", + "data": { + "header": { + "beacon": { + "slot": "9567456", + "proposer_index": "565124", + "parent_root": "0xc01e019b5922b265a8d51a6e21207d63e6316bee198304549aac807af2d25511", + "state_root": "0xa51c31780fa13238750a19af0de6a73e6c1020b2093548568764498764c7184a", + "body_root": "0x5f649113f29921c36e3ac8087dc8d5ed3d9f459f665d8bea616d6be914a23cde" + }, + "execution": { + "parent_hash": "0x7757c28729aa0653f1f5f26d3c89b8b7a25acf7198f18a2498f476146065991d", + "fee_recipient": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97", + "state_root": "0xc51ad191ded785644e792e03583a54dcd4329d605560734c93f6cd9b5eaa9315", + "receipts_root": "0x490ba5474de11f90b2b557f668d907ca9773a38b90a6c6493b2023e520e1a4ae", + "logs_bloom": "0x93273d188d006101239203f3ac910a4d111d7893050360c70619c6ebcea38cc084e5b5f5211f629846d61b5a3f2e91941fa3894989a230e26bccf020b53fc9741604de090fcf1889ec58d76ab0e0b8ba040f19b142523e336dd670c1d8e727101aaa5c40e66083f2683c4db76882eda1a39c46c120858e148260689cc41801800a2389481049f28639d86b6c52a3c412664196031b68528945b9297a64d49aca0fa4113dcab8a1079226b9e818983fba1e09c4253943824ab4aa24bb080cc271c7b034a707d99e0079e4ce1098eb98c5270f200e1711c4342ca1fd0657052412f0d7b57b27d3a58856cc5c95a06086568dae3810a8b46ed4671d0376b3c4dc34", + "prev_randao": "0x53503a5d6718f39e2fcc0db45d04da6462f06095459a05b9c7bdf7f495d87058", + "block_number": "20360596", + "gas_limit": "30000000", + "gas_used": "11805504", + "timestamp": "1721633495", + "extra_data": "0x546974616e2028746974616e6275696c6465722e78797a29", + "base_fee_per_gas": "3420341872", + "block_hash": "0x8a5009007f9ba1af6a5ac8142fefee972a3e96d21e3db6498fbb6d410376400e", + "transactions_root": "0xbfacf36d75b4b5b6250c73db298a08ba95c8eca086c9f06e442843369eafec8a", + "withdrawals_root": "0xf8601e4524535d5dd043c3f6835df7b0a8000a2f2f3d23543e8d389a6ec3de45", + "blob_gas_used": "0", + "excess_blob_gas": "0" + }, + "execution_branch": [ + "0x68d7d6fc8ea273478bd7c6c4d9b6f97d55ec5da34f7e9f484af1cdf930c3aac5", + "0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb", + "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x5d83dd16f26340a38fe78f19d2d18e2e4c817abc896327574d5b7a4869386ff2" + ] + }, + "current_sync_committee": { + "pubkeys": [ + "0xb4ef2ec5e6709e75dc817f73a3a1d073fc3a038f061923f96233b22d1dda9bdf7e9a53277f0e89d657182f3d3c0bf5e5", + "0x98989679016a284797ba3522c7bcd2255a687225ce71cea44c46c6a6ac50a9e1ced5b6cd9f720d6397bbb554b764cc04", + "0xb859f0c7803f4789e9b3c64dcec3d63d1c59c35067d29e5fce354fb5342c532fcf5ba51fde58f8890cad82b2aff3059c", + "0x9034a6e81126add2d5d353b8c21797acd1642bd6d52409d71f79af84179e2c9036130bce0669163662b977d5cde28857", + "0x811a6887e8cc4c5c09eea9c52a170f53931d75190e69f4f550d946aba8e23abf0f6eabb0305f15d60088abe60a600fbc", + "0xa2119c76d6085630fe62d79608343166c0b3fe6dcae79d38764a4bd0a7264e3fc7eb15f5192a46b0c22362cd9d220b94", + "0x936662e86c0db78035cd3b22e90bd4ea646ad040a9c3bfe630e2ce97475d1f5a8c31885d10d4cf93e9cb6e9274e3a4f2", + "0xab54b137af28d7cc1e1cb6df59b585bc915c5400cac5542533a8572131d8a8763b65a640672701371dc2b66ac0e095f5", + "0x95d139ce26d998286bdf83831d72f70b0a645b3a97a8f5e9b83a48f0dccd7f88e726ab1477b107ed432b168afb24b932", + "0xa74274455b71b7d9cfdcd6425673e1a3b3227c22a4d824e2b739ad2d91fe108fa6b06a4a146bdb3711e6b8ed8bbd497a", + "0xb6a421e39ccd3b1df1b8e5a6091f6de4862678bd0c8ad3b2a1c5a6bab0468153b3f24a98057115578680390d93885080", + "0xb5498f8c4827cb1881a03c2dda9762f2abe4e91550bb2db34ec6a5b77696f7a45b87a16467e450bd6ee4558c0a6a821c", + "0xae2a69c10d703da4da06307b9bb07c834671448355757b625bed33de793c47a164a5524f1a88953dcb1f0886063b23df", + "0xafaa74043a74522b179d845781e7260510227d0d43f10f35cdd57fbf92d3fc9db70543ace547bae47ada52d987a0b858", + "0xad40410f7d985300f588be18571f73266a9eef2cebb566ff46a7e0bc9241de09cca6964a126c31a015c3e0091bc9e50c", + "0x8409a68ad87a0d81d0ead766c6d713f063dd6f1776ef1e36a33bd6b308ff729c86ab51ff2c6d1d3f50cbac87472d9162", + "0x8d888ace876701b85de43f941c268a84cb496c2a7767103d8e3fd85324070c5a8c944790e4eea9b4b64c5b77cad33a4c", + "0x911912d271b971de2a751681f1b05c1512435d30eacb48bd7168f142414ca0bf80b237046b015c063c65724c65efdc0a", + "0xaca20e5d5b9571b8fad99fa24341fff0d3a666cd62901ea44bb73523165cc88e80eae66855cdbdec4841054db9ae8258", + "0x8eed1d89fb64d82b62ce8dc44910f541a947ec1c0856bad355f7ea8fbe57eecaf1a6b5aa145cdc87fcaf38c8764feb2f", + "0xae08e6569a4c60db7bc19db8356ff1fb8e0db8ef4990823f8af82c402d7b2f0a766c93cb5ce89ef2687198f9b83f7252", + "0xa055f03ac82a055dc5af35ca8723cdc6859f9bbe377bc45346546caf88c4ed86c973a612763c296542663ea0451137d3", + "0xab57ec3320347f1e27a2fa779e82f4ebebd9a23e13e55efaf932535f4fb978230f3d44cbdf6f5a765f6446fdfba1d683", + "0xaa44cf009cd7a0e8b3113e142e3ab1738f98d774603baf1e1de96666b069796726f6bb1b3541b2e5a4dcde83deaa4bd1", + "0xb5ed67ab63d021990b2ae1e87cb7bf41467832f4e6221726296341c0a225cb80203c93c2fa54950340cb8b40c99cc69b", + "0xb75bd545be51e8c473fe17b3b93e1176b36dce3e6c8c3b504bf73a3573e7ab4aded7981e61201c1642c22ebb0333b8fa", + "0x8d9cd76e7b0cade496bd3936556e379f49b59bd81ce0e3cf5f7fead67a0ba03cc9f76e6e0b30ac32f20310a8b2d56688", + "0xb7ab605214f5f120bcda6cb0fa9876fab477e89c265682941699a126cdcb6f279f31d98ca9d7fa0c6ba76f7d2c983edd", + "0x86aad05d8552e999bc21f6e6d0e94df627e7c58ffb1d78d7513039d821dc7c5e08134475d51b90f7a22b3c238e904bd5", + "0x842e814e47a2f700e1e308d30ba82f2cd5dcdd45c0088b9f949e65244aee36efa3dec55e6af3b48fabdeffca72ce9083", + "0x95a7a509d3f90615b4d0de6dd3a07c4faf9ee5eb33f677318523c58ab97ac3699c4175add7795b3a3c41e37cfaa29b44", + "0xadd68367f6900d6cbed5d260de002a42a38b1ec367a3dc649022af7f73c0862a46d7e02288badd2a94be509b17bb9b60", + "0xb51156ca598b825c8b3ce328c58650081adfe5758c0765408246c01612be6b63819a96042156ebef7a39debf3f54cbf9", + "0xb466c3f9dd39a36675b8624aa995eb7301f3043de406f35df248e8ac6c4a5c9e91a966f83d8da2eb7a4602152518f04c", + "0xb2637739bde896469084406c8449182c201f9cf8ed44e34bb5e5c1aecb2015f5e2ca4958b54e54682c779b44db8cb8e3", + "0x832b4dc1cd62ce71e5740a006c261bcd0549b9a613af34852f77174f197bc4b925485b5e75c785571a64fbe4811e4da6", + "0xa0790e91177318ce9d089276ee4b60b23febe6fbcd36a5d3edafba634ba55dc3ddd2abb30ad0129db8efb2623387a99d", + "0x986a9a7b37c62ff818951d51e3addb2f8544325ec23a2af336bb0334196dbb7dd00e0ed0113c17b41e45d54a342d056f", + "0xb2c67cd009034880b6827b20afa3ddfc055f6b850d70083c03e5941713bd42faba1028af71c7fa38091a71b100d0ffce", + "0xa699575fe6468ef7be3e020241832524801ec9282a49cd9213b9a9141911ad780b644d5ecec69cc412ee16409d325b88", + "0xa10897dd0f5bb85e795c6b0713fe7a3977510cfa9aec4f06c0f0d713b11613996e4688a9b56c525a3c3833adb11299e2", + "0x8f37520633221c75ed0a071d7116c7ba38f7ae81031a7114d0870a5fa6b0e3a01d38e40a91614ef916363450094d8756", + "0xa3fd5dc49e6c0a0b8c1c7acba1b4685b4fd5af2c01f5cd347085836aea5d9be07c7d2f667fcd9776c4d4ad232a2f3f37", + "0x82b8ca4fdff9ec8b150166ad99863c508de9d01980ef81b0a7eb605f816d379af6bf9944668eb5e4a3813c3a47a3406c", + "0x85b7a6ab8e0a02067141044697d98e6814e73b0700127abe7a8f13a500708ce342ddaa8a7b9cfd8e1704d9b5d40735c5", + "0x80f9bf026a20238cabafa50b486d9978830e1af1d67156f8cc8cf72b474b29ab53595dca6c7114f681638c1350fa9614", + "0xb88c7b7432538a4f42615c4d2ed510405ffa2bb7767690d2d136782606d8dfcef04790894eab3b4a7674a30b61e444ed", + "0x84ba57ccb080bd9091e1dbe38cbe94e059877d811afc5b21801b10aef2caa3f02f0fb3454bb0fe27f303ada8ed28a7a8", + "0xabd04664b305a3e9ccac7713d0a40a7f34a007b7f82fe24232a54ff4ad52d5edb436e88791fb62a615342debb09086be", + "0xa1245eb7e10ffdd9c05c04892808aa434131dd420a505efa8bfbbf59c523efa8658d852b021223d093961d016c7b3a7d", + "0xa82da85a14d6b98d1fb995a1438b9ca83c181751f6bf21bd27f51c1426b5cab227610296598fe4add2aaba5cafef8f64", + "0xa3870e839665244995e8c250b28de53c216814bc25a20250a36cb111f6f2f333c087c822ffd696367eeffcb36ba65a97", + "0xb57a9bc2058d6c041c18ccbe52fbbbb22ebfc81c579e710fed1a23680c8068187232c086da9c02e962407958681a3ed8", + "0x9576a6e700d7bcc83d3ccadf69124f7ee1e2aaa9b4d7663398dae85d45131556d2e2e66e2a47c16f782533be249094b6", + "0x85c706d948b58ba93fee178787aa9cf26c6cad0c7369ca97472a24b1a30d88ced1c3355f8da17e92fd48a98261fa8fbc", + "0xabde70e2d2a2821c77f3e982b973459d7c8ada5197d05b81712491ca85dca8829440349a7d8fe82ab9b4c4b5cf76fd3a", + "0xb2d03579b90a617defd65809ae2b96f2e0ad3a84e7405dd8b953bb400c13f5a4a9faa3bdba5d749af25c8233ce420d3d", + "0x84a05975b607ee25ba7c76391eaf78334467fdaf0c5c1eb9cdc1f09fe7a7b3124d144c06926ccd51578820f602c3f8e1", + "0xaa4065634ecad096f71880afe10f0fbe9328b473f79032f34db1c2c39ac44b8cacb3bc189163e00192a6dadcb8c29477", + "0xa9fddf562e4272fb9a4a057842f80d2d24a693e9214e16af76ccaac86f7e1956c221ac6508fcf684d5d3d93e028b2927", + "0xa65a317c233f423ae97f023c3cfdf4493473437d9605e95e7093e7169f55cd5a4f5477deca5d82d437d0cba7c75f8420", + "0xaeb0e393be630744e39656d02d913bfa89aabde73d51be9eec4ad16a172de02835e62fe97b1fa3b574576a1526bbd5b3", + "0xac79c2344ef704c083bb12b48eacc5f410438c14ee86972e8b13fe0d8b2a3ef8e968bbc1ed3ff6e87509160a0b140f16", + "0x834c7b39d0fc5ef89fbd89cb63c2794d5d176cd85bcb1417f882c36d62139ea6d25b0b24f022df3ed2c327eac173d98d", + "0xab7ca731426957d2d9e16584667e82e0c1c077d457bb767a5504735da0244bd28dd943a58d2441b2b0a895ced711a4d2", + "0xa13a4931a9472a7880769526539d18763da5fff374a84ee5d514a1dabd94dd9780254ccb4ae36abcb5cb849fa13bd85d", + "0x928ca3ffc0dfa874bf6a5693f38ea946a925f3d6d9777e58abf6a404d4bd6abf4d28b281b701f24f2452a6ce3a105861", + "0xa33b76dec7c4d43476592ddb180320d989ea53f40a9531c5b27cf51a804c997faddebdfd9ce78b19b88ea79157994998", + "0xb3a37d349c9e1bbd70824b90f5f98152f7f2b9f101cf12b13b58bf6f59c25c123682c562b240ac8297e2723b0b1054b3", + "0x94fab9a2f93a7699239e4e84b26469d430e74ee137d9c4d3085d34922ef69ed71653f909654127c52fe1c36373b5a2cd", + "0x990f7e51416013c433691b974e13a3a1ad126e1a2c9530446356a31ffaeb9d0e81e32eefd0873665145b4eac32b6afcd", + "0xb2ea0c67cff600a8d920787dff8ef5e3f6397b4e1218b12f7d5bd9e6d775bc2f6408cd91d33def563569ac6b0edb1d88", + "0x99f83488ff6b8935c55492b4bf56726d04c84338e8502a0d357acc16f54f63f0d3cb570c9d05b847676bc653e2ede7b7", + "0x8d2e99c65e841b78a0e02559f0922a46105a0fe6fda83e9a99919766ba79278fed17af8b1d8ea3842abf65916241268e", + "0x94a2adaf8befbf952276bd98a5fd2d4c226f577ac3deed47db1db9a8db45d17e8fe08dc84ef2f4221c7c9a70dece1479", + "0xb6a38ac50bb80edb236e77a01744d2057c8569d3873a14feff81c219e3451c8455aee77da989f82d31031955b7d690cd", + "0x8044e124675db3d59106d3ae617235147f98248f122e27bbfd914a3335bbb6381225384310a9f5019b5bf384223d9c32", + "0x85685df5c79a675422ec78e3eef11fea56a8c73b9f49cf26237e2c85f9e01ef91e08ee749d422dbe7357d2652fb02027", + "0x86b7b17c4ec94f5201288080955232b88e01095fe849433af5310126526fb2cccbeb3b3bb03d3bfeef971e8b7dcef5ec", + "0xa16fe26d602ad5a9185436ceca847627e19495144f9c040df87cfd758457b44951e2e0e640f032d323024acab208e2f3", + "0x94221915a4ee03b79ffea9fcd2ce64c080bb28f17b9201bc595cc9573c21d5a3e676410b704211e00d140fcc8b5f549a", + "0xad7b92e3c1869611cc2f8c9a4b01104c46fb8634e385ca7b93d7625404b3e3fbd1349898770d32b03bc529598ce7e30c", + "0x8d50a2bc55a48689082e48cda911983c0c0df32cad4903c2c620d7c53fb75ba1fe70fdb6b98f12012ba649c315a56b79", + "0xb38650f1d799c4a289219e0efb1cb9e1ed190a79a77e9a6834bd28a61c90f0b9e308272501713f1d19695311eb35bc2c", + "0xa53aee7572baf69a68d7af62910a79da16c123b1fc56a4933a754b9e7df9e48ba3fe91174d2d4d1a4048507d3e11e201", + "0x93f6ba9eb4a87a370ab83f00457ad5eceb3eda920c715089fd57edce784f007a7badd3baf1253b35881dfec5acd3b73b", + "0xa7d0d1fb4a6f0b945af76034d2e44d63ac6468d2274d26180b34d78b32198113e14a207430c0a2254c40b441bb37c4e4", + "0x85ab971b611e80686a5581ddc2428851aaefbc8c0e0dff881e57c470016bcc76ac90900a0cea79db4ea5c9319f49bd58", + "0xabf99c7f26627e156bdea48ef152499e186c0edc4e0cb07c2a2e9d20060c4d4166557e16d46bf02c5da12dba2350539c", + "0xb106ed6bd99af63fc7626e489500c257793c7f4d44c6881c870cf18af6ccdcb144a97c70283a1cf7564f850454a5ffbf", + "0xa4d824eafcb95eb21dc613319733d9b8d1a34a402baeace636515cf6d3a47eb641245cab87a68ea48aa859790602d121", + "0xaabb892f84e485c5d886a3de26a0b697ee18fce56e4ce9c1716968a82a05b5d70ba09b316ed53e82bcc33a6331e769a9", + "0x8e6fa2fa4b3c3c63b865a12af76504d1f9e439352493c6f7d7cd49d0f4b749939d5263f7ab026f8e0b5e497b00756975", + "0xa50ad6f76a7444e75cc578a226f3c9c07fc406d3130401ce96b7c45eb8aa1953af8f801d821f6e774203a40ec5d0df7a", + "0x82f3e7dcb37ae15e3f54e12a96a84f8d355dd68f631ebdabcfabaec14a182252caec0adb9892b3ff24831a29f536e8be", + "0xa1db02b3e6ad103e56f3756e1e2be30d628cc03948d967b5873f967a2b35d9a83ec236cccf7b358345f67cc0c605da40", + "0x8424d695e1bafb708a6f7f7e9b7451ff96c468d10492c7cb69f0c919b13576ea4a81b2a52d27e97431903ff8d795d03b", + "0xaf30c351fed46fdf564070a9d1dced524541e1633e45eb68f634837d716c81577de5cd66c9845a5dea480efe4be73d98", + "0x80a23712f6b14d7a94f80748b498728904025c59ed7b92a4a9e14aa3d4a9581fef56ea07e7d6ff1f2fedd9dfe3d67af1", + "0x91f4aae3e68bbc9bd8e00d0fd22f7bcccca1b904fc8fe42ebddd671a548e9b648968642e6c3a916819f10a1116810e04", + "0x9860645316d7b61a847c1c00ff0014e38e148637e8318efc33cd1654a1906699d2d422bebc5e3ece851277c708c5477b", + "0xb8ef0936f626d52cfc1bcde2a3603852d9d862ac8060be0332d5aed97b2c99ad75462a4239c0032a9242d767a063d9e2", + "0x87c6f99cf7478a6e4e0625c670a05d2813ac3a917f61e892706db2bfe9f0f16da459b55704de92974d0dbfce1a6c9f16", + "0x9148c7f0e7fbfa01f6131ccdfc697b5394c0aa9fd2aacc8705c5bd0fb5caa03e7021deeb0c092b8e5c527da1a31ec931", + "0xa78610efa595287a93dc031b56828b722e084e5e28596383a3fd44510dd4c2db3265848aee40a83e5a22495359957164", + "0xa3a05e25b9eb2654dd30ad51a77f3e00416c2955694b1ccbc7bcdf57a7f036e3a9cf6d8fb9f1ae0c65cf4d0e6222b889", + "0x8ec28bcc33e83eb94aae8859c212106346639a57e8ef1a071fd65ee4a14554d5ff9fc99167bfe909c9ee396c7ff892ab", + "0x862979ac0f3fd962d27215d6c8e4f88907ab805edf6cf5bb4b710239cdb2488bf3767f5a47b1ae998d948cc938778335", + "0x90765d2a62ca4a62b837b82b9b1e46889cb3148430138c1bc1b11f4e3fa8611df00cbb85d41d08ffb6792892839e1237", + "0xb0d0167c5c0da7ebfec121dd2ad5295a69cfeaea97c7417756bab3c8787d1f49e803ac8b5039c3d4227dcc0c4db7313d", + "0xb066e4580132631e6dd5e8aa8c61f6d0e16d62ff682bf3eccfe69b585a8a63cdf3eb9ecae207051083e85c32516d587b", + "0x9055063968d6e40093f1edf804d176f0f5bedecd0ae67da494b4f4e15d89ee40b293003871933d44b2de2c3bb34be591", + "0x829d977a408144d884b11b273bcd54b62b5b288cf670366b845c013ee47ef16f7ff38472f5d5e781be75d490c458de6d", + "0xa05e72707008d02e41b24ccd0ebe94b43daa18c957c93ab13022060f26a383015d6feb10cd5cda8484728a7027b3439c", + "0x916750d66ee3c4964124c6bbbcc5256b4a18345f91722c56e59b4e19c50268b5cc39ba45eadc046e7e5e3936a8493736", + "0x91df10a6ec3b190458266eadb7a38cbf2944166e890a9f85c43cde20945910a6bf3593cc872c2b5e02c5fc0372c41979", + "0xb76e0ffd430313814740c834c8c3202177770c7b433152e4d001d54151aa6baa2ccdf61be099d337af06b223a1eba30e", + "0xa28207fcc4e565022bdb3f66d33d84263e1014645999a7ca2fade7ed763aea074b57c9c2f7ae46332ea7c12156a4056a", + "0x94e7243bcc6caa5353ace0fb2b4a2ff7f56eef0ee409805668e2e02cacad0a7fd7d53e73346c24f0091696b880f46f59", + "0xa6f36e32343bcd5d8e5b7f5164a8041b77e4ae717d01bd0126eb84ba07b1be081e64b585a489243627fd98ec3c3dbf7e", + "0x80dea46312d5765e71d30f87aacb152acf96a492563c4ac5c1fdfe0986028eb5035a9949a1e1980b6893ce7fe608cef7", + "0xa5efc333bb12fc8c7b98c56acbc1699d02d37c4b21f706cc7a5ff46e40bac9a6415c65f30fc9e3f850ef2efef527bc2c", + "0xb543fc89e2a41ec1332709550b1aad44f27133c9220ab9013e52c6da3df4b3bc64a9675f37534a33cd06c702497b315b", + "0xa63e12431339973cf43f4919aeee85d9c077ff4ed463e2378963af36cbe1cfb579f8f195bf4275c97ef8f7e211933212", + "0x859ac7a1fa154be88bc2e3aa2cd3353fa616347c8172650da82522c3efab3c46f6979f95da30b161a0209f1c6694e08b", + "0x826c3af951cfdfd09c8b88d5db2b11317dd9fa44d9dcb9d7e6066569a3d6c17f1bd462d31efa462fcf6295330ecac717", + "0x883054603a45d8fd7c415c43d111f4ad3b0df74ec934e2e779ed574f6386a005e33789c76884ac2c7067a07f49ab5383", + "0xa6a483e1d5f9b6cca4eb9e337cb1420caf829782a17dc60aa87dd6538053cae6c852c47485fbcb9ca1b9f5ecd0caf966", + "0xb9ac3994204781bac0b6089fbcbba43c32c4297ad75c47395c77a9bf4301fc7f9b50e26f7446ef11c21d13efa1e93ecf", + "0xb39b220685a0bb4e94477ca8f79d02b34dd4b9085ef7435c2eb96df0553208a6254929e1d51b79357f29113cbf749219", + "0xaa3944750f1ee79d0fea09f77f8ef6ccf6cf2b84a8ab67163b0c851efce9052c09b77fd88743d137dd75c27d554d0b9f", + "0x88be568cc10c95a4e73c2b4a961a4bde81e744d5b2a917dede5bfe69724d53b3adcfff5948e71e4acd9c6b9441a0d377", + "0x90d382ebdc2a13a818ba7fe2faf5d5b946ece217279fc87dd93c2578237cf7ace123fb8deda474ca96223975f5e3fd03", + "0xa56e43dee41f245bf2a57cdfc76b5e5ceaeb806ad6b4d88b27d30da64a2b7aa9cffa9ff307eff547c9cbf44d49e7a721", + "0xa34b1b12857632ffccfc0631bd1554a972baff17861e8a651788d3037c5f4e621302c2a6df9c9b1bbd166c3a9aa080bc", + "0x977e45d1a450f7a3bba82255c47fb938da2ed041631e4c2b1942ec0e05c8785b33d40eab4e918b2b906f937a4aa9bc83", + "0xb03e7a6a46dc9ccd2bf25550d470a74801978785415faf639ca745347c8fa0e4233aff470aefcd9ce0e546683edf9d62", + "0xa6a6c84a8aafaf58d40f1b5d47577076b64fa767b38609821b1621598d3ebc4742d8ededbaacc2b642545823f257d697", + "0xabd94a661f813c4780c82837c25d63ddfd7318d199976674cb3f2608655b9cf18c821c39dc097c46ac98183e76817f06", + "0xafa24824bb072124f05ef86590a462b6715732fedc28ba81482ea8ce0f55f48bd5ad0918caf41df175ad33acce2508e4", + "0xab7f9f1df367d8c56d7903b12270a74d6c5a28b6fd9413d2a7c6624cf660f9829a742dfba4770813ce52966873d9049a", + "0x929e7bf5bc4ea5d8a58f94cb418f941b514113634701a221d7b408d8a9e9e7276ca68ad357cdc74120b78852c61f5343", + "0xb4721d64491a34f76f95a9e6d10bd9492f1dc6775d5d31ac0908c8936555cedd5ad90c14881e04e7132362be9990e954", + "0xa01eeb9643120f52c7d92364f5d8410dbc662a38d625cdd607fb9999e3cec1d4a975f253820b6ee4188790624b710273", + "0x9200af6ff578ddfb0be31f39d58246febedf38f36c59601d4fa5345b5c215ee6a192242b30a5469e0d9d79a653cbee7e", + "0xa41cabaef490bad68b774da049d71f178db31a4b03e5592221ad90ada7dd6340cdf2b70e40ff59f18dc87d7e22fccf4c", + "0x88559a5b8245d7673ac9b3307130cb979de71b97ea785df5a6cb7acfebf0c1228e5977bcfc77a4f1fa6085fc0518173d", + "0x93991d74ecf899c365e33018879339726ac69c539d38af48ffb4eb68b413d62e9a1917d3eab84234a6fbe795ab81500c", + "0x983e0cbe48428a66ed3a5c6ae93fb22d7b3b019a8b74a1f1591a9aa487a4a52cf55cb9e1c32b94d68a8e99e6a19e43a0", + "0xa06badb24645f96ca43f5bb0621c711e947e0c0345ca352e574045442a2e47cc534abeacbc0323a917521e83784bd549", + "0xb37d1745fa5ebcbf6e33a6c7af0f2b0aea8784db346d77435ed9fb74df14f8bc0dbcd0e8064429527e689028256fcf16", + "0xb8dbf2b12a500e103ad9b8908bed96cdbe86060e079105c0d67baa589dc3ef5837f94a03f609b9e475bc4f2255af30c9", + "0xb270735ee3a654414cb206d5f5864c0a498a3c4e672df6e64955d981176bc1a0fe1fc1ce05c1b898b204cf15cfd6e2cc", + "0xb191559ea5db56a8254eb2fafdccdc552a2f453e8dcd5fd5d6602ccfa50b0ec2301634557214d6cf306fa2217b4b6322", + "0x8434ef1cdf36e64e315ec06ca72b4e3e16d5f4e62c7bf6fe25a79cf54bfe5bf40616b77cd530f21a849b0514a2d76979", + "0xa6bfde68525778872052bbcd968d20bc3a4837f12aa8866df3ffebb65f860f92481e4f1695f22056126612f8eef6685f", + "0x8fff682a41e951a91769886514556d073083ac5fcefa40524f41fe1878280aa8226383a9ae0a226ee0e75c1d978e9902", + "0x951ea96db449d155623343346f27542811c17de3d371ae692f9dfbc01b048a6d30ceb539ce0385cb3f27f1414a43217a", + "0xa1f3e8208a945a1bf88f8a10f4ffd53b51fda7630a42c3582edf587bfccfbbca8a23da4014b4199f93c123d0d0d7936e", + "0x914bb4be2361e1194c8ca60f520988911a5929c2a27d85def95d3e1ca01270ff04741fc57cee49156e176a89d9d3445a", + "0x94b55a2477cc65774f0b39f2b44ad59e1035fb6c72ec0263f86df45bdb55538b6043f54b8f7af6a5141a39a32b027e9a", + "0x8dde053fa80c52967b4fb4cea795d8e0112bf5af196c394ff5857cc672e7c1b21f0ba65149f732711f939cb8290dcf3f", + "0x8adc83d40a75f988427bf4f56ec090e3fd6c682608ade2cc4a621cb837750ce5c1e38758f8785e83799716611d3cc8f0", + "0xadf7863928c4587d5d3b003043dd198b9c510d394ea7de0f3b96d03f06c55f03ca9e7d651b7f2f96368ee3ba8e485faa", + "0xa673db2d0273aaea02c49b1977f59b048deb5a0ab15de69dfaeea117e0040e0056d98c63ebe0438e88d7fc720d154b94", + "0xb2e150175d1846114119b62ea47b5f572753a0e224a3c6f972b5cca0ce4d84b59221a90330e3e23f590b5a66f714ae11", + "0xb034b750b6fcb0525e2906ba3a76fcb63bc0c6215c4e70bef35b2ffdbfcbb58732605ba056611ced299ac7052ab77afa", + "0x8c752ca5bf34b8abde444896c8857289dcb39a1771008e282a579c3bafbf743f69354bd8aff3a057440e7d390ea0be63", + "0x888d2c874f5744a3365efe2a50c538a063d1eb90634719df1af416249482e96d1e3be7c88ae8bb123b701aeea2c058ae", + "0x8a979c10e21afe5195571fe1a57528ffd5fa0d902920f2ea75e3ed99a6c3735e018a823432e8513b22f7eefd18999019", + "0xac83cb419f2aac737f99126658b7f8660a11f345dff02974034b68123137f3008cfb81ae17c724fa69d9828c01b56b2c", + "0xa761efff1a0a04119c11cf2e4a6259dfbfa47d685d9092dc58786af386a768c1c3ca552519817711e2a3d29afa08f53c", + "0xb3a39021ca6be9c14340aba04cacc6444554a6053b3d5a75a11ded72e88c45385f3cf2942cf75cbb34ced00bcd2f32cb", + "0xb5e22de1b256ce31e3aca18c72c23c3d452da0144f14512d82dbaee6e54a55926db764b6a687c328ec245e2ef29fc56c", + "0x8a28044c0a5dee130216f6c8b1f6820b7b296f9d0c9efd9834243679836eac600bd8214d133f44f8f59220919f060d37", + "0xb0495130e0da21bcb427c59d09505d63174227d35e9e477135d56dc8e8035c07b429f3397eef11973279a473830cd221", + "0xad3114e30335c0a8b1e46f0576f81fd71aded1a56533c5d41fdb7f59054f9261fdd48fd5cdc919d3131d667f6f869239", + "0xafd631943f15dc5c4d5239eeee95292dc12d480781d7ec65d47f1aadbfeefcf91636271e53560bf8ecaf3c5a2e5c08b5", + "0xb2f7628d874a33ebeca3d6316dfac40384d69f14eef73892b968985a37ade46e4a19150adf63c46f9eeb88d4b3e97016", + "0x866a89dee2e32e0b7096abe9b21a90cdf53659c62638f62a3bf060800748334641fc5d06ad5d776a657a5b53e953dff6", + "0x8d8ec17fe8ee1005d2efe710b1b4abf156a6f5bdc996599eed7bf1c358c65aafab1d6a5a4cf462d8768fe8979b45a899", + "0xae69aa0367c2533ab27882693ab9197a52a01c855138d544c21b4f384bcc9a6de61381e3dc05bea6561a4fbaa4c36063", + "0xa188aecfe23366069b098d93f2f37439159ba5f8c48ae6ead48d339dff2861a626c1840e9c402b0e9ede81706693ed84", + "0xacc6553e6bc4572df696a12377d5e031af86a0399831f2525b602466b659e5d67bd0a84c56372e94d1168a6fbc73b6b5", + "0x8c9b496ecfc732055e2fed8cc781afd987d65cdb0d281a791c7384fdbe875d216e7d3df30d1b1b0c474bd19e693a3f8e", + "0xae431f02c3d4217cdb790d44eeb93ea16689dd482d6c61a9b475daa06a2b233bc5238b45cd3c36d688cf67da02ea6876", + "0xa39998052ad2de4128c19231d209d4720cb381fcf76fe00de52b98f47ac55c80e6c75d44f0c01eb01349ea9c03ed64d3", + "0xb532ab0ba53af273500e308d8dd059c9dee571325c49d61941f470aacedb6bc7229e6577ec8fecd8a862883c9dcc2231", + "0xb13c5fb905d163f7ade99daa612261351ef25e9846cb2eef3a64354b60669f30ae8ebd411b966c07f23e902622cde857", + "0x8690e73e9209abb0089545849f50334c1fbb88393981c84283a7e86117c0dc23d47ad0bf1a41a6c45e896bc14f152f26", + "0xa55f3f3b6dc31038714c1b4425e8343f5f4ea62e50648be053218a52e6de88ce9187b1644943cc3f85b68fcffd881719", + "0xaef44c2f2ab329038777dfc2cc584a4cf616e9e74c26594258e28e41028076622bd5bdf70bf109acac359dc3170b21b5", + "0xa068dedfb61a5b140fbd59d70dedb80692f3e4ef9ddb65fe97c397b340e82c71f8f0f0bbef5ea7e87f5db6b377c9fadd", + "0x8b036725c60178d040990aa8eb501056cc0280a8ec39ab0fa7e211c8f7900dab449320c3a3d3c434acfd56a101c7fd8b", + "0xaefe0eb5db3b9bb0dc2df48bfa0141af5eefc34fac5f51e2c930733b6396a09019a0101ec564de60a82699cac23139f1", + "0x8fd0d9f11305777d3599c3b66e9eaf22445ce591700f0dfc6927eba7a7205dc89f62713412855ef9383381956cbe0a66", + "0xaa84ca0970b084530084292059c15a3bb80f94dafa9a86ba0458bf305090dde83c03de90dc7ada670487e7659fae6bfa", + "0xb884515d5219c5470291d32f2c170f2ab919f70683883b49084882d1d00979d6b716d744927dd10b63fb7efe5f2e20fc", + "0xa1f6ec7b378122da23605f615717635f895449517e673ad8dd934f3f7bd4aa9fb1ba09869179cfcec60e6699aa155431", + "0xaca24e10c5b3e5f49c5487f84af0904124cec27d608ca60fb8ff4a15cbb4dfe5276950c4590eea20d4ea3abf9a50eeb3", + "0xae52d18456c317a3b6afbc161c30de0e672ad7db00206a73bcc7f2ebe096a2c71170cd0b6e0b0ba64714bfe95be878a5", + "0x994106d7447dd286fdf638ccc4b058854bd5e7ea57f493d6d19fe2188463b682c116070e44c2f6126c4cfdcc9f2e4170", + "0xa7f09e029ac66f0c57f43daaafde2e1fb02043522cc1537282806ea00641a5b1f402afe43dc63af2ad91563893a3c5dd", + "0x8bbff5c10dc6cdceb2627cc475835e0e7ce9f0204d63d2f4be4894e2aca72b39f8cfdb8658b70cb910edabbe6ed39fb2", + "0xb4bfee4d4eee6b18ee61ede61b85bc6d8beac5d199b6718b933e7622c18dacfd42dd152b6ae017ce00dc1e707cb0f76a", + "0x84cdf18a20f9d885b4818afc19ae12231dcf10a66bb8ebd2666d8334e19f791c13c3c6d26764ad8b1062a6f2c012c4d6", + "0xa30349751dde787daf5cab591c9725b7b2bb242351c619583ceeebd7b0195076f1d9276e0c06f9bec7c81bc1d275e5ce", + "0x8777e8c23b86ecf94c33a25e9114f012e8d5a3ca1ea78b5e0059e66bc99c384c456801a8725c1112b6b41bfa28a7d5d7", + "0xb3049b1c8e5b94b55d681318311c39b7e7d392d4aa78c5875e476bef5853e227bf95f95a536c0da90306b8e2c7c69688", + "0x969d348e96c17599824630332962540ea0de0064df535b712afd57ce4dd3d5b90e5573c18c69ef1cd797e3073a0b11c8", + "0x83ee0da01033bcfb1ff68845257d04f6c120eb640e4e5dfea8ba868384ebeda18c0a1cb726a6da2a289ecf07a71dc487", + "0x81ddfb441f9b2592a2ace933c8c56bb84b30d0543095ee9130f4c02af8f938156a740f1074907acdb16e88661b5833c3", + "0x97e17391dbf1d67ebeac90fedfb33a3f3e43e4b0fe1f8a9f5b9836032b9e754e9944313decaa1a242609a66ac2703e97", + "0x93d8d4b77dc76c9bd5442f881af124a848db23b7121a402b09272ebed8f81d6877a6a269acbbc0b15657df20ffaba5f4", + "0x97c7b0064d65dc61f5fe1df12e0bac2bf37945548ca5a3234c5bf798f7914a3da018ecd319d724f7d5feecacec6c1b65", + "0x93835717feef6e7a3e8eb087cf442de0f32861265ce80d59edc3da0144c4517bb8a0e9150b060ae07351635913424b40", + "0xae5220ebfa94ce0f413a04cfa3c21c70591caa687b2640c3a931e9205c6fbd2151b46a4aba8db336fb79fbcab8c3a7f5", + "0x8857a5774aeba66380ae5f07a1eed522a5d53500a7bbc6ffcd137f759fe551035eeb33f44ceb09e2703bb81e36a44f95", + "0x89087074452421266ea654221a6b859e387e2eaf3353b0183d4ef1760d8ba16e22188e122573a81067ab8f873f97d2a8", + "0x8da852b5286b236e11d5e6c1fa22b08ba6868d953769ad8492eb553b8030941116498fa53bda00f1de132226da44e609", + "0x801b7862338782e6b0f17f9ea3d7f75983ab3d58a226c7744e93809ea131d865ab6f8ad4520c0d277716d4dd2c7235d1", + "0x84c1e09772adafc01a16a34e2f9ae0f5fd60811cf93edeee7ebe461e7fffccb7e9b117e950746254730050ebdd89c157", + "0xa53a66400ee9533d1af90741cf3d1218521b3a016866df93e4035db149474b9a352ccf825d8c8d09df61615d71940e86", + "0x8e4d205750fe36b3fc073b0d4ee8d58971e745b70a2e29a12b5b6d8abd29bb27ef808bd701eb9094e396b6df86a3ee07", + "0xa6169002b95c7a9a1b4c73fef261210bf2d6fb4abe2460b721c1a6c9379a42be7025cfb131d6c61cb9b0869abcd18bab", + "0x815de9ec86bd519b769fe63e00d17f441600fa8b5eafbc6ada52cccd857849dfc3fc4ae7eadbcf5243828d9bbdd667d7", + "0x844bf3df1f9e734549a647a579bdf6fb67f6b0db1724eb54434c5bbf9e5c377035f50f1201db58fd9ede5b722b347e46", + "0xb950ee8adcff019e9b1608aaaedce88d40d48da171f21ecf2b79a4479522bd27b571865a788a43bab8b46acf52c0e3c9", + "0xb27e6e8a3037ead85ba3de1ac48f956475a8c1498fcdded4d7c5f83f22f63405f2272c53c3ff5275af352847c2c180ea", + "0xb192def5108368228c659e80dad8161e58ca15af08123ff8cc52b75cc59a2857a8efa355c413c5b1faab68ed27c23f0e", + "0x8e6b066d496df543734cd4215ed0c527d3580feadbd70d520df7cc960ef21b4b7c4956555e401f372a5e40268a12c01f", + "0x98df0431e1dcb661bef24a4b607a042327b2d9a506bcd3257dddd6bb4d9ef61c87200d6a1746f6691bb1a5a02b60b718", + "0xa2cce5afedc2ee48ad27c0f608f54b3a0f247bf053ea1ac187c3bc0adf90b36b609f3ffcea25e30324bf0da17a405c07", + "0xb764ac1792eb8608cbc625ab3ffe283331130416abe1195a0b4cc15a95d945e77aa449bc8a8411ce5db998088c25c521", + "0xb704d17d1e7778bb23d97f9369dc95102858f71f24fc441dea84912e5c73e8e26142ed0e941ac8b19047802ca70b4a2f", + "0x8939105ab01e99b515a3b64d82916eb204391f13a7ad6b0e056ba20caf340e319b34d56e2b5a0691e1f6f60de27ff66a", + "0xa084d192d3dfc85bdca6ca637dcb27b81c4da7a3dc5353867121c97d897850548e8e51af809e9a8d525618e29c9f9f31", + "0xa44f41d22356433941f20a3f89e995275ddcffd16e5326187559df036fff1489aebd643aaf5a9fff56e59c3638001556", + "0x844ca2442f20653052026896064d44636f6aa21949f621a89a06c004d287e4461cfce010c493b8a3844d28f4c61d405b", + "0x8fba945c72abd8730f254e253e344d1b98cd908b19c645425bf4cd4b859ff5cc7840092ce5d3c482b21df9e8e3a0a3c9", + "0x850137be3fe722fb6aa5ee0a91d19e28955cfb70e6d56946066ae1c9755317c0d3b9bee3491cec1ea72d1b0f04ea1587", + "0xa1b954c4af51c2ffa253bf9901b17bb02c32ecfd1533bea5eed1e9f9e9f79897c6d647bc1de60c97249011ae6c1c4318", + "0x996a229a5c859f7b79d0952c6c318cfd70417641439ad3376036d98d11316070e0bde721344ac5d415f0d55e3fa099fa", + "0x94bba30198f5f02c92b48dfd3213552d505ffe162e0978f3689dfaec8e127b8b3aa4ae571a4e504322cbe0c62b8c85a9", + "0xa5e6881272327f93e9286afa51e40cd0b339ca9db1acaaecc1e1756eeba30b497f9d2898e08b2605ac91e35a790ac7b9", + "0x889b3f9d015359b4c42957395347a415608f359e77c6531710835483ccf1317349cabe7e6fa7ed069c0f650dea6161e1", + "0xa77e518326b77f59f1a21b930eeb4a72079aa9642e1212442f7d62d49292623c93f87aa0d7beefbbb3248c51dc1db6c4", + "0xa4a8d348f75f47ec3550bd644d4a0015b812ce052ef25c2d35b30745dab58a28765d90369a94d0b40bb747bff0f8f4ee", + "0x87321d70d2e22f41395b02cdc0ebe597e9c1953e1ec5442e901ad1673c3d9dccb3098c25640195ab5c0d1845614309a1", + "0xa6b902eddaaac638f745eb9518495ee605baf05550400a142a107c8eb3394706f96ed8ddffed21ab34e2cb4dd3009e4c", + "0x8a4c3cea69a86c15d96a04ecd94f96834f4543cf698744087e52cb0585506df017a0716067985dcf51b1c281ef82e6e7", + "0xb4e0901f9b10204bfe6a5261599e0747a99b1f8577644acbe39517e3eafe307515394c46b292292caa121e13664aa080", + "0xa4df6ac9c8a5f3fee7dacb91f2bb4a083d04b67be45588e8684e727e67693fe9cad558b586d0d7f357657915a50d4414", + "0xa12efb8a20cb91bb3bf02ada99fc7353e3d2e69937b43f16ef2a53f4101e3efb8bda293b953c1c6d03966f584b324e5f", + "0xb036b6432714d43c8f0bcd4fdf04cb437f70ef8929b191a89a4a1a8af2ec84c39fc8be12f85cf91f751fca6775f8757a", + "0x8030dddc9900813999e36a269c94eadd04dbb7c0fcff2da60078513e4faa14cfe61ff6fcc4d78fa3d829bc5b4d5f07ba", + "0xb8c5badf3097df37e2c4ceba62f05f093f163bd878ffc0bff89af261aec5eafceaf77c53aff308660e9e24eef86c77b2", + "0x939d1d3975efdaab50018e86954213a9d87b5a193ba75dd0ba17444a52801bf292c5c59b93cee90721b0382eb9914c97", + "0x8f8706dccbde24bd3daf6aab3aff1f785b979e5ce6dd49dfaafc836f7617430ead20d00edf7f233654b1de768c22cb6b", + "0x8bb7686d3543d61078754ae70b4a94bd79d535b723734218a88f0c244b26ac7eba609cb4ef79f903e513d4baf90c0a3e", + "0xa90f86fb41057aa84bf237c001fdc777bebd7d68c470d9b5a15b5f062e0862824f512d502c1952a6b99476cd7a13f765", + "0x94d47a807dbd6a1c757f1ababd01a3f6d13c54907a145eb10d137e858aae953981b484379b4259b80ec530a8fa101542", + "0xb1ba875251cbb6c549ccb62514f9ed811f649c6ccaccf9b640c3d9769ef4271031ea6725853cf140fdcfe605743f6d2c", + "0x8ebf078d25c14e3163dfedb2052c9dcef945346f8d4e5579fff5d3319a7d7257032f2dff6e254aa75212abdc2badf650", + "0x8d4252f59217f1b1f3745321ad3339762176c9d9ec6472f28426aa29c6b6393deb225ade1dea85d6f99d1d56436f615c", + "0x99e87a92135c3e88ef0f0649f90743a6e4c3a0ed28088ba6e5a953874a2a2a9485ec839155cb1dd910f146dc880b47d9", + "0xaa07d59092e8e518edff78b5cfa3f5553876ba2af093c703d9081617af758221a48f9833a2746c1ec144b68371c4e7a4", + "0xb3cec14c1d0e96ef38aa72f2d4b7138105c61b84dbf86686153ded7c849c59266db7cd56575dc2710c43794d3c8b726e", + "0x99bd92578451ac957026884143baf75c429f517a82a8cb6bca4e27455d4c9ea266c4809adfe967e772df2caef3de0415", + "0xa72beaca5e08c8c6959a4fd476820ee6ae64ebeefc176ce06732311f1750983842cc565fc0e175b9b3306b0c8ac53c4f", + "0x833057a5583436081bc5117c290ace89d383ffaa1b40eab2d116820b7ad3dc223e8349a79372bb2c78fc3f1231710e96", + "0xa41979668d13d17fd2cfd2bfbb5bf98a527174fc6a9bd4669026074df3bc366807c4d3970c2d6135c6041e824b06befd", + "0xb5a3edd047a3f99307dd277cb2fe87488b88293a9cd61f3f2062eba34d411ab6c6204f3f16f07e7c5422f276c8f75f4a", + "0xb2acbd2056fe2ade3a0ae1799d0f36211508627a516faaa57769f5c1981530a4415a88888176b2f133cd3b4cadf86eaf", + "0xa0d0955e796f8c5ce0a5070a88d9f9c29a2ff97dc0f82a692e97ceeb9b8ae643b1b6e8f9742c92627bb5115d43d099a4", + "0xad979b7838809051776cec6a5bcbee4d94b7af9b814d2f1a938fccc412962c2f7d85a32de9abe2d931a34e7ad30ded3f", + "0xb5beb2a3622d1df859b180da33539457bb1918433a1a26e430c401e51c948d6af77b51b0ca7098852fa45253ad039bc9", + "0xa2a0b139d6adcf7c5ae76fb92fe0bf5f9d542de7ec098b290ffa369d3f22db2f7b0154f56f924554eada041723cc2daf", + "0x91b1650bde309d99de762f75462b1ccbcf868488ba3dab56e5a17c1e429b4c50ab173c8aa1bffcfd5e68c94202062519", + "0xa4ad1f2aa100e4e9876bf6f9d8c82a65ba52986e683443a22e529de36f684143b6d3ec83c55268ceb1c0f056e4c936a5", + "0xa18d74f03868c2c4d3a565da5cdb3be08b5fd188d40cf2632b08866fe9ba08950c983bf649c44391d1cef53ffa299993", + "0xb833d151ef363edb7396685d360e4c3cb1d81ece81491c0df2990d51d6d2e32ea085b1992b7ea4d07f863e954579dfcf", + "0xb02e03369019480c81931142ec559b1b08a2d049a562658ad8296dec8411ace84ae00a32fc24d20687a0dc28f5dc072b", + "0xb637e102d0e191ea73fbdeaff03a100e7c0735f0a3d3bf128adeca04aa575bea82464b3b60fdeba6653763100a546e64", + "0x89e0bd136d430c64be32b30db252c89e84f1ae5314989f648317f9e07005f24bffd11f34a79fa4b7c7e532a66436ffd6", + "0xb8f1e54e4b9e9588cac376ed135c04c0f8de2f45a69b3549084eb5c349ca9796e4a56a5096121b1e854a8875a3f76567", + "0xaad1d0209345ad9011265288136d555bd767bad5123fd2c9622cd4be2808bde5cbc1b98e61ea008ee66c808bde35c516", + "0xb4ef098e6157d58f2fe4adac030d543f7e8a86f4ad9e9a335cfb0dcafb589d0e32a4c3f271cf97896b98ff2cbd0d457a", + "0x93cbb3ba3ac989425e9b7c84a39e729d10d61ed69a21687a43a44f2277e0a602b7040bb992d481c7fd9aa4e054a3b4c0", + "0x8f0fe9fe59c153979500aeb6e3f1fbfb134bf0235e11c8b5eb2c819e391db8b9133d793d61189f04eb74109c13ca1dc4", + "0xa3219b12a66a5a9dc8b6b1d23a38a90ccbc0980d75854419ee5c1d5670ee23b6250f831e4b7b52a530ab8d73775ae407", + "0x97b9a099c2eecddf05e1064ac0454d13d761a0a2d59621ff5b5240c760b0b4b2a8dadd779740fb621aff1f325420fee5", + "0x927cfc0a8061ee7a3d175a2546480039dfb5b27088142354708b59aa30d48e66ea417cda6c92b5eff5fb5b76ee28c3fc", + "0x8c9ee1c256e54ef075392fd6d00213710a8dd5ca916cbc5b36b050fc340285437641a69ddbf40cb5c47f1c58e4ead67c", + "0xab419a6e2eb2812c2ee954787f955458f6013242c05f6eb563d18112b8b667748ff9a8b491d1ff267116edd801c37809", + "0xa9c277b324ba88d80275368006dbb91af924e10bda0664e0d433bf4c60dabe62c9f15e14b109ee597cb5acf057176103", + "0x97aa9c5c12f1dbad15344ab8204048f5c27388ea6220925259f5a352d89b2ab3c3463a4a9569fb1fcebc6cd39756432e", + "0xa8916b2b73d1921c291d51184e01a3da2b9f614521bcded8b5d7e1b64cd1cadea7ba3afd1c86b068f303af5014d50af7", + "0xb493dcffda0dbf61a038ad316a60b379abdd22da5441e1855a78d5b4104f9b55cec71a0f2bd86607b0ff7bbab0f47698", + "0x8e43f9466a8152ccc5bb5533337664b5fe65c70d3a6e1f733c76d27a2bee69279db6e78d395138fa5966a8a403d73655", + "0x89d6164aee564ed5ceabf3a7d71da9e77c7de6e95aef6a6ee89aee13d186c15f893b40ef20159b71b630274eba3dcdf6", + "0x8e622c528ca385e3be67c76afcb9523d72a0216b4c50a295cade75e467e78f2c87d55253ade6511f9f4d065cbcf013d9", + "0x95160eec6dcb8637987c873d1400d04c093c1b1aeb0bd337f9ee99e772e430a0f5d79649a9644999e53336bafbd4c743", + "0x95654348357fb4eb705bfc554b560928a116f4567a8992cf06ac894d6913d2d348b4b1abddcd7a880f24dedec7f2d8fe", + "0xb7d3b6c592b2b41301d1f8283b07e2c20f5725b755b71abbbf2fd6f2f578e0ad9848861d325c40fc66900e9a1ba05d03", + "0xb08a1b74f157df6294d528c909f0a3d2816cc9086965e3fdf31f829b9b7dcd7f8d6edb0769af905030226f3f918de638", + "0xa629d61830efa093fe0623d592ce6d785fd5cf07aa6ff7caf3c4fcdcd5f7d208b1268bf48935b87f1e06f0ab8c24725e", + "0xa0dbd8c624f2127dfe7c8f0f0e8ef4ab9215df465e44dd791b2e592d6f7b35aaf350eaae9344a484cb9e0e5f8a5cf20d", + "0x8dfeb7f8fac2da7c659f865904afd11b5aaf40c59eb209bdae31305bd1d7d43d80f8d165dbff8cbcb7e9b33f798cbb87", + "0x92b0be29e381928ba243667dd0a0437804ce994fae1f1b975a6e1efc013bf30be41092f84e94bb9af15b8cf11186ee83", + "0xa6a970c953cca1056753f4e62b6b5e3ef086cf1ec4828fa76f505f8179bd68cf1dd711f2a601e0ec589d07fb1e8d8bdf", + "0x85659e378c7edb5201e71072e1489485e890d254713be83f3792c347c5e35d94fefdaaa33816c52498a6bd06b677545a", + "0x8aea99ab04f74159f1db70d03a8db8554c2d48bb25a0dfe5b615562ebbf978e174a033907bd014a8243a16a631cd50b9", + "0xb11b7ef9cd17708a5868fb7a31b7ecd4350a75533d847a2baa3320e16e9536ade432cf754321c290e78d33bb56ed8159", + "0x8d15d0c611bc2b657d34926ff7ab937023ab05e48a89154fa85af89b7aebe28e57c5e5ebf994dc1fadf227866d40a19f", + "0xaed50e83cc9610db6b8ba16e6ca79d2c3ba23dce35592a1ab9ec7ccf21b109a01b5cb1ebdc727d6a91908e021bd00235", + "0xa3fc60297a7c66c05c01c430d864d86d9e99b57aea9e4db2db57a778325693df9499c0817fa2781a10708def9fb6b8f4", + "0xb40d781a5c63fe535959062efa6bd72558a4746f703432703c97fb9e3fa8aaeb3e33e57cbde1708cc059822eabfbcb2f", + "0x99b690e72c8edeff1f1879b13dfd59fe50b88c4ae93cba9f7e10281557e67979401638650260d6432eae10fdd772985b", + "0xadc6c44b66837b7e30eba9e35b42d071deade1ab5d0e3030e20cc25218aa6f93a27a1c9fbad98e5297b65d015641f8fe", + "0xaa4e515ca24eb59d1681e8735af00bba4d0ea5175e05ff672cc215e41c8392babd45867552866c0f1b935826a891b35c", + "0xab54e7b2863ba75695e11179c25921d9a09b5cc50fb271011bb5fd87c954ee3fb9a0aee63ce54adf47be367a44bc8132", + "0x90f1c0881f4202f4fe0b6a93277640687c98df0adeaa56c32c5103bd00471753809541b2160ea9f42eda5ba4feeb75b7", + "0x82096b168cb5492b8de03928d6d0f369f7b4ce10b9dfe3df19b634d2115c5c7067d81b1439676f4e92d8d0cfea4974f9", + "0xabe48f7b7a074fac7269dd11cf4dca13d23ef17577d2baf535b73b424e592482e348956662cfc8a509cbf9e8ad23f022", + "0x99b461834d629eb81c2e965a70f0ab56cf8bb2137eec2d4e6b2a5e97338a1ec1cb8db124682a3a141f2950e675d86f05", + "0xa2e9d0e474ea0a35dc822191aa96435a5c04ff57747d103d0a63446bf39551ce91c727e9900c5c740536a26a9ceef2b6", + "0x8dac23b1ba18f2c501a8b705eb9fc0302f491c2a27026f56128ad66ec0534f7fb2fd540b83b8a6a70c5ee5cf33b6598b", + "0x987b7559de8a482efacb1e1feabc99c3eedf41e84d95f9dd8df15adb7b64ac0075c21c9c19486dd06e4a7c4f30b65dc9", + "0x930877f052b8be2cf62c322fcab090ff4e0399efbe6f0b2bb84b2e45bee829528a833754a365ab79c6811783edf97b9e", + "0xa48a5b5fa0402f2eaf6a1fbc51b1fccc31f13dc44071734bcc03a16275b9874d195a7164d4b6bd3632eaf0bbbc9a3e8d", + "0xa23481665a7b323530842219fd7f1609f306abaac01def0e3fe1be02041711ae5b37bb701d0db3fbb7f900eeaa593596", + "0x958a22b8b2d9b44dd280aa6d5665cce3f3a45875cdb1346001e7ba9464564797dd582cbddb130c687424b6e72dd5466e", + "0xa626b2a6f0a279948a81eec284a60fb811d6566fd1361c8a67a371d7a4615af36bb5fdf0834c0352a316481cc554112f", + "0xa22329d9509e67ec4a7be7678778bd151f961c18e3c56b89aeaf0a13faeb9a08bd2174816e77119d7c4276a14014d3f4", + "0x93fec35b207612c5ead94fc81dace83d279389ad176cf6d87f286d448faad654e3874438089c09d497e4811db6a2aa91", + "0x81eec110cc0ab2c549e156e962db9a47890291f5eb1bc81652b94096d7e3f405f5f71482d06829a59cacd8dcc8099726", + "0xb38bb282ad594f60a5cea85f28b01b8b365371c264e7f6146327d9f5ec12deb2442ab3e9541c67c5fa6e123c962b7279", + "0xaf1f08d3003573c7b4c7f867edea5eee90f5655e13ea46253174b1b5a41c869502bd969236c233989c66d5272bc05ad4", + "0x8b2fe6fd7fe2c758122d016afc300dd865550bfb49807c3c29a2001a157a5e1a9b271721deca2e6a71a10292b3acbd12", + "0xb6560a18d2f0be5860f989a67ecffb2f127a7a5781b4978fbe2abe95477d897733a0cf98c31d47649c4e48a319e81eb2", + "0x8a9b195a575c7766753c13befdacff3a6a65c7f3b52591f7c38b4cc4a841bda6df9914d913d4bf667f9a63985a8bdca8", + "0x8d9e886eef6365754b8659336ac8c022b50f99c95d0d87e030eb55777ff8f3b1d1cc929d15b339b2c7d11294f2ca7de9", + "0xb50c7adc338248f8659dd4f1e1440d3192257ae34b40b83d8d35a07c271c46e96b2414dc992131e3fcd87d520ef30086", + "0xb27844be2893af0a1b30365c3cf53add8a87d55c33148948d61f5123c7ed92972e082cc7c5057465c8930ba8e184e524", + "0x92cb2abe39ba26a996997eac32bd53c62d7ca845082fad057273a0db8eb55bc303300e28c77896679923eb2949e39c0d", + "0xb8519152df5fee2f803110751b62d4a36ecb11d14807fb58fbcc17dce1f44bbe327316e02c38437f53654c9b27560bb2", + "0xa515e2f39d44ad272488dd51e78f1c5768c2b6a662cf2b0e0cd7a93fd17615630d196e5360bdecf8120b604e1cb5d58f", + "0x8552daef0ef677a1c44eac6eda8b9d6054404744f0c051f6bb576afea41421e61b4186f7ac6f1904ba9fdff604ca0c3c", + "0x8ac3803ff14b9f1ba563c22bc2bb52139b051f017c5f03d0e6e9bb79f9582ade6971456780c8f9b141ac0366c4c2caf4", + "0x912718e1a0a18f8fd5a568bb4e924a67ebe42f057e6836caf2c278f9e2745c9f45eebde7e68d5e7e83d4df9e422573a1", + "0x99119f1c0df1eeeefacf6d180f28ddd8ba6a604097977937c3791cabf79451ef36aa69c1f9507f63fd094df456033239", + "0x91315d998f432101058d410cb74dafaad61de11c36f435e7fbace93f5b0f316bb2d44e4ade1871c8e40543592f7058a8", + "0x96f1d924ed1b034f94ab1d8a384a4ac5071138453ff84bc571346126a1517e0c2755b01bd892bb72368992a6ea6205c5", + "0xa582ede1bfdea0e6de3468fc85606707f5485814ec81c7c0ae8135908adba0f8159415a5f7aaea4f7a7d97984f7ca678", + "0xae1d3be68f11f5ab6742ce3568708beb71901cd5d3141948db4662f0b1ab14e2d1e563fe51bc056df7c4c6b2ab573862", + "0xa579704e5196d4ae8a31a99f1d22cc274fdfedf055d80baf5e14a2e5ec0092668062a6319c11b76df0478a3a6b92df0e", + "0xa682b02c55536f6cae5353c848e77d649274cef8bc93a0895f4d4c51f8d8e04bb698ba83383a6baa9b4a05ef42682827", + "0xa295a12e025cc9c5e955beafd10e6f2961aeaffbd11f28c95c590a877a963006ab36c3fa6c543b048c14a9fc6854d0a4", + "0x817602715833b0f18a302bbdf0fac83a39c484eb2e639c9ec4b3c73a7ef5419e04398a9c7f89f5e17148a78e77edeabb", + "0xb38c10ef515c6690d7206fe22839b7336c44b60bc97afabf8e5f5bb72afc5342f55f904a9db15168dbc1f1937e8b3e9f", + "0xa1bf0f5689c8d1a23d99d43827c6067a8fa426abbd4efd66e3031904546bf24cc337a2a93239c988c2064c97276f19c8", + "0x92a46e15b88090d8d8e7a959af7a2685526bb87d2170621042d4fac807c05792b49bb921648e1baa1367353b3302aead", + "0xb09adececb41b7010daff328cc1620b48dd3e257c4fedd4926eb905ff81625b7049f15ca09b8b7a71816aff88448780b", + "0xaf8a83fc487dad0e5888618030eca6beb2ae1102ed54a8469347e363d0766480846a07008193075c00ad05b4201b1f0f", + "0xb4a53ea01091d89468ded97b9bab7ddd38e9b0f87e238307891bdd192b0d63e24d720745ace1f9dffbedb6547b680266", + "0xae4ae9e4cf44230d9c0ae84bfb5198010e76effa541d7a248617e5d7462e0d883ce071b58a2e4879f2d9ed41cd313fc5", + "0xb0558abbcac22b628ebe50d531fbd24627d3f53c19dacc44b3803613542806f9dd72a8fc48cf65245327d23fecd2432a", + "0xaa492d2c4cd8c7e3fa7ac0abfd44e5465fbc9b1aa663c45ab80df965b147b25d2521d47e9024cf574f4d0487ab9b0524", + "0x962fd27de42906cccbcf58b2de039d4fb18f493f6d0822e63c6817c8f5065b824c684341473a447b63eb1a5aa412d10b", + "0xb76451be8eec9513f0bc13041f5b6d01f78e565bb06fa762b37767042decec38aaa7c17a73f1e0b528216b3979bfe263", + "0xa97446e8a0b6fd7aad3beff683488272990f26b9cd29b1e9268dbcca952f6482ea337639cceee9ff004ecd9e394c4bc5", + "0x8d3ab968daee832473159da46cdb3c45bf8f3c27ead8faf108cf33277eaa64f3af758ba6fa91c165511b708e538c85f8", + "0xa0f90e5d6ba990665c523526c3e7f015faac5b74693782d3c3c08ac8db1a54b50b6df27beb0ed836d9904129ea9f9ae8", + "0x812ef2fe35f2f3c7ca06628b32c77019731e2624ad1b7724b7b1ceae9c8fa0387c58fc40ebbdaf3901b8dddd0883fc1f", + "0xaee3247adbb6cfba4bff37cadd6b256969c40a98f51633574a45c9526e74d750173b9d71eb043425400bb42f671d220d", + "0xb3e925154fbc2139190f62d26057850c23d2e9a6e39175fdb3908c7ff8570df77a965372b70819c0ff79dc3d6021768e", + "0xa1dc74752e979934f006d33aac3884b28af1e4bd500c9652920f6547eec696ee6482b77e87c861af1cad29d3c5f4042e", + "0x8d8cb213866e8b07c20011b6b32ed00dc7297bec9e0f784e5af6612303cf20d9ee97a7312e025b78d6a53d5850033973", + "0x8d65cb204a8a3a4a5de34d97f7a1081f3fbbbe061ad2bdd64a8d922c0d0bc85bf96c7b0de204ebe292dc3e42fe6d2c72", + "0x882398f454bcc17782e1a1a2887768c5fd920b2c7ba7dd38e132dbd1d9ed2014e091de99ced2b82b8289c8da48d29577", + "0xb1d5ba8be79d450e7d9f565d513c21fb8d9ecf8ffce3cac12c9313752c69c84d61a319bd994c14947c5bb74e3639dddd", + "0x8efbf2927ee8f027dfcbae74ed6f2e26f9cf90d3d41b91e62d18f5680d2571f33cc7f3657ae7fbcb2d5d22921daae341", + "0x8d6761605f73450fbb2312884eef43a2a1e38a83858a1c51bc1a05a01fe1f330f791b98dcd15eefe58d5c6bf3bc27a13", + "0x90d121302b83ee045dc1e497fed7976106830ec0ffcac6effe963f0c8aac29f1cd0df63e77c253568bea102c0b7c9f1a", + "0xb25498ca62b7de5eef058dcbd5e381105ef55d7cc66deb3e443e89ce406e9786b94cda762bad8ae314ec1371a77bfef4", + "0xa68e646fb2be77e2ac01f9b93fff918418f2ed53e4b4935a6f7d657cc8a612dcfa8636aada686cb407dc7de173a38e4a", + "0x8c753d2e8a6649032a2d5ec9a5921aab0ab65c5022c950600d60cf94fd5af0353c5ef14950946f538c03c99dc12adf98", + "0xa80a2f083fe2d7fbfcaaa1eaf05d32872801dd9f7b4c1771748bcc6318fcc26db1a37cbabdc7673cea5916a9f7e9c13e", + "0x8e3e203ba6d846d51f77782bbe2fe12e7156112ee4d9074d80de8dc8d6059c0f10607a1aeab9cba947eb3c7ba88f3837", + "0xa5b72e6cdc1b500a6937a29997ad628a3394fbe7846887ebb46fe5e3646e38ae2566400a28219e198a9bf2f9948b3afc", + "0x9722da66163400e6c2f8dcbe69ce8864cbd1a80680b3a50723d6bf625ebab767eb9fe50c7edf7fb89d4eaa2f6bf8c2ef", + "0xaad547d9be68a9380edb1d7c631d9be63d03adaae9afdb849acd8dd1a5b4b94e43286a2226331156887b22ff0cf229fd", + "0x8fc9cff6afe3e413967405ff6462687f98274367ef2b7b682c371231a2ee9a332ec945262ed12cc186b17408c5debefe", + "0xb2cba28604110ca4ef1761cd2d62c25d65c4a93853e42df8b2baca5804b5c8b6f835fc927a577ec6ce400e8f0f98e513", + "0xa4b7bc6543cd65b7fc8a9c8181d761b2cacdff0c00031fad0500631f105384a23036529c3c90321491c096bfaa4fda95", + "0x8621b0124016389b99ebb63442401cd7b52a730011350005bb27864367308166c8eb354ed3a6bbcd605baa1d96a580db", + "0xa7a4298189b992183cfeef0e4912409a262ad5ef09896012d48c10e70b5dd8c5c6af97e50f9386a3edd6a6c5baa5f877", + "0xa9f52427eedb2d7d030fe959c68abb603bccb15ef868cdc14667b191683f214aeb4fb0d42e439551aa79163e5ad33f00", + "0x92acc71c4f02544dba1f494e08f476e75c4df5f883e25123f631b03cb96d50f5a0bc84f5d80f2e314ca42800c08847c3", + "0x8e2607549422f81d9626d508ca676a8ba81d40479accefd01a2613ff299d016d347109e2e676727379037a8f175a7bba", + "0xa3719f67828b9a4147e476f0fb74b9abde2c9a2249402d4fdc2f269df0049fc509751e5592b7bd5555742566193f4339", + "0x946774766c713e2afb881d9bdf62819cba648d4494038082bf17cbba0172c352bd7eda1be05d159c0a3086ce127f93e9", + "0x811ca13fc78527890ca4fb343b9b78927ea57c18d90531829873a3e7f4717756fbf774ba91d21ead4c17cb78c428fb4d", + "0xb014b7a3fe22ff65fc55e026b8432f129ceb8a57c17cb540b2d2215f71bb585c43101129e26658936b26808e2f5dedba", + "0x8d8548f74b4878c0c030298529731b223ac37066959b8e9b2cdc7d5455f62c58084597297fbe4891b2a4946c32c94006", + "0xb3a4ddacd66bbd429f1a2bffda79d4f6303ca8f4c1d7726d17e97b9da2fa365e1657d2a1ce21a6835067c7aae4137ed5", + "0x9833e7228aa1ef01da1ddf48f9d45f35e2dd175ddd92030db3ff142a393b109ae212b4eb4ffaaca06d113eaf672714e7", + "0x8c2c96b987d0e678939e6b5749f1710901f6d9f98b9cb439ec1608d24ff62ccdd990eff3e1f838a7caec07b1bc465ce7", + "0xa4a96ec5990780564adb50cdf358b3b67cfe289f83bb86d69d33df11c0e0082e5e5ed50ca6966f394cfa6c3d077b389b", + "0x8b8f782013e56849c22b6482e8706cc05557618ac84ed63f224ff3265ec9867b189fdf3dc90fd660c7a78d0f24c0a8e2", + "0xb9a9c586aa8cf7ad641fdb2f7047856c5882723ebbc2722a2a7cb8f7fb9cd3193ea5702dc4a300ac26d1aee6b39acb67", + "0x836203c5229e9baee8a094be806f21161256e45a0ecbda3a22bdb42c5e05c9ee9c5aff2b90ff9dc820699769dcd78342", + "0x81d42dc6b11ea9c826d8f1c08a7924b10d1627fecde8d17aaafb1ef37121a3d09516f19f28b36e61175053998f792dfb", + "0xaaeaa826c2be6b8f19a803ef6be7feaa986951f4f84ef37430e38ac426ab28cde4eafbfae56ebc5352d91b0afd5a45b2", + "0x89e16dc55ca4f931160628d14c9bf70c6ca06aadc90e264030badca28efaeb3fd772db478134e047d553377eb13af46a", + "0x9210e51c593619a2baf6aebaa4a9071a24698e9d0a763b3b5565c1c850e3195724b0fd8b9d2879bf9f6e0d970aa9b077", + "0xa594012a8bf117ecdfb1044fa581992aeb821cdbbe6a4b683e620996a834493fd1bdabbdcc59e34c58ec71712e5ef5a8", + "0x82245650c166b775d72c42094abb5de99a8f8da1163c253d6f7e620053e205c3c5554eefe5009425d96e5264f78cdef2", + "0x958ac5f259824911b78fdc2e6a8800bf31cbff6c2d54ab5bc1d09d4e6e02b90f942ebc0b3f3c5ddf555b3d2ce979a7e1", + "0xa43f99372b971a6453d6bb25b953396d79607f9af019c814d8c8f69e40773f3ea7ff995b5b0c574a4f899cd998e84731", + "0x8ecb9aef5a5811ea9b7d185f19b9b5561d3f71ae86689a9f1a5bfb25ac2f6752d71ccd4c2da95cc6c928f58246d8f379", + "0xa52ae5efb3affd6cb3dc64dbec08844ca5a9cc87f2d9e2a8d69f0d5e00f8ee7dbb452efe55bf892e0fcb29afc8760a4d", + "0x99792a1661a4a98169af514c867bb7b5e59556c6ddb8936a3cbfd3835c08780d76aa40f91b7ef6fc75b72af18e3b686c", + "0x859f94fa5a288d74f770ac5600e3cdeff34689562e0c22af09f3e85076719834c08c3a2e3c54c54074da7a6731a3b2d1", + "0xb03cfbd581e753754f3af1a58181a47d0305d3d298222608c78d8fb39a20fefdb215b2871ab9cf3a4ea08b5e2113c4d5", + "0x97f164590d068f5285f87ae80b4077ecf62fdbfc8b891b6903e62c6cce1ea926b13fb1ef091df9ffd753fbc97ea36dfc", + "0x8e5ffa5d13ac9bdfcb2ec6d8119feb46650d9d126f5ef459a6591292e731e02e59fbf0bd381408f7ca04c0740e904f1e", + "0xb6ce82c613a8c62d2277b07b343c9b4b5e07df4746ec6444aaaf258032f4364388fb92e30a16795c15b6921ec49c84e2", + "0xb28516f266b8ea355b1b7a4b04a77ddf018818e4b8757abeedf47a378675689dd9d3f54419a7de90ab7c0ce97b0df221", + "0x856baa5fe8e482183569ebe10108c03f96e49eda24886672b28388cb179d416c8a32de2359d5ec8b06895f264b705122", + "0x874e211339b9e9cdf3dc42fe06553650614efe41c37391fce584e88cb5edb81cf95f7c3f3105f22da322462b69d01ed6", + "0xb88776ffeb63bae2374bc29b10f85f0ea23ca4293cd9406821e7861a23680324df803e4a6ef9014c259b272233fc7775", + "0x8bd79784779eec9edfecaa8cf9d2da6b58ddd508d8df4b95a2339e89e2c251c46fcadbbd6ed87694c307f3a223199ec5", + "0xb0226203060ff31c1c8ac3d423447d05ecc6b8a718d09e7407a64b26db756ff2353877cd6216cc2a2e8744f6ca2408ab", + "0x995fec7f6c78c0087f6f8d9768539675bcf03f68017e8e333e881b26920e58ddfebd1d9fe359438e090fbb31518c9333", + "0x9898784a300d7094ce827d184cee627c3e39bb399ee189f756e878e3a03c213d8ee0843708eb602c4ad36961c74a1b5f", + "0x8c62cd5143778b121a1cca16fe5d7710958acce85a02741b2d6043b6968fe116cf25d96584a2e9cdd2996ab78137f85f", + "0xb19372d56741b4a131a3064c444ff333f132d231a1e238530659a8f21e36559b375e4ed3249f8feb01c9844b6e0471a8", + "0x8b7f9f2262ba3ecc409a1386b41eca8303ec28164f7fc7e4fe1192d659ff13520ac92a0a2ccdbe7d338cda6f04a541e2", + "0x97757c7c1751468ba37e1d358c6f267da60aba8af4912a97df7bb643bba162b8947a34b5aedbe4d04c7ed3058bd96dc8", + "0x8b591a11893f83d124f5124b5792591c0166bfdf8c6a6cd4592af35b1139065145448304f09567efad49ff0aa02a5a39", + "0xa7a20190a25b4217fc4ca7824401b59678081ce88425c7ed54a7cf17a92319a86927de3c10e316d3618656c26834ff23", + "0x99ad152532fdd40b8e71ffd082bd33d9cff8c9aa0b569c9a7bd3dc131bb2420d70dd1763aa22d6d35efdd621c82ffb4d", + "0x813db4350ba9aece4913211bdd5ba52cf477ad1f55403b22b417201f4f6312fbb949bd47b9f5706ecf712bb840b6f705", + "0xa77e2f1f70112c1e47978db6519dbd81896593a38e486bef2e3f2c310aa53f05c891a81747559459c50781371f4f49a8", + "0x929154d1c5380143b21eaebee29ae84c40b1c468ad5dcf2cd3451d2823e00c76364fab487e591679ae56aa55ae253056", + "0x918060be740bc0212248384bb18ce3703fbbec9cc676c39eeb9d7e6d9cf250dfbd3baf40f8e66445ed615d9a74f0ac74", + "0xaef2a36b549fd7180cd11fbeb218c7401ab4cb1a0a2bbbbdb929335fe9e6cfc7a5d70cd561343e2eced0002ca053ecca", + "0x853a7b7b69f65085045208308538faafefc18044460c2a46e4a26533bf0aaeb6a8ad2f068a3e3daacd081dcfe54f422d", + "0x88e4d3da343a3f8443630d2eced9b32c0ce42f1e302876d6c23e376a8799480703ab284841dc4379231a623cafbd23e2", + "0x92c8e409b149f99855f955c688fec54403dd4baa651e233954fc16c5e1535347442a0f011684211fe3e11fd3e3c5539e", + "0x992c4288e3b4e187cf786e64644df3a99f5bf90b090e0ce4c1514456684f4150ce114af6903a2e684ecd5c6ddb8501d3", + "0xa23ca8526a43495b734d8370a660290d080f3aa1fa597155ba8e73bb1680c4ef7a8cd20033cd1ed43114279f0d336940", + "0x86f027270c3944ff3220eb4f426f89762632764a05b9cd469d7d8ac16373ae1d8aed56e78df4c1fb23f43cbdc35147a8", + "0x8fc04077979c207ec645ecdb813ab1f22b9f14e29a9d4dcabf2d8cba7ec85722ae7cb9aec82d4683e41cbe97879499e0", + "0xb580cbabb8fb7233b317f6db97c21b35cfb9883db530d84b96ccc2813d29f4775121983ecb33238f2dc9c5f0f584f4f7", + "0x97261553d1faaea8edc8a37f3bd9472dd0f50fadfdc81ca10663c6a9055e75f8d2a34aa0f725ff9b21de6468cf039c4c", + "0x9843200b3440c840dabe1f3d57f5b9def1dc3f8f9f5d234b3874487712924090b07e118fc286926fcf78fa7174500d7c", + "0x8ef1388eee293cc2ce5f6095cdf06f9c67e41b36bf4790470510f3d366787d6b63acc513f093ae6cd82e6bfdc87a0660", + "0xa6609890f861653b1cdc5dcbc6e0ef59703444f0d828a828b7444072e9bd79f942517885deb8dab55c9d251a3469c281", + "0xb191dde229dcdb950622ed863c2c420e758f6f9ea1fd0d5cf33412c6ab1d12633147640e1faafd68efd476c8e95d5347", + "0xb0dc7324ac3c380466804e4dad907b477464b8e91f936369a812066309c3e447915e2c0a5e0fa7832ce83a9f5edc6150", + "0x95b537619672cb2bceff5e8752b5174321163e7748a5423c4c34219e4b17db7a7f72ef19b9e3750aac4dd62a96d04ea7", + "0xadfca4c02e663ea4bd8829d15d41a038e0b41d8af06775834f288dbe27dda89df7e73b270f72247dd3b161a83bb816a1", + "0x8616aa71307593c8ac49922b31e407e9efb6878819defbf4fa574def6c916a8c4abbd850cb49585ce451cd31b030d05b", + "0xa5d3c08810a1cbf7a293101be8963f778caf6bac2b626aa1a884110afe1c4c99e0bcfb390e60b6b5a51322cc72154af9", + "0xb8db346da5cd828b4bcef99adacc1a06b3a3a020450244d5c881e4486b9dd0d2c7c86dae7e381f3062d8eda344beca48", + "0x84527f1b39b50b6bbf3083f8c3ccc018243aa19afc4148cfa6a85b78d4f56964d2401ec9fdc7db2c8eaa95d8631399c6", + "0x89401e29dcc0019cfb3132c69fe79a2bbbd704ca06aad937865f896657fb4ab880fb97064b845d2e0307fd03ef609f31", + "0x92089dd692802845093443965e0206be2d3cc2b08fdcf4f26dd1fc24dde9970b5e8fa953b293a69abbec451f53481887", + "0xaa597b2c548a01b9a2aeb5b6bb28f13bdaf7678f8f6e52fdabcad7b77595a2212540f8334aef9c9139775b90194ec34f", + "0x83a2c0991bb8337a3dbe63e6679072b565d1cd27a41d973e95a21236b7fb4afc45331b6b16c83da2bb3d2a87f8e6f414", + "0xa5ae5d94fbd7940ad1cf38030d97a129e6e7fa8bcbc3d2b2981b1f5ec7df0f5a557227ff8933784f1469e1cb1fc4bf5b", + "0xb3063a730ab007abac949934459104ae70186c10f1cfe72c29740c2ea48c58a859aaf5d139ed40590589b912ba00e5f9", + "0xb60fd166567979cb8a4c617fd035d5a6ce818680eee3471aad95aaaba6eed3b83a8c0dfff12ef529b12706f5b4c88e58", + "0x948fec68548697fea684281d893c3d36d3c553cafa620a1503cac3b2401deb242a6d5cafaefc1d14bfd6d4cdeaac935b", + "0xae4afff2bf2cc44f14af996e5222d918f28a71f5c1bb98e2ac624255ab48c55e75448bb4fac03722cef8eedcffcda0a8", + "0x8c2e8c5bd74dc5583d5207b5601d32149933f9bc1e192a595d8dffd31825640607490117cb613f57bee47e9aaeb78386", + "0xac2819142c282e9b734c26a27206c6000974ec68bb687805024716c6956f8e46e570d7b56c6ce8c8318016a433767ae7", + "0x9180edbd33465d4c315dd24ce30db93266ba762aae607a024f998713c0d233d2805a9deada9bc58e72dc46fcc4c65574", + "0x8451bd222a519a83a84e3967f13117fa37dda56d1fbbc52af388b0937b51107ce846fba5c55c289fc123361113c9e5bc", + "0x974460d66d76da975b645969240016285a5b0f51e2fb2d0119ac0f8c4556d6f9f5d0b271f63927c6532880e80d1f5870", + "0xacd07f889e012222f38f691b5df98395b93d76990dc805ad1dc8b4c707eeec4329f0adce86c02320096365b6bc65b635", + "0xa176ca89fc49040c0d9561ba75ebc002f9f436fc0f39ceef74349e060547962c371fb0bd41a894a0e841300e045ec91f", + "0x8881cba6164dcdcb7588b09ffcb36fe221762f5fc6f6b095b004c0c99283357a8f1d809d24ee3246e8254c66a3a72016", + "0x867879c6a94d3cee024f8466a04b3471f0999e2b48c88ac8b0128b9fa511ce80b542da8bcd3464a8f6039dc5a50b1414", + "0x9860d928882d8377e8b1ed0469f33732601bc63a0099bde6151776a3d52912a46804591707b7f01790be65014e352b43", + "0x955a4a1d879e1a5c5048cbac60389cb08d94a6b711d17fe782c3139c53ba49e6432dcf07c89a777e0e5a7fe45b50b1f7", + "0xb2ebf77cf1bacf1ad8897f974e28ccaa346e3a26a8411e6875e1051e4f311b6433523a45dd81f65850eeae3eebef7a89", + "0xb40bebe8443381bfbe6d7eab9448630671aa439af7c8c943dabfdd9e74ffa1f7977143c5e6cb29aff19e97707bc0a159", + "0xaff97a4bb20cbde360086b2c24c87867b7eb73a4dd638c033a8e22876e168b2771ad0655ca8ff61bdb74118c9ff168bb", + "0x85774b40eee826025910b3e44ed1c33a5468b494c6aaee4715df8b089fab6c971e7a1994f25f4467550f8221ce226494", + "0xa6d9f7f15c728518bd5cfe127c1834bec935883eeaae91168bcbda3768006322d18112eb8dff2e30e1f8a78dfe0549e6", + "0x8e1673d802b264c6b6f6309360030e73b6e16eba5e9afaab5ac7a1f2e308c286b1ad60737cabeb79cd59b0dc5ff6bbb9", + "0xb6a8b025c01dd6c2b92ad80af959aeaa372faad8ac067a1cc47475032479978d5069a4aea6d40303a1986ca60146b9b1", + "0x8ac924255d08169a422325d24114309ad29625d0f56caf763d10480a1b1bc8f478e37b86d1141126c62ebe9923a668db", + "0xa7f1b463e1a14448a5d35c4568decc9d3bfa2123be2f5a019763e241f9db1eebb7df288092614eff4cbcaf7f735b5061", + "0x8eb351129b5ca104af2b8826e8bcc73f8adb0e0aac383336e7d1e38668179b0ce497e82c7220879cc750aba5cdb6bf18", + "0x97aefb4b8e2683f7e376a548a03405af79d4278d55ff1b30b24c3ddcee231d912ffc5300ff925d4a66fda8c829198a11", + "0x998ac349abcb080a78f31aff4f540fdd9640d1aecd345c0be3eed133ae2177822d0873b0d776d823e86954f8c7729c35", + "0xb5f4e3b87feb8c06c50fa1cd147327f04b00e18afeb141b73e685a592e16def6911d396d57bf0c9fb87ca043efe8e37d", + "0xb4a387c496215e1e3d67185e85fbeff5ca6d9893c9bbcafa965253874a7683945ac9397f32d018ac559e2863071fb4d7", + "0xa418b58c5a13b7ca06b371ce086ec0b49a171b288fe9386cb9f8b9fbc356a6007a017cd49448ef19cb8f55397a16282f", + "0xb3e9c21cd1996c4f34cb0ccd10204c23a93ec419818d460fcea3ce858dccfb47217035688b8307443c04beb716bcbe02", + "0xa12357dee3a05c2c5d78541fd13fff78cb6eef01132146396ad3d5dc0a428c9d81c2c96bfa4678e3ea93e469deecfced", + "0x8bd7d7dd1165dcd24c09382bf9beca09545cfceec6d26caadcd972ab6fd237ed0c9ded30b5ac6eb2a44bc845c02eaaae", + "0xa42b3bfc7f3b9155668c3a26c80a5e70b1647614ec2a222146f464a3d00e8d8ccf19ca5e4bdd14f2b15fae31ed44bd90", + "0xb8bf46320b42631d5f238ce7a06e65ecabe989c244905baeeee3cffdb876dfce199dc96c5a43ee83c0844922d5a123c0", + "0x955d8e83d29e8fc6f963ccfa952d7d67939d65be5823c453a324afed7d9cc7d915c7703d157b793eac729c3b0b2cdfb0", + "0xa4f57f189cf2078aed8186ff2125b7e998c7c9dd0960414bec6bb3f2af5dbae1a609f3b191d701d7fcc8a73585a310de", + "0xb1fcdf9328a5df80a447ea969774d66b17ec88bc6cb327a1927dc1ddc704cbb1191d042a65f412412b33cdd16e56907f" + ], + "aggregate_pubkey": "0xa7be2af0275529b73127a6099e6abd4de879694501680cd2db4146c7a79cd8154f223837877b099c15c587b15b00100e" + }, + "current_sync_committee_branch": [ + "0xd5f8f157b489b74f493366543b812e11ac53510bc0363dcf7be8497bfcda9314", + "0xa23ed9dd5838c429b4316e0c3af23bc478b6f2ea0f35f78aeb01555df1529b08", + "0x4e95abc8ab0bcb31be24f4115f41f542d62243722b2215de8902b5c04986bb95", + "0x8c2b56ef5dcec2cfb28f4cbf10f5089e7053ee120d97bdc287900a86531cc1e5", + "0xabe848e2b172ef6fff398f986235864ae6336d57a94926f2893f412fe54226bd" + ] + } +} \ No newline at end of file diff --git a/ethereum/test-assets/inclusion/base-data/EthGetProof.json b/ethereum/test-assets/inclusion/base-data/EthGetProof.json new file mode 100644 index 00000000..c3f5931e --- /dev/null +++ b/ethereum/test-assets/inclusion/base-data/EthGetProof.json @@ -0,0 +1,37 @@ +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "accountProof": [ + "0xf90211a0fc556db36000babb200148bda819383737706dc685a85fb4202b4b180f2aa8b0a02b3db4553c3c8f783731d50cd25976c5ad906fddd8f90c027fa6241c3a4af8bba0adbf6b1927b91a3f43de1d8b0f93984039e32866983114f43995fb719c4c6f19a09c9a0d774aa2728616d64144d1bc45571f6af3ec3b5077153b8d22d42a5d3632a0f3dafd6e5e09782d03c8febb737623930dbc9a092cdaa9ab9a32964fb022518da0428d8c5ca6ca02357bfa1ec6107b25851d9dc0f5ea5e8e98e38ede4b9cd359f4a0a68f96082a27e9cab664b04a49af1ddb254b8985525d091dad62f818ef15c7cfa09d00902d448b152d1853c41769b62a69e15ffd442d1ef2a5014bbdbec7650ee8a09e45cf3341d9aa26fb5ba9096bf7d96fb63a676b74612ed7a32746cde58cffe9a0573bdbb73744de8c8643818744b646ca6f0f8418eb221277e179879c3399da9fa025ef5f7b4d57088ecbfde90e3abd26629491dc36d79d81aa37f8ba3611f034b1a0a537a9ef8af19371e0fea2c36e3d413abccc6e8ba6e928a89408ddf20d8b12dda0bb7d8157b503dba4d39b2a9a5c40aa43c0804941ee55163e783e79e632bf1bbaa0fef5ce2aeea938787402440fb89aa79e4181169a9fe96766f81b622fbc4fa22da039851a5cb45e78c12aa18271ca7ec1a446db2bd99ca5362043c01dfac9f31653a09042c3cd593e1a1b34576400cd5242997dde4577f97436f1b78eadcdeb1a794180", + "0xf90211a003f7c7c2164a1b6ad29afe768d410d7623992f235097f346d3769c04326502eea0eb9fdbb6c19a0da5d7df95bcf0cfd17f9a4584ba0264ee7917eec7e759abe4c0a09d1fde2f0d200aad5c05ddbf018bd6647678232e7b59592299971379ceb956daa0f7adb44c6248a22d4e1ef0822b81b590b410ae1a489863189252efdd9f9dec84a04eff0cf2fd2cb7117598c9c074824386caab82eaf810908bf05d88575cf1c7e0a0da7d33dfd991d19ac68dd50219bb6970581048818ca320d411994c6154c5ca2da0edab138c3c4e3b341751512d4a88945795e8288f90f23cda6bfc0df880459aaea0a33b94d4d0ba9141fd52f1fe07d8d6c0b496a46f3a6b36be6c21cfb6db6b5881a0032667681b6bd7104f05f2e6b501369d4910134c724f60ce49647be53212402aa0836f4d38ee3e339270fdd06c7cf6bceabc30b2a736ede712d7387f3825373efea0c9b0ab76be88e638585b2c773b81a243398c3be2fab70589a2c86ed6bd2c761da0b82e1af8e59b2af10966cdfd5ad0d2f176c5f9b35470ad356cf389ffa14b908fa0af4803f4f13c9a5246a792204331ac33a5307536ab040899a5a5e3e1565120fea0ebacd53e962c2b90fa52476dcc1e001a41d95bf5c24ef08851ed3c497dc0549ba0260085cfd63d795bc46cc0d758d6e428652ebbb5ab9e2f9d839ddc961f13624ba083ddb42f7dffcad184a30cffea59bb565bc790ad44a174de833a8a714c217e3e80", + "0xf90211a00fe8534a6953490ec6571d6b35ea852de1378522adc84c5e31d9c3ac7872f09aa06f095745ad1e35250578e01ac3a24f6ac3c3571f451bbb37e203e02266e06589a09b7fae841aac432314298ffb7f76216cf59cb192ba3f5ecd02065a28ca282b82a08a5ea4e39121fb121d6d2595c8e5603266ad94ca70c4f5386c94d916d9ec32c1a0444439e93028384168fb39f0c25d9db778b212fa3db7d4ffbe871542101b937ba0806936c72cd88dea7c21137d097f5d81ea0e8f6448b45d67c9e5bd44a5123b28a0f75cd08f9f8650c458903af0062e5f3632e15804442b8182411714f5f9e2f79fa07f5e333aca42dfc0ac5be1daa6de5e7d5dd3ad1f7267dcd7779ac3d965f42595a0beb747660d6b0e6f70f3fe4640ee97a130e87c976775814aee662a74fc7e8703a01f34a07dbc9fbda91eb4e6d5807ee6f80a95d9ab5ff84bae72339dc7e2277d28a041f6ec96ebc4a316dbf348c52a855d11b5866461e80f953029e1972281ac7c15a058e3a416ef4a76ca73fe6dae084b7051da8a91736fd67f288dde48eb2cf3b41fa071d9e41d279507e38cca16667f13975c6416e2ff19fe2d4f67c5eb211c9f2c6ca001c6d283b85542b3a9af3ea4895e4d05c0d36756afc77204006748f296ca8bafa0575e2f3c34b4a727aadf46aed2cab3d965c6a4454836ee0aa38f7c1b0f3e7096a0779d18ed75ba510f8c291b5ed716dad0f4f3bfe4193095f3a777e0e81613b88880", + "0xf90211a07eb4dea3ba017284f3428bb1dccfceacc62a84f1b783b23a5be06011cb913edaa040f48df283b69487bc03fadfce483bcab42673f90677511f0bf9ca00838411e4a0b340784acdd8d0d5fe432728c508b49a39bf98781924deb412d945df3c0a5498a03ef299b792ab585e7f6a52f3d069e179bf4369b0b0783a2a594e380b0279132ca030d408b6359137472ede0eb3d85ebd4a5e301fc39a79f5838b6a03773519499ba07d95d571bd0bf7e48c6e7b17daa7e36821913b73c962dfca5afac406457015c1a05afdd4f3f3482e3c7a71789b51b6181fe769d5b2cebaaf5d8757df90cbb16c4aa016a025fe494b3975c445d1aad2b59adec60335c1e261f38aff5fd8e24b7d12ada00ab92cb407af0c351f34c4be51e508ee8ec048742ba2e8b7325afac843a4df3ea00f19893176a67d655917df396a84550d8c81c6da61905f3c9d9f755c78498dcba03f3c69a85fe9a92f88bc4e0a94eed8823ce72ad11e73244e98bc48b879b636b1a007db0446ebbdad1763d805d411f2149d3bc492e5e8453879e61eed4fc1b7c244a04958f51934a9955fccf6f7cf2e67e06c49eb8ee6f79f362539bf383739f148aba0669f57ded8a970c14b9a70f227d61a7424946ed560eabcd3428b12a01ee26123a0af59bc6a58e74098960e9b64d28f6476ad9bb52da581d1f389ae777a6a530eeca0755b0752944305aa4044766160b3a1d7c2734022ffb87ce6a305c3e13a589ec080", + "0xf90211a0a9e10b064143cf72cd81471cfdb1e51040eb1cf7ccb0429f0e459da0338beb8ba03d4eee8b6e82adfa44df5982c13c1a9774c07cdaaa48f093c056c66d292f3f5fa09a2db375861df869757806850913e7e67d86c3604db0064df54add6c03cd6632a025cebfb0acb6fa51024ee5cc7f310859da5fbbb677538c870af5e6621b380c21a0ff6ba80b68278ac8ae2fe2ab430a8c265f5698bdce13761d2236603ee94d2965a05aef9484868f72aa1574965b940b6380c923b2f5a885d9082912488ff0e2f823a0014abfe851e216c14fab754875bc3fc4c3256e261ac35fe46476f8d094655a59a025f71d87448695688e92ae2987477ac8ec12079a7d4373e45ceec55d4f82a050a0412edb2b84f3d51b34155a632d09698fed5d48b84c7e8a00bcc9f1920ed9d7a6a04f61f348829ab3e446ca26a395334f39840186b7aa07689bf9da65f168ba7b7da02d7e90447acddaf6ef4fa07db7f6dae678f06e6718dfd022287417fca8b62eb8a0f2821179562de3d2d1087ad1bea77e8ce11bba3eb71d32c3b86fd2813ee785d6a0ab45d7b488cfe0fff3b6ddbb42d6e041935668f9f78f5603a18e7db2336bffd8a022c1537e65ab7c37518b983886d07a4e504a5df2001f12e2e108f1415be48d19a068ac1de01875972ce9483fcd5c6ee9c5b1d442b556b45c2918c5356b8aaf8726a029becf3abaffb77dc83f3b50471a192963b821f7bb26613d7130b44f6b9f865180", + "0xf90211a0459abecb75f6d7211f1b11e5aacdcbdba8c7575ee9a95f379fbff8cc3eb82c9ea01a77280c4b5154ffa3d9c1f9d0214853ca8eb524217da7af826e0dad8dc0984aa0ae078acf204e952c0faf2102a4a5676efc9ba8148d5619097e6f1360e7e97112a03577ecc15dfd4deb70ac1a2e09ed9590d7ff3dbc1a7401f5434ddc2651767d9da095e04cbb2c4b8072c65e73a6534a2540bd9e3532c44556a4b176dd455d2cee2ca0463c0e2a3c940584570c95c06658dc07c74125ed110311c0d3b7f8d1bb575432a0453ff502060769ea24e852c574f5008bb01de9e932dadbb58b923a3efe4de3ada0feddacc60c209eeffa33263dfe3cb7a0cba8b8e5905c61d92abb933005556459a0861f9983ae8b44057b6bcc0166bca10ecd0d1ff2ecbb9c7ecd54d191be7a550ea00a70f45da71efdb2e24e27cb271b63358743620ac8bc8c05e887df6c56ac36d0a0c2be30583bae9fb5e470e53265ac24030119cc0eda8bbd980cd5ba59f016ee2aa0315b6917e73564f0a3ec27a5a01f551c1703fc8b681168822e6f31a2b380c240a0835a9284af7f06ce47ac16bc4d601dd298e8882a7b4a8f4083e7a831158321bea04471a95e0ea03c77f9a53eb578d91406f8964a495ee7773807b34da9812b203aa0a587216af357289bb037ae7f837d625c7dd42bd35809a1d2ca6944db877fc1d9a0150b3583e5cfed62acfc991e044b36998b24e6ed1583e12eb613d7871b949afe80", + "0xf901518080a006a24b303176687716fcd8a01db4e8f46d41eeb6422db80be87a220c20ace449808080a02ac70939c8391da5cc478930deb95c53f07774909cd395f7e7b77b77c45c38aca038966a0653fbe6bbe420adc831d6a1a1ffc34689ccae7055ed6a9b1173fc4c71a0980f83a8fd00a7b260dfff9e8fcd09591a22cdfab57c0f0950ba473f14d07d5c80a03fcc0aaad67c0d8ef7eb74e1dbecd6b597cb017b795e1f35ab85ed9733a90ddfa0967265118a6c8880f399770a71a7a2227f3d1d0778bc59d9ccba585eb443d1e4a02c504839fd2171be106abc10b7ab3d9a4f2d3b2e2411b6d4254bb77fcf14fcb5a08f233832630a1bc6ffaee44813cb59a9664a79c2c25a333661c93e4a19394492a0c623a87ee95808a778377f53065c02f81ac078916fd38d363405ff11355a6cf1a0ea36d7c30d5a2125779dbe769d018f367465f127deb8067645212fc3cc8318f780", + "0xf8518080a01fd07f0ff4727ed9417b682322f8ad5b4e819bbed630452c8a008404f4405499a090daf444f9d436a54d18b5eb39c11d3812e325122fe31dab7a50d30f9ac372ee80808080808080808080808080", + "0xf851a0c698261136a63482fe71a0442a2c23bd2f964984d769fc300ae4bc0dd7efec1b8080808080808080a0baa1b5ede936362cb1e9dac2cf013297afa239f98e970da125e3e464928714a180808080808080", + "0xf8689c3a172d0a479f6add89c63b29dce29b6071b3c7e486b0fb4bc431f885b849f8478305483580a014f391cf42a5e4885a0ff2e9a524c43a9638684cefe15ac947b8076eb577edb4a0bab145d02e7005f0d84c6c1639d39b799b0ea16df99ebbdaf5a14d9da820b4e0" + ], + "address": "0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f", + "balance": "0x0", + "codeHash": "0xbab145d02e7005f0d84c6c1639d39b799b0ea16df99ebbdaf5a14d9da820b4e0", + "nonce": "0x54835", + "storageHash": "0x14f391cf42a5e4885a0ff2e9a524c43a9638684cefe15ac947b8076eb577edb4", + "storageProof": [ + { + "key": "0x290decd9548b62a8ef0d3e6ac11e2d7b95a49e22ecf57fc6044b6f007ca2b2ba", + "proof": [ + "0xf90211a08d360e5dd8f36f5041340e1557c071a067428ff0980d96d12fc066e6ca80f186a02767c4cbb2c815d825d9858fe193fcc854d47538acb964a3bb87d2838aa6dec6a038779324a6c40f4a5b856d1062b63d4a3f701611842d6e849062110f11449dbda0171749ed2c4015c22b4538cd4b10f17d3af38a331042ef4fb0a5f7433b6aea3ba0ad7b86eabbbc77ea1f602f4fea1290042a7232d11c7d518af09ba9c10b7d6b34a03a3283b36a4ca2018434d7c0a641e69be8e001775e27be6e721315a5fd384f52a051210d909646938b3ce9244d394143e2a8ca3465e9fa53a3082f67fcb470bc2ba0f4e928eff6d2a112b80bd825f058f67167f4a8b37e449da903ac2d298ebfe37da09a4e5840561c062cac21ddd0e7a6deded318f83cd995b29b1fc48c549af4e63da039724d922cdae8dc978b96c2cf92990054cae497501a6db02f99aea67a878106a0ac9aef6491074390ce52709f739b58d93e6ba2d3118652e0084e61fec23c7983a03474c66dc549e8b680ceb99e5c274c4cbfc4a880ed9be7d093b6e1dd839390aba0f46c5ac3c5738a944584505e89a72c508e782cddb60d0124d3fd44b034c58b2ea069d2bb797ccaeae4efd5f8f71ad9252608617af4c8aab673f548096ee39acaa0a0574bd49a2302462d8fb0ad3b139cabe85ffd7a19d0a2942ee561ade8c24b355da0ebf50e01e4bad7aa6320a8628b91b56a0adecc0247186d3683ae47b12bbea4b780", + "0xf90211a02f400f051c638cc67748c42896d23f5e65aa19ce059a9f8a305955de1cc89f3ea030590b72724c85666d7d2c8ae74ac12fa2d47e5ad2732935e05417e1cd6fba7aa01d631dc1f9127fc703e80c4419a262a9ce50084979d4ee278a131e702bef2310a0b9ec19f7a1c61b0bfa907190d71b7d74ea3f582742ed468a6098f56da0860368a0c3ce360363b58326b324740aa7349c57f332e631c953e6886b0b366f1c305de9a0ad3c6c83e50f65d6b59a29f8a7ce54add602200c02356fbd5e07e3fa78f44dfca0a4e8a571696f05bb8b41900f85aa559aa8ad870932a30b6c833949c78c25bd48a046e4793a88d6cf514f7abf3149a48b1c107edc31ae90cf53b7dffb4874be5eb7a04c834a2635672f8ddb6d4d8ac1f44679ddb16d9c242804d06671e536d5cf288aa0558cb52fa53307be26518950b9e05ddb480bc4b409738e960a42119cfbaca13ca0ca9814d8a4ba16b51efcda3b9c1c5899580479467b6cc93268aaa0b8180533d9a0fe067a1f69d34d7f0ff8f2b46069fa07eb86031f086d86210f48a27873227c33a093b47ccfe6b7bf8965601a775dafc12f5334bd3d4c8b5448ff80c9444f971205a0cf869e5a3b0adfdcc78f5634b65689078d6599e3c210051958c2ced1ebef8442a062a7fa8f38c9301538c5f04961d00105f2c05f46c1222eb356395bf20d783a5ca0aea1554157828a6f3e620de00b81c6ba615d086ff9dbe73707eb952380cd7f9780", + "0xf90211a06cdbbfc9d861f765be82299a833c5912345d7f16b425c39378683e0993fdb14ba08435605e2a02949e6b6cab3040e9c40fd7ed636fcad99d5a2a757c93b4907d82a02956584a6a0f8efc7aeeb6c247c11fb2ecac4cb48eab85cb29ddaedded6a65f9a0cff246c4c79295950191f11c56101940b73d4c905dba0a0de550a7bf09ff5558a0fc9667285290df351a09f09c53fb2c36066dd252ce488db14d740d6265d05ff7a0c1227810bb6c38dafa8d0aee4c21ab74299eae101b0be0a6057d128706cef486a088ab558c3f7f20473540885076738639f8815fd869d2df7925f91e8b6f208a56a08609cee7b3eee0cefdc98a70bee9ed7a457048c046dd6ab1274327365fc98359a0e01fec1e8e39efadc56198b41036f0208e81a4326e226fea2eb663094e433457a02d4330a1e894f490e9f26bee611cad7d31bcf0d68542ed68df05994a423d922aa0456a546d88237143c14f09d3bc3fb7ff7d641f83463cacefe655c9806b6b6214a0b70f369fc5d68a1c8998b5fec5808972ce23123c304c50c402521f081c686cb1a06abdbe707c51afbc41578f3f05c8aa72037cc07d4b8ae3ef4f73f79d4c6deeeea0afdcf159496f70f4935a3862e93dcbd8bf62838e31569f733df58b41af54c1b4a036108baf1b417cd978f856a320ef2b3223af3abc5f310e3c49a6ec0235eea110a01a8a66baac8359ca3ce44115fed1430bb897627324ba1218813dbe234af2f27380", + "0xf90211a0c8b580a2125ecd148b523a15c984d0130b29427cf27e51a73ba51d46e3f50ceea0c09ffb011a442f9b1c37239d537c30f5fbba70e55632c2fd47e4310c55d0daeca02ffcdd820847006142c5bb47ef47f87b1ff47e11c22b0b8ab8bdadec3d2242d0a0f04bb63c1c06d4e452ffb68a0ed5247eb2b450c1acd853f600cb1012baff1227a0e1388a17624879ddb30b90b68afe571971dfc5bfa4a1ed63cec022048537ce02a05d0d391494bd90aaeedc50c9e7e5cc1bb15c9c63f4807235737f25f1fead3928a0ea2829dfade12dff4f65710c68cde0d26e77fca2e8f659c3ef668bf8fbe29830a0ad60cc489e44bf3b4bb7f1388051677ecd0d192afcc79af6d73b079e8719aadfa02282a71862fb8f02372eba8a2cf2a5feebe999a96a2e28d3a987ad098438421da0a3e3829a73dd3c0b40097e046d9c6c431d915e9585a7716a8b5a083effc3ff2ea0213225a75ef6fb9b604cf38d1968034b6b177a28b7d4504eb1e21713e5bd9056a0aceda93a17ff1dc618fa61c275fd23f9beea79a4ea5b060a9cf7860a0f2882a1a00acfbfc09af1641b8f713a2275c2b9a5251c46d8b6c402d46f9c847c91ba78b7a03e9c762f96e8f2ccc49fcbf42bbe7cd04ab018d998ff266cffeac33df178b902a03a897ecda7c3beecb5ce71e0cfe023097f6b3b9618aeea72fda54d5490aa9982a0280e4269ec48dd7a211e0bf8c47f41713f961c772e16bc16582c12502bb3988680", + "0xf90171a08359cc500db50bb6a9866b9b6af62a77c3d7d287abc25ff681a75de0277dfd0aa0149343b788cc007042b5a5605b744be6537deab075348e1a515331442e872feea09200c0b8451a8a9f40c46a4207ae2b83d64d73a924356d3ae15e0e98a5c807aea09d7d6c414593412f7732f4bae9dab8c1dffb05aeec71aae3f431dbca9ecb7e6480a02dd9250b0a78fb5cd45b19ba640edbe93eb0fb0f3eba00d3cc4f932c3eeacda180a081da3e559439e974a32daf9dc4d5a32b56d0a1583f3f6274abc93ba74144dd4fa0e5f352e92ad4f5fad5aaed53bbfed93648095f0cfc0aebdccab9818ac33499328080a0881ad8f7ea09c9c744f18b2792fefe3ab666c325193c93663dd273e18f8a724ea02a0988f4ca0628a13ac64355e304cf12911b5adb2fb11789642a009fe26ea82fa0251847b2837e37aa1743616e20b26a47823669e9fee43c3029942835c71a3aefa08c7fc7b3935e4f5cae513228c7863cf714874c05db964256660def60d74e16ac8080", + "0xf59e308aa5fe6c8b010d073e5e4e03083270b6b5428afcfe075041665582472495949de16d0dad0991323062cf0d30398a2d56ecf2d8" + ], + "value": "0x0" + } + ] + } +} \ No newline at end of file diff --git a/ethereum/test-assets/inclusion/base-data/FinalityUpdateDeneb.json b/ethereum/test-assets/inclusion/base-data/FinalityUpdateDeneb.json new file mode 100644 index 00000000..a6c54d77 --- /dev/null +++ b/ethereum/test-assets/inclusion/base-data/FinalityUpdateDeneb.json @@ -0,0 +1,86 @@ +{ + "version": "deneb", + "data": { + "attested_header": { + "beacon": { + "slot": "9567542", + "proposer_index": "1133709", + "parent_root": "0xd1a60a454c6df50c308459ec0718469b3571e79f91f67657560e9cd9b14365fa", + "state_root": "0xee5ddf023d3e0f4eb30a78a0f4c67679211cd81cbccd49b70163ee65aa21a591", + "body_root": "0x4464e9f4682fb7be1b78f483c875aaa6a792f58773a8a6582c2c4de5babe0fd9" + }, + "execution": { + "parent_hash": "0xb8509310a109a9d432802c262f2167d2d617e354f6f77295341414b24c61589e", + "fee_recipient": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97", + "state_root": "0x4adde0298c56dcb760cd93e31a0e480109867e581a1108c817e94a2383d70d3f", + "receipts_root": "0x84dcfd1bbf60d407ac70d066cf8b2b19b19c758778a759ab37a9f8e2100e52bc", + "logs_bloom": "0xc5a393ff7d71595f733fe2faed49da0395654a1d5e3370506a059fe4a0dae8e5da6511ef49ebf96c7ed5df40de3ed591deb2826edb312bd161ed79ad65ee6594c607cf5b23cfc8cfec13f18eb4414bbb0f85c753566cb874b8587f50c2ac87d47fddcd37a763f5a283cef790f22228f7d6f9a0cf56d5a742b74444fef61b58cfe3ae0a3358403a808d769e58bb2ae69e884d6fafddd83dbd7475b97770f43f58b3c8c96ae18d733df24e3fe2dbde9d3e57bbc032b88c5e654df30e7e362fcdf573f25d1b6ffbcef11232c645e86bba54953a3283d5e949994e7b774ef5e0e8c682fc3a6f187605323be45a81e452cf0546e1f729efcab8c8734b2876520cb405", + "prev_randao": "0x039aa6e322823005aa01df9cc6ad63c8d3b195e433f800dd28e7e47f59c6781f", + "block_number": "20360682", + "gas_limit": "30000000", + "gas_used": "15526750", + "timestamp": "1721634527", + "extra_data": "0x546974616e2028746974616e6275696c6465722e78797a29", + "base_fee_per_gas": "3139480071", + "block_hash": "0x34a1aba24fab67289c0c79ba799cddd08e90019a0795f846847e1544c064d3e0", + "transactions_root": "0xe27acf325dc5c81ea0d1abd8fce6cc51a092f9e27a34f548b46c29f81d7afd24", + "withdrawals_root": "0xa1d97639036ab4ab51c49eaf596f9a116f9a97506312e10c6443efe9e2041986", + "blob_gas_used": "0", + "excess_blob_gas": "0" + }, + "execution_branch": [ + "0x93983ee28630887491c6b25e654af131ef7b219dc6a05893fbbac54d8f630334", + "0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb", + "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x525ea57f56c4d990fe19f337090d89a0ddf557a5122d5ddeb57025bb804150ac" + ] + }, + "finalized_header": { + "beacon": { + "slot": "9567456", + "proposer_index": "565124", + "parent_root": "0xc01e019b5922b265a8d51a6e21207d63e6316bee198304549aac807af2d25511", + "state_root": "0xa51c31780fa13238750a19af0de6a73e6c1020b2093548568764498764c7184a", + "body_root": "0x5f649113f29921c36e3ac8087dc8d5ed3d9f459f665d8bea616d6be914a23cde" + }, + "execution": { + "parent_hash": "0x7757c28729aa0653f1f5f26d3c89b8b7a25acf7198f18a2498f476146065991d", + "fee_recipient": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97", + "state_root": "0xc51ad191ded785644e792e03583a54dcd4329d605560734c93f6cd9b5eaa9315", + "receipts_root": "0x490ba5474de11f90b2b557f668d907ca9773a38b90a6c6493b2023e520e1a4ae", + "logs_bloom": "0x93273d188d006101239203f3ac910a4d111d7893050360c70619c6ebcea38cc084e5b5f5211f629846d61b5a3f2e91941fa3894989a230e26bccf020b53fc9741604de090fcf1889ec58d76ab0e0b8ba040f19b142523e336dd670c1d8e727101aaa5c40e66083f2683c4db76882eda1a39c46c120858e148260689cc41801800a2389481049f28639d86b6c52a3c412664196031b68528945b9297a64d49aca0fa4113dcab8a1079226b9e818983fba1e09c4253943824ab4aa24bb080cc271c7b034a707d99e0079e4ce1098eb98c5270f200e1711c4342ca1fd0657052412f0d7b57b27d3a58856cc5c95a06086568dae3810a8b46ed4671d0376b3c4dc34", + "prev_randao": "0x53503a5d6718f39e2fcc0db45d04da6462f06095459a05b9c7bdf7f495d87058", + "block_number": "20360596", + "gas_limit": "30000000", + "gas_used": "11805504", + "timestamp": "1721633495", + "extra_data": "0x546974616e2028746974616e6275696c6465722e78797a29", + "base_fee_per_gas": "3420341872", + "block_hash": "0x8a5009007f9ba1af6a5ac8142fefee972a3e96d21e3db6498fbb6d410376400e", + "transactions_root": "0xbfacf36d75b4b5b6250c73db298a08ba95c8eca086c9f06e442843369eafec8a", + "withdrawals_root": "0xf8601e4524535d5dd043c3f6835df7b0a8000a2f2f3d23543e8d389a6ec3de45", + "blob_gas_used": "0", + "excess_blob_gas": "0" + }, + "execution_branch": [ + "0x68d7d6fc8ea273478bd7c6c4d9b6f97d55ec5da34f7e9f484af1cdf930c3aac5", + "0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb", + "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x5d83dd16f26340a38fe78f19d2d18e2e4c817abc896327574d5b7a4869386ff2" + ] + }, + "finality_branch": [ + "0xe78f040000000000000000000000000000000000000000000000000000000000", + "0xb69ce66878affded1f28ddb3c4e8b7d310f10d9575520ddd82863053ba8f24fa", + "0x43574ce84e163fe1e21af79c7a2750bd0d683391033a642cccdb498b6b934879", + "0x4b33f9212d1255fc5416610bf958fc355c710ef57c4f97176f95f397311788f0", + "0xa12bdbc24f2d4a8e449884c8523d60b78eefbec6a501b404c592f71dd0c7c274", + "0x8b26ea3e7ac397a9d728feb01ca3b0ad9934f263d93a5c227fad778907d40fec" + ], + "sync_aggregate": { + "sync_committee_bits": "0xffffffffffbffffffffffffffffffffffffffffffffeffffffffffffffefffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffdf", + "sync_committee_signature": "0xaa04bb3f516931ac299c5b601db6955139d25d7f8be008ffe61a1ed0ec9fdaa43f716ae9c7fb603e6c71b9eac21c5df3066f0571bbdfa97304404ccfcd4ebf80cac815d98f6623fe9e4b25dbd7479cb33711b37366758c8087d187bc95029c20" + }, + "signature_slot": "9567543" + } +} \ No newline at end of file diff --git a/ethereum/test-assets/inclusion/base-data/UpdateDeneb.json b/ethereum/test-assets/inclusion/base-data/UpdateDeneb.json new file mode 100644 index 00000000..877d5ae8 --- /dev/null +++ b/ethereum/test-assets/inclusion/base-data/UpdateDeneb.json @@ -0,0 +1,612 @@ +[ + { + "version": "deneb", + "data": { + "attested_header": { + "beacon": { + "slot": "9566271", + "proposer_index": "1482122", + "parent_root": "0xcefaae848893408228ed768cd31da658e754ef97c214cf93f1634b67a9179be2", + "state_root": "0x4ad91c0a1e943b59c1e9d9f900d7e50707ba1854bbfb27ab6c6c0d2fb8f08c24", + "body_root": "0x9541130a65a9c40ad2e414b143f8d7f0a761cee10e22be811e97941ed1ecbc67" + }, + "execution": { + "parent_hash": "0x846531c471a4fa863b6417314293e71fb8d1282a4073f486b1c07703e401628d", + "fee_recipient": "0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5", + "state_root": "0x19b228518784e197045be09c6bc278859a9409004a8272f09bafa8fef154e462", + "receipts_root": "0xcd80875b26405ebc067ed5b7aabc11f8ba09137cba0e04239694621658fa2e51", + "logs_bloom": "0xb323110e39060140206920008911914a15892884b001048c424102c2902210a4950c0603b16300004b0025494056b120172188b1888320a67449e04b0c2e81244202a408c242609b480c55ce8280a0a0a50231a7c4501828e092910588a50a10882d00056640c0ae444852a264a00d052209601041930666ca0a213c201c02001800804a62014038284da0608072030004112001156080a800411048e8d46a021b05104c90ec21424a2315c608520a0c471108900c5483298448c50250462100828051471190491414384421500d01c00b0e001222a1c81c200b40065520a01a00513540004058a8062c4180a4cc6022496c908a9c4024c23010e04000e02405", + "prev_randao": "0x9c65aff5a77201e02965a47a68ea4d7fdd39b6dcbc016ff73a56b4ec93897ed3", + "block_number": "20359418", + "gas_limit": "30000000", + "gas_used": "9946534", + "timestamp": "1721619275", + "extra_data": "0x6265617665726275696c642e6f7267", + "base_fee_per_gas": "6565135643", + "block_hash": "0xb14d84ed4538669b111d1b469a7610fc32fee78a2df5867b85b21d9dbd051473", + "transactions_root": "0x33f2350a367fcf8b259b7ef9369df7b35ad4bd9e847571508793c7a690fd8249", + "withdrawals_root": "0x2a5c219f6a8f155581555d543604b3a05889473e89ba49632069fd02851cf74d", + "blob_gas_used": "0", + "excess_blob_gas": "1966080" + }, + "execution_branch": [ + "0x9dd898d04e48109545d78c1c14de6781bf33428641f5b586a79f4c736de89663", + "0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb", + "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0xfd1c48b51415c075102a5b4927df4de86763deba9e29246813cf8d18b3c1bd48" + ] + }, + "next_sync_committee": { + "pubkeys": [ + "0xb7559f6e1918879a6a20391f7b5270d0ab3e8f7e32e0ce713946aea2022d1c4fd14c48d7ddd9a8bd4070e465b6e70003", + "0x8702a6cacd27d7bc813be626e4835d221b473b0b91a4ec9feb14e1a875284b45740c448612eb184a1c27ae3396a86b12", + "0xa67c5c3e7ff3ce9b11d435786124f88eee28406adfb6959592c90f5e8bca8c109aa4eb27f5dfc6453481a7c962b268e6", + "0xafca45f7f5629816c57e1d927b607a8a0715064e3abfa64c36a01f08db3a5833c18c2a9310c091a88972dea208cfb55c", + "0x958b1d199b6de717f0500a3b7ee49aa78eccb85ebb4c132cecbaad329016df75fae587afef39e949c0a409edcb2e2c33", + "0x8d3e968e83c68622782dfdccca5bf474a34fb68af3956ef36646a30f045e769e4a32672ff78bd647042c5e19978547c8", + "0xb3ce236825530626d7fac4b7f3f4759c6525a971ffa05bb0cde7cc680fb4e34dafeb9bc1e5d1461ed3a1891708bda235", + "0xac82cec26d98107cdaef81f7e0a9c6fccba289453dc71fe339d593543632c93ba9ce25e6b19031c06f2e2831b418de1f", + "0xb583894b316471b9e91de5e61152205a622605fbef0d8e5e82d9735d1ed0a84b5fcf7d4b14dfd9c7ff62de0332987d3f", + "0x98b4e7544c4ac7604912d092fe39b1fa00b25cec8facd433baff2a2074f515804df7170a14a27327e82ce4f21e691487", + "0xb47d9d99e5fe9b9872206ddd882aa7e35bfe5bf5be38ff1de482af201bc3381bb8893cef6a43d3fd1d4e4f33aa6924f8", + "0x8836a0e4ad5e39a06d52545b3aa2d374e023d67d630f18998c8630a80fb23e60101c71544691ce27c7eb9f6b0091e767", + "0x95c7a67245cd5961c24855307e78b4634ab325d0d783a74a1e3da23e87a1d9ead258d7fc7f89debd5a62c6dc6be0e084", + "0xb0d0c042082134c789bef4eb91ddc7c00f4690e024c527fd15acad2e6203f6066bbda3a006942a8b8de5f201e2ebb174", + "0xab78ca949bc77d1d489d3137b4dbc2eb53630ee3427883b5f866e5b980e6400cdefaaf7c8760f30f9e5e2e02215c8e3c", + "0x93716cde4a802ac6247857ebf7b218304d6f99819f8fec42951d42445ae2e512c4b2c2c0256cf643ab1e901c77daecf4", + "0xa5d9e2e56ba12f50445c68ac81a22aba4bd5d21408549b664eab30f4b9e639eab9a41604056779146e7d261691f3489f", + "0x8cc2ad9c899e60b3568590182bb5ddf256e0349fc95a449aea8d96fff3a923b964a8b367e0e1241865dd9d2a2e8fed21", + "0xb3a4f3917d1845e7fd5c80a58f9a7ec7559aaa182b30b6231f5af94ff1ac4be17d640b9f088d2c90aa6677390dd4d98b", + "0x8ad7ca8d3e4d438a64c254da045c7f4a4b201db76e20a18b1d040c4e0894736cd5bb15fe35d47c0a2356b42c18a6d3a2", + "0xab3ba626030938efe7774f6412dafb93f1a7e0e6bdfbc9368d534fd27a5bc9015f2e05dffdaf2d7022aec07d09a94396", + "0xaefbdafe5b68e9e0f06f6a68a0699ca21b26020f84e7ebf50e1a432b0c0c3384bc0a90cd7e53ef72f9f034f55501eee8", + "0x8b96a44a8a17a8e394ec00b8e90d7ccbdecefff4a0373578b2415e1577afaed9b68f695e52ea83827de6c7cd6b820b49", + "0x956fb610628a0e866b175f85c1722848edd8178c435d96adf89972074e730c949c3c9e83719473915dc9329f472c0888", + "0xb269e4ef7fd774b3b19ef69ecb181b7263fa94de0487c495310a1422b7918e538e4fb8ce4106acc9f6c23f0a0bdb698b", + "0xa449d348c5f45ae5afc0dbe9b6a8e57e4273f1856ba040c3e69cccfc773cfcd350b63b4f13fc097803f4e58b1ef74f51", + "0xae9be699c44ac68cc0025fca4d37b212f1ecb84fcaefe3c0c0c20bee7698534c095835af1b3fff3bf4f839af2b0d2573", + "0x80a483e42dfb20b5150b7252142ceac25112d7dbf91513da633c20ea7dc6e6a2aa69d107da44d7766d02046a0d9d4602", + "0x959d3dddd1e88c5211ea1051906a1d08b07255dbb3f95404842763b63fa7e1aad5ef156402f2f423e0f825820748c7b5", + "0x8fa3f9b3645de94ffa75d2ffa42443633d7999d21b43b0feeab5824b2d3dc1b580d3e04914e6ee5e402d26a0d30c8197", + "0xaa8e7df02a3ee4e1bb1344669c89634bcf6f1b8ccee6e28fc0697b01aca670d944d56d006901effa5c31d20979cc4add", + "0x8b28467a919d305054a5850cfe50bbc8135a317b97811ab94c085a5232e68e64d25a79b7258085d76c17a136faaf8055", + "0xb3f0ee98c7593e6d2c9dc9002f6eac8c58d68909f86d683ad9e4321f2091111fe5b4b2d5c4af5fce6370adc32078a448", + "0x92a3db29abba7c8d6f48866d367d2ba7710b1eb4e1c51c4aba17a8ab6ff7ade942d2b7076dd097377fec44c24024bd8f", + "0xa757aec1d11bd76629c2ec89d66e17dcaa7fc435961ca11ca2cee431d390a19f59ef0442a91c73b8dbdcdc8ca4315166", + "0x9141b0570f362dbda1575066144be89d3ddd6b107c266482b91db7428d78533be182adf4ffb1ce4c0f46cc96ab9414bb", + "0xb761e2618d299dc9eb20698bafe6baa193bc1bf4b056897d11b4aafd66f77963d4c5e905c80722000986770b55605a62", + "0x894f1a4c7ad99492a6a13fed215b9279444924187b3b93bf433e45e4df26f32fa65abdc31c4a30745fa7217be4bab7f8", + "0x88766648f12abe2700baf2ffb115eaf149b6054584bc2cb7ea42ac86417272da3a666fde56d8d39ded6e585b8fd42eda", + "0x8e3e67d010c825122d69cc9353f9acf18f709e7cecdf26d4951ec8d56ad36d6a96a57cd3f100b522a9351b8236e02b69", + "0x8d02630bd624445f96398ec33f2fc71c433af7da2c1d9454d4d9f5c934f7131d98df2cf69cb2ff5834acacd4552c8fe3", + "0xaee4be995f42953fa8b4ee0584573dfb0fec94cc74de05864966385807650aa33b559e46ed0862a73a75c5c22be33d9c", + "0xa2af5f26a1c7ee34a122a4836fc96802d472a4ccadf7b0399877a78f1a437c4a64568d28997a699fcdd033ad260b9979", + "0xb726eea2f336ded68b79ea0cf765dccce27c9e983016b3c6752f265c8782db04aee91b489862f688b113d9fdd7efd871", + "0xabcd56d4e917895da90b2637471bf685be726ebb83e6448197ea2ee201f06fb7a70be4c92e1533a5484f4b49b77d7e2e", + "0xa68ea3d31e8c2eb3489508e60bab01662079f6b514679ccef85bbd0943b0d49e229a73e60f72c725827851d3fac87ca0", + "0xb61459135126d5f25751c18e3a186db12f0fae8b9ec1667e000bd9968daad5008b0b31bb5c6d2ef366169237aa286ddb", + "0x8005af06ef45c1235ba74a357ecf01c777b8337c2920f85c42f1557efa43aef537c3c433316bb8bd75d7e231741bf5ed", + "0xaa21063cde9c809588238d9cb8fd572cb391957eb438fc3ca6a10fd4a226eca5bc4cb892c3649e93077dce068dc8843a", + "0xa463f5119e6e195fb462947dc49f7fde81963aa90365c6d0124e1647fd5e160a86bf013ffa2b17539ba19f05023686be", + "0x9084192baa16021dca9800a021ba053416d75dc443cac0f9dc71f9108d76814bca7988f00dd4dc19f023ceea53dd02c5", + "0x8897a68235fe671a624ec9ac0ee1d4ba4cb8d5e2e020bf1c30d40772cf514d3f94ee997e604f1f39bbbd519a4e74ad79", + "0xa34e17898047e91d388ac4d7ef84dd6dc565f270eefc89ecfd1f07b7cbafb6cc4702a9c68e80647339152752d01e493f", + "0xacceb3477fc8b51f847d95560744b58087cee327219b839c0dedf93c3a7074001af61ca0fd4240bbc163430d48056066", + "0x8341801ce9a3b3012ed32d9af1d2d60412460a2b30adb5081b0b1df112cc1739935a239f823fe41fd5e95451bd739564", + "0xaef0b2d5f81022292474fdb4409c50d72b2c8f752ab7d77c1ade404cb20c339ac8305f781269472f8b704408a4b88f73", + "0xacad42567c481ae2b43196e2cb0b01a22fd47b82f36aa50895e26e2b3e96bfc9b5582a7f573aa00da08301da945deff8", + "0xb8f6eb2ca8bbb292d459ff303f35bb4aa7b0bbc343c66ae662490d7777f943ff528d074db73efbb909ba5b8b79cfd35a", + "0x945d79716356d1b51d168b392876282269a09c46a3b61e0e7214ccb0e2c38cd0ded5c842e90b31fcf3b2accad28aa20a", + "0xb2c1d0cc93a7ae50a0ad727f39638beffcd1f7ca2d460121d67cadd67bcb44e0c7368c4db8e6b36d2f2da2ca7ebf926c", + "0x865d1c364511a0a8a953cdbedf0be907aecebcf5fb3e71c0ce2c8ac11e1ba789e1ccb76fa1615d99484d78a7659f68fd", + "0x8a9fa9dc923cc6dabfa4c0aa55d5797667a78f89db39e7df0c43fb9135e673e5ef2620a34e4663d0d2f39303a276abd2", + "0x83e9a26eacf873cf3adf2c175391e719909765a30ddf8c8f6bf1e01e7da80e5f273fa46508e04fc6bba2d3f7c4b42ca6", + "0xaa2fa21d0cc69d6eb37354b170c66e6d0921e42b0a916d6797fe063b2766992dcb421838fea86d742b1d20dbb2ce7bd0", + "0xa14cdcad9fa60dfd1542cffe0c36303e0a0e4851c44ce4a549faf26e385ae0e4d265250985507ccd3fb7e470e205cd2e", + "0xa9e13f0a60c8fc6609b9200f3bd1d3f260bf1c326c47b2d26128b1c0d3b3eca233ee1b8290117e370570bc08caf344e6", + "0x98590a765b1a3ca5c5c33803ed6d98b4ace7c057aa7f3beef764bcdb40cc3ca74d79a97d8dccf9d6b594fc1732f3ed73", + "0x8d5bebf2dc1b9236e95e7d784178d4e9d9de79547368f0eab55c50981d82ad04398c19ccd038080fdd75710cd70de29b", + "0xa0252bf5da6a105539143418d097a1f15c2826e1bd3b94ede2b52696d53c5e270c95171618cbd4314290b2cd07c6c8d6", + "0x96093e50ab0ad6488dc6ceae5ee4f6feb86a0a48948bc6822e2d29693ff5f4b7b46645c47c66865e6b96e19b37163979", + "0xb37c20244a3bc0c20f92dda38c5c49c585ed1d546c77fb5df36c4f70b0240fff33bfb28674b62d3fb295c75df439a726", + "0x834808902bb8169509a227a1ce4bc32a62b5691e0191f9eb152faa172b8aa96ed64e505667f02a009750cb27e017aa8b", + "0xaff4d9919d34e000af4a64823a14a31be3ef86f56159919021a1a06e65f2a7c187b4d118de279528850e42731939902f", + "0x8edcaedf105dc0e4be5f26c65d5da6e8b306254fa86f3e7eacd4c32098006e73fed4450bcd8ef9c00c8530c103ba9f17", + "0x873782a18b011def6ce0d2aacecf782bf6ca3c38065caa43e9cf09da64b1b772927e53dfa89e550a721052df2227a6e6", + "0xb6805ace9a01a8b7a2331e38665ea6edc5eb6d4896456386861f95cc55852f55f6aea8246b85ddbc9c21b0f75fc4b698", + "0x8a640dfb3786f41ebb61c273afef9dae151316ca20ec5f144d18619ef79522e3fb74056321645205422a709d6e341e40", + "0x8a394be4ac865419c816c563c4ddf932dd535cc3d6515498cf013c8de6ae08171364f9f21de577d466193a52eb6c6d50", + "0x96969fb28dc954882bc0c362c80453e0e739da8300ff49ea67b9f2c2fb48c3ac9f18d5b7a01186061883ab6382f9ce25", + "0x8e5f6c559f7dafcd67cc8cc44d765515df3cf9fe145448abcd35008059ec075cfd7a0df244cf529adf3e4c343755d409", + "0xb4fb57b4638fa94313f8952c7412be33a49daf8f0142ba80bed1e91d42c6856c556413b3abdd0107a9013c12f8364f9e", + "0xaf3dc419ee077c982f3619d068bb088650473201d81044f6f3f3e142a4cd1a65000f554d6698d881c5f57f46f79e7d45", + "0xae56a4d152b5e05bec7dc24665f6753171f9a35c3963b8bd39aca920f7ba06a9fd5ecbc975e799abfee47a95426981b4", + "0x8144527933171d19251bd03380b90f657d48792094c95c81b3b0884fb8aab7d3287f0c5584146f107b2b67b3fad54b1d", + "0x8be7489a4c1e446b1fefe710d1b5d5fb2960d05e931f6fe0b6b85d4a9d4609370308774952614e889827eb7fa6017d5a", + "0xaad849b2cd2aa59de40b0a09f6965cc865a5fc97e8b99c9b4e8a9b7d7a2ff19b75429cfd1a881d9d77b102d97d9f1e51", + "0xa2138a76e2336dfc9e93f93f05beafa9d23e75283f35d6f5a2e99e320235650d150e765fb06113506b5e3de5b5265b97", + "0x8fa5893e98d2ae0b279ed46886ed6cb124d6228634f21514e86d0046fd7fc10362d7f38759da0d8d9d99bc8a09376392", + "0x87f5da317d0e3b468e9ab258fcc87c87c6cf0aaf7db05345edd6309e451704e85a52a2942736e69d0ff9a4ab7b35450e", + "0xac9f8fafaf7319d9eea3e3bc550d8ed2ff4d41f4091254cfefc406b04880416d5c7180e766d0c9744fa4ea393cc45a6a", + "0x8d63945b991b8363e00df209a625d7658b593f565ddc1465a7e0f008e256d07b8f52f9a4d5312e2bbda4a3cb890c9a8a", + "0xb0e3ee0bb808c0050e1ea813d17101ff11cfd1babec9d90626d7dbf1e6f809eba3616017ac3516d163ec188fc3a5822e", + "0xb36204e3fa86490abdd1d72d116f6c43ece799cc098edaa3b22ef42695b5f28da7ca85cb67184ad65e9e52a99926c5e3", + "0x84f8c95363a4b6788eb2dc6a94a1ee56909b5d74a8a65484826abd5d5bdc57d2f800d2592991d73a7985a60aa20b45ea", + "0xa27bddd02fcfe8604c9a5804c6a93f3192a636e23428a20f59250f807719ae5d06612f794130412797750aa2142d8db5", + "0xb2834b474effd0031bce50cf1fdd91cd1dabee50f15b6f7c6a605b6ba417ba7a2dc229f1a692ad1325a725531e35a8c3", + "0x8f2f55863fb10366df531fe26e8103e9948e5be8cd7a6bca9fc11aa51206281a7cdaaf1e66c023881004d325af34da70", + "0x94c645945131c32958fce1f43a8ea9ad1e48ce2e798adfc9fe73db4c179477676bf1c8adb4a8b08e78737a0eb07def59", + "0x8d411dc669578cb75164efd4ae1d6bfa8a2db10ef151e41897766c41750b6df1b4fd4b79c4a93c0bb1d95388d4cc2ce6", + "0x96737db1fb416f1584e2c18333c2431feff15184ac0b744418b3b09ce9c1a0d9b904bbf92cbf5702c3e1f63a9ecea28e", + "0xaddc44b4783cef43e322acb9120eb2d958ef4fb67d2b37086b210fd6affef401eb208d587e402d90bcdd2b607c1cc6f7", + "0xb79acad8909a2505bea72f926a32efa9efc0274aecacc9c9c23167bb0821860939cd791ef4acdd4344949c8c6a7df8db", + "0xad12d5acaa196183e51e09d8a7c920874c4259024430b27e59a4eca169b45a63ecdd3fad9061317d79adbe07f2f884a1", + "0xb57f6458210a06fc492d2c276bad69d31b6b462b51e07ed7cb3a9c2994914abaf8063b4b151dfe95984ce5f3c4fad81d", + "0x8a3caac9cfaa74fc841470faea3831389abdaa255d3b355af36e282947785b2992f5d483b7c0ea5c6a6795c78ab3293f", + "0xa6403dcdce07cedf5aa38d1485433c7f6a7158c97affd74e227fdd4071353117378b283738c52042214ddd19e4bf3653", + "0x8ab5ef423d23ff29c69152108f22822d8d7932c24aa69615c1f78fc7371798e8e91a5149f01df47c6282f1979d0c69e7", + "0x93562472746b9149777581ea290e2df1d513cc9278b774f5918b4c692c0a2fa799954363c605d11dc19d76cda4e653eb", + "0x8e9144fcfe6ecee1ba2ba168ad32f1da5ea9bfd3ba311c0942931c3d22a811a11fbebe01eaff698c52eb0a922baf950e", + "0x92f167a8ea3fa647d07dfebccc8c19cab17487248620a9c04c13a7d1411a15949ef58d7fbe5036a63237b50cc7c30bd0", + "0x8089b033561346da5800569d90d0508fcc9387db832c1b1361d46181c27baf1abc26bfa2c9a8efee75c1623cca6452e0", + "0xaf377e57d40f44fd1ec85b9f7bb82ce9c558b9a17d3bf6fbb68f1e33ceb94c64364e3581d67c4a113bc0085d864ea93c", + "0x8a2a8afa4388fc7c5d9e4cdd6ab45bd5f4c9e575e1a7fe1bc705b6fde0a5081d8dfcdcb80a83fa73ebffd7d514e577ad", + "0xb7f47c38104960fa3c1da36498168c2222a4f9315ab28c4e2cae11c62a4a6875d818472866c3b39baea6deff99d0271e", + "0x937a16118cbb90c3ed18a3dfbdd38b9df1d73e317ec0b5e07d65e19b92400c7dbd9a9a2580bff2b15388af3e58c76469", + "0x82294f2e3b0b44b89b3cf0c6325757f468d31dc0814c34676c90f112a7620c82324c548df4be968ac9e889423c9435ef", + "0xa7585d0863c77d116657e86612eae29ed859e40e0125ba31f11f59d29205a3ce6fa2aa02b0bdb32198f652001de53515", + "0xac252f53f47474a5110b9003417e7e4f06bd38a84adb222016f4806e74be6a97d272776cc9d921a636e7e10bea866269", + "0xa94a964f1551f7e1f8026e7d28688bceb46bad965377ea79983de7402942c0a722efff86567a22e8d62186e807ef529b", + "0xa81d45c00baf0de086c0eff65b4945227ae07dadcae6e171bbf06264a2bab5058fe176e319318b312ef34323e8b4a371", + "0x868de195008db03560cd68a5e343dab891a6f035244b274c9dabc15935a666068bfec086965a361185b1fe2a208dafa1", + "0xa6f6612d99a6a7a56d3cea2468445acb3ca05b520c22fd428fd55b6f07060bf1497a5fe83f210585898748036e9593ce", + "0xafac5ee4a55838e45776c165b1ea5b87711f344830355a6c908c0a9f629f77f33ebc98ed20c551b27dc4cf5c52e95e4d", + "0x89d723bfb1ad764a627452423f3afa145cb50753c3e4409b4757cbcb8aff3c1e21fe491bf9cf600e18113705cdf257e3", + "0xb1930cc2cef5952c0a723bbe54df513945b0437a7393d2b67ddb94686a6b16e3d0d8fa755fcdb61f6cf21c3901aeadfb", + "0xb1139ca4f1a453636e4100d9b34c0498e4c005b1c9c9e85141a1d01b6a7316acf5628da77bffbd6ecc7fcd269a20d317", + "0xa124a53b0332bf87659b3571b6daf603c757686c40eded4db5abe2b776a35f6911048efc3eeffec60e1e831fe227f08d", + "0x91245a6520361eb7aa4339ee8a90c2661f5cd47d53e3362e0848561258f09f66235e641f3ae696b22bab14a377eb6f18", + "0xb0d48423195f3545ba9e8c75de425143ac608c9fa0dbd8b111b9c7c4bb66e885a76be7398c989b87f2d1d78d0515d216", + "0x916cff73e83dfcdb9ce1e9354fedc06f45362bd6131019901990e347287261454f59702e0aff8698aa03742909a6e618", + "0x84047e9a1fb345d82a5b6db0b909689d6d55e036f83e3633097e4dce1e2b051f391c1603ec8b323d0e61b23203c861f2", + "0x970261ce8787b22b6a87ceda5289c20af66297cadc1b8555fbeea87ffbd2c359ecef7c8c43d628bd07d45085c93d9822", + "0xa9a51bfaafca2b6cb99cb56c8a0ca07179535704813417a313feb547e91d818c2c16fa725e10bff33b09b6c5c2ab7715", + "0xaa19444695cc8b653b6cab821ee0e721a08b707a300caffb324ab001cb170427b11ec47c8a7c442e6424112b73b37cd4", + "0xa8a0cca953816ada475cc77592e56c1dac370635fb9c33d1183c485e9ef7a76063d34f985ae337dc4c0163a225560b7b", + "0xa743a3f2a1cad46e26a12feb6cb93af019d845bc92fb8a7f7e5442cc758e30521b432d0269f5a53e7cae1c842f0da666", + "0xb0d1cf4092acb6cb50188daa7954c17ed876d73a983a70aee706e747888adac962bf8cf6eae2e2dadd376573040d10db", + "0x8fcb57098fafe52944ec21d6a7b11b64e62a279ce9f6f4216232aa8aff426e4a1d31ea9d8be514032cc883257504a151", + "0x93db98915d0cef09f9449f0720bad8071aec8f1f7818cc47774c8deb46f3b5215cb324cc9947e4f57b9756b31c3f3759", + "0xb67ceb06e0aff215a7871cc2047bd4c8eec011a5664160a37f7178e4d0e2bc7fc5f6012af79c86eb2b8b6e228a7081f6", + "0xb8c32d106e5a3d6394c3fa30e7a1b446a1aa423c7a5a8f369dde08980aedc0f7fb6a5a8e795bd8c04aefc25340bfd6dc", + "0xa720a346e27dadabb4217877e7fc7b2e59ae897105beb33af1b799ca418a5436dd8997c29d1047b2e02612d040b74f6b", + "0xb20ae110527f3880c883004491f898328ee89b155e81be1e8761a941f8bde044bc83450d7d1a4bc06c2a01da2f83e773", + "0x8b92de3645d8595f4b02fcc8b770c1bee434175d7554e43f3fb99b68bf7e7d28beb7f75bfd77636909b0ac021cbcf1bc", + "0xa51e5fda6a2b1fb427bfbd1ca4bc8bbaf4981bde2ca487b05d60695ffd084956bc2169795cb95bce4cf350b5e59539fd", + "0x8a7806868cd48ff1bc62aead5ccccfe79a0c5e4d91f33476d427a262eadb528c72d303e2f8579e98916553578fe657b4", + "0x8ab981e0e7aac0ed47f85d171c7d562bbe39d405a4d5919aee7485004654152cabcaa886e577ea5d977c4fbc0c1e75da", + "0x997d80ebc9e5a71411e96767bbc01a0b32ab09182622990bf7d7d8ac2d909ad4ac5771bc09c0989a1bfc429c66399efa", + "0x970e47eed1fc389d90431952a91e965e5f1d1abe453fc6f44397b94f5fd6a0430b6d4835c8f5f154d30a891327a5b594", + "0x83dd87451c3031a4c9f8cd01a91548c3542f4a717cee38631b1b7da5fff521d881bafdd3d2a2150cf7cd783ebf465634", + "0x941f309efd17aab6f3545d56236db5517f15ae0ba07a410e45973ab4521db609d1fd6c3dedf0a0f1604f18fdd63a7690", + "0x8e08bd07ced288be316d5dd96265023fa3f1188482f747e56266e96055a6ca455e684a41edd3f5bdd717a96a5ee210d1", + "0xb193c2f6638499f923babc39f490dfdc14ef30d9f0faba1842354f8071892e083b344caa02d81a028a63fbd77c8cab85", + "0x87543a443d475b1a3efb0f08d982b549070f292de38cded0643406c74b536daedfdc7cfb93aedc8daa00a3fc22481835", + "0x8cab9b3a72dd6dd039248975167bad5f44c5ec93b9d29457ed33dcb6594db9a5b8e8e995a42f8cf41c5ba15dfbe23cee", + "0xa87c298225c196f12c9d11a8c8a86a9e6b3b5abc68afdc2da4dbc2aa98bf189e66e5b8776d21b838eaa096b2bd82d1b9", + "0x86cfa66e268f14ac0364e749951bdf3dec0477a1a2f1e0bc0f3a217bd980759a03ffe0a5f8a2f8235912d99dc3feeb03", + "0xb52e55f269e414b6c0f78f67ba3de528be81752445bed65054329070c7abe650e8ae0c58e42aa0f139403abb7a5ddeaf", + "0x9973af2797aea24c5aa1dc2551e8d7bb52d6f94eaa0a94f780001ab6e12c885c29794b1d4b538c4bea45dbc748f0a713", + "0xb5c0471bb5a0628b814bbf89bfa15127418f935a4313116d34ba93f50663020e723935b983405a0d26dda099c0639381", + "0xa2c3391a748ccf00083fcb5e176adb58d19fef0220fa6f283018402440ece8031a84413ebee922c56deaf42b3590fdf4", + "0xa78ced1b3ddd5ffc5a4213ce3d5192aecc10800a5561416cdd5b8385bd317d3caaa5508493b7894451645d2ac3c187db", + "0xb21e439e0285db976288dc97666addc006c1802fe7f3214ea965d8ffc7a83711bd8f72b0d45cb6b8637db8b52a6aa8d1", + "0x87b64f8a8998c466f784cab1a1f78de7e615fbf180ebb487037fe9b62e6da722d31f45f288d8a28b471075d638ae731c", + "0xa78b509e6bd294ed5a68b008d873d7011befdf5db086f470ee7ac34f6f4396b60d5c9ec9ee7540fe2b50497ec4777b07", + "0xb266af35b43c6f14eeac90dc5b2663f1ee446eaa6b9e1d503cd0f0ae6a468c3654884aa1c0d94d0ca80a42c08415a62c", + "0x99888ea3d3e98e3e526883e33e611036ebcda83c5a34b3990a73cda3fd9cfa618d79f7ecc33f923322d035851cbd3053", + "0xae715508086a539b2ed0f09b02c2c9b4e94205bd160eaa46f9722f0207a7ca76f43dbb9b4f168386495f5ee7ff01289a", + "0x83bb6873c5d984a66ab744e6484cbd2f62b14d378293be319074f81bf37fd3dd0be7a2d6a420ef37ef262ca8ba6996f4", + "0x962e727b3928f07b87c9671f2169e8a23ada2a020fc922f3dc9db00fd26687d75dd6bb30df8d5dde380e4e876a4d1c70", + "0x88d8f14e368a86e3fc6b783a343281f685fe2e07efe8363413d02e38ac4ed18df57b9141f60436bcbd7ac8e5a23fb684", + "0xae9d49bf6971274f91fda49856acae556b03491420b48227ac2d345fc739ab3d8b5ebe11744f913b1622306304c9f398", + "0xb62da1439f6c2be3e76796d45d40af41b64d1352f248c183b7215c9deb9b48a27cdea0f2f0e32530b1d40a21368718bc", + "0x93bb2900e63ec03b23398ccb59b80322b2a7ccf990fb74cc3528a70236181e0d1604b52b6fb504e143faa9730cdcde0c", + "0x8012bc3e3cdc0cab14f1bf64232f34ed2fbd434c93021f544321dc2eb7caa0961b7bfbc63c49d67d8f88d236a0c22287", + "0x85c47c423cf03812a7841ae39be9225645b15d7dffd4054fb4013e7df0c4530067d4ce196571d9160119f2714bca75fe", + "0x87a1bb1acbb60bb32d7007a4a2d6326d843858ba17682dab24a0ea4e9a6d7fbb374e81fb53bdef965a7f1b589424c4f6", + "0xae0f50b81c68f020dbc0ef778e1cb761606137557c916304061dcb482930a9d77396aa57dc9cc66b7cb0b4ad8e6451e6", + "0x977538b7776e8fa744779e1d09fbd0cdd520137b5c574df18ecc202095db994b0c7c0644a8ff33081885952a790169a5", + "0xac687da04bd17aebda040c247c13d6765ca393bceab3f7b24b225a21a890f760ed332e759e4014ec5be26d3ef2b51488", + "0xa153a94ab413a94fbd99508cea827d43547bce3886e4d52fd748a250e25b3c4dd317b00c2e4e4eb6231edd51cfa57d4c", + "0xaea2c624bcd6d82578cded9e9ca8675a7bfc39969e966257f855b98006d3750cf2294d9de86f789d03e243860f1cbb1f", + "0x933c7ff8efc9fa8d3901b60695124f9f1244b8c03bbd5e3ae1d109cddfe81da3ebab913e25db8ee2e33638c60dd408ac", + "0x8c3fc617b1ce32956ee8b7def46c10b99ed9cdc5e618b1db294899769a84c053be3fb6639830ef43034215f5573b18cc", + "0xb32000abf391bf07f1d350ea292138f632cd59781c098fea9229b99a2e2592fc45500edc7fb5179d1d4c33b92f10b311", + "0x93e08a4a45979a5d83bc459045e66fe39ae1e632cbb8fd1bfd89f0f93958ef393522bcdc0a4135877fe198e6dafe3640", + "0xa2b177decaa154ca16b1af42f0e0a4b6dcfe0bcdcead61de742a5a0d9964ba29f7a5446e3f2c8e51f293de7f3f690471", + "0x823ef845d0d555944ffb4a5d15635d822c43b51ed0609930195f66b939def475f11eb2222b542b1efd64825124d1398e", + "0xa3b86c486c93b61a12bf176ebde77904e6313fd3ab1f92e473f79b02fe4064cc7952cef72faa8365903afd62597b1c46", + "0x99969160362f1889340083d87ba30a560b03bce81dfa3fd629f729d250c4d6297262c02b335a18e820d36bd6652b761f", + "0xa18fcf37180e9fd5ca9f7d044c95ee5f43b760bbda519c83edf63639d19b8a8756f186fc39e810082b514d79226dc40a", + "0x86e1ea880a9eb419237ba07d1ba7eb599f1819e113a97034ad9b063590e134e6237f48936d383f15bd4270ef8beba3ec", + "0xaa463dda7f6918b60e20f9954a40f8e8ff6f30c37d231734eea1308db8d15a953571e7837e02a5bdf5f6914eb4b5f42e", + "0xa2df98b53b3bd05aa417363385965a9cb48931674dde109c6cc261934aba49c75423061bcfac88f00f894d749ea34862", + "0x8725770bdf70a4fab3c3d88708e8dc5ddad2939286ca0bd60750459e5d79113d22077afc0f8542ab404a54fc5db45fdc", + "0x9084ef313ded22930e36ecc2e88b9cb884837a1a613e860521b9d2894dcc3a6645a5e4b7e848cd545122b98d6aef1fef", + "0x95059a8f76c4c4a47449242b9e3a619d4308b8ceb9dcffaa50c19ac439da3c14241e8043d1eab7e0ae82f45884bf0d4b", + "0xb8059a3495cdb04048171c957c30b0ad79af651ef43f954ffb9861cf18da2cba39d8644de9a15662c1d57329831dd941", + "0x94b6ca51b711180876715be21575b177ecee1065961234d1c68d91fe1183d5a6f80f334cb8f8bfdbf81d7b7e8444b298", + "0x863aca3a94f18c1d3a48648f4d1ade86614c9439a8cce8a83817b77c3d1f293a737a88a2c9125f6b684670f2a3e4e503", + "0x8157c780d028fab97bce3780c01a474e18dc6b6943333a27042877dd53f9937ec2833b2a031e9460761badeaeb2deabb", + "0x89425011f98d89f2375f2871d51ca5ebe4057bf8af2cda7b700761c68cafc15267406e361d16a9afdff9295046c59646", + "0x861310603e7222c6e5bb5bf0865a27f989a6948594f9a9abfac58271b803cabb642870465fe2b03f87863bac848bc237", + "0xabda7b595cee6efbd2771b14becafa9ff96c6d2ebcc3f601e1aa267abc25c3fabf597b8ac8c61ee800903d6960e78ba2", + "0x8f4c91d8d2cabc4133a1c1493335e2066953df264a0335eeb1bcf8fce44bb9c555e47af5c08e566aa0c9ec360f9fd8f3", + "0xac8ca765c26385786613f9b6c5284e177b4013e20a83f9c666d6c77872606d50721bd9c9c46fdb42a947262ce9ff48e9", + "0x8de332b81665f0e0dc2a65898c27b21cdca1b7b1f023b085945fbebe8849eed0d47a9abe544e61a1f1b4be3b93526e56", + "0xadb265c9822b0d797aafe11f84d6963bd74d66b845b995112c87c060209cf402d5ea05a64e4e4d77d9eb55fcd6fd43d3", + "0xaa5bad7bebdef344b3d26d02b3bd379d9b2a7398da7054e6de7c049569a6f7479b6bfe647f250a318af778b2af9d907d", + "0xb10eefea34baf2b2702fa39fd6b4c082ababe2bbaa1b58840df2f72f6353967f21e75b8832255a6fd1e8579b2012b5fa", + "0x82022b2bb61569245bf8f341f28d84c1a9d14ac45b7a4d7d85fa6e98189e6f7111915b75013c0af38cffce3c86b03a80", + "0xb3b27692d597fd7a278874b87007f0ae2ec97a25eaff74847c95fc5755a4ce55d7ab5b2fbfe8d571d651d509ca4b3eaa", + "0x984edbc68bf928169b913fd1aa572e51cbd18ad7938ae6a3522a731cdc3e7814d1fdc1f8a3ceda9fd6679c76b991c6cf", + "0xac913dcaf701ef291020625528b368961ffa3ef67bc89dbcb2b415fe1f64e379fe232c6546acbae804da7bad0405c96b", + "0x8cf71dd5a2d2eee4f191dddbf348a8e1cde727cc67b83d0da3123f64342befedadbd5e85c42a4e6545dd589fbc591166", + "0x8b18d98019c19365c4063cebae910fab91d03b1efb3941bb2f56a9f122ac46f017f4e8822cef2fcd2e327a1281e74013", + "0xb8311f5c9e0384fc877122a2a52cb3a258b092f415a82e329d143270d5215e80bb6b887755d7ad2ff60f4fa9946ee9fb", + "0xab96f9f7771b73a73a7b9c11c049374a14c060dc60c96fb280a8404d4a021cc26510c1b27832f242c58ff7f163e45b30", + "0xa045fb63ba24539abadf2362dc484eee5150fb2591aedcbf79e78cec67f66abc08ce5ad6e265ae6e0563d618d6a121ce", + "0x8514d142a56478ca922334fb8468db768963f37d9a247acc9402e80f6e3712758dcd113b168120b65471fc0894f04e12", + "0x94793f1916c126144331447d6b0ae08baebf5d9dc07bff57e61f0fbdef0d5536b0c2c809effa75a2a85d7ad6335ab0c7", + "0xb44780b860aae7edb10447c880a2130420356063d6489c01c5eff73dc27c05a79607702b02465ecabb82ccac944c8db0", + "0xaf2f9516dd3cc3eab78126f8e12dcac5efc012b23ce03d276c0f2356fb8e090e632b723db55893f4e44b1c526761f758", + "0x9920254b89b84a9cacb25f5c7350734cba08b555ec7c768d5451bf47edd35a43a1cffcffc41239911ff9c896300b503b", + "0xaeae5bbf87102efcf9a036b7004eff627dc1b47d4bde6072a97db84fbbbc52c04bc5ee9033ee8e751d07a8990a3b935a", + "0x87a5100ad2ac0074a9e1c9844a87a600f2e8437a46e44ee2638c4438212e7b5fb4d5d0ac1eaf334a92f93d227f92a586", + "0xad4359eb5361106ff84ae0a7aa9726fe68eb8a5c21108d2d70c25b443daa24b5909981d262c34519f6e5eb847c2fc554", + "0xa2eb817d7c6ca45a4f44b892bd746550b1391dc84ac4603142ec4d5e79e835c8969b368c54f90d98d0e7d7f3f40b8bee", + "0x94dd94a11b00eda3ee4f673dbdd0149cd51ed9b1bdce3a15fad74bf881b441c851adb7f943a577484b46ebfbedae63c0", + "0x875ea42db69a1a693a25bad51279713cb69d1dadee2aef10c568df4ec6322e5e638c6081e34968815b8a83bca4a82218", + "0xa3c1cc2ccf0696bc5e742fb33e39ea66edce70e3f5589c4577235e7f8fd1dd4a421b445b4beeac9dbd68800c77fe8dab", + "0x81d2a373a20871cb91c5cb0d819e4155679e06c30cf964cc869b2311bf712f70e5086538aaefb58f4520f161329720c5", + "0x9438a4e4b47151cad6af90d522fee5436616146df4ec477242e8251429dfc56965e8a5e55001dc58e7819f266754546f", + "0xa2ce909582e06d6deccffe671a3a822dbd53521a4754ec7ddd5623ec162fb772e3ebbe52f2035380af53564dbd2b0eca", + "0xa00add7a151e0cf74ab82814432546c021856e6689793a6ab798d9cf088ca924ef0bf0392b357149a2c04291ec9be84c", + "0xb153541b261be864ed3c49f5d60dc28959dd89601c362bdd221e308ad60f08d8f302e9bdc47bbff1c91be89007a2cf3b", + "0xb51b545b61e85a91387ab610d262e230577ad9ebd107364441e6218a48bf9239d1f118841b34242a2b16268eb198bd9a", + "0x8525cd2e7ed28c5053a73c964924fa28dac978fa6189ed668fac5b70de5fd1b61065639dedfe775382cf66af09ad6626", + "0x90de15549a32de24ae4a44a8d61e2b0fd2144991c96b735af34c73c3abfc139007074b930df7647e6a3e13f04994b99d", + "0xa4828cfc519deb6a072046152ffdfcca79f0db5cbb9a5abbf510a09e606adc4199bef10dcd5d11157152195dd0f5546d", + "0xb3324b915e5c957ec17c45ac6413070d158fcca924663ea790144c7a0973d732abf2fc3a57f28797ae51da94f2b4fbfd", + "0xa5670433d068351113222b9693ebe4430cd5d86883770a472ea424eb02cc656b15c58c41ca59b192860eef716c5cf930", + "0xb245fe43833d7b5164823a1166fe2efe0bf95c40339ed7d37bfa01d3e73a6f40b3bf67327651a6148e8bb7adc95deb1e", + "0xb1a21dad7360052148eaa3a2acd0ee4962ae8ecdd1e491350a74567b0fdc0801ec8d68033d254b4af8463c9596d1de49", + "0xb9d82a8cdab95495d439c35ba692674ebc639039b32c4e5aacf98cc28c9c666c6babca756e9d4e940bc6235c66e8b3cc", + "0xa0f0fa292de740bafcc02053332a4c2854cdc05137f39663fa7d6fbd8120fd267651014aa69d8bf5abc8e63f4c99146a", + "0xb7113f86eed56e74be479bfcacf1779e255387dd5af3637476212e5f578d6c957659d5762ef98e2a1022eb18957a1c4b", + "0xb578676c671f9adf3dd87bbf3ad5d73b1dad8f9d13e1c7744a95727e79d5d828c0a323408e5f535ea5a987cb131bbb7b", + "0xaa87fafc51fed74be7f39d7e9b2c4b1ba241586832e767bbe75d8b0c11cc4759fcec468feae4346ae70bea48db60f753", + "0xb841f0d6ebc54befaa3109150b371026e1959f1fa4817768cdb565634dde7d59ad9eda3e70bb992df0fee6de0636bd4f", + "0xa69af31f9c1ce4e2dd31aa046f99d296356976169ad0df60194606aa14102d4ce69588fff8221803639c2c290a6fbb8e", + "0xb0a3392843eadc5d6af0a371f0c56ae1ae12634e3b29428e7c6805b76740299f2f51341f894e00f7ce63c365bb0a8efa", + "0xb3d6114ccacdacc16818837edf224360a6139f035b9de79bf281fd21bb46d314f1b6a42af8412837c56e4afb94c03695", + "0xaeae7e6e04237322b13f93501a3fb354593d765355a48475ee21c591afb183f7ba4f012884ae7c209ab8adc9664933c2", + "0xa460b68f720b1c1002de8294873fd99f0667e194b33b2d662f357031ce8148d929e41e2fc8a0eaadc5dcccd49a0362fb", + "0xa2d1f6143d875d7e0894d44378d4c2e3b51c1ef9374c2a432aff59106891b186b085149f7bba7539ca7b4a794032038d", + "0x8c8f99d245d7ed334266f10928e659d0463a5b4ebe3cb1a4d4dc6b77e3c5b3e12a3762aa6b21c924a186f94c35c239f5", + "0x8e6e123af6ede67803dc4b2d48e672e4c61da372bf81dae70ab85d52d7c840970e362cb70129125f1f15a831b7aeedf3", + "0xb4eea7cd0dff8d9bf50c6aa1885497df2ca95131073c73b6389ac3ec6f78a465d82ed7c147f36af71d2e014bfcf28b6e", + "0xaa6e044563b9c5c64698d51c2d04d3861afbbe3cbb1b6114a758d219b1970e3b4c66c277e911cdcf5605be36c05fff8e", + "0x911827b86d1887c0a2e89c4f68b3119ea417f52d2487b23391288b3f1e08fe6781a08bec278128b63ff8730a061edb2e", + "0xa5f0b1bacf1c5a350c68ab6ed274ca99eeadcab81154fd9ea8788b786fa955666d87de398e4038c21860df51fe9d6b0e", + "0xa1e4f7bc73eed371eeded7d9b5bae799a1f94aa85f641357176624509e6b1bb73b513a300ee403f0b257e2699fe81ee1", + "0xb5338e1308ea5e1e2918dfed710e52b0fd68bd9ef4faaa580a954850b6211fc20354df0c2593f2d4076bfa6f7902b8ab", + "0xa7adabd335b18cce5562aee52a0c3a12c7c224a902b44de09c7f5e25891b166e239ee459353adb68de9ae71d72ffdcda", + "0xad92cf834fb64ab2b63da14bbaee8a56d588a8a3632e136c20936c310e1feafb43afbc93fb4b49ab20e70da43257cdd9", + "0x978d47d77289e8830f54ee787cf21d9c8fd9fc1194f21d5856aef1f58dbef0d58ec1a01678df97a9dadcfab74eadaa72", + "0xb6c385c049c257df1540b85bc88db9da724245407fcef2bbd7d9e4f3028f5b85adc2166783f544e74163a97db7afb73c", + "0xaf85e954978e46e7d5a5dc9a2e3dda1379a15787e4e1b082f7f4ae3c6cc90f3e98f4caa01e8830b833bc0d1e727737f1", + "0x990111556267dc1a1f73d6f013e639a14a44573d793428742441b146c5e4b7001cbb68e4f606a479fbac925db591f158", + "0x9960ff603ac72061c940d2a7e66f63af1dc84f4fe8602eef03a84f498e6e64e84133a114f1c097c6d187842dbaa59b1f", + "0xb8b2444749a8a6720176af4d8e278a26d7764c91a346722bcb0962d3e787cd20afb436b92a805e24c36a05df74764c62", + "0xa65221303f9b8b9ea4156b4efe72bdbb710a5a944aa4680e256d89d6ec34b7d8803337416d75afdec4d6d761d9739f46", + "0x960b86678691adc13eaed09ebfb655d0ac0157e03a96799110de9092302f00a965988eccd87bf14f8d24ec0793f0ab9e", + "0xab43cfe2179c0b75a084d003f5aaf37fa4098b0e7ff62afca5531cb7ea975c8bf6e3eaed682d8552a2f640ac4f417941", + "0xae7a7933f7c7c78726688dc309ec3d97efcd42e42d62f5bf8475503a0dac5aa828cf069a4ff534d48a111f5a5c8666ff", + "0xa69364f715d68b13687fc5130a00da7de19937804d54bad8eee3ea0144e747e7e64fc0d284140d946fa4c2ba78ae93f0", + "0xb4a4a0acc47d3205891a8c5f7d9cbb086e98c5ffe014689212b2793cad9c2f54d20d7babb109006281b4333c54b600ab", + "0xad145c00ab2528f51bdb3d8ed8f0d1e0978fec0e967847b2d9f33d6ff22e2d0e7cf58264d3319f8b497111d6c13d82c2", + "0xb8de07edbd95bbb1ab20dacf33dbf52b772e95bca2b96667b3a6886049c3722cfdea11feeda7687f4fa337ba3c99d563", + "0xa82755d7ef33d0bad8f2448a80737ea1dc3527d70bdbdbed6c0a9686888408719bd3d3542d3dc51d8aebc93f45af39db", + "0x8ce02bfb4b79b8015142683e201bf05e918f364fbcf9bd9c9c5677e62e7c5d524b59fe7a25fe8c81e8d2f945fd95ec32", + "0xb58262374f165b074c73f8d20dda33b69f118101d1aec1a45cfd6b6afe481f8bdd53eb2dee8dcafa83d73e19888b7575", + "0xa9d418ba17f359cc23da79d102d97fd963ec3383a584c920119022400247b4d5070bee3c749c9bdfa8e32bd6ed596102", + "0x8dbfacfca8afceee0783e873413b551b78f5828b29e17cefb3283537fd131fa5ca9d335fc006e1d002ea688d481cb6cf", + "0xb31d500227d528ec8df9665e4880b41b9dc70e42172b173bfdb042b549d3ca1751510b3d6ffd47a85f133c2c912d4433", + "0x849e242f11b886b02713e44911846aa15e3374ea7bd0e34254cbd6268d5f9bf18bcc69e6fe194e81c68e52f840efe7a0", + "0x8ac0db99454cc2a42e8454ba50d525cd36113b8bd69e058534c25c03695a675c4e80df2cbf8edb95a15fcced4c035a34", + "0x99403a33621dd9322f9cc8e16f076e34edc7369b39a5c6994e581ea814e13e457c54bbeef91c7fbfe281745fe3965893", + "0x980058e563b3c28c78eae33b1af085a1a37d463b5311e7a0b3f04eafebef075f5a1ecec73250dd8d6ddbea1968cc2327", + "0x8cdd081907c31244cbc19a0ae1f9d17170b86a405ff1c5349bfdba092f5ba60511271447e7ba850cc4c06c1977db4051", + "0xa2bcda23078ad50fcd658666cc7573031dc837d59df6836f02583ff70950c495b82c8ac1c7c1e15d9c4c83ac8fd9dcbd", + "0x96f0ccfc728fd265adafc79a4613eb5eb977949338c7be0a088b848731e0c4307b81fe067836d3cade8e7c29b80af460", + "0xa627664c43ccc66e4d8b0cc9b9d06ed867aadaf30b1567fada112fd0d9b64fbaede109c220d4d469f3987f094e6cc74f", + "0x92e80e43a0d93984bfa29e7b37f1e9347b0188089c8ebf6e0a0c8500f62e486e16791bb6a6193a43f91537d16a1c8bfd", + "0xb555e0c3b955a5736ce7f89d775da77861ddf51626f30d31f161d921e997a2a73818337f7ffe10688f1e732d1bace826", + "0xb04a2c290251fe0e8fd3b2cb5f0c89e40ee32708c3af668f71bb8ecca1f9adb42514e5a3f78260864a490a96a003e3f8", + "0x93728372d678d56e820818350833fe9ca8c27647f0cdc6df41214e6e08005100da99123e976b2357a7aab3ab2cc1e409", + "0x9387839c27e7c104642c36c5a44e6f5beea77af87eeab24e1b41e7f426491132e81a6f0b7af4511ab3545226b928f068", + "0x882bafad86e30c780c9cb357f6c7f7600879915b17ba66a56eca58308695319f4723e522a7f39ef512c98b18ddfd9857", + "0x80d83290d7b10cd24b0b5aaf58c1c5a6852ac6934744da8b6dba1f84883860bf7391ebef249f9c4449879a851b5a0808", + "0xb893b08548b4845e01ec7dc6844e61d600379b03d7cef0e5206dfdc1026a856ef2284a4ea0450bed94a0ad57b7d3735a", + "0x84c5084dbab936d20210e861d0d49c4530d4d4d9aeebfd30842a1a5ab02ff87acdde5bdabf9a2747729b4b144aa83535", + "0x8b5393a64eb2d1f1b61a494c1794556cb58c90e7369e09595dbb1008ca92d38e2ae0e6644487d90e9e1b5a5745478c69", + "0xac86f92aae6db779519e481baa603e76307fe28832a3a32ba257bb8e2709fdc41ff3c18f5c0c081885a269595ef7f896", + "0x91e56e0e21f5f5396066b6660c3b3ae3d6fe85f202dcf23df45fc15c71f4d65093257687971544b7fb4aa1b3a12a6b45", + "0xb02d38289b41144e7bad69bdf0670fbf2b0480a0f417ed325a944993f98fb16593126e06c34a41ac0a993813f2d75260", + "0xada6230faf448aec707286295be3ad6711c565f0f30803c11361284f09da7e1eb3da49b7074267499c136a5e338c2fdd", + "0x9695f93aa72a34cbc71e73f3e286240cda4b46727ce8e2455dabba4cf42e15a2e8be582073b2507171f3654f584ea4da", + "0x9115443f131ec0198c012ed767208390cd4d20b961b66b5d559eca05f3f3391965836d97c13a46c423f84434ff70fa30", + "0x98ff7d5ef0be339dbc3b8ddf617de68735261cf5c67482bd62f8e8bd3e333d827ea2c78ea2b97d45fee5b850d0ae2b0a", + "0x8adf853eba7bed5c25f74dcfd419738754ff61cea0860752f7fefc9ace5d9ef6d9f376aabd63b7ff2d61a5560aa76197", + "0xa9f1423ca97152ad4698a4d069cf2283c69fdc8bd38881516acab4c3a0e1e0855726ca3c372e34ec1a29ea5c317f99d3", + "0x8616c220d1ebbcc9ffca811d40e198cf1f427216141c3af49879fa63d7598c4fa17a5fabcf486a7824773089387e1ab7", + "0x89825b4a834ddd0cec37e37e987f6e464d33c0f09dcba806b2960b7537b424b7d1797776a8187cfaf4e02eab12bbdceb", + "0xacf253ffe04a4ee786809d9a7b2c44d2c5b50c267a97eb6c91357a73ddeed01af2960ea939dc61eab8eda8e30333e2db", + "0x92ba5e1e5f143d6a3116493ded51bbaf4c37ec7e0671bade6d55ab4854d5759cc9810b71c109bf44ae6174bd280468bf", + "0x8f8c578c546b1b6100b863f2aac0dd2d03acf7977b49dd669437756626ec84f260a3a73bb3c576500c7bce5ae8f328b8", + "0xb1223687af95e9ca602d2e4789bcbe3e96a4ff9d391ecb2db35b18731a77672d30b654e13fc6d0dd590b42cf676219e1", + "0xab6d850eba6ff62cef18067efb5518ede37fb20515bcf6ed90de53e983914586b5674d50a79e2bdd8d7712f0ccc35ec2", + "0xb3c5b805f9483eccbeafd49a669b7382c1e7d232f4bef9c0b170e2618501769c0a6feb2dd21af473de8fa6357b39bf59", + "0x93d0120f57a7f63a293e9a8d06fa6ecb6bc48028b0b2080ae443ba4f083dd53fd93da2547526aecbfac630335e14466a", + "0x96561f86f99df916d77b8dac9c6f63cd2e151abac232c565c9bab0116bbe85212014696cef5f5f8759ad7c5cee3d19a3", + "0xb9876b16f59dbc6476a0d38ebd694fc2bab1a4d6c53e74769e8492badb7d1b181e8bcb2fb0d16892e6eec1341f81eb7f", + "0x89670a196c17d1e49bb2890024b9640329a6adf3f8ef3558fdadbd376d0efd04c69433b45135d5abb62045ad794f93c3", + "0x8e0c307634ee92e0c62fd34774700b2224ce219f116462864754e797e1edebd12ea96ef70095afbca3c61380f4b3e69a", + "0x83e9afa66539a3b28b16c7d8d20feb031c90115fa807f221e95da1127552c94314bb44898143a289ee27544716589e5d", + "0x94e384c19ab22ca8a66cecb0bb9145e15f5a8f12328ef12fae8f4ff8e102fc02c54d8b4d52f993d293379af5ab87ddaf", + "0xb4a42d3c1239c3353c74602489ad4fd13ace354e4fb6fa6056e06cad68fac8418c660e6835349343f25bc801ba094139", + "0x8cf4a6513ae845ff9764708b2604a4b3396aa61c0835f26453781c254aecd33f331baa01202c1afc936038494fd5bde1", + "0x8c75cb35af71ae7c903933de3665a44a4af2993585f681ad3fcc45ab4c6a68122dbcdc2fd6ecc3bd45ab6fe02ad913af", + "0xb445c251be436a474b3a126b51a92a578519592098a66e7f82da5f24a069834db42226636407371e1315c4ce486bb040", + "0xb39800d9c61494edf1cb7d30886dd0898f5a2da72a3a0b847470ddd45e8e265febaf77caea5b62b2543ca04b2d4b8703", + "0x85e82ee14c773f59d6cc3634a99d6ca6a18e706ee2bf850d82112a3118ab1e3af2fd4e28bf249f16ad37115aafe836f6", + "0xa3f388dd9ccc96149d371ab71c1f335de2cc836847b44252325be2089774f2b2175371afbce7fed08a7db1cd131d1b92", + "0x8d7495f9b1dee27609ce683678f7100f6c814ac0f63d1ded5bc23c3515c99384c437bc3481f8d935ee0109922b14403e", + "0x951906705b73451555edaad1702cc0237e79814707877a603f619b911e384d33ce5ccdff03c42cb6376c2649ed0ab086", + "0xac3bf43d0c649007cc18f030646a7f2bb5516fb291890a43db75f07689934c5f7fd7b3cb5cdac9fef90f4138785d7121", + "0x8ce72fb739d2f3af04ae9bebbf135513ad97e40aa0e2b6663ff123b210123bcd3324b7fb7ac8864d2eda97e6e02abc42", + "0x8e6645e26dc470defb98d4db7d39cd151231c1647754713deea0d91ed36ad4f40a6d88fe01fe9ce242579dcf5190b925", + "0x91f0282f1b14648940bea38c6b565a82ff17309e0f004a3aa8254ac94bafbef6ab3be387648b1cb70f6f98facd632fc3", + "0xb8b2ebb4c164ee762d5b7359eb4d4470c0e04169a4906b6b154b051e6e57e8b0b57edf92bcd38d37fd8ed38cf57831b3", + "0x84162c332979c9e5520dcc08c6035f79e8918936bd457517ca449a288ff3f6583cc87440cdc931cc7ec9d9311e56a658", + "0x81052025538ca7116d882c87b148716497749eb95ea88bc500e385ba0cd8e88e7d4302be3863a9e092b3ae6cb27185db", + "0x84dc7f6c4b200a4fb6ef8eedbdc448ca9659eb6b1ce0183f6252146462f8383d34a6e036e925b6a7aef1dd6ca4ebaf9b", + "0x85d9adbe53e4062461e1f2a11a699adcd40750c4aa6406ce499f9b461cb41474558280e4f90a41ecbac64b867ad06d5b", + "0xa1d96bb5f189c680a874db8a0bf2024ce9539e6cd9a1cfff0616a5fb3d808c200bca3c463138a0f953da0eb3cd730e4f", + "0xb8a32dd359aa36586760eea26ed55a2f7652e01bd891ac6c32021c5e661c4485508ccbd1b9c93c3610145d1a016ae37a", + "0xab2f108639168cef2c09acbcb06300ab750c8d172c2220e0384b530e467e324c07c047cda46b3f1b2d0cbfb1b74e6732", + "0xb96a2bbb6f7f58c08bde059f9525cf154d663eee6df456113513b8ec61221b0ad57cc7de15b5f601372c0798ae3d862a", + "0x85f4760953d7acd136c389fae43d28a8679d6156716cdeea4d0be2b75d54c515f42a977ad968ed8e34c7c1ebfb4683ec", + "0xaccd5b65b591ff2770107d101946ae7755ae785639d1f6c764bc293f0fd7fdade3df22719d1e8776064fe092b4319cd1", + "0xa7220ac62840a4aa136ee34228353ce144b412f1eefb7026c1f4eb5c60da3d4fbb7a2892254d26ffbb09b4f34c54019a", + "0x848d2bfc890377bbcd2d96b6c3b2209881298bd1ead9f287efad4617cc1a0046996ee25de9754a20568760e346d74693", + "0x852730a577e0983337fa2b93634c8470ea93f73b505ee9453446a7980018b773fa62e80072d89bf740aa3b91266c9408", + "0x8541824c37e7f318cff0929acba876e7b23e7381ecfdaf72f47469e0a72498e5340bcd0b2a47119a02de558334c6292a", + "0x9284c961db34e366451cafc499f5db135592de542c656f080e2dc2025c8593eae585fb92a7f6d0090af37cd5efb1bc48", + "0x87f1473ae713624e222a949ae8bd7e1e719419cfe2dd7f40723aeae964dd1a61aa63653e77db1c312e6f1b94ed86acbe", + "0xab4bf363fd5f01cf64b23c3905055a1008e41223d397eba621a5a580f99e11ef72b61319d2bdb98447003ff2f8badd7d", + "0x93b9740102e7c885d316329861629b3860000beaf5ccd259b1e1d45bc70ff3b1f8364582b1eb06c1c2611027e70b8e5d", + "0x96165c02815929157d50f767de180eb86fa06552f364d9f191f3d6a4717b726836af6124c6e870c6b16157bef20eed3e", + "0xa83ce4ce3d876db1a7aa10e9a5973416eecc2282350c5fc507d46a39f7485ae91166149103862db59f2b2c207b04cd83", + "0x877d74e5c6af5e71f7eaf068e85c3e3ec0cdd123ccf405b56bcd86b64ff3d65b6e5aa695407556bbb5eae0a57d69a8ef", + "0xb37b67395e616b54b6caa9aef7e0768f174a21c5d56fd5205d665368600a7db28071840ecc41d1e732fac065677ab910", + "0x8565efba93f5de3d975632b6a26593f1bb7c175fb64699e1ad501885fabfac5febcf7aefe07e19ec061d7e056fdc0d93", + "0xb3aafe7cb1a1c3d034402e838f71d92e5da4fd1f01ae156ab92e2a62af8959d0236c4e97b511ad4918e8261bee0db311", + "0xb6c68719bfb140ff3c0d37b8a87ab8edc6186699020367114b92e41a1a3d65f3d975e92323766e1ccc8d93cedd7a173c", + "0x8e216a47b0c30567f1d6be44e7d7416d9cdf08aa4df14ab0f0c967cec13da25f2571b37c38412463adbd932d604b6c30", + "0x8353b33d80584a9387881d2892341df08c467c9f057041877819ea5809c4480c76a21f0fdba6385b6169e807f72b8677", + "0xa6e92f377b6807c1104e202d0202ebd0725b7ea07e5c4a5c5216358fcac160142c806ae93979965c3ec954aefaf7c5c4", + "0xa977e19b8ba7868f33eca30832b90217a0f74f9e5256de26f3fa7ed6fe01376537d2db5dd51c913a6da0196087528175", + "0xb71d0cab241fa709bd7065a6eed5a195f32f8fbd7572d5e71f17ba5ab9732635475a457632bf9760d4bcdb1d55a4615d", + "0xab0579fd053e0edfd4095048a17c0c3d40a36411df926fdd26df8913fc4b29d625679eb51b80ab41b7c725a331583191", + "0x8bce4d88c95a98f25768fd9ea9cdd899a86ec832798e292fa881306c7209bdbe980942e553636f0f354c28296fcec084", + "0x94d55f160ccda82f8d14904cf1cc7ebd97e8ad0ebafad5395e399b78a1fd51b28d3fe8026aa9e4693fe5be29c5f40eb3", + "0xa3727471b35fb9c828b213fe19e7d6bde19c36dc243c78a3901d52cb3555837f7bd4edcf7070b58b6a9f274156bfe642", + "0x93b92a0f770f51720f30c1c8ce3311a11c7fac6c1e8d135454ff37e2b0f0ca8dbcec71ad197498fd2d1f84f79631de86", + "0x959ff2b3f117f8442eec57e043343af22f64156782258679a51aa13b64114294834492ad3e5b477638606c9d59592c5a", + "0xb0a8711d7866bd11dce16f65eaf7cee894144b5ab807f2845701646079f0134212e2dafdde48798fdad45665e7dfbae7", + "0x859f8d8d8d0b3ff20de2901789533a5a33187eaaaf7714679045e16f1cd8d1dc83142f759acd4016b9971f2e49289e4d", + "0xaf2d47c91ccd8949b7807c81af0f8348daf598dca391def28af0f188fb9f8e61ecabc8e96720c4874b7e891ad4507558", + "0x8c75b9aa614f02a53d053f827cfa2dd2e46d62b0a58e3396b4d8bc11c1a276a4b9b96dadbc4a89c4113954c60101c3f1", + "0xa3a1f3f815c038c09b40837e816b5163ee4ffb526e2554fc2393e4d46bc8ea9f960d8de0eafcabc3b3509eec11af378f", + "0xb2bae2fd931e3a016d8f2e21da9f210a9d238d918ffdca7224ad79af79a5d921ea675443e9f2335fbed068dc274e84cd", + "0xb1fe8a0e0770fc933fa023a95686fab22ce752a6a52552a22dee3c25e6483686b17908befedfb1c8b9836870b8d59a1e", + "0xae9a0f711c42af933e4c999996342fb1ce8f1ed7ed44bfdf1584229d0f8efd000b0f3581c86c942fd82369bd7f2c0a2b", + "0x8011dcb68bf101b215dd04a1c788af442efbbab0655abba91244c8a5c725f4e0d7437827a7d12f4bc4c8dbecc2927420", + "0xb7927f551b0bce22a689dd2b3c37eb96be11cda4e230126af21efe16f1e5d8042de884d78bd8189128b3e0bd863115e1", + "0xa8c5a1baaf13e91ee54276ada97a4243ab5d0376787792cf35f91e502f8f4e785ed4f2251c6c8d589dce2a7309890156", + "0xb038f6f4c1570879bde217cbf7dfa7872c784856bf41d6896e9cca417b370365cf029baf78eedc83ba203c1b89d30da5", + "0xb65fdcea6c48f38ed0d4c0b3c041dfc94ad03f8db91e9240a5613ce385cb308a45e678130ae6f2f0c71671d112ef279d", + "0xa251b65035a9988c2786b8d5ccf08895aa299e4d357a5e267cc4f091f845249f133679390d7a8589dc4e5411ee625f4a", + "0xa784ce433a84ca87d4496c3ca9b1a498ec4f158957ab47f99b0119e4d08e2ea808e7ddb98ddad5917294b323a3d908b0", + "0x91770314826a51fb921b9456e0de553e799575e7d56dd97be3a955beebeef3e7f32bd4da8c3328283a454c9309b1973e", + "0x8cb859677b04c4a47acaf1d8d40c86a1805bff862bd3bd16a7d945d48b9d16d033ca6f8afe94008bd04e91c6ef40236a", + "0xa8e309ff8c9c58da429283c6760ddd457c9ded00c689259171de01ba161b9318ec85c0467d8676dc973407b1d215b4cc", + "0xb5a56abc110845548f9ebd82d333655a6cdb8c716f61654238bcfcf671d635691644d4dca137c9e022209bcbb21b7c53", + "0xb398d95f620912f9831c4efbe21c35f1f18d69a5039c970ce74f3ce772f24e487db09fe9166d0533e2c559ac81a6468c", + "0xb5fdc825a8a5fc3ce7bd36bc4d5ec793d410eb58529858b6358ed994056473ea1a1feb936ff519c08089824590cc782c", + "0xb02370884b0c86a6e8608bde54c8e1fa80fc974559116e247a2efcf7e2ef3e5f1c166521ac7436b84c07d2a6e341d857", + "0x99e3f068df6cf1539344f885f573018d52947fb6eeb78c39f2f4f01bfd8347842dac84b64a2af2f54776c62d3bbdbb09", + "0xa6575312a2895cef95afc375757d9d5c43acaa2cf7cda2b32d69678a04936e18194e09260eeb3775f1d1937fc648a881", + "0x80b337d3121683e3a5ba0b327f84e7573c91b0f71f723099ad126669d7fcb478dd0fd76931c8cc9c21930b28c858e7e3", + "0x826f9e027c84b53381bb844990c84aee3c31c945557ee4dbc89d82dd60c26ea6173f037ed7a4d5ebe9a1230fd21300b9", + "0x8516dc5287926dc8cbc705c243d8e95fc8fa8486a5ff987436782476e9e6798a3ae4887c90b0313e2558fcd3693590e4", + "0x82075cc4f40b5530ad046ced11a0999851c1dda4356898c602dcc97979661fa7bd170e53549e13adf5bc9b0701e0794a", + "0xb3d2a606b06894ef17f4e44fb32b28124d364e0edc42b29c5950061b58a1decf9b38c38eea932d9f1871f8f2caf3b665", + "0xa8731fda22fc46893d86f9d580503acbf551e61975516c15fed7df52853aa7dda3a26e0b675105f7831c520107a6c593", + "0x92988b0969382ab9ba0ddfc4138cce15e7375c028af482bc30e81db7a47afab30964b459b9266f922f427e1f832ea677", + "0x8c94bcb01df4be1a8ee988dd0137a5221a6cac13adec7a31d620fb70011ba93a50dac11d1af272b7d361dbb753b0ae97", + "0xa2b0faa03c9efe2d3227e17cfc5a6ffc452b7ed9c5df01e9e21bc0ccf0f37abcd32d5595b40193908d861b440a8ebf5b", + "0x889d3e29bcd376bb36404baf94c83289782b8927a1ee7c13f43c99de62848e9478d582a15cebe2b1ab6f4d3df3a26a9e", + "0xa810bb06178141f598bc80c66756022c1f7e929a38565b0dd3a5fa71259214c86f998913da473d43de0489e252b929f4", + "0xb2deef765730d041b75540ba7a96ebea34a25d52866604f43bb08f4e7cfdeb779c3657756c6c882d4894dcd6dcd93018", + "0xacc697b09a0ddf60458e1e2be902f827339b4927b281c09c9e45a0dbd23bddc540daa37dcd233aa90e06467e7c8fc9a4", + "0xab80bd18fd2f94103a416f468f0e9eb3ae58d9edf61d35683636b4e5bb50adf5f341d753a304cb97981ef5bc0f0cf4af", + "0x997ce23fd497265051857b77329d208b7bd0db4bb43efbd52b264a431ab8aab64e6de9c1d0e7cc6014b4b9e55bf62775", + "0x886cf87f26a158e38337afec3a9aca8397224054616f6ff57cda8f8080cb76b1d7a4d6ffe3816a7c4fc4b85b858cfe42", + "0x8d54a607b4721c0df7c15c97a6d5da3cbb09c6ada2f8fb1fcd3f65a44abcfd5e67d9cfc8dffda5f50fe0a560508d2615", + "0xb4cc312d3fff80c4e9c2ab1ed783a98e77bd4e12d53390b773fcc41927dbe9e323cf933ee4387b09acecef0ad6fdc446", + "0xb412daef90f67651fac1306379ba6dff27fe3edae898ee43806a186d9e741f83ebc72fa56a8ba25a95065a8d153d2b98", + "0x92490c767159fde4d5abb730fa4c2f6d97abe99d24000c7aa99a8c526b598dcf30c803ae380b9fbf9852eb52a849aa5e", + "0x8345ef9628017dec48131a70e8ba5450f03604e4590f053c7ffdfd02ef5251714856652b3fc7d6fa7eedc18cb1c2430c", + "0x94b1dc47b139480501436bba9d62d2631606f3807b3462704e36aab2d26f37c260c37758193ac378cdbf323477771e15", + "0xa3929a8e140e99d4f59df8df3271af7616d2f16a7ea3744306d91e36e7c3cab4cbada9b9aaa7849c4cf45e0117efc986", + "0xb30e2d55cca484e5df94cd3a56bf8a10bf77a33c6d230aec4013f736c09a3f77a5f3cc95521a216fa6c02521269c754a", + "0xb201c7ec94976144c09d0fad39c7de2543a2686d92c30945aa3fabf5d0f51ba6f760a5d644e5a635e04756e6e04a82b0", + "0xb9cf1df02c4e21c92ece37062ec66a790600345fdf52b6d41d7715b238eb2c8eda5dcbeff4387141d05041f4c84fdeab", + "0xa059b7ed360d1d478c73e2b44c320f0cdfefb7d027354fd338a232ad4aa4abfb8d22d20164fb886a4278385dd3645a59", + "0x931cf384e27f0453a16d8d860dc57aa020e5f9a647edae14df80fa78ad989e78ab42f0755fdd2846f4af6bf959d78646", + "0x8b249b4737377c023216d2de2d0b5c4cb18b2d342c91e3a3c7bc73d2c08d3ee9aa2d3886259ed56a668b013bc91b09ef", + "0x862a2903a4a58bb41a9c08b9b1b9971163aa843010949248ffb0e71a03a8377d56ab3d3bd0010e93e6ec4f9f65a5494e", + "0xb6c4a9fe8ab83243ee53c36f19733519d5fcc14ba17bf951e6e6264686572e0278116a7d169ac9d43e9ec3793cd11a9e", + "0xa60dafda88902ce64f0a97e37295916e1b0fe21bd6d4c22035e845104a85ee8306d3242e3314c25eecb9c05cc601d579", + "0xb370b6e0d5eea06472acd1bb12c53d154f02176bcc351c8cf6da5d9d6bcd56d0ff2dabc0280029724cb1e5ba7e80e7f3", + "0x8eaaa899be8020247d58825d48e0028dc0340f78410e9423a74a6f9142cdfc82ae4d093ed693754491002d12f37ba426", + "0xa6721c27a07a81c81a26c19a5fc365b9f9cbdb9efdb6f338ae3e0ad8cd83f3233ab54ce31137513b66e0b92a93b1c234", + "0x88d776c9930d3dc524a0285f4ded51624446da4795635846c4e341f320c95d7331635b9ec02f245a132bd69e12523499", + "0x8252437640b1cfcd852f44b0e64ed666082ef4242d72bbbad318e9830b5b024ebc473ae9dba061e046616e8265622b97", + "0x8d9d5b936a5957359738bb92a93bb9859b9b063409857285d0cf4e756ba2b326c985ce184f2a6182fff824c4ba2f413f", + "0xb8ce17c97ebdda2e23f5398867f4f10b2375a558446b397f74794afb652197d0ae2a693156510ab6edd4a507d9a095f9", + "0xb42a456fa5de9e033856292829cff365c49dadfe74e3632d7d7072f1b21736e551019e81839639ec5645a353310d0c06", + "0x9012444e98da9f5a56592e2e7bf0fcafb2664691201a3bee949f74450bcfa8638d7886a2454cc6bc872a23ef5de665f2", + "0x9466d20b499ff6ff09b567b901a98d43601259763a8207a6f026b2f87c7161e94765ac77fbc948da7cf5e11b9fae3573", + "0xb8a33f7c7a913592f1e2dc719080a2da3384b1210bc98e91894711667cf53c832ba17b37516a8a3d03afb6159ef47773", + "0x91c8c1bdd5fc736ebb61fcaadb529a2690bce9d7818ccbdd52280822af974ab1cdc661b93d517a7c0a9a47dc768485c9", + "0xa7cff90be6fb1e68cb4608050085be6bf458ee5a32d152fdb83e662af70a8671f06146da3ba5246d23d634b19a1760de", + "0xaf72daf482c4c269c90124f9208f646e076c63a21dd96875ad8bed98c5c4d310ff8df1b4af82bed53aba34f0e066bcf3", + "0xa46d8facd51cbb5eff15d2281fcb16d8b4382025fe3b3d7a2cc77c6ffa61aa311eaa9e3fe3a34ac1463b820c37f33811", + "0xb13233fa225e4776c95fdd10ac867fdea04be033a9e6689309bac0df977228df45d74cbd14fa1a84c2ce27877e358c2c", + "0xa543ef63c2e6297795af167d354f1d9b4defdf6aa40c0c53e21775ecab33fa23b59b286df6aaea07d6abe68026a0e36d", + "0x8b3784352836b3403c92aa394879d311a7cc1aae3e73cc5b343c9195b8f73f9c40fe176cd31c72af42fd56bc901cf0d9", + "0xa9c847d9151973609b2b3c90d0ee26067f96bdadafea60c3a82a7177445fffa5817730840883d1dc7a48848f430aad7b", + "0xb28b6f6ff503c00fd5d0a354b1545789c940d9134ad81ea0ffc263ecafee4c5bd4452aecb187b89f22ccc0368e905101", + "0x8b1f99fac8a7d9c8c42342ac0963862ad2ceec8d7cb3c7b805b98fb57d8f44c2364faf9ef604ab13f04ffbf9190a2d1c", + "0x82ae739032291f4fe8e9422ac48395e7b93f2d014f4f5162c70b06152d579cd3d4dd4e967ecf883f9e9d4422204e96bf", + "0x91c6248eed9022bc9d7e71ddb92a7246c09e4895283a7896549235a717f7e7a4f1a52a06959f4396f6f4031df64b5cb0", + "0x86305458419573f3ddd39c5bec83266e43c976efbf5b34d16779af23e2fa11d82dd13ec83fc5efcc9178dacd43b4c77a", + "0x8ec710b2ae85bb335b507c1aba0fa555d1e1833ddd9843954421f4012ec42d6d9751d6ef0958559f80140b43fe4c34e3", + "0x90ef6a19140bc4b464a8cf160ccbdce44bf37b6ad80b70b0401267b68dbc0ccca96e7432a720ea1791c405c27511a432", + "0xb836d0ec4e3c2810d9139f8511e715c7c2514f6e624f73236224fa868ee4c1482142a0b1d000436b104877ed77fc98d1", + "0x8513ce98c39aca3256de87db32dbafefd73a5b1166bcaea572b2ca209173e301ec07eadc2c57153b9c3dead7bcfc9b8a", + "0x88dd5da9d00f357fa16ddcd94a3ab852137b1d5c4839abe60fcde81d0d5c50a86f1ff146b4da3a2a2b1d538f35fe4889", + "0xaaee72c10032a3cdb8801b4df5fb89ddb01c4e28e6bb2fa034ed2c93ec11ccd244b0be708fc55edea7bf56c191497552", + "0x90c01913f2f61bf24e8cba1db0e222c8a4d93b3564af655442675b609f7d1bbcc1e3295b4fdd1a9a4296fb880e590bd5", + "0xa29b4155e6d5e9f318a4ff4bdcc6df387d7213fe73b5c5b13520688c4c6dbe8e310c36f2a94fe7f29c8f1f97c2ed8d59", + "0x946c7943d5222ca703b318002c4f51e3eb8863ac5f6598f8f3c384e752a15b4efac1eee37e4a9b2a3d5545b066836cc6", + "0x814681e39e932e20015d6d44740e3ba47cb581a895d9c0ec637a93b7b03c26b577b39e631a811fec5e131d315e09c74e", + "0xb3396492004b4b671b0761866522ab0232c40b7b10713bf697759a8f6b4ffa39c52e8ab615d6cac94aa074310296cbc6", + "0x98f9df04daf8413dfe56eee69ddcdfbaaa0d1b6a947d501523dbd788cb6ad32b8fcf07882fbdc86209caaa6ca028e715", + "0xad96cd9084b8683efdfd10d744e3f847d67dfa574361584821daf90e0864ccf591fd2e02e3701d01749672aef42a7e33", + "0x979f3b9181ba8c3f1d58d5276c94612b865011d53d63d1e25b4f3076afff0cc3e94bf42686a8aae5d636a013b7c5ca54", + "0x84d66d92e93d1aedae1151f105905fa2ce82dfa71be402a0d5552c1a01d9ad18528c65941ab79303dffc70d4d48fd790", + "0x979e1016e0bfc6d05a2fa325d0a3c2323ee47cae8de73068a2c0fcc153715b5f565071cde74deb674063e0f42c531fb7", + "0xa38e8db0cf6830b89c0ff805ac466ffa5d43fe0a5a95c91f58c9db6755cfa95de9a190bd5d6b982206afca7074270407", + "0x8612f2f1c31b5aaa41f8944e04cb57412496a5650a459a3c1797273925ff87cb4373d9644d62ca74bffb3f2a0a57957b", + "0xa05bb4284848461b8b0947bcadfd3fcf77c6013a559236d6541e1b904e520df93161f2fba68634c37083ed7fff079f54", + "0xa4bc82e93af7eb11cc175102e93726bde624db3fc1b3345d892eeeaf6899685186db877061f9f5576ccb08a3394635d2", + "0xa76493ccd96e215771d629809e7d5a2f263aac56503f67a6b5027d9392efd528705d720fb9364584c4c394e94f59d752", + "0x96b4d0ebf0a09348fe9dfc709c3b2422669848a0147634ec8e7fb31258aab9570db6aa2d9b59cba99d6a741ed906cf08", + "0xab50188dc677da54b7a07030235ec5116c6a48813d71d5188e74d9fd99aee4ae8e849714c2e5369b0d9530e5e9754571", + "0x832b7577056cbba1887ed18f49ecedb2a417b494b4e7d07223b94460ff8450723af1031eb907364ad329c28d2d1789d4", + "0x87b7e8c1f31486be31cccbc8e02a3870fb8365a1f8fcd5016a4c8a1120e5063fe295bac107f4d784a5eafef71a0b4ca3", + "0x9624a0c3760eded25572e4f7f2f109202be47db2a5075eeacff899e12ea14bb3740e7921f6bf28587eeafd068c012656", + "0x8f62204473ea4b94f99905bae2875dbecc1b66fd8de2415ac8e6e6988dc084e2435476566476363ec4404650146cc526", + "0xaa733f8827fc74fa843938e8ff536be5b608513381d09f8e53116c28da37a3ec9bafc69ac303321705247ee7f067ee4d", + "0x88edbc0a9f077400c7b502f4db9fd8efeb76f2c7eae31199618ffff4d007abc2a83b5e299b5e202485cb7367e0e8a210", + "0xb1fbb8ba7f88e4780ac0cb6ac2773b33a0dbecc443d5207c215d4ee9481a2b6c9a9931fc0fda8715ded1494a6b499142", + "0xb32083c30022babf149c698c245bb6e866c051046a5bdac4aab0e00e2af5c099a0d3d1ed68d359ac0f03cdb9147e8516", + "0x8c2fd8d7fc87be6eaee92c3702f2648473389b35f60a7b1da957499b90338941d9e60e99eeaf251fd1f4f93697253d5f", + "0x8845764fc118c5d47defa6ab96468cd704f723e6f47d71d74a11cedbdaaac0326a54186637a5335db2266f53ac784290", + "0xb39bfa899405cd5637f310aa150f0b4700f77a0cc049d8549af4ffafe5d261bf1599296c2b9b165d19d484b768120e4d", + "0x8518b1af4e4e6995fa1620544413451f146f48d0760722a3280b65b9c3f9cfb103b43efce8400cbfc6141a0df4a81497", + "0x815020215d78ad095bf943d3955248444a6bba9595d0c61085f6eb624273c5e935020b9989239b846b93c902d6077204", + "0x8ee0c0688321d30e55f046ca3e5581dd1f07b288552c05a3902847714cfa9ed6429401156b5c6b6b48862d606fe442d6", + "0x83b90f2d1426c59b23bfe144668b3e88cc3688cd59b13a3583fc1407d3bbbaeaf44d555354b00aa27fa6c04ed58627f0", + "0xae85419f11466864d54f6180c9fb310344348ac52b2980f8912478fdd1bca65376f8ec0256a0fdcc1db19d1e1dd03ec7", + "0x9081d66fd509491682652ed6649d7a8f1602f97610819d3f4bb2acca11bb3940a99313f457f491461ebd3acd02348200", + "0x8ed3c17e24dd0b7384bc4053d4c68dda3cc990481e63ea4ca7b1a32b69496b3bfa49ea22db97e3403269718d478654c7", + "0xa4402584acc226fb733895c69353b397be329bf23ca3150d60172382ec7faa4eadd35ac11e01daf8e747755205802978", + "0x84f055b40c5a407b78de2dcb9c5b8f6c0b5dc9a62ef9d129fe85b73089142e60f72c9b44693c0843d17aece8a50d7703", + "0x948a7ed9c2fe1d7dee65dcd9d821b477b87d5398b6f66be29bcca0789f589ec3591042d1211fe9c68ca5de4e5bf19c39", + "0xacec3fd4dfce42354a67db4f016dfdf5039b6d3e9af6cdab1ab26e244bf28250b47839f8a5d0e9169a44f66a77037da4", + "0xacc5b7deb19af4001cb26fdc6672400a048132c1554663f3af90ec6a82feb5b030c4db21b4d86b3ba409a52173c90924", + "0xace5a1461ed94e10017cc3b1c446d47f0a1169d2adc6b67f4e3c7131cb59278788908fae088061f484f1b17a5196096c", + "0x99e9c15268dda26903fc0132403f60071f4a49c67635a3665f32a95fdc32d825314d28e758ed1e8bf7b11533e7acdf26", + "0xb813e95082a2bda051fc42303d7670ff54057ed7902dd7c4c9ee629c7c93b4b53d1c580a92e83147316df87485d7efdb", + "0xaac985011c6a8f1eec22f8e587133d5b141075b88f31433896c7963eee71c2461fb5a9fc77cb3ce221d95ac44a01277d", + "0xa2adb437bbcd6a81cd85168f0bf9dc5729cdf70601fb419b5f2b9e72bbad6bce3993f01d4e0d2ffa4f96111222c34244", + "0x99c7fd5768a65a343578dd7ca9926e13814db2572a202cff8c27c1e14471e0768ad773c9e18329cb608681b89b70bbea", + "0xa1e603890ea90298fef3a1025b5aad43e43b047da6be430d16bcaa3d61f5c0d812ebcde328e55f29df221391b911cca9", + "0xb1a3f56a6ebfe8fe65bbe8a14e28f0380f23ce9d4e006571e602cf11a7926558bd6853e674a1fa88849b83800b1df5b2" + ], + "aggregate_pubkey": "0xab27770459b565a3c6f018200828d1f0361bb3fd2b830eee48f54d149b9d926455a992a12c2b8de38ad7f782a326ec1e" + }, + "next_sync_committee_branch": [ + "0xd342042bee26dd87f462d2eaa043cb2781163509ea55269244d0da0a07c9f232", + "0xadb6382a3ec5d2c4bcfbe39a9c22194c8976ed9d190468e768f270e41940d1e6", + "0xeca6fb5c3ef0f0daba83a1942412265838e968d7784c040c34b58544426a73a2", + "0xc60f5b3b9717868e84ebb775141238e9bfe0f16eefc448d886bb6e8184d1128a", + "0x913e7e5cc7929038e920e82a5556296dc7ffd0df69421bc96a6115d25be8e506" + ], + "finalized_header": { + "beacon": { + "slot": "9566176", + "proposer_index": "1475972", + "parent_root": "0x28c7d49817116c122f24a807c3ddf02e8f842ea2452e36434b358d71808dbfc0", + "state_root": "0x928857b1f2d8614bded06c2048b97f327dc7a346263fbd23ac9399eafd253eb2", + "body_root": "0x3d6478faf7d6f3270b34ec94003128c3aec46b093873de008c729a59d55d994b" + }, + "execution": { + "parent_hash": "0xe1796b7fe01cdba74e97e090e5c73750197cf145c32563ccf9c7b521b5f2becb", + "fee_recipient": "0xba169ec7f10a84a7292b42de438472e1658d678d", + "state_root": "0x75ae790e7a08845b64c79258eb5515118105fec6d89fad7ffcc8f26804a505fb", + "receipts_root": "0xa4cc1ad2cc34c9e2f2d78fd616835c622aa26b9b39ffa0900916131543c76e05", + "logs_bloom": "0xc5a3014da6614520175823d3e71090417627092e2a245014489928a8c0526ac6431d44562271625d42ca822594fe8bc6eb29c1969a2262d914d4f84450ef13242c2a1089cce33ae9ce24551e82c082308481d6a154440a91ea161c749c70c495134a63a22240d0e28a0c469828a1ab560b0c9001057b250542131b5e093823296e0ae4e1be414321454893801226b067f001770143ca00ebc4832e6a447a36211f80818a86403a667300ccccb9528706855d80ba30fc30bf0930202b008258d715b780030c10fdb104408401081bca88a4ed0406526a8b92051772827be0e4b439d0a055070144100b0ca6eca260982604b990239bfaedc809c5b02458c1fc07", + "prev_randao": "0xd9b9b7f4ede5917845aa74efa4793e10acfa228e747d14ec7db5e4a6342bda0f", + "block_number": "20359323", + "gas_limit": "30000000", + "gas_used": "9803230", + "timestamp": "1721618135", + "extra_data": "0x4e65746865726d696e64", + "base_fee_per_gas": "3976982258", + "block_hash": "0xd59d0ec696f51158f885607ab4ecffb153483fee50c991641e56181890352f09", + "transactions_root": "0xf58b4c255e209e746901f1fe7874a68d80d58d5de31f25b24aacafde94225bb4", + "withdrawals_root": "0xacf7c10d68ddc61cfe83442a1588fb92673316d70f74e47caacdc2e470ee27e4", + "blob_gas_used": "655360", + "excess_blob_gas": "0" + }, + "execution_branch": [ + "0x4e611caa93648e49a71e7f0cb5d9c10117ce1ac7b14458e5552474cb5feb0132", + "0x198f847cdc1ad5a54acf2a232966646fbca64509f1371f620be31b358961e15d", + "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0xcccfa21ebac99afe7d65b78db18963652eab320f1a53702ff0ac8a3ddc03a0be" + ] + }, + "finality_branch": [ + "0xbf8f040000000000000000000000000000000000000000000000000000000000", + "0xcddd79ffaacdc106e08b8b535462cd252a0f9a544172f6eb7bc43faf9ebc4c95", + "0x43574ce84e163fe1e21af79c7a2750bd0d683391033a642cccdb498b6b934879", + "0xeca6fb5c3ef0f0daba83a1942412265838e968d7784c040c34b58544426a73a2", + "0xc60f5b3b9717868e84ebb775141238e9bfe0f16eefc448d886bb6e8184d1128a", + "0x913e7e5cc7929038e920e82a5556296dc7ffd0df69421bc96a6115d25be8e506" + ], + "sync_aggregate": { + "sync_committee_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffff", + "sync_committee_signature": "0x80012e3d323df9ea5804a535778582b36caec4138aeabe335f67e6cf8ebb977f60c057d39d5148c9c9a601b08d522755114c45fd432ffde97c2e5e650eda81423178cd16c8c4df47baaef801403862ef7294a9eb95e1d811b4699faa559eccff" + }, + "signature_slot": "9566272" + } + } +] \ No newline at end of file