From bc7997aed10d89e7db81a00a122b3753aaa1c337 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 21 Jan 2025 17:59:40 +0100 Subject: [PATCH 01/14] add event support --- Cargo.toml | 2 + crates/steel/Cargo.toml | 2 + crates/steel/docs/steel-commitments.md | 2 +- crates/steel/src/block.rs | 47 +++++-- crates/steel/src/contract.rs | 2 +- crates/steel/src/ethereum.rs | 10 +- crates/steel/src/event.rs | 155 +++++++++++++++++++++++ crates/steel/src/host/db/alloy.rs | 21 ++- crates/steel/src/host/db/proof.rs | 97 ++++++++++++-- crates/steel/src/host/mod.rs | 38 +++++- crates/steel/src/lib.rs | 24 +++- crates/steel/src/mpt.rs | 65 +++++++++- crates/steel/src/serde.rs | 10 +- crates/steel/src/state.rs | 46 ++++++- crates/steel/src/verifier.rs | 35 +---- crates/steel/testdata/beacon_input.json | 2 +- crates/steel/testdata/history_input.json | 2 +- crates/steel/tests/corruption.rs | 3 +- crates/steel/tests/steel.rs | 86 ++++++++++++- 19 files changed, 559 insertions(+), 90 deletions(-) create mode 100644 crates/steel/src/event.rs diff --git a/Cargo.toml b/Cargo.toml index e1230cdf..d9503a34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,8 +26,10 @@ risc0-binfmt = { git = "https://github.com/risc0/risc0", branch = "main", defaul # Alloy guest dependencies alloy-consensus = { version = "0.9" } +alloy-eips = { version = "0.9" } alloy-rlp = { version = "0.3.8" } alloy-primitives = { version = "0.8.16" } +alloy-rpc-types = { version = "0.9" } alloy-sol-types = { version = "0.8.16" } # OP Steel diff --git a/crates/steel/Cargo.toml b/crates/steel/Cargo.toml index 2bf3181c..1a8926d4 100644 --- a/crates/steel/Cargo.toml +++ b/crates/steel/Cargo.toml @@ -15,8 +15,10 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] alloy = { workspace = true, optional = true, features = ["full"] } alloy-consensus = { workspace = true } +alloy-eips = { workspace = true } alloy-primitives = { workspace = true, features = ["rlp", "serde"] } alloy-rlp = { workspace = true } +alloy-rpc-types = { workspace = true } alloy-sol-types = { workspace = true } alloy-trie = { workspace = true, features = ["serde"] } anyhow = { workspace = true } diff --git a/crates/steel/docs/steel-commitments.md b/crates/steel/docs/steel-commitments.md index 83d77392..d747b0c4 100644 --- a/crates/steel/docs/steel-commitments.md +++ b/crates/steel/docs/steel-commitments.md @@ -12,7 +12,7 @@ Steel uses [revm] to generate an EVM execution environment, `EvmEnv` within the // Create an EVM environment from that provider let mut env = EthEvmEnv::builder() .provider(provider.clone()) - .block_number(20842508) + .BLOCK_NUMBER(20842508) .build() .await?; ``` diff --git a/crates/steel/src/block.rs b/crates/steel/src/block.rs index 3e9fe16d..6a3b13c7 100644 --- a/crates/steel/src/block.rs +++ b/crates/steel/src/block.rs @@ -17,6 +17,8 @@ use crate::{ EvmBlockHeader, EvmEnv, GuestEvmEnv, MerkleTrie, }; use ::serde::{Deserialize, Serialize}; +use alloy_consensus::ReceiptEnvelope; +use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{map::HashMap, Bytes, Sealed, B256}; /// Input committing to the corresponding execution block hash. @@ -27,6 +29,7 @@ pub struct BlockInput { storage_tries: Vec, contracts: Vec, ancestors: Vec, + receipts: Option>, } /// Implement [BlockHeaderCommit] for the unit type. @@ -72,11 +75,31 @@ impl BlockInput { previous_header = ancestor; } + // verify the root hash of the included receipts and extract their logs + let logs = self.receipts.map(|receipts| { + let root = alloy_trie::root::ordered_trie_root_with_encoder(&receipts, |r, buf| { + r.encode_2718(buf); + }); + assert_eq!(header.receipts_root(), &root, "Receipts root mismatch"); + + receipts + .into_iter() + .flat_map(|envelope| match envelope { + ReceiptEnvelope::Legacy(t) => t.receipt.logs, + ReceiptEnvelope::Eip2930(t) => t.receipt.logs, + ReceiptEnvelope::Eip1559(t) => t.receipt.logs, + ReceiptEnvelope::Eip4844(t) => t.receipt.logs, + ReceiptEnvelope::Eip7702(t) => t.receipt.logs, + }) + .collect() + }); + let db = StateDb::new( self.state_trie, self.storage_tries, self.contracts, block_hashes, + logs, ); let commit = Commitment::new( CommitmentVersion::Block as u16, @@ -91,31 +114,31 @@ impl BlockInput { #[cfg(feature = "host")] pub mod host { - use std::fmt::Display; - use super::BlockInput; use crate::{ host::db::{AlloyDb, ProofDb, ProviderDb}, EvmBlockHeader, }; - use alloy::{network::Network, providers::Provider, transports::Transport}; + use alloy::{ + network::{Ethereum, Network}, + providers::Provider, + transports::Transport, + }; use alloy_primitives::Sealed; use anyhow::{anyhow, ensure}; use log::debug; - impl BlockInput { + impl BlockInput { /// Creates the `BlockInput` containing the necessary EVM state that can be verified against /// the block hash. - pub(crate) async fn from_proof_db( - mut db: ProofDb>, + pub(crate) async fn from_proof_db( + mut db: ProofDb>, header: Sealed, ) -> anyhow::Result where T: Transport + Clone, - N: Network, - P: Provider, - H: EvmBlockHeader + TryFrom<::HeaderResponse>, - ::HeaderResponse>>::Error: Display, + P: Provider, + H: EvmBlockHeader + From<::HeaderResponse>, { assert_eq!(db.inner().block_hash(), header.seal(), "DB block mismatch"); @@ -137,12 +160,15 @@ pub mod host { ancestors.push(header); } + let receipts = db.receipt_proof().await?; + debug!("state size: {}", state_trie.size()); debug!("storage tries: {}", storage_tries.len()); debug!( "total storage size: {}", storage_tries.iter().map(|t| t.size()).sum::() ); + debug!("receipts: {}", receipts.as_ref().map_or(0, Vec::len)); debug!("contracts: {}", contracts.len()); debug!("ancestor blocks: {}", ancestors.len()); @@ -152,6 +178,7 @@ pub mod host { storage_tries, contracts, ancestors, + receipts, }; Ok(input) diff --git a/crates/steel/src/contract.rs b/crates/steel/src/contract.rs index 72ec9ef1..eba7cd38 100644 --- a/crates/steel/src/contract.rs +++ b/crates/steel/src/contract.rs @@ -284,7 +284,7 @@ where /// required. pub fn try_call(self) -> Result { let mut evm = new_evm::<_, H>( - WrapStateDb::new(self.env.db()), + WrapStateDb::new(self.env.db(), &self.env.header), self.env.cfg_env.clone(), self.env.header.inner(), ); diff --git a/crates/steel/src/ethereum.rs b/crates/steel/src/ethereum.rs index 7a408395..4d281efa 100644 --- a/crates/steel/src/ethereum.rs +++ b/crates/steel/src/ethereum.rs @@ -20,7 +20,7 @@ use crate::{ serde::RlpHeader, EvmBlockHeader, EvmEnv, EvmInput, }; -use alloy_primitives::{BlockNumber, B256, U256}; +use alloy_primitives::{BlockNumber, Bloom, B256, U256}; use revm::primitives::{BlockEnv, SpecId}; /// The Ethereum Sepolia [ChainSpec]. @@ -79,6 +79,14 @@ impl EvmBlockHeader for EthBlockHeader { fn state_root(&self) -> &B256 { &self.inner().state_root } + #[inline] + fn receipts_root(&self) -> &B256 { + &self.inner().receipts_root + } + #[inline] + fn logs_bloom(&self) -> &Bloom { + &self.inner().logs_bloom + } #[inline] fn fill_block_env(&self, blk_env: &mut BlockEnv) { diff --git a/crates/steel/src/event.rs b/crates/steel/src/event.rs new file mode 100644 index 00000000..d4289531 --- /dev/null +++ b/crates/steel/src/event.rs @@ -0,0 +1,155 @@ +// Copyright 2025 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub use alloy_rpc_types::{Topic, ValueOrArray}; + +use crate::{state::WrapStateDb, EvmBlockHeader, EvmDatabase, GuestEvmEnv}; +use alloy_primitives::{Address, Bloom, Log, Sealed}; +use alloy_rpc_types::{Filter, FilteredParams}; +use alloy_sol_types::SolEvent; +use std::marker::PhantomData; + +/// Represents an Ethereum event query. +pub struct Event { + filter: Filter, + env: E, + phantom: PhantomData, +} + +impl Event<(), &GuestEvmEnv> { + /// Constructor for executing an event query for a specific Solidity event. + pub fn new(env: &GuestEvmEnv) -> Event> { + Event { + filter: event_filter::(env.header()), + env, + phantom: PhantomData, + } + } +} + +impl Event> { + /// Executes the query and returns the matching logs and panics on failure. + /// + /// A convenience wrapper for [Event::try_query], panicking if the call fails. Useful when + /// success is expected. + pub fn query(self) -> Vec> { + self.try_query().unwrap() + } + + /// Attempts to execute the query and returns the matching logs or an error. + pub fn try_query(self) -> anyhow::Result>> { + let logs = WrapStateDb::new(self.env.db(), &self.env.header).logs(self.filter)?; + logs.iter() + .map(|log| Ok(S::decode_log(log, false)?)) + .collect() + } +} + +impl Event { + /// Sets the address to query with this filter. + /// + /// See [`Filter::address`]. + pub fn address>>(mut self, address: A) -> Self { + self.filter.address = address.into().into(); + self + } + + /// Sets the 1st indexed topic. + pub fn topic1>(mut self, topic: TO) -> Self { + self.filter.topics[1] = topic.into(); + self + } + + /// Sets the 2nd indexed topic. + pub fn topic2>(mut self, topic: TO) -> Self { + self.filter.topics[2] = topic.into(); + self + } + + /// Sets the 3rd indexed topic. + pub fn topic3>(mut self, topic: TO) -> Self { + self.filter.topics[3] = topic.into(); + self + } +} + +#[cfg(feature = "host")] +mod host { + use super::*; + use crate::host::HostEvmEnv; + use anyhow::{anyhow, Result}; + use revm::Database as RevmDatabase; + use std::fmt::Display; + + impl Event<(), &mut HostEvmEnv> + where + D: EvmDatabase + Send + 'static, + ::Error: Display + Send + 'static, + { + /// Constructor for preflighting an event query for a specific Solidity event. + /// + /// Initializes the environment for event queries, fetching necessary data via the + /// [Provider], and generating a storage proof for any accessed elements using + /// [EvmEnv::into_input]. + /// + /// [EvmEnv::into_input]: crate::EvmEnv::into_input + /// [EvmEnv]: crate::EvmEnv + pub fn preflight( + env: &mut HostEvmEnv, + ) -> Event> { + Event { + filter: event_filter::(env.header()), + env, + phantom: PhantomData, + } + } + } + + impl Event> + where + D: EvmDatabase + Send + 'static, + ::Error: Display + Send + 'static, + { + /// Executes the event query using an [EvmEnv] constructed with [Event::preflight]. + /// + /// This uses [tokio::task::spawn_blocking] to run the blocking revm execution. + /// + /// [EvmEnv]: crate::EvmEnv + pub async fn query(self) -> Result>> { + let logs = self + .env + .spawn_with_db(move |db| db.logs(self.filter)) + .await + .map_err(|err| anyhow!("querying '{}' failed: {}", S::SIGNATURE, err))?; + logs.iter() + .map(|log| Ok(S::decode_log(log, false)?)) + .collect() + } + } +} + +/// Creates an event filter for a specific Solidity event and block header. +fn event_filter(header: &Sealed) -> Filter { + assert!(!S::ANONYMOUS, "Anonymous events not supported"); + Filter::new() + .event_signature(S::SIGNATURE_HASH) + .at_block_hash(header.seal()) +} + +/// Checks if a bloom filter matches the given filter parameters. +#[inline] +pub(crate) fn matches_filter(bloom: Bloom, filter: &Filter) -> bool { + FilteredParams::matches_address(bloom, &FilteredParams::address_filter(&filter.address)) + && FilteredParams::matches_topics(bloom, &FilteredParams::topics_filter(&filter.topics)) +} diff --git a/crates/steel/src/host/db/alloy.rs b/crates/steel/src/host/db/alloy.rs index 878231de..d6ae25f9 100644 --- a/crates/steel/src/host/db/alloy.rs +++ b/crates/steel/src/host/db/alloy.rs @@ -23,14 +23,15 @@ use alloy::{ providers::Provider, transports::{Transport, TransportError}, }; -use alloy_primitives::{map::B256HashMap, Address, BlockHash, B256, U256}; +use alloy_primitives::{map::B256HashMap, Address, BlockHash, Log, B256, U256}; +use alloy_rpc_types::Filter; use revm::{ primitives::{AccountInfo, Bytecode}, - Database, + Database as RevmDatabase, }; use tokio::runtime::Handle; -/// A revm [Database] backed by an alloy [Provider]. +/// A revm [RevmDatabase] backed by an alloy [Provider]. /// /// When accessing the database, it'll use the given provider to fetch the corresponding account's /// data. It will block the current thread to execute provider calls, Therefore, its methods @@ -91,7 +92,7 @@ pub enum Error { BlockNotFound, } -impl> Database for AlloyDb { +impl> RevmDatabase for AlloyDb { type Error = Error; fn basic(&mut self, address: Address) -> Result, Self::Error> { @@ -171,3 +172,15 @@ impl> Database for AlloyDb> crate::EvmDatabase for AlloyDb { + fn logs(&mut self, filter: Filter) -> Result, ::Error> { + assert_eq!(filter.get_block_hash(), Some(self.block_hash)); + let rpc_logs = self + .handle + .block_on(self.provider.get_logs(&filter)) + .map_err(|err| Error::Rpc("eth_getLogs", err))?; + + Ok(rpc_logs.into_iter().map(|log| log.inner).collect()) + } +} diff --git a/crates/steel/src/host/db/proof.rs b/crates/steel/src/host/db/proof.rs index 3b597ba2..39db54f5 100644 --- a/crates/steel/src/host/db/proof.rs +++ b/crates/steel/src/host/db/proof.rs @@ -13,30 +13,33 @@ // limitations under the License. use super::{provider::ProviderDb, AlloyDb}; -use crate::MerkleTrie; +use crate::{event, MerkleTrie}; use alloy::{ consensus::BlockHeader, eips::eip2930::{AccessList, AccessListItem}, - network::{primitives::BlockTransactionsKind, BlockResponse, Network}, + network::{primitives::BlockTransactionsKind, BlockResponse, Ethereum, Network}, providers::Provider, rpc::types::EIP1186AccountProofResponse, transports::Transport, }; +use alloy_consensus::{Receipt, ReceiptEnvelope, ReceiptWithBloom, TxReceipt}; use alloy_primitives::{ map::{hash_map, AddressHashMap, B256HashMap, B256HashSet, HashSet}, - Address, BlockNumber, Bytes, StorageKey, StorageValue, B256, U256, + Address, BlockNumber, Bytes, Log, StorageKey, StorageValue, B256, U256, }; +use alloy_rpc_types::{Filter, TransactionReceipt}; use anyhow::{ensure, Context, Result}; use revm::{ primitives::{AccountInfo, Bytecode}, - Database, + Database as RevmDatabase, }; -/// A simple revm [Database] wrapper that records all DB queries. +/// A simple revm [RevmDatabase] wrapper that records all DB queries. pub struct ProofDb { accounts: AddressHashMap, contracts: B256HashMap, block_hash_numbers: HashSet, + logs: Vec, proofs: AddressHashMap, inner: D, } @@ -55,13 +58,14 @@ struct StorageProof { proof: Vec, } -impl ProofDb { - /// Creates a new ProofDb instance, with a [Database]. +impl ProofDb { + /// Creates a new ProofDb instance, with a [RevmDatabase]. pub fn new(db: D) -> Self { Self { accounts: Default::default(), contracts: Default::default(), block_hash_numbers: Default::default(), + logs: Default::default(), proofs: Default::default(), inner: db, } @@ -79,7 +83,7 @@ impl ProofDb { &self.contracts } - /// Returns the underlying [Database]. + /// Returns the underlying [RevmDatabase]. pub fn inner(&self) -> &D { &self.inner } @@ -113,7 +117,7 @@ impl> ProofDb> ProofDb Result<(MerkleTrie, Vec)> { ensure!( - !self.accounts.is_empty() || !self.block_hash_numbers.is_empty(), + !self.accounts.is_empty() + || !self.block_hash_numbers.is_empty() + || !self.logs.is_empty(), "no accounts accessed: use Contract::preflight" ); @@ -218,7 +224,42 @@ impl> ProofDb Database for ProofDb { +impl> ProofDb> { + pub async fn receipt_proof(&self) -> Result>> { + if self.logs.is_empty() { + return Ok(None); + } + + let block_hash = self.inner.block_hash(); + let block = self + .inner + .provider() + .get_block_by_hash(block_hash, BlockTransactionsKind::Hashes) + .await + .context("eth_getBlockByNumber failed")? + .with_context(|| format!("block {} not found", block_hash))?; + + let bloom_match = self + .logs + .iter() + .any(|filter| event::matches_filter(block.header.logs_bloom, filter)); + if !bloom_match { + return Ok(None); + } + + let tx_receipts = self + .inner + .provider() + .get_block_receipts(block_hash.into()) + .await? + .with_context(|| format!("block {} not found", block_hash))?; + let receipts = tx_receipts.into_iter().map(simplify_receipt).collect(); + + Ok(Some(receipts)) + } +} + +impl RevmDatabase for ProofDb { type Error = DB::Error; fn basic(&mut self, address: Address) -> Result, Self::Error> { @@ -265,6 +306,17 @@ impl Database for ProofDb { } } +impl crate::EvmDatabase for ProofDb { + fn logs(&mut self, filter: Filter) -> Result, ::Error> { + log::trace!("LOGS: signatures={:?}", filter.topics[0]); + let logs = self.inner.logs(filter.clone())?; + + self.logs.push(filter); + + Ok(logs) + } +} + fn filter_existing_keys(account_proof: Option<&AccountProof>) -> impl Fn(&StorageKey) -> bool + '_ { move |key| { !account_proof @@ -311,3 +363,24 @@ fn add_proof( Ok(()) } + +fn simplify_receipt(tx_receipt: TransactionReceipt) -> ReceiptEnvelope { + fn simplify_receipt(t: ReceiptWithBloom>) -> ReceiptWithBloom { + ReceiptWithBloom::new( + Receipt { + status: t.receipt.status, + cumulative_gas_used: t.cumulative_gas_used(), + logs: t.receipt.logs.into_iter().map(|log| log.inner).collect(), + }, + t.logs_bloom, + ) + } + + match tx_receipt.inner { + ReceiptEnvelope::Legacy(t) => ReceiptEnvelope::Legacy(simplify_receipt(t)), + ReceiptEnvelope::Eip2930(t) => ReceiptEnvelope::Eip2930(simplify_receipt(t)), + ReceiptEnvelope::Eip1559(t) => ReceiptEnvelope::Eip1559(simplify_receipt(t)), + ReceiptEnvelope::Eip4844(t) => ReceiptEnvelope::Eip4844(simplify_receipt(t)), + ReceiptEnvelope::Eip7702(t) => ReceiptEnvelope::Eip7702(simplify_receipt(t)), + } +} diff --git a/crates/steel/src/host/mod.rs b/crates/steel/src/host/mod.rs index 338976b5..a191088a 100644 --- a/crates/steel/src/host/mod.rs +++ b/crates/steel/src/host/mod.rs @@ -131,6 +131,36 @@ pub struct HostCommit { config_id: B256, } +impl HostEvmEnv +where + D: crate::EvmDatabase + Send + 'static, +{ + /// Runs the provided closure that requires mutable access to the database on a thread where + /// blocking is acceptable. + /// + /// It panics if the closure panics. + /// This function is necessary because mutable references to the database cannot be passed + /// directly to `tokio::task::spawn_blocking`. Instead, the database is temporarily taken out of + /// the `HostEvmEnv`, moved into the blocking task, and then restored after the task completes. + pub(crate) async fn spawn_with_db(&mut self, f: F) -> R + where + F: FnOnce(&mut ProofDb) -> R + Send + 'static, + R: Send + 'static, + { + // as mutable references are not possible, the DB must be moved in and out of the task + let mut db = self.db.take().unwrap(); + + let (result, db) = tokio::task::spawn_blocking(|| (f(&mut db), db)) + .await + .expect("DB execution panicked"); + + // restore the DB, so that we never return an env without a DB + self.db = Some(db); + + result + } +} + impl HostEvmEnv { /// Sets the chain ID and specification ID from the given chain spec. /// @@ -146,13 +176,11 @@ impl HostEvmEnv { } } -impl HostEvmEnv, H, ()> +impl HostEvmEnv, H, ()> where T: Transport + Clone, - N: Network, - P: Provider, - H: EvmBlockHeader + TryFrom<::HeaderResponse>, - ::HeaderResponse>>::Error: Display, + P: Provider, + H: EvmBlockHeader + From<::HeaderResponse>, { /// Converts the environment into a [EvmInput] committing to an execution block hash. pub async fn into_input(self) -> Result> { diff --git a/crates/steel/src/lib.rs b/crates/steel/src/lib.rs index 196e553f..e2f6579b 100644 --- a/crates/steel/src/lib.rs +++ b/crates/steel/src/lib.rs @@ -24,16 +24,21 @@ pub use alloy; use ::serde::{Deserialize, Serialize}; -use alloy_primitives::{uint, BlockNumber, Sealable, Sealed, B256, U256}; +use alloy_primitives::{uint, BlockNumber, Bloom, Log, Sealable, Sealed, B256, U256}; +use alloy_rpc_types::Filter; use alloy_sol_types::SolValue; use config::ChainSpec; -use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId}; +use revm::{ + primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId}, + Database as RevmDatabase, +}; pub mod beacon; mod block; pub mod config; mod contract; pub mod ethereum; +mod event; #[cfg(feature = "unstable-history")] pub mod history; #[cfg(not(feature = "unstable-history"))] @@ -50,6 +55,7 @@ mod verifier; pub use beacon::BeaconInput; pub use block::BlockInput; pub use contract::{CallBuilder, Contract}; +pub use event::Event; pub use mpt::MerkleTrie; pub use state::{StateAccount, StateDb}; @@ -122,6 +128,15 @@ impl> ComposeInput { } } +/// A database abstraction for the Steel EVM. +pub trait EvmDatabase: RevmDatabase { + /// Retrieves all the logs matching the given [Filter]. + /// + /// It returns an error, if the corresponding logs cannot be retrieved from DB. + /// The filter must match the block hash corresponding to the DB, it will panic otherwise. + fn logs(&mut self, filter: Filter) -> Result, ::Error>; +} + /// Alias for readability, do not make public. pub(crate) type GuestEvmEnv = EvmEnv; @@ -159,7 +174,6 @@ impl EvmEnv { self.db.as_ref().unwrap() } - #[allow(dead_code)] pub(crate) fn db_mut(&mut self) -> &mut D { // safe unwrap: self cannot be borrowed without a DB self.db.as_mut().unwrap() @@ -203,6 +217,10 @@ pub trait EvmBlockHeader: Sealable { fn timestamp(&self) -> u64; /// Returns the state root hash. fn state_root(&self) -> &B256; + /// Returns the receipts root hash of the block. + fn receipts_root(&self) -> &B256; + /// Returns the logs bloom filter of the block + fn logs_bloom(&self) -> &Bloom; /// Fills the EVM block environment with the header's data. fn fill_block_env(&self, blk_env: &mut BlockEnv); diff --git a/crates/steel/src/mpt.rs b/crates/steel/src/mpt.rs index cd80474e..cfb1206c 100644 --- a/crates/steel/src/mpt.rs +++ b/crates/steel/src/mpt.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::fmt::Debug; +use std::{fmt, fmt::Debug}; use alloy_primitives::{b256, keccak256, map::B256HashMap, B256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header, PayloadView, EMPTY_STRING_CODE}; @@ -67,6 +67,12 @@ impl MerkleTrie { } } + /// Gets an iterator over the values of the trie, sorted by key. + #[inline] + pub fn values(&self) -> Iter { + Iter::new(&self.0) + } + /// Creates a new trie from the given RLP encoded nodes. /// /// The first node provided must always be the root node. The remaining nodes can be in any @@ -101,7 +107,10 @@ impl MerkleTrie { /// Creates a new trie corresponding to the given digest. #[inline] pub fn from_digest(digest: B256) -> Self { - MerkleTrie(Node::Digest(digest)) + match digest { + EMPTY_ROOT_HASH => MerkleTrie::default(), + _ => MerkleTrie(Node::Digest(digest)), + } } } @@ -301,6 +310,52 @@ impl Encodable for NodeRef<'_> { } } +/// An iterator over the entries of a `MerkleTrie`. +/// +/// This `struct` is created by the [`values`] method on [`MerkleTrie`]. See its +/// documentation for more. +/// +/// [`values`]: MerkleTrie::values +#[derive(Clone, Default)] +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct Iter<'a> { + stack: Vec<&'a Node>, +} + +impl Debug for Iter<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_list().entries(self.clone()).finish() + } +} + +impl<'a> Iter<'a> { + fn new(root: &'a Node) -> Self { + Self { stack: vec![root] } + } +} + +impl<'a> Iterator for Iter<'a> { + type Item = &'a [u8]; + + fn next(&mut self) -> Option { + while let Some(node) = self.stack.pop() { + match node { + Node::Null | Node::Digest(_) => {} + Node::Leaf(_, value) => return Some(value), + Node::Extension(_, child) => self.stack.push(child), + Node::Branch(children) => { + for child in children.iter().rev().flatten() { + if !matches!(**child, Node::Null | Node::Digest(_)) { + self.stack.push(child); + } + } + } + } + } + None + } +} + #[inline] fn encode_list_header(payload_length: usize) -> Vec { debug_assert!(payload_length > 0); @@ -543,7 +598,9 @@ mod tests { // generate proofs only for every second leaf let proof_keys = leaves.keys().step_by(2).cloned().collect(); let mut hasher = HashBuilder::default().with_proof_retainer(proof_keys); - leaves.into_iter().for_each(|(k, v)| hasher.add_leaf(k, &v)); + leaves + .iter() + .for_each(|(k, v)| hasher.add_leaf(k.clone(), v)); let exp_hash = hasher.root(); // reconstruct the trie from the RLP encoded proofs and verify the root hash @@ -556,6 +613,8 @@ mod tests { ) .unwrap(); assert_eq!(mpt.hash_slow(), exp_hash); + + assert!(mpt.values().eq(leaves.values().step_by(2))); } #[test] diff --git a/crates/steel/src/serde.rs b/crates/steel/src/serde.rs index 563bb2fc..3da9d249 100644 --- a/crates/steel/src/serde.rs +++ b/crates/steel/src/serde.rs @@ -130,15 +130,13 @@ impl<'de, H: Encodable + Decodable> Deserialize<'de> for RlpHeader { } #[cfg(feature = "host")] -impl TryFrom> for RlpHeader +impl From> for RlpHeader where - I: Encodable + Decodable + TryFrom, + I: Encodable + Decodable + From, { - type Error = >::Error; - #[inline] - fn try_from(value: alloy::rpc::types::Header) -> Result { - Ok(Self::new(value.inner.try_into()?)) + fn from(value: alloy::rpc::types::Header) -> Self { + Self::new(value.inner.into()) } } diff --git a/crates/steel/src/state.rs b/crates/steel/src/state.rs index 79853886..24c8f6a6 100644 --- a/crates/steel/src/state.rs +++ b/crates/steel/src/state.rs @@ -18,14 +18,16 @@ use crate::mpt::MerkleTrie; use alloy_primitives::{ keccak256, map::{AddressHashMap, B256HashMap, HashMap}, - Address, Bytes, B256, U256, + Address, Bytes, Log, Sealed, B256, U256, }; use revm::{ primitives::{AccountInfo, Bytecode}, - Database, + Database as RevmDatabase, }; +use crate::{event, EvmBlockHeader}; pub use alloy_consensus::Account as StateAccount; +use alloy_rpc_types::{Filter, FilteredParams}; /// A simple MPT-based read-only EVM database implementation. /// @@ -47,6 +49,8 @@ pub struct StateDb { contracts: B256HashMap, /// Block hashes by their number. block_hashes: HashMap, + + logs: Option>, } impl StateDb { @@ -56,6 +60,7 @@ impl StateDb { storage_tries: impl IntoIterator, contracts: impl IntoIterator, block_hashes: HashMap, + logs: Option>, ) -> Self { let contracts = contracts .into_iter() @@ -65,11 +70,13 @@ impl StateDb { .into_iter() .map(|trie| (trie.hash_slow(), Rc::new(trie))) .collect(); + Self { state_trie, contracts, storage_tries, block_hashes, + logs, } } @@ -108,22 +115,24 @@ impl StateDb { /// addresses to their respective storage trie when the account is first accessed. This works /// because [Database::basic] must always be called before any [Database::storage] calls for that /// account. -pub struct WrapStateDb<'a> { +pub struct WrapStateDb<'a, H> { inner: &'a StateDb, + header: &'a Sealed, account_storage: AddressHashMap>>, } -impl<'a> WrapStateDb<'a> { +impl<'a, H: EvmBlockHeader> WrapStateDb<'a, H> { /// Creates a new [Database] from the given [StateDb]. - pub fn new(inner: &'a StateDb) -> Self { + pub fn new(inner: &'a StateDb, header: &'a Sealed) -> Self { Self { inner, + header, account_storage: Default::default(), } } } -impl Database for WrapStateDb<'_> { +impl RevmDatabase for WrapStateDb<'_, H> { /// The [StateDb] does not return any errors. type Error = Infallible; @@ -186,6 +195,31 @@ impl Database for WrapStateDb<'_> { } } +impl crate::EvmDatabase for WrapStateDb<'_, H> { + fn logs(&mut self, filter: Filter) -> Result, ::Error> { + assert_eq!(filter.get_block_hash(), Some(self.header.seal())); + + let Some(logs) = self.inner.logs.as_ref() else { + // if no logs are stored in the DB, check that the Bloom filter proves non-existence + assert!( + !event::matches_filter(*self.header.logs_bloom(), &filter), + "No logs for matching filter" + ); + return Ok(vec![]); + }; + + let params = FilteredParams::new(Some(filter)); + let mut filtered = Vec::new(); + for log in logs { + if params.filter_address(&log.address) && params.filter_topics(log.topics()) { + filtered.push(log.clone()); + } + } + + Ok(filtered) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/steel/src/verifier.rs b/crates/steel/src/verifier.rs index 42bfb907..a082c062 100644 --- a/crates/steel/src/verifier.rs +++ b/crates/steel/src/verifier.rs @@ -42,7 +42,7 @@ impl<'a, H: EvmBlockHeader> SteelVerifier<&'a GuestEvmEnv> { assert_eq!(block_hash, commitment.digest, "Invalid digest"); } 1 => { - let db = WrapStateDb::new(self.env.db()); + let db = WrapStateDb::new(self.env.db(), self.env.header()); let beacon_root = BeaconRootsContract::get_from_db(db, id) .expect("calling BeaconRootsContract failed"); assert_eq!(beacon_root, commitment.digest, "Invalid digest"); @@ -55,14 +55,13 @@ impl<'a, H: EvmBlockHeader> SteelVerifier<&'a GuestEvmEnv> { #[cfg(feature = "host")] mod host { use super::*; - use crate::host::db::ProofDb; use crate::{history::beacon_roots, host::HostEvmEnv}; use anyhow::Context; use revm::Database; impl<'a, D, H: EvmBlockHeader, C> SteelVerifier<&'a mut HostEvmEnv> where - D: Database + Send + 'static, + D: crate::EvmDatabase + Send + 'static, beacon_roots::Error: From<::Error>, anyhow::Error: From<::Error>, ::Error: Send + 'static, @@ -109,36 +108,6 @@ mod host { } } } - - impl HostEvmEnv - where - D: Database + Send + 'static, - { - /// Runs the provided closure that requires mutable access to the database on a thread where - /// blocking is acceptable. - /// - /// It panics if the closure panics. - /// This function is necessary because mutable references to the database cannot be passed - /// directly to `tokio::task::spawn_blocking`. Instead, the database is temporarily taken out of - /// the `HostEvmEnv`, moved into the blocking task, and then restored after the task completes. - async fn spawn_with_db(&mut self, f: F) -> R - where - F: FnOnce(&mut ProofDb) -> R + Send + 'static, - R: Send + 'static, - { - // as mutable references are not possible, the DB must be moved in and out of the task - let mut db = self.db.take().unwrap(); - - let (result, db) = tokio::task::spawn_blocking(|| (f(&mut db), db)) - .await - .expect("DB execution panicked"); - - // restore the DB, so that we never return an env without a DB - self.db = Some(db); - - result - } - } } fn validate_block_number(header: &impl EvmBlockHeader, block_number: U256) -> anyhow::Result { diff --git a/crates/steel/testdata/beacon_input.json b/crates/steel/testdata/beacon_input.json index b49577aa..792029f9 100644 --- a/crates/steel/testdata/beacon_input.json +++ b/crates/steel/testdata/beacon_input.json @@ -1 +1 @@ -{"Beacon":{"input":{"header":"0xf9025ea085ff12048f99eafed21668fe41e3f5c32ab58a0da3c9ef4e3057f1718fefeabba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794c6e2459991bfe27cca6d86722f35da23a1e4cb97a0fdba945fc701521d1d780cc3678e9b0d117440c90ba8924b098f96d3e06385aca0f648b484e108d7ac90d9cae783b88f6963f76bb3d38ba13b22b3af8fc25aeb0aa0b7e4b4073748dcc9f35e6a1dcd90fe28fa1c5bd899fd55f823b97d746eaa8473b90100854118088109428d121218b70084219a00a14094064d80002e5029c088c2010200bc81cd012248142002d8072b151688461204128804c4807072fa5cca7402103200500808043882c688294b900ec0902400130202844060010c4409b1108213008102401e01a0411910873144000871800828c4488108c1082000deca29200303a6714911ae74067c0291640561007d05012e301021120894073bc42580050c0e0a02021481480448c90044922a488c12893a498a442b06818082331112eacd492472821c13922418631211bf0242104814429011098d00c112945c00006210afb10a0677580060010361a62102411c80c2040afe12020404056c1c19039206808367a88d8401c9c3808401205ba78466fbc16091726574682f76312e302e352f6c696e7578a0fc22b74c7a6fe4da0844b6da8e8b84ec50ec14eb1efd0aba40dee26ddf8dfe2d8800000000000000008536d318f68ba0d9f1e567661d214eb0af52916c44a49d3174a1dd6d3275ce480ea169ea8f0378830200008404e80000a03fe210a5d884689e9e507297f08be690843161fbc9efcfeb759ffa6573b2836c","state_trie":{"Branch":[{"Digest":"0x4ab8e184e859f9525a865a3d856b3a841109ec5fa01ad7d050c9bf806493c2bc"},{"Digest":"0x6baa7c1834ea673d6ff7b3d0bd05eac6d058a847dd1cfe6db9f483c4e4fa2917"},{"Branch":[{"Digest":"0xde08bf2764058279f0c2c1c779bc75bc9acd4e55f2fb77d6f80beae7b2beaa33"},{"Digest":"0x75e81861e9cf5a98289ca56b6772253ea68c276f56c7969203e4329aedd5b61e"},{"Digest":"0x4b2cac4164968696908dde9b9abd146989212dab27116dff683b1a0269ff317c"},{"Digest":"0x50b1bc361040ec568f975843620162aa8d5359469c8941401c18037f8c3fe57a"},{"Branch":[{"Digest":"0x8ca170a85cfa4821f2466ec1e5299ced318c0d16f77c127908776be11fc5bda4"},{"Digest":"0xe4fe157ea19687abd5fe0d1bb8fd359b748fe8df1d81ee928938b2f1ed988876"},{"Digest":"0x0b40acf13e3e5efe1710b9159996f7c232a655a2441b3f983fa6c42993c675aa"},{"Digest":"0xfb03fd41f144fffa0e491271bea438fb75d80f13a6ea3e08e3b1fc93652a93ae"},{"Digest":"0xbd9d56520af043fecd7d94da59fc7c5768d15ae176c39ef1abac9d8a93aac27a"},{"Digest":"0xd192b1f87aa126664dfa2c97a59c6ff4bd713d821f5270a53e5f103ea72d338c"},{"Digest":"0x19f0e8a05d3f09e588db469d5126b87b4a640de66f3283b52802c4c9bca17e1f"},{"Digest":"0x3a581b6357bb523197dafa2e79997d1ae0584d8604455ea0cb0da7c3a76e55f1"},{"Digest":"0x8f9f3748f51e6ec0dd996a0b147c1acbe8bfaad8e43bfa2134c9cad4e45d53c8"},{"Digest":"0xf9df6993333d4e8dbcba4fd62dadc1ecb0b0feadcc1002890a367841c81fad8c"},{"Digest":"0x7477e778ef99466fb75a4a7efcce294ecb6c6a671ad9d29b8c947abf347debbd"},{"Digest":"0x3bd58ef14ca7b688016c4ec9b96011587939c35820186c453e3f06d40e7a3549"},{"Digest":"0x2dc623a5a7f0016b502c0c15ea2c8b12d7aeef3a1f882a44d2dd7821028445ba"},{"Digest":"0x540fc9aeda3525fd4c3bdcf72642e0ab41e165a4829fb1678f909514096c8aee"},{"Digest":"0x52d02f7471ff137c0374bba43653562961a9752ce0c7298fb631fbc5fd192110"},{"Branch":[{"Digest":"0x05874ea022ba901c2d3bc4a24144b3f45991770d239620e85fca0846310d498f"},{"Digest":"0xbda332d0cf6544dc89b63a3b96d1980a00072e1c2407f5c151ff1dc61f94f215"},{"Digest":"0xe6548c4af231f8a84ece91fe09443fa167b6afa586298aa44f5c9de1d42f84d0"},{"Digest":"0xd79d1dd14d46778105a5abff292506caf027736cce07afc11e17898c7ed39a88"},{"Digest":"0xe85139c8ed7d2b120c17a53fedf8eaaff295412b3bebb3cd131004fcfeed24d2"},{"Digest":"0xff8cd7a7fc94ce410a001fb178a88f2f79a827aba693091209de5241d00f9bc6"},{"Digest":"0x3551497a0439f640571c034fc777fba7f6d64c536f4ada7eacc5fab53cb8574c"},{"Digest":"0x3515948c7d7ddb11ecd4eda0b326f70864ff485bf3e31478d952ef444c157196"},{"Digest":"0xd3e25ac5e646b7175a4a8bde80ecd686713a92695b9e3f2c4b9acc260040fd73"},{"Digest":"0x297e852d803fea4691bd25ae28f5cc82f21bf44d364a80220fb44c8cc8398993"},{"Branch":[{"Branch":[{"Digest":"0xdb28048328251e31b2d3328dc517f370e4661cf8ce1d5fa345faa9f51ce94f9d"},{"Digest":"0x35292568f46d6bb85536804d457243974a5ef9557fd02fdd9c414150039dd570"},{"Digest":"0x547adead9dca2a0a5a68a59b0a9e15e76e03c267aa1bade08bb046f2bd4eb073"},{"Digest":"0x27d35383b43d2bd596638fd20e8dd09a6ab63c96f90ec11c6a5249bb4f4dc2eb"},{"Digest":"0x406a49a5b08edc39727921ccee69f2d8585f1658b581cc21f65349a13be8b129"},{"Digest":"0x8e3c6433db2e2b9bb76200119bf51313cb82d97200d633f988c2222980901f9a"},{"Digest":"0x1e379c0cbf9b976f7917e8dd9cd6e59314a75cff480f6a476984321794bde9d0"},{"Digest":"0x3432854290ecfba5f449eeef9f941897a935694aad97592e7b7d9d681437620f"},{"Digest":"0x644f86d76acd1f8bb5a55119608f0fa73493b2694ef0950f1a5f673e8a7e6753"},{"Digest":"0xdf89fb84a1f4d3a48d788b242de27b80ef31b634c1321f5506a6e6158bb8dcff"},{"Digest":"0x2cf4721a99a7be43a6ed31637c001960276b54518ee3541e349aa47776752196"},{"Branch":[{"Digest":"0x8b92b40f358d29115172a38e36adc284772b7c2440b55e199e31f6d79dc52ab5"},null,null,{"Digest":"0x32e92fce0570631395ec05c62413a521ed320db25bd4a95992ccfc47c4c74a39"},null,null,{"Digest":"0xac2a299a9f99e6f0b275d38efb601ee9d1d95199b9441d46058781dd915fafe4"},null,null,null,null,{"Leaf":[[6,12,6,8,5,3,5,0,5,7,9,13,11,0,5,7,3,3,4,7,14,6,12,10,13,2,1,6,0,15,6,12,15,15,13,1,5,10,1,4,13,15,10,14,15,11,4,11,3,15,1,8,10,14,13,11,0],[248,68,1,128,160,230,193,154,246,15,58,46,205,228,200,169,39,165,222,29,111,88,180,121,74,112,127,111,57,245,32,5,244,60,157,186,100,160,173,162,122,66,135,249,23,26,77,35,164,213,151,124,154,88,61,113,137,6,246,170,45,109,127,36,115,156,57,115,6,242]]},null,null,null,null]},{"Digest":"0x924c1290a02b6550560de2f36ee20c66a31e4e2e1997333f3a8642403bbc1b9a"},{"Digest":"0xd6a2b5a75d24772a9e6c35cdccc8f51ac75818870ab706fef68c0e53b4aa5e40"},{"Digest":"0x2d6bae5f11cf0d8c8aa8858af8caa1a125595e8112eca81d2ca618d2d4758ec3"},{"Digest":"0x96066747f61459591574c48f97d9af2793f04d8258fe6eb7f4c1260cb2a9ed8a"}]},{"Digest":"0x3959262eab0df5cb0ff6ce4bb34ff9af758a35bbcbee37abe5990294e0562fc2"},{"Digest":"0xafac905211b114f21670e002795d86542bd89851a38a5aabd7face23feecf318"},{"Digest":"0x5067f564588be95a99e2f468d72b96462f212bf91b58b69e790c0199bfabb031"},{"Digest":"0xf5bd14502ac3ffb3c931e67fcdee688df840196a89e9bfc7c96fcb3f52058341"},{"Digest":"0xfec9be1378be2a793ece6049f8a10766d4289af8ee1e6aff8e748b74fb95cf16"},{"Digest":"0x4fd7ecbe4c1f9958c6da124c59d0bbea0160c56bf32bd6eb72c672f9abc44a92"},{"Digest":"0x96891f3a45ee91d99cf3e168a61019c3d8ddfa00dddd11b83a3e81c7e5e35589"},{"Digest":"0xeb6bf0cf183778116004b698ef0f5e70995dfa9478bb3255f0b29208d5f92808"},{"Digest":"0xc3caef74fad501cd0ec832b44fd6d19474b9fd2a2153b908e3e8063229b5a6d7"},{"Digest":"0xaf327e16ecc2b46b9eb8560b73410d573daef3486c108b7d4e50aec6fdd8f546"},{"Digest":"0x21fe976c00067f58fcfe4ff5aa689f7a263cf97a879debcfa88ce119a52e5d7d"},{"Digest":"0x66fd5a9d629a870d36e270e332c6bce939ed7fc2a9f2e2f334c65a630ca3ba0d"},{"Digest":"0x5e7d45a26dc6c2a9875a2d6b87710a5eebcfc5b76ff5eb6624c72bb574070dac"},{"Digest":"0x1c3f804db6dc200cd23518a4be871857ac04b8e1bcd87f743bb86a459c6c2c22"},{"Digest":"0xe18a3df3e569acca09459d2ef00b1e4fb3e8d1513cde0e83fdccd25db5d57c73"}]},{"Digest":"0xc366671e6d92e680ef4a210a57bf64f5ec14a6734eebccb548e0764dfb510f77"},{"Digest":"0xae055c2ad055a21614f87feb9de5b98dd47505c4fcdf7b2e21c2df56ec3cf21f"},{"Digest":"0xf95acfb1cf14e4a461ae9d3b1d0fb69e5d66ae663f6c0630ff618ac076be530e"},{"Digest":"0x683d9927ce5db8dc2e645132f672f1aafc98b33492b5651eb899c1dbf24eef6b"},{"Digest":"0xdb58eb782462c4b917eca16ce13ee0864835dc1b4b7350e23e75c8425b7f6c7c"}]}]},{"Digest":"0x6ea2065a22b9e4a28743909410af4e84438df3b30c65d5c6551b3daa23c03ddf"},{"Digest":"0xa90bb4ec2c14e5d97e73e4df945c70b48aff67bd883d4df40d27d6c6264ead2c"},{"Digest":"0x848517f50326c1310c81a8b21296d573663463aec5fefc4d9e982271e7ec6fb8"},{"Digest":"0x74f77d27ebf4443499625dc739201ebe485990c6f5d37cd372fdb4d4703aed60"},{"Digest":"0x9fd417c65f3999120d0f58de80bfc0823c2c903bc119c7c8e7c0dbb9dd492949"},{"Digest":"0x95ed9e9d6dcf821db4b371244e10a84de3074271034ed73dc6c39fc9209275f0"},{"Digest":"0xffad330d236e351e102d0491dd113c806acd75626efdc2482b99de37d9d9f935"},{"Digest":"0xd0810f4d6a130ba0488108eb439529a918e53898a7baa93961d73b50d8343733"},{"Digest":"0xd39a688579fc36f7d587a1818e3370722227c36417d064b3cb5f30894469fa1c"},{"Digest":"0xead73f4b6ff4f085735d27d3768f6633e55e77fdb95e65f3735466ad49fa75fe"},{"Digest":"0xd8766327db36de0ae5355848f8a6b67f0c2213b26945eb57aebc92b84f9f7922"}]},{"Digest":"0x53eed6185fe16f83d1cc83783df4c29d73f7c3327e947146516b80ecc298146d"},{"Digest":"0x9f222f105a27afbe7c7fcb3bbedb8d52bdb4d4c7620f7075335f8dbc2e3a7437"},{"Digest":"0x33ffc48352b5e1e49054a975817d65e3be60dd5540432a5c50e3a135ddbaf88d"},{"Digest":"0x2c00f8ce67a24be43f6bdef97b39da14235e5a467de13f73cbf271095212fb4e"},{"Digest":"0x148b3dc05ccc87f13ae340fb1c96766ba61db098a59f01f7eb5fd8485d8bfa08"},{"Digest":"0x8e07175d8e23ecf080bb4e0d93767b7f02aedca250a3e12f445f1081746dd715"},{"Digest":"0xa66346535aa2a93f1831efc876d3796ab4ee3024244a8a62f7a12b924fca57fe"},{"Digest":"0x686e4ca194cf710671223265d74805f409c8f546d05bd0b0c71d6a5fe1a6b2aa"},{"Digest":"0xa9ecf52d4d2a4fab791318aa1409d7dd6141b19bdc970b7dac518a38a36c557f"},{"Branch":[{"Digest":"0x5c9f0bf4f2c06981edc6726008470b40711fbf8caef652ad150134abe1db85f3"},{"Digest":"0x92c89262729b12c1ad9515f62b79ffc0dc3d94ff1ad9d5f7ad953721010ff60f"},{"Digest":"0xe72c0df3b4806f3ec32f6eb248bd6113546f406320adf76839dd643ea8f71087"},{"Digest":"0xeb2282087cbdb101b85a521159cefcf423cc5e2df2aa11cf9ecfbeaf8a50d63c"},{"Digest":"0x7b7399185826ba84e492985cae6b946017d71558d2cc95d5454aa4e58c13c5a9"},{"Digest":"0x4b2dcbac57108c17416e192460f88eb7abbeb80373e3ec22fa64196f66dee0dc"},{"Branch":[{"Digest":"0xa2d06fa9013378cd05f3d1f88c92d456222a3b1212883b17f9c352cd534937a6"},{"Digest":"0x13d2d4f767964c5163ff602f6878d742ec6bb5d7e2076696eb90630481346b29"},{"Digest":"0xe65b669649ddcba1f7ecb4499c7405587c8d2e8d7a0fab5fd4857ee290e9e87d"},{"Digest":"0x60a3751002055113465ce0873be8ba2f94305fc17c154636491dde2b57b13817"},{"Branch":[{"Digest":"0x3ad4b46e8ffeadd54a43f06d253c1af449f3f4fab55c586860e58574ef83c7de"},{"Digest":"0xd9f0c4f3eb048641b60da40bb3e04698ef4024259a6272d3a585106a112d7947"},{"Digest":"0xbcdb27f8ee5854b9c9dbb78fecb8b5a366e60aa8e5449cdbcd15478b42ff6ba7"},{"Digest":"0xbcea6fb35f13a0cb2e3c1ced578e447f245efe8c8cd460b91d40a2b75acfccff"},{"Digest":"0xe902c889bfce1a86a498c2b0fef7bb45e6e7351fbc0a1e80636bade5c19fcbf0"},{"Digest":"0xb15fdd031140fbff9543923ae6a943377b8ba839805c81887374e0284d7bee28"},{"Digest":"0x976bb7896182ca32d84e7ed1c0372a232bfc6fd7ea35f05509b4b7f13d61eea2"},{"Digest":"0xe824221567f42b24961e5b65f49951f75a99d684e6fbc765d49f53d85417d6cf"},{"Digest":"0xd12969ecd48c615cc17bd62920d1cae02c25222462bb8fd9b01b4d4738e8af72"},{"Digest":"0x46c867a53cbc216bdfb29760376ac91f7ab4216e3436a3293341a3be1a4b3f43"},{"Digest":"0x298e88aaaacfdc530341649bdde25072c7e22c13e1820328a8b0103078d5a407"},{"Digest":"0x8b9636614cf742beb60eaadc927be79cc69c23d9c12ec849dcf4a1925f471f00"},{"Digest":"0x0f399e9f72189558470f7650857b8011bc223d8c29812500fbbbde45ce0bd696"},{"Digest":"0x6b71232f57e38f8274bd82eef71920adb37722dab561844301f0d6d180af86e1"},{"Digest":"0x5d957b95e9ac7c5c603c8b42d747fb48623e88b738cb6337def740712f7e07c9"},{"Branch":[{"Digest":"0xc43d6fc9fea0f239880c36a1b147291287782f11affdab45b7e1afe690c3dd1b"},{"Digest":"0xc65bd105ecfd3bfeadff306567e1cf55c750a9e264fc47dd3e2debf472a4b6fc"},{"Digest":"0xad446ff8fb40b2dec6f173f39b99c02572bb53077a4bca461a52d4c374fbae21"},{"Digest":"0xcb77197c7ac1cd16630d91d250fe37cb6128551695e887fc2d57dea9e5274bcf"},{"Digest":"0x0bc75102a1546274bcb2ee4c28eda640c30ee349ef9ce1809d4cfcecbe8f7eec"},{"Digest":"0x1c6ba636d6a225178396da9a0a8fae8112accd1ac985da7ac9c638f80910cac7"},{"Digest":"0xedd01ef6be9c454d5189b94d26c6bf06e743a737d1525c27e359b5663fcdf1fc"},{"Digest":"0xd9111dd948d64be0b7afc654a538efa142ea32373e3ecec5aa77de9fd51902bc"},{"Branch":[{"Digest":"0x079cdf83dc79847fb2c4283aef06f28d36094f487bdb60435e087b09ee526789"},{"Digest":"0x34c966c91c89c91a0313fe3a258574c8f9b08959e3fa43e40351b4d4bab3848e"},{"Digest":"0x5ffd98f00d0b954d49b39a9cef21efece0ddfd3b62a32bdead8bd131714d7179"},{"Digest":"0x13683ced6ab57daa01993d7c98d0ca12006177c009076434762cdfd98ec0fe39"},{"Digest":"0xa47cc0a8e6b4256fcd929350dfd550e31009a2242203d0b5750625d7cd8f2051"},{"Digest":"0xea61a70cb09f7f5edb51de22253a11d3d987fb7e8f7912555c045d1c466db038"},{"Digest":"0xdbca5b81410deb3cacc46da378cdaec0d269beaa14370f511aee9da7830942f7"},{"Digest":"0x3af98cdd656e7c6575b205b86537b025fcb6acf75a474fc5ba47658b1a7f3545"},{"Digest":"0x601727bfe573710324b2cbc9d34708979870423adca4ec7ec7f6c34c63c5ee13"},{"Digest":"0xd502230a431bc09ce667db68ec89bc81a8234be75fcb5594c5480910548f737b"},{"Digest":"0x3a37c1ad7341c2bdab8ce15ae3bbc1e8f5983493f6eee5578c3df12eee5bfd3a"},{"Digest":"0x679906dd758da0848ec54a7e1a1560e6f7bc2437a96c0b74115f4ad79df6d8f3"},{"Digest":"0xe81236712d30704c3c8e97761bb155d338df6536cc5c1f376bbb505d0365c738"},{"Branch":[{"Digest":"0x132b7ea0c3174dd15a631d5d3acf7846149f8e2b0df7daf9f153a8cabb881941"},null,null,{"Branch":[null,null,null,{"Branch":[null,null,null,null,{"Branch":[null,null,null,null,null,null,null,null,null,null,null,{"Digest":"0xb85f4322dc70cb69433f1011cd7d86681e5fb3a8b8471220ebfe6ab99680e907"},null,{"Leaf":[[1,14,7,3,14,1,12,5,1,3,8,4,0,0,15,0,9,13,6,12,14,9,0,12,1,9,2,0,14,9,0,3,6,0,9,8,12,5,1,11,1,9,3,6,12,7,11,9,8,10,7,13,14,2],[248,78,1,138,2,43,218,16,14,178,56,8,171,111,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112]]},null,null]},null,null,{"Digest":"0xaa9a1c9a362e7f26b92c7cc6bf0e260746a1f0282706486f28dec3b5ad2244a9"},null,null,null,null,null,null,null,null]},null,null,null,null,null,{"Digest":"0x324af29be87648f1e74281dfc338648b6919080973f4ad9b8fec7c4ad0266f20"},null,null,null,null,null,null]},null,{"Digest":"0xbe175a9602770eb28e02cd034e27395299c64ade95df0e07ce20b61106c6397d"},null,null,null,null,null,null,{"Digest":"0x8e4f92b107a3210fdf7c69a4004eb409bd7c5123dc04bb0e184110adc24e25c9"},null,null,null]},null,{"Digest":"0x6349fe57d19d7918d2f608fadd892f99d9c0f9244d3a048968034ae3639af0b3"}]},{"Digest":"0xd8562444dc649316b670625cedea8fb000fd929eca8d51ca9ade15d67b020b9c"},{"Digest":"0x10fa9fac3eab7a2d80440a7a99370a9c277e0773fff1fe40906c43517e9d2ca4"},{"Digest":"0x41fb7dea82b2310e064566f4f5dfdcbd8ba9ee925b3edb03b90db08fdbb9f6cd"},{"Digest":"0xb1c8c3fd9456a2e63f6092f5b1d8327812036619481386b0dd42ac2b316ff2cb"},{"Digest":"0x09d1c11b0b02ad95148037ae40fe8969b729743f680635b2b5fc09a9da8aac0a"},{"Digest":"0xf9bb7ec6cf362e2bb5700357e6d07aabfa89d9430d6cf3d9d7a82a161712800d"},{"Digest":"0xd49ef7e7667ec1b0cfc1ca1112927759f6ec7844c563e7620d65e72b14c5346d"}]}]},{"Digest":"0xe49f3e2e5231dc89cd93886ec80e191ea3f796f00b6b63986669e9f2e6891d6a"},{"Digest":"0xad268ceb7b99c464ddcd285272ec172f8478a850cc622815370dd113183dd13b"},{"Digest":"0xf6c59ac04e1d9c65c7f45273a451000d75565996bd7cbda145b134bf727c00b2"},{"Digest":"0x6b3655472e24d9f758bc15455b7c847a6d778632ac9845e3abc9c8de92ebe6fd"},{"Digest":"0xa0ba645ae6280c832fbf24d19cbeb1e7f647606551b5ec587b4940408a2ad9df"},{"Digest":"0x4ad8b330f32bbb7698204b8265447ecb2d439de315dab029b638052cce48eb81"},{"Digest":"0x9adb650231bc464e56a148cd7b8a4a2c541c23574b943d20d8ed18d80f951ba4"},{"Digest":"0x1e6a8f9877462faddd7bb90b51347751aa7a80cb1e970cfef78b106d351c3072"},{"Digest":"0x5d3caaa7ddf8e955dd9910496d9a35f059ba165e223ec3139e7e312dbdfe0050"},{"Digest":"0xdb462a19ddfdea24451f5a4e27a5594b583d8ee41bf6a0b78e80ee671bb3cf38"},{"Digest":"0x1c4f97704727e4bd58ce52a433c7b10b6527533d2aefe75e774d3e73b5b34f97"}]},{"Digest":"0x302d9354b573a429d22d0c486aec9cf7de7500b4bcf98e73c3ac697543d2490f"},{"Digest":"0xa57d3b9733b3df7dda1967622638a84bea14a65f04fd11a0ab8afb25256770fd"},{"Digest":"0x0ab81d4576fa942bb6a84bab248ff6e45c2360b3c38f0705ccb02c47486c657c"},{"Digest":"0x513866db1cbcb67bb09e4568ee3334725c5d835b74225396488f1775f687760a"},{"Digest":"0x4e5ec4495d7e6adad9077d30ccb3d480721ec9b74e5a0561cb91c610e6f0989b"},{"Digest":"0x260c9262f5d66c4f57ee841d26ddc9080681467b5a4d95d23c0d8b4a46ac7b09"},{"Digest":"0xb811b7ee8dd06b4d996f07f1923877235432b9eb7e817211d78ee671b0d1ebbc"},{"Digest":"0x3fb08c49ff0564b3305e4554996e0129296773ad62545673ce2e2607992b40d1"},{"Digest":"0x04be653bc9aefc3dba9fa1cd73efb7c4b945b00ca184410e956e4f091abc46cb"}]},{"Digest":"0x8f020a1a1c3cae0a59ad231da00345ae089cf235d42665b232699abf9f14a49e"},{"Digest":"0xd5fc482fe9cf579960cfa7e737640e77a33b7ca5c8d84f5948df8d89ac361373"},{"Digest":"0x175571d3e3ad1606f1df4051d0030b16cbd569493c32eb2bcf134600c4fba39e"}]},"storage_tries":[{"Branch":[{"Digest":"0x56544afefeed5e361e4df3e2d663bb228daf6f3a073afd6c995327f7bee32cb7"},{"Digest":"0x591c9d0acd182840738019fedc864367512620f91ec23bcedbed07f99a476923"},{"Digest":"0xbd4273a3fc00e2a5c700caf4a2775197a5bd17bad1abbfd74d0c87f904a44976"},{"Digest":"0x4e45197d666cd89f175f4eb83d79d2d0a3d51c4d9ba623fc2b0fa1989f1e3a31"},{"Digest":"0x32cf5aa9660540fb95834497a5bd687c45c287de74c7d188152e52e1d7946c18"},{"Digest":"0x4062f7f555550a5035f6651105bbbd665671f33c9309bf2dc6c8b67b8168141e"},{"Digest":"0x7939f313928fee8b56cd07d57974f4d55e1f340d93f25197ed354a578acf9d7a"},{"Digest":"0x35afb0b9306eb976575d65789e19510628f9405a8f36daac79a6c8f037de5a5a"},{"Digest":"0x9097fea8996befb8a4126d3798cf79a6c7e0d1336f5ac36bfbe652137b305f82"},{"Digest":"0x8d857ba6ee988703b647ac79283cad8d382b4754c60be47d2ab80db2e1aaa377"},{"Digest":"0x3d7d2abf687c278ca3c9fa351f2e6bbed471a412b59b578e75e789988797b09a"},{"Digest":"0xb72f8830126db2e2b254db43a787c85e94bb449585447a0523344fcb4c6f2836"},{"Digest":"0x32562672655a89e13bfded3af8f56ece0e4ac753e60ce7172d84b4fbf8cc40bd"},{"Digest":"0xc33c225e5e9ecb7b02c074d758e2500674ea0a02534433dcdeb0a137d96be176"},{"Digest":"0x46c6e2573d95970c5068685b56eebb28b5d6506eb486235c010198af9d474fb9"},{"Branch":[{"Branch":[{"Digest":"0x02073d18333e691bddb8642ca82b732db6415c9f84a1149b3bb710824214ceb2"},{"Digest":"0x31d5bc9659e75a99e973418b4794c0d9241a3482d6359cb11b0753d0e460a269"},{"Digest":"0xe79421201d09eeb52b36e427967ed621d245fb04769487d7ebdc5cf7d44b17b4"},{"Digest":"0x18ef63217fc35b0ec780d2427113b6e35a714c4c17b27993cf6227b551912f58"},{"Digest":"0xa53a1b7d3f70c40201345314bf7fb4446bcf79dde781102143705d6b66486e53"},{"Digest":"0x007a444b6e07e59e910751aca367d5fb2d4db3126fe9b9bfae05a7f652cac56f"},{"Digest":"0x460db8fc9fcb2d58cc58997614c5a6545b8c4ea7342fef05768a5691ca7fe5ca"},{"Digest":"0x35ec4099628336dd7f3a13caa20a54d2611b4d8b97a112ff357e0eb0541f189f"},{"Digest":"0x49355ad2e8f7bf8b6ce8084088aa894c07ded44b315695aa1b3fb3551d35d4fb"},{"Digest":"0x83638c0eed723390afd17ac07ad64aa3f298affe5078a3ec49e9b7b463c12fed"},{"Digest":"0x90424abf55dbe91f187e2eab0a91771c4909ee989dddd2263c5ffd8353e44a91"},{"Digest":"0xf708a9096c48c1baed6a8cd3f9409b1863eae8276801a89a6152806947f90a7d"},{"Digest":"0x467c6d27ad319df67a07e54aa5ba51d914c1191c6f179e045ba5e4b1362e1265"},{"Branch":[{"Digest":"0x957c5ebf39508dce06b519f3357407ce9b0c7e325a5b5baf20356802119e2a1d"},{"Digest":"0xdcdcda02bab51aee6cec341859880c7d3a74b2a708c6837a283e9140d742ae71"},{"Digest":"0xfe878f6d7851d2c4a89a747005f6ec12211eea53845502d577358c38d99b0540"},{"Digest":"0xba01139006d0b39ceae595d8736eeb0614536ec331df968bb7a87726d663619e"},{"Digest":"0xd835f0fb96ed233d45a950b9374600896dce6e9f9e9f415e16f56d58db6328ea"},{"Digest":"0x763bc0283a452d3e45a3c40bc33ace9c3bf8327a4f98f3939b6fb10797692ea9"},{"Digest":"0x926a4be03b7bfb0176a0a07d1737c8bf6d7a73d1d02744a1bf26736c3a853227"},{"Digest":"0xbff83b63f63ff94b661fb0a7c3cce98b8407f55097a90e1af5351b21f649d32c"},{"Digest":"0xe0e716a063b31091e183787523f5532b2dc7ab69a1dd66cc90cfb116ad477d20"},{"Digest":"0xfe7d2af4a9f50363f9fc87756d737bd5ea2ce08079a592af54285923e44cbedd"},null,{"Digest":"0xb883893ad62f19b1ade0ead65ab810ea10bc653dc37b2d6e9536ddffab16c44b"},{"Digest":"0x1a578cb4375a74230fc289891bc27480edb2b7b162f8d0636ffd9cffa155cb06"},null,{"Digest":"0x1ab003882db00b52c3298b9f8e5377e64facdbd98d8a31376d7f4b4f7014e11b"},{"Branch":[null,null,null,null,null,null,null,null,{"Digest":"0xf0ec532af391e6dc77f2c9867afce87e39293059a5f8ddf2b21b38d8e4dd23b6"},null,null,null,null,null,{"Digest":"0xb92295774b00d67bfc53715b07b142a21c554b7f1cce914aefc2157459fc289c"},null]}]},{"Digest":"0x45b01213c9e56a5527cbb6ac2dee8cff756ebbec4f9a4106794a62d73e95bddb"},{"Digest":"0xb00a95f416324179cea6c4a2af4bfb813a2925aeb02da845510630a1ecab965d"}]},{"Digest":"0xd2b6f5aa79e4367be1acedfb774fb31ff72d741d7ba63f0fd54057125c6bd4d4"},{"Digest":"0x6d8c5078e4f7cd7313e3a7e93313158a1eb2f61178b4a3a7e955fff12d92bffb"},{"Digest":"0x89eb39899f8e94c8fc33d97a00bd24c9d9b8291595724ec90f94ca777fb5140f"},{"Digest":"0xc24898b9b1d020be564e759e1a8e6ab071685d8f0f6ddedf7dc40f57d5769c74"},{"Digest":"0x54dfd5d63e4d92ae013b4cc1bf1d9cc1bc275a5b23341424a003b24d9bf80ec8"},{"Digest":"0xa71719c64486e2adab39b2ad208f08d3f5775b8daa5cd2c06ec1f9d6903655ab"},{"Digest":"0xdef3321462d8cb9948d0c4d4de63e604b11cb352b70781051b33f5ac02453ca0"},{"Digest":"0xda0b890c9c5ca63b53939d3fcaf8f663a16d0c64866f0730dafc061273030532"},{"Digest":"0x83780e60779372f92ba09f2008d94dd81d1e61703de74d3e2de72ab475ee4a18"},{"Digest":"0x3875c5b603e498fe47a7dc24ecba5fffc29492d74a453ea6bb80a82c3de6e2b1"},{"Digest":"0x21fbc721597b9e854b0f29ae0e5ee78c039bcbe2bc954d9a2f2f7b80659700d6"},{"Digest":"0x4ddf483433da88aca29480ee15efb5ed56468717f55be6f811f55f3b720ff5b1"},{"Digest":"0xc51c210305336706d9e14799b45ca38cf015518ca5aed8698eefdbd46f00a7b0"},{"Digest":"0xd530cfea8782e19146a8865daae4f1a3c6ddb6e23fbb0cddb0a7131fbdd5eccc"},{"Digest":"0x45e57bb66f6807562ca3a128a38bdb69e6a736f9d0216e76912eb0f2fcef21ee"}]}]}],"contracts":["0x608060405234801561001057600080fd5b50600436106101775760003560e01c8063715018a6116100d8578063a0712d681161008c578063d505accf11610066578063d505accf14610383578063dd62ed3e14610396578063f2fde38b146103dc57600080fd5b8063a0712d681461034a578063a457c2d71461035d578063a9059cbb1461037057600080fd5b80637ecebe00116100bd5780637ecebe00146102c95780638da5cb5b146102ff57806395d89b411461034257600080fd5b8063715018a614610283578063781603761461028d57600080fd5b8063313ce5671161012f5780633950935111610114578063395093511461022757806340c10f191461023a57806370a082311461024d57600080fd5b8063313ce567146102095780633644e5151461021e57600080fd5b806318160ddd1161016057806318160ddd146101bd57806323b872dd146101cf57806330adf81f146101e257600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b6101846103ef565b604051610191919061129c565b60405180910390f35b6101ad6101a83660046112da565b610481565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101ad6101dd366004611304565b610498565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60055460405160ff9091168152602001610191565b6101c160075481565b6101ad6102353660046112da565b61050e565b6101ad6102483660046112da565b610551565b6101c161025b366004611340565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61028b6105ea565b005b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b6101c16102d7366004611340565b73ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205490565b600554610100900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101846106e5565b6101ad61035836600461135b565b6106f4565b6101ad61036b3660046112da565b610791565b6101ad61037e3660046112da565b6107ed565b61028b610391366004611374565b6107fa565b6101c16103a43660046113e7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b61028b6103ea366004611340565b610b1b565b6060600380546103fe9061141a565b80601f016020809104026020016040519081016040528092919081815260200182805461042a9061141a565b80156104775780601f1061044c57610100808354040283529160200191610477565b820191906000526020600020905b81548152906001019060200180831161045a57829003601f168201915b5050505050905090565b600061048e338484610cdd565b5060015b92915050565b60006104a5848484610e91565b61050484336104ff856040518060600160405280602881526020016114d46028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020908152604080832033845290915290205491906110bb565b610cdd565b5060019392505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161048e9185906104ff9086611102565b60055460009073ffffffffffffffffffffffffffffffffffffffff6101009091041633146105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61048e8383611112565b60055473ffffffffffffffffffffffffffffffffffffffff610100909104163314610671576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b600554604051600091610100900473ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff169055565b6060600480546103fe9061141a565b60055460009073ffffffffffffffffffffffffffffffffffffffff61010090910416331461077e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b6107883383611112565b5060015b919050565b600061048e33846104ff856040518060600160405280602581526020016114fc6025913933600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d16845290915290205491906110bb565b600061048e338484610e91565b73ffffffffffffffffffffffffffffffffffffffff8716610877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f494e56414c49445f4f574e45520000000000000000000000000000000000000060448201526064016105d7565b834211156108e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f494e56414c49445f45585049524154494f4e000000000000000000000000000060448201526064016105d7565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526006602090815260408083205460075482517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958c166060860152608085018b905260a0850181905260c08086018b90528251808703909101815260e08601909252815191909201207f19010000000000000000000000000000000000000000000000000000000000006101008501526101028401949094526101228301939093529061014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000845290830180835281905260ff8816918301919091526060820186905260808201859052915060019060a0016020604051602081039080840390855afa158015610a36573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614610ad4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f5349474e415455524500000000000000000000000000000060448201526064016105d7565b610adf82600161146e565b73ffffffffffffffffffffffffffffffffffffffff8a16600090815260066020526040902055610b10898989610cdd565b505050505050505050565b60055473ffffffffffffffffffffffffffffffffffffffff610100909104163314610ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b73ffffffffffffffffffffffffffffffffffffffff8116610c45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105d7565b60055460405173ffffffffffffffffffffffffffffffffffffffff80841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36005805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff8316610d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff8216610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610f34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff8216610fd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105d7565b611021816040518060600160405280602681526020016114ae6026913973ffffffffffffffffffffffffffffffffffffffff861660009081526020819052604090205491906110bb565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220939093559084168152205461105d9082611102565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152602081815260409182902094909455518481529092918616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610e84565b81830381848211156110fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d7919061129c565b509392505050565b8082018281101561049257600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661118f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105d7565b60025461119c9082611102565b60025573ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020546111cf9082611102565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000815180845260005b818110156112575760208185018101518683018201520161123b565b81811115611269576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006112af6020830184611231565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461078c57600080fd5b600080604083850312156112ed57600080fd5b6112f6836112b6565b946020939093013593505050565b60008060006060848603121561131957600080fd5b611322846112b6565b9250611330602085016112b6565b9150604084013590509250925092565b60006020828403121561135257600080fd5b6112af826112b6565b60006020828403121561136d57600080fd5b5035919050565b600080600080600080600060e0888a03121561138f57600080fd5b611398886112b6565b96506113a6602089016112b6565b95506040880135945060608801359350608088013560ff811681146113ca57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156113fa57600080fd5b611403836112b6565b9150611411602084016112b6565b90509250929050565b600181811c9082168061142e57607f821691505b60208210811415611468577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082198211156114a8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220eabef41c79e988bbef5573106f3825656f6522b0a2771b005adfc744729606a364736f6c634300080a0033"],"ancestors":[]},"commit":{"proof":["0x77935a302d194a1262ae6923113ae86db0e6e19ce213f5617d9d4cc2f626110c","0x3090bafc416d3cc1a56b97d38a63efea01ba1eba02242b606525baa463529002","0x749c8ed86568b30f9629d0172e0e7fe26f58413cb83c871b6c48a41fb11131d4","0x246945f975282f5ec2e8f59581df1897c3e419d5b4110bd6268b0286b5e5dd96","0x91dc9f8f1e388ec93c8d3b2176d5587aed5fa9643b121f2d0d5e4cb08d3cd188","0x948527f1b9cf52bbcb126333f05a197a1720b0e5c795cd5355210148737ed7d0","0x7e58387dc24ef528448144386ea433a8ce1d476a98fb225c054c5a54d526729d","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0x5838724cb04e7784e11f296abfe83c4ea9cb7588dc627b62fca673e2a65c6645","0x0000000000000000000000000000000000000000000000000000000000000000","0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0x191fef23877fcdda042451463bb3c0356c9e9cf3ffa92bd6d4be44ddcdb45a01"],"timestamp":1727775084}}} \ No newline at end of file +{"Beacon":{"input":{"header":"0xf90253a033a5941fc9045a1a90ca948c4cebe46c814b67066f07ab175d1560f9f31b230ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940c06b6d4ec451987e8c0b772ffcf7f080c46447aa0a531921dc3f13e990768ab9e30353c25b437bd44bcd425fc9ab384624d445ebea07d409b6f1faa6927caf5c58081e8c6e4eaf3e8a6347f5f2988638239280db42da069d2a7a1350fd9162484e14ca98016a5007d42ab6428bff8c87b15c88f77ac43b9010081e80c4c2d066908491411d2a6381e9850c2adde6007120b4b3491b2768a4d92b09e3dc0081160147063036b851c00f95f1f20200e1324180c0e1a980c2d3201f4a0098269645464702036dbd50ce92004d68cd0816710d085634040bc02b23d68c6017a0ec34b4018e6ac20153048a0386a62d38ead8686a7450b90008dda25a2e739023fb0655cb72e00272a20d1110844c981170b4ecc774901f83c810a1d228e60d7e7a830194170040629b0a95702ebee67c012146e2685339320b12cc8498685f64540860d1a8b2a9d0816240578e02084b401b8530064d10edd43e00931705188055848c4d964134178c4c72dda2a58744a9407578d822b495148da1080837311bb840222a353840107e34484678fd158883136386163623465a05d18059e45781941084c495d9d725e41f74083f000e38376746f4ab864c8b21b88000000000000000084cddc56b1a088402e5292988c7d7a2a07457fde2a3ce4c0db058f67075c81c5121c8ee269a18304000083aa0000a041a66d890ff94c1f3069ca6e778cbab4d4d93a3c23f92937e3344270618b38a9","state_trie":{"Branch":[{"Digest":"0xa5a3932bc8860f75558399dea97e0a9786ad25d3ffbca631d451ffea00ad813b"},{"Digest":"0xda4153bd0b8fb87a94a0b12d5103352da772d6f984241ed7fcfda2414d7fadb2"},{"Branch":[{"Digest":"0x5a6864a38e808b2e6eb3b704755e368bd59a952acdb8befcf5672e5fadf6b1c3"},{"Digest":"0x9ed214a2dfdfa07779a0de9aed5df76b3457a18fc9ba7d5d350497cb05a91174"},{"Digest":"0x7bf0f25d2ed1f23bb56b88c571e3cb2c708a2351cfa17e1ec117a7af350a4d6a"},{"Digest":"0x9176ee33eee5fb2087579bbf879464bc7ba9ce3c2bbabddd393e5a34623c9b57"},{"Branch":[{"Digest":"0x5f582e6c829faba8e45af4b030e858973159c384fa1d147377e692fd73e936fb"},{"Digest":"0x3eb5b00f7d6965d7f49274b97949f0df1be0e51874ac059ea102e34aabf42a4c"},{"Digest":"0x37fcf9eaa23555a5dbfe4e8d564190ab2a7228a1ecdd78969dffae542711d4bb"},{"Digest":"0x91544200377a75376c728cf079e988116916e1009625b86ecdfc7906ff67bd2b"},{"Digest":"0x49ce8778910ccbadd08451c0f584aa4cc767e5acb732f26b2cfaeda88fc325ad"},{"Digest":"0xe1a3f8d0cf1a12f06505e062e44dad6182e590596670ba3c8c5703114066f64f"},{"Digest":"0x9633806724a6eca901b8c9d79728a418e9601239cf6339f12bc7382b0068479d"},{"Digest":"0x782f0bcde2066a98c6c25ef1de779d4b3d24ba8a02566b6d93b59d4f675382a2"},{"Digest":"0x85155a997466317ae5efc39e4b11c6a493367f5148e6f322cc52a13060cb4a39"},{"Digest":"0x591e55bdce51648f02a428a1efbe39972f355c4dd86f9228d3d369f9b8e0a39c"},{"Digest":"0x04c24f1787ee2d70ca3d540f5af5791ad1cc639059d1e8806dd4eec41cb76ccd"},{"Digest":"0xc87efb12293ae5948123d7c0527be89a6c0deb352154180d1b17cf1141d1e345"},{"Digest":"0x3f14bafd485e1f930251dd4b2f1d31cabbdbeceda994dd1bbb003b3f042c9b79"},{"Digest":"0x149783d25ae2aec132e61b0da6217ce3a782893549efec58b029865139894937"},{"Digest":"0x5ab41335b57b36ef7d47aaedd3d21676bbb8037e24449a2aa38c76544b96658c"},{"Branch":[{"Digest":"0x52d54434fa8694085c98cead8e5325ddca9e6d8c8bfb6a54b26a275a8d21b8e6"},{"Digest":"0x025090aded1ae4a14cc7111ce50824f88bc21f25bcb8a189c1392be4bbef8fe3"},{"Digest":"0x178c681a749035a54e8b75ead3130301e402da29d6942be6531d3baf8bdc6551"},{"Digest":"0x808ff948596d3b2eaca2ddb9bcd9558cb0d454ad6ae45c09e4c5e5cf4b179b3a"},{"Digest":"0xbb7710fdde09b0fef4b24618cb5a74ecc2384b8e78a990cb4bb7bfef554eddfc"},{"Digest":"0xe63e197caaf7220fca244ae6da7bc35b9543724123ac3a0d9b267c246f5cf97b"},{"Digest":"0xdd30fc81361f7adc6498c0b206ae837eb5a910ed549ffc0983b935cb6df1a797"},{"Digest":"0x4363709449bd22039d05ec13ed3049c8e6e5a72a0cc0cf758dd24e8b604e824c"},{"Digest":"0x4a2b755985c996f5c0cab76191560515222295fa6cdbd89eb2c843228b769da1"},{"Digest":"0xe29b3407f21865195d3838b3a8af3884a6a213951652dc830eeb7f11d25ac337"},{"Branch":[{"Branch":[{"Digest":"0xdb28048328251e31b2d3328dc517f370e4661cf8ce1d5fa345faa9f51ce94f9d"},{"Digest":"0x81d446edc9f6943589e0a95e027e2fc9313976a2850b249e8dbc0a36378d049a"},{"Digest":"0x547adead9dca2a0a5a68a59b0a9e15e76e03c267aa1bade08bb046f2bd4eb073"},{"Digest":"0x27d35383b43d2bd596638fd20e8dd09a6ab63c96f90ec11c6a5249bb4f4dc2eb"},{"Digest":"0x406a49a5b08edc39727921ccee69f2d8585f1658b581cc21f65349a13be8b129"},{"Digest":"0x8e3c6433db2e2b9bb76200119bf51313cb82d97200d633f988c2222980901f9a"},{"Digest":"0xb17d400444bbae6813151d24afe8fb0624b615755904c3f26f191af82df87e9a"},{"Digest":"0x6145add4d419d11c184153988c5bc5769c764ba2a7675272f6751152b69abc63"},{"Digest":"0x644f86d76acd1f8bb5a55119608f0fa73493b2694ef0950f1a5f673e8a7e6753"},{"Digest":"0xdab646f81ca96e9244d88db3c49b36a2e1a4085a255ac571714718e1dc2505e3"},{"Digest":"0x2cf4721a99a7be43a6ed31637c001960276b54518ee3541e349aa47776752196"},{"Branch":[{"Digest":"0x8b92b40f358d29115172a38e36adc284772b7c2440b55e199e31f6d79dc52ab5"},null,null,{"Digest":"0x32e92fce0570631395ec05c62413a521ed320db25bd4a95992ccfc47c4c74a39"},null,null,{"Digest":"0xac2a299a9f99e6f0b275d38efb601ee9d1d95199b9441d46058781dd915fafe4"},null,null,null,null,{"Leaf":[[6,12,6,8,5,3,5,0,5,7,9,13,11,0,5,7,3,3,4,7,14,6,12,10,13,2,1,6,0,15,6,12,15,15,13,1,5,10,1,4,13,15,10,14,15,11,4,11,3,15,1,8,10,14,13,11,0],[248,68,1,128,160,129,27,87,37,243,39,102,193,35,151,234,85,192,100,149,184,89,101,1,208,164,28,106,23,70,209,175,25,193,86,119,30,160,173,162,122,66,135,249,23,26,77,35,164,213,151,124,154,88,61,113,137,6,246,170,45,109,127,36,115,156,57,115,6,242]]},null,null,null,null]},{"Digest":"0x6fee6a0286c5da4191cee1b6a07739758f8c96f1539a98e30627fabbe0466990"},{"Digest":"0xd6a2b5a75d24772a9e6c35cdccc8f51ac75818870ab706fef68c0e53b4aa5e40"},{"Digest":"0x2d6bae5f11cf0d8c8aa8858af8caa1a125595e8112eca81d2ca618d2d4758ec3"},{"Digest":"0x96066747f61459591574c48f97d9af2793f04d8258fe6eb7f4c1260cb2a9ed8a"}]},{"Digest":"0x510fb870e6ff1af9282e7cafec6afabad92cdf02f795ee425c5dd760cbe80849"},{"Digest":"0xfae24aff7b229724462def40d3a113f8b438b2e92e9cb7e0020b5cb2ec4d5797"},{"Digest":"0x48c3d5b0bc4d23e5712c0d1d4803178175cf70650ea139f28a6fd74f33652447"},{"Digest":"0x2f6a5d7e2a1e020964d364217de929f47bd9ea6be7262323e9728fad2fab5667"},{"Digest":"0x7fdfc4eeb2b5ea8a218acb3327961ef3c3a551838f799adfad9d429f219a20e9"},{"Digest":"0xddf72c7ba849a94b74fba9ea1f8068f34445a6be789e4cecf1d421000f0ebb46"},{"Digest":"0xc77e8f9b01c01fb0f3bafe116d58fb05d7bde210b94a1eee4df5263ffae5a5ab"},{"Digest":"0x4d572d6620424e2d63f4cf6e58ad843a12a04841d2306047b810535c2cdda007"},{"Digest":"0x9d3c621f38e2c825309590531af1e86286d2d6ea5fb517ce26e619f2f7144531"},{"Digest":"0xaaf9b8b5761a356543d6c89ce90259e2360ab7edea4f0d5b53489737c064c181"},{"Digest":"0x404d28317de51dda8ff242d18501dae51c4cf0fac09241724276cc4f65a50025"},{"Digest":"0x3e9787cf06d5f388439614e469b7de7e55a26785716e5f3f484b861ba63f2409"},{"Digest":"0xc8ce4a4bd000ca801bd1effe737ffd1ac8162a24e7b154ed915d0a5773af0f3e"},{"Digest":"0x1bc26ae1ec41d087484efebc200b04fbd9fc62097773210593eaa4ffe6c9b909"},{"Digest":"0x6b0c1c1501c7ce6872fa235c4862735426758f92035f889411d4a9dcf66d338c"}]},{"Digest":"0x5831467c6bc689a0dc383da310cccd40585db93e676dd3b94c1df9e41524e7f4"},{"Digest":"0xc9800ee83d3738529b3eb97fa6b35d182379318ba194b15e584aa0fbbef2d6e5"},{"Digest":"0xbc8fd1fe0e0adb1eb1e9f8c0d42328b72143004dba1ccf6c72c4250b0d3b0c8a"},{"Digest":"0x2a287550d0c9eff316ddbda1ee77b3e4dbe398af4a8812f8da6f4818b0c68652"},{"Digest":"0x51ba137162a9599bd44fad77ce91c37fa0de35a398e305a184a8cded9c255240"}]}]},{"Digest":"0x31995e84bc7e4d4b8f422675135df73556fff6297746b304deb61f4d1ae8b4d5"},{"Digest":"0x1333cf2f61b030edc4de3e25597c40c334991365600b15d504dc3802c7c4b146"},{"Digest":"0x7eb5d51e9e413f1bc73b71124f2be6a730224af7dc7cc43837522ee7c41d8d57"},{"Digest":"0xdc9514b2277bd703cb766c0350b05869225537c7a481bb433c9d83c7a4e136f2"},{"Digest":"0x703b58cd4be60713209743b2b22a7ebc4ec23335638cc1b52a0bac37c13cef0d"},{"Digest":"0x8f22cfd3a6e58f16319bbd59c281acf2eeaed94ed64e190892c0342ba8f23614"},{"Digest":"0x49f61e1bf2adaaa39729719e6ece46dbc571058913c0593fabfbbf464a87027c"},{"Digest":"0x8097623cf0c235febf23477381dabd5a3a5e9b7ad1f654e6fb169aa73281b47d"},{"Digest":"0xf52422ab3af8a7ac2a409e30a1f04ca373ae6d34c76febefb88bb0e35bb0f321"},{"Digest":"0xea83e4c5e7439cda1c77f27e7ad7acaebcad716ba1561766e752f4621242c427"},{"Digest":"0xa922032ea488bb1c8f8c39b361d9e4ae6296fda4e6d9a34485fadaabc05f06cd"}]},{"Digest":"0x3f8b9d4ed88fc3e0ad33b54792c102d32850f88ab19328c584bbafa0951bc288"},{"Digest":"0x62afca22d022966683d10812c8e1ad6dd54c579ec96e59f32e4ad972903d89b0"},{"Digest":"0x92a0de8daba9c48adb44608e0625e9d3d7eb1eda4b96016dcbbaae72024c9ee7"},{"Digest":"0x67d8dea586846e88441be45a707e98a72663b7f9ea1f519df22292fea015aa00"},{"Digest":"0x1c797c20692e91bd95698ff50519a1119142f21966caecd2246c7dd25a1797e9"},{"Digest":"0x53e69ad5b39cf36b389e2718e33b4eb2248e85f4f17efc280169aa5914235b92"},{"Digest":"0x20de69f04bc28a8b6597c7fa8f68b0acd25322552b769d5af33e7109d0393b5b"},{"Digest":"0x263a6e9861f95ba9b82f47fe195b14d84e2f5c785f9af4d782a6ce33782ccfff"},{"Digest":"0xf807c35dc1000c37c0ae84ee1ad9d02fcd808c87b15bf07ac3b51fa93dd1d075"},{"Digest":"0x3b99e8db4b2063d62df1a7a791820d105f7e630bbc6c7cc05197f74154141a30"},{"Digest":"0x9d06927ad4c4093402023a9f895a8adcd62bd50a96d56168b8cc91741fbb1ab3"},{"Digest":"0xb966ea14a3635f48a1e9fbba5a3516248a30796f1448c5887c970aca8c1a082a"},{"Branch":[{"Digest":"0xe8425be6f1f41c77ddd386997240969987a755e89b1004555e2829bb8cea114c"},{"Digest":"0x4459d2ff8e5d9fd415ee6d0560e68bf24b6225e24563ee730937657bd9d10a28"},{"Digest":"0xfb798b0814438a1121156f99322c121e551475cc8b02d4a3077857f2a9de085d"},{"Digest":"0xb17d5f41bbe09d1a7aedcc4df0222976f994a4475edb9d72806da2f6d6442c28"},{"Digest":"0x06e25caeb1aeb6ad0b7644b3a26e56079c9596f91a0b245fcf0f67f94a2efe56"},{"Digest":"0x13e0decf7c983d1dd190a74b27f7b8cfbdfc7b9bdba5c440bff278a9e385b4e9"},{"Digest":"0x0bba96b2533bab27a23144727b535fb68e21286493a634f642b24db61df01ba6"},{"Digest":"0x8868b30ece4c9ecc90835afce3094980de103b971a739e5a3868ca7b2618f7d4"},{"Digest":"0xff70062743053c66da67cd52a0311a5c6f38b3ddcce2098e683b7f38dd99e785"},{"Digest":"0x7eb6efbb4ebf2a45cdda0f9f62f6cd62454ac441c7a9b803e03a9e6f43b2c1ce"},{"Digest":"0xbb345511677e2213ca50b47ca4264f89902cc8ef29d7138a24725749274ec28e"},{"Digest":"0x7720d5efd7b59ffb70cc25b4ffa91388534a4f48378066fc0badb1d00a997772"},{"Digest":"0x504732482276a95760465b2c92369eea0a221a3706a2fc0a2c4cf62a659f2b34"},{"Digest":"0xdacddd143715847c74bf1199ff6bb1e64ba3e15ad22a00f35252daad20a867b4"},{"Branch":[{"Digest":"0x8e18545774dfbad487b1277f6f62b8f4eb68ced84745b712a604eeeed8d1adeb"},{"Branch":[{"Digest":"0x88df302672e873deb19e8081af9b50d93dd871faa211f56d91bee002fe559516"},{"Digest":"0x0d2fbe761179e53f5e2bcaeb94530a74c663bc6946c23d38cdfc6ca7dd5abf39"},{"Digest":"0xaf02d45e8fcb6db1876dd42a594e15f531c76c11cbd16866a25b6f9d50919669"},{"Digest":"0xd8f3493f35002318b43577be29201b7330551f3655a2db0b1a2d2d9774860881"},{"Digest":"0x6757b3ad3584c281c7ea349baa3aa6cd59ac397c9180441af79da5fc6a62f288"},{"Digest":"0x08afe45cec318c3955a4ad85a17f9c215f84467dbda53b155589e21763e788fa"},{"Digest":"0xbd909a66b5146d601b353a6fb48b6bcbd86a663f214f66e7d45d7ef757ec8205"},{"Digest":"0x0430f04906a37c4981ef65aac8f4cf5fb8f0944f0ca34270eb9669e172a3e99b"},{"Branch":[{"Digest":"0xc9216f39505800caba545a8b2505d378b5f91a765ab780c6299c44ff251aea32"},{"Digest":"0x98ac3a1f128f58100021d9ad2f0b81c3b91819b929c2112aa84aa31a646a8683"},{"Digest":"0xdef8dd20eda1059997353ea3249d5b0b6a0839d561b6a748c199defa0ee70741"},{"Digest":"0x55c5ddb21344c1f2a98fc18f7245a2a33a38de6c5ca8307d694d4333b5006233"},{"Digest":"0xb31bfa319ac0fd6d4c017d9a5f8bdfbf565ed3f040348a91cef2a46164dbf0f0"},{"Digest":"0xb508283f3d9c93669df193dab32e8d6691a1d8fd4d277ebd4ef003d6bd503748"},{"Digest":"0x6c50497df80160ad980aa3cd328454e5601247af6e93a06c2dd981e7c648dac2"},{"Branch":[{"Digest":"0xd7c1cbb543dbed2a8ed6e3bce15fca95b4588ad4048b16cb05c413e4487162d9"},{"Digest":"0xd578264c47a3c8152bf84cb41ba5f4fa21a0098e49325cea95e6b083492170ec"},{"Branch":[null,null,{"Digest":"0xf96aa5ae728d2a2aa145fcd78a6e3b71e1e19f78bf17912cec6e0e420a431d1f"},null,null,null,{"Digest":"0xbf417cd01e9f9b8d5c7c455a42f30a9e5c64391d4ef34d0536bee62668839577"},null,null,{"Digest":"0xd79110cc61822445c11944f67385802aeadaa51b882bf323aa758d5fa03d4914"},null,null,{"Leaf":[[8,12,5,3,1,5,2,6,13,5,11,5,6,5,0,0,14,15,2,14,2,12,6,10,14,13,7,6,7,11,6,12,13,2,11,2,7,1,10,13,15,12,14,0,14,2,6,9,7,12,1,11,13,4,1,7,11],[248,77,101,137,210,178,81,110,207,196,228,209,48,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112]]},null,null,null]},{"Digest":"0x5f9084f019bdb64d691968c58e8d19b42bc7d4ee4b6e9b595a8332210e957bbd"},{"Digest":"0xe148271a456ae2a4aa3465d7669c2f488a1be4eec6ad23564047875216fd1b4b"},{"Digest":"0xda89ae53bc57a27629fba20c2ccbac9eaee6a8490de17efcdd9a9b8a322332c1"},{"Digest":"0x895a77ba20d46ebdf38a61c9145b0353e121cf9eb92ee8fdf984fc54d57bfed6"},{"Digest":"0x7659a4a8fa53816bc40c0f6843a0e5b6ab377e7213f97b84919494c5546cf13b"},{"Digest":"0x3d77084a1de573f7b30ab3e264b8edc48449d3c84f9bfc15d47c32929642a931"},{"Digest":"0xa97bcbcc43ed4c42c1baade564e27a549cc9f41cbb36723a5ac062a5afb2031b"},{"Digest":"0x358c5521723d3fa6584fc07026070ec51805559aaa1a1f7421d8ed0706c98585"},{"Digest":"0xcf2abcf8538b6be863f88eb4de9221dbd84c46cf51f21e610ee41d60e9358b7a"},{"Digest":"0x2b120c2b5fcb269662bbd9a92e3297152097290e086aee34615f65aef64c0aa3"},{"Digest":"0x8eea1be10605635ea07ad976df29c8fa506865d98c243d212cade6275ae7ee46"},{"Digest":"0x3af198cb2ccd3eccfd91e0a9c1917a529623e35cc5af58bda633bd677beac5ab"},{"Digest":"0xd2e866c45ea9e9bb57776a8ad2e41af15fa1751100f8441f08b423b7e4841a35"}]},{"Digest":"0x0ba1cd8128f7b148d119b344c28668645951053ce5f65d1b5e84cddb9f984dad"},{"Digest":"0x2faac18a650961c6ae6a9e5dc78c6e2eaaa111aaf49fc20f8ced41ef156daf47"},{"Digest":"0xa24643b90bf45ed8b6ce0cb552e1837ae45a8f7219bb3b5ba6fe9992718c6f24"},{"Digest":"0x81fc1ad4b4a9dae68f1b73d1f73fbe1d1eeea8992d4e26e9311c0fc4a4b2dad4"},{"Digest":"0xd0ed17b8834dc69ecc4fee7caaa389214a9caf55317ef0e6f252ee196f0ce8ae"},{"Digest":"0x23a284cb2dc2f9d03b820532d0d5bfbb46ba7cd890842e618c19ddfa9b402991"},{"Digest":"0x3d6daec432d6493442e8719af25dd3b1ee03cef7930ecff3a5a3596bda92a687"},{"Digest":"0x982f92df24f08617a4e15bec20f2f4209092608f7a1634bd4797745f5cc905fc"}]},{"Digest":"0x2f290ecb7ef3d71f12e13471a72707c5a68794b2dc9ffdde1929bcd944920f39"},{"Digest":"0xaa0c5f0a992c9ae15bc777f7bca1fd30f44d607810c554eaabf4836dd41f66aa"},{"Digest":"0xdb2a23006a09136b640d91b8abc0e3562ae09ec5722fed95889638fbc6828ab9"},{"Digest":"0xdeecfbcb85a0ce9f6c03034c39ebdde204fe638a8d20acb135f41874a2de320f"},{"Digest":"0xcb2d3bf71494bc8378f2d869ab5ddca5626f886ac9a064f717d4dbea74547eb2"},{"Digest":"0x019e189b40e07cf3072d16da52a98e3bf1a9bf3826bf28d965e57f6b92e527ac"},{"Digest":"0x6eb2d14705b24b9b96cb735966983ee2f4fe27cc5bc5e00787292dbd931ddb46"}]},{"Digest":"0xb0025ee0be5340e32836edd8aa3a25b153da9a9a0f499ebdc450a4a889299593"},{"Digest":"0x9509ee91d3b2c82f8f01219d9fa57086c208477f54dce61770f359a3652cb980"},{"Digest":"0x0d47c0f80b5e38e3e18c8e5ad1390f6f11a23718633fd70638aca86b5c413917"},{"Digest":"0x710b1def04aa10637ce74039ae7c6564fa32451cbef1140b23b6b648ec78801f"},{"Digest":"0xbed52a83620609e3ac0fc6336fe798f5e7578d3d53eead4cb3c922da2f0a9fbd"},{"Digest":"0x06ff169d3434de2fb06ff59a569f0571bd344194930c867402fd53db2999d7a5"},{"Digest":"0xdf9f83344ee201a7260a3af0aec51b47f327ceeb07f98ba55c07557ab39bc466"},{"Digest":"0x3629361c2837c23c322f6a0652973fbad5fffb130505fa6814e660d8a355f712"},{"Digest":"0x08aa5a66ab949210d22be3bc5305bf469894905614b80bb950323e1b6dc4d118"},{"Digest":"0x55a040364b52a75ec7b44cb93710bbf0ac6bc19538ef3094328931a3659ba849"},{"Digest":"0x3aeeabecb39f05681fd9bcf6ec1688720d9571fe74e539c45f79f45d6766fd25"},{"Digest":"0x531dcf027f2aacd660a63942575370c594e2eca48c13a3df493c6cf5b5ab69a2"},{"Digest":"0xabd490f7b1d6d955571a567cb266db0a4e138efd5e9e45840ca68dbabf645658"},{"Digest":"0x5882a7239419c57a595e78aa80ab6b5e8c945911ebc63fb5c75461a2dab767d6"}]},{"Digest":"0x37a050a54701861553d414616f269567dafba2191d2360330c4e42bfa8306f5a"}]}]},"storage_tries":[{"Branch":[{"Digest":"0xf3c49aae9ffc5c5859f82701ad88aa33c9f44ee72aa9ab50555dd27d9b46ff8e"},{"Digest":"0xb7d4c2847846a686da8209096e7900fa4dd716f0eba0e0afb7d25fdfec73e683"},{"Digest":"0xabe140263b83045f80eaec799bf12a625ba88c5ef26bcf86dfa4e992ec81d98b"},{"Digest":"0x691374e6c78757fba9010e038c4f4e0a516b939e193491974be022eecee12636"},{"Digest":"0x9bcbc4906a7dd569dc937690ef7e352698d1eff7c53e86b2e94a00406f3eb5aa"},{"Digest":"0x4bc91d87715a17274a73d8eb2e037ce50d976cba9244cbf6ad259b4ea9798d93"},{"Digest":"0xf1caeebd43b5dccae32d12e141eb10b03533f5dd8a5499b2e80b3dc33aa372b4"},{"Digest":"0xf30fe68757e7a15d2c812b36ee28efd70e1b9340ef969ffae2fdc82329b3591c"},{"Digest":"0x7c685970bdbd575e07d3ea1910dac453368acad013e82c08e9664b63040c6f1f"},{"Digest":"0x602a5d1cc5eca1d476a52cbfe0f5947de04a42471efb09806788cce72334e5d9"},{"Digest":"0xa3c039226e6a6dda938be124b7f3fcd9fee96a4c27bb102d517b32d741337ecf"},{"Digest":"0x14db8daaa5545f3e8d323298ee9279e25c15809165487441cfeea28bc4317e1c"},{"Digest":"0x68f0c1a3259356bef4802dc20934f3cab0f4bc83e5398d1ff9424f2a10abb519"},{"Digest":"0xa6a8fc3a5f3f13bc4667f29221c83d58df9d0eab151efa69b37292005679f03f"},{"Digest":"0x1c1b862e59bb50cd1b298986b5674db4d0aebf47a112f619899e54d6d25e726e"},{"Branch":[{"Branch":[{"Digest":"0xaffb365301da6b6a18b0d7ef4efaefff324ad65c3b57388c877d90e167a9609a"},{"Digest":"0xcaa301dfeba77405004b66b89f61853db26d981d927b2eeaeaeac8133ac20182"},{"Digest":"0x2b1fbbf1dd2930136257f164a263c467c75eef558180678b8cabf110676d74e5"},{"Digest":"0xf60d899b2db311534675632909a5ec1a5822f6517d15d2991b8814c6540587fa"},{"Digest":"0x7756d9367ccb981133ed3d4c879355c16cf2cf6bcc4972164384edb43d7d0b6b"},{"Digest":"0x4807df2cec95a95f4a733495282816388da5cd25243e666bc8cfd1fe4ef12954"},{"Digest":"0x8bcd643182696868ffe097c638367ad6ffbeb3e5b449c18546341a8652fcfd3b"},{"Digest":"0xcf32a84d4499dd2a0174286e6a361e16487ab07c1dd2b0f123e271dd1550a9ca"},{"Digest":"0x85959dda8cb42adb0d6dc37a9f515cc45f503511ea1d7d23288c93b46d7455f1"},{"Digest":"0xfe4dc360a9b7e51f860228d0f6ecd084bb4b00407a308e718f8f6c44a1bc65b0"},{"Digest":"0x70db0af24c46b0458bb32f35172080da3996d848870e521961548fea6d652c68"},{"Digest":"0x04a6db5188dcbe07aadca0d0bad9fa1715170fcef5a2ef1338055d092a30ae4c"},{"Digest":"0x49363d2a87ea8e825721c76b83b4f61b9fa5a437e91ce5c8dd0bb6bf11e7f1b7"},{"Branch":[{"Digest":"0x6f6d69fb2d68135b5ebb7b860fe9f1feea9b019a4395a8a8ad68c91f49f55ab5"},{"Digest":"0x32aabe5aa1bf8f88e391c540716064703a32bf90ee12ab8ce19af0da535d97d0"},{"Digest":"0x88130e6326f4f132ba71c5cc13cc56fe15758fe64b6bf39f096e286cdc231f5c"},{"Digest":"0xfce56c70bf134c1f93bbce177197f35d788227e0c0bbcd7c3c9d5a7cfbb1bcfb"},{"Digest":"0xaf296383d0361b96d3fba4947bda01b88525f35e07d5fe39d9d92e49f5c28237"},{"Digest":"0x4e1dbbc2fb7141c60c6780e027299818036c33392a9e9fe9b752021524641a93"},{"Digest":"0x488c3ea67626988d85f3cc0e35b55198e506954f7167ac248a36441f2cd07210"},{"Digest":"0xbff83b63f63ff94b661fb0a7c3cce98b8407f55097a90e1af5351b21f649d32c"},{"Digest":"0xa3a5c6092d7fbef03e66035b326013d54ac4c1c24e6f20b66131fc594373a2bf"},{"Digest":"0xe312443ec3a904fe56b03ac4ff12986946bb93f0dc5209fca60b22510ebca148"},{"Digest":"0xed34ca35abf8b9c0a849c6a9f8141b4b6404b661c68c3a36d4c04fb1a9ee4404"},{"Digest":"0xed4974e0942b8c2c4c0cb67f6ff8b3acf392fb5f87750a22311117c34061a49d"},{"Digest":"0x92a75579e3d7e435206711bfa34bce20989a7cd31c68f9f03484ac46271859df"},{"Digest":"0x982da97762a67163d6f03c9cd0fddd75c54415859f50e8bc4291ec74d316c315"},{"Digest":"0x1ab003882db00b52c3298b9f8e5377e64facdbd98d8a31376d7f4b4f7014e11b"},{"Branch":[null,null,null,{"Leaf":[[0,1,5,10,14,1,12,11,1,11,1,13,3,4,4,1,15,10,9,15,8,14,12,11,15,0,10,15,6,3,5,3,13,0,14,14,7,5,4,2,2,10,3,2,6,14,8,15,14,0,13,8,14,2,15,2,15,10,8],[132,1,236,139,132]]},null,null,null,null,{"Digest":"0xf0ec532af391e6dc77f2c9867afce87e39293059a5f8ddf2b21b38d8e4dd23b6"},null,null,null,null,null,{"Digest":"0xb92295774b00d67bfc53715b07b142a21c554b7f1cce914aefc2157459fc289c"},null]}]},{"Digest":"0x63c5d95b2841f2922a349e5c6b4479b62da76ee9f6c279d08d928e203710f3ec"},{"Digest":"0x30705db3c781f5e196f488ebd318ea63f734113008afcdefdf34d0d15e03c21f"}]},{"Digest":"0x87f9fcf8c604513f50a86e23f2f0989f9b96f1d3d99540a8b315a7806d07227c"},{"Digest":"0x812b731dc4f77aee3f5101bfe40193bfcca7e9cb97980098bafaa0d12bd39d16"},{"Digest":"0x9b126e01a082b7bf24e2b890f98426d5dd83193a3aae6403f2ea928f77325344"},{"Digest":"0xe493867ed492e0a552747a07c854a0e0b846b6bd62834f0d4996a42bc2e1979a"},{"Digest":"0xfcb0c15e4a3cc13df884a0b396d87a319ecf195db3d4bde4f02d1dee8210a05e"},{"Digest":"0xff8b139d44ca658e3276f749ec76164c9a07ed0e4008410bda1b2a970943a403"},{"Digest":"0x7175912619273587915d3028208d14edfc0ec4804e6ca7b8058a38af41e6ef34"},{"Digest":"0x44a96fe6833a33f89313f2b69a636c0e6040078648792f1641b125ab6ae5c2a0"},{"Digest":"0x7a55c044ebe65b274f72bd33156fa094af3126961448eb6f9657afa235528477"},{"Digest":"0x2c0dfb78537469b8908a3d3118d1079ab512af5050b2c012f72200cc99b17dfc"},{"Digest":"0xee2e5b3ea0d5856748c261b9b3d50eadf498a221cce69dde2189a806f80f0b4e"},{"Digest":"0x3c020e102cc457f636414b9999a1969ce4a92be8474a47a1320aa9ac66bc765f"},{"Digest":"0x6b61ba6119eb34dfa15b0d56e510b099067d9ea3f1c50b169db280ce8abf73ae"},{"Digest":"0xf02f56d6e0034aa24fdcecfcab208ec41317dbe79659487748d378e994a954ff"},{"Digest":"0xb9117371edb3edbdf7bcfd78a8dd35ef477651fd894b0abb1839c83f88571887"}]}]}],"contracts":["0x608060405234801561001057600080fd5b50600436106101775760003560e01c8063715018a6116100d8578063a0712d681161008c578063d505accf11610066578063d505accf14610383578063dd62ed3e14610396578063f2fde38b146103dc57600080fd5b8063a0712d681461034a578063a457c2d71461035d578063a9059cbb1461037057600080fd5b80637ecebe00116100bd5780637ecebe00146102c95780638da5cb5b146102ff57806395d89b411461034257600080fd5b8063715018a614610283578063781603761461028d57600080fd5b8063313ce5671161012f5780633950935111610114578063395093511461022757806340c10f191461023a57806370a082311461024d57600080fd5b8063313ce567146102095780633644e5151461021e57600080fd5b806318160ddd1161016057806318160ddd146101bd57806323b872dd146101cf57806330adf81f146101e257600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b6101846103ef565b604051610191919061129c565b60405180910390f35b6101ad6101a83660046112da565b610481565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101ad6101dd366004611304565b610498565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60055460405160ff9091168152602001610191565b6101c160075481565b6101ad6102353660046112da565b61050e565b6101ad6102483660046112da565b610551565b6101c161025b366004611340565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61028b6105ea565b005b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b6101c16102d7366004611340565b73ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205490565b600554610100900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101846106e5565b6101ad61035836600461135b565b6106f4565b6101ad61036b3660046112da565b610791565b6101ad61037e3660046112da565b6107ed565b61028b610391366004611374565b6107fa565b6101c16103a43660046113e7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b61028b6103ea366004611340565b610b1b565b6060600380546103fe9061141a565b80601f016020809104026020016040519081016040528092919081815260200182805461042a9061141a565b80156104775780601f1061044c57610100808354040283529160200191610477565b820191906000526020600020905b81548152906001019060200180831161045a57829003601f168201915b5050505050905090565b600061048e338484610cdd565b5060015b92915050565b60006104a5848484610e91565b61050484336104ff856040518060600160405280602881526020016114d46028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020908152604080832033845290915290205491906110bb565b610cdd565b5060019392505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161048e9185906104ff9086611102565b60055460009073ffffffffffffffffffffffffffffffffffffffff6101009091041633146105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61048e8383611112565b60055473ffffffffffffffffffffffffffffffffffffffff610100909104163314610671576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b600554604051600091610100900473ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff169055565b6060600480546103fe9061141a565b60055460009073ffffffffffffffffffffffffffffffffffffffff61010090910416331461077e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b6107883383611112565b5060015b919050565b600061048e33846104ff856040518060600160405280602581526020016114fc6025913933600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d16845290915290205491906110bb565b600061048e338484610e91565b73ffffffffffffffffffffffffffffffffffffffff8716610877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f494e56414c49445f4f574e45520000000000000000000000000000000000000060448201526064016105d7565b834211156108e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f494e56414c49445f45585049524154494f4e000000000000000000000000000060448201526064016105d7565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526006602090815260408083205460075482517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958c166060860152608085018b905260a0850181905260c08086018b90528251808703909101815260e08601909252815191909201207f19010000000000000000000000000000000000000000000000000000000000006101008501526101028401949094526101228301939093529061014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000845290830180835281905260ff8816918301919091526060820186905260808201859052915060019060a0016020604051602081039080840390855afa158015610a36573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614610ad4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f5349474e415455524500000000000000000000000000000060448201526064016105d7565b610adf82600161146e565b73ffffffffffffffffffffffffffffffffffffffff8a16600090815260066020526040902055610b10898989610cdd565b505050505050505050565b60055473ffffffffffffffffffffffffffffffffffffffff610100909104163314610ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b73ffffffffffffffffffffffffffffffffffffffff8116610c45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105d7565b60055460405173ffffffffffffffffffffffffffffffffffffffff80841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36005805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff8316610d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff8216610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610f34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff8216610fd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105d7565b611021816040518060600160405280602681526020016114ae6026913973ffffffffffffffffffffffffffffffffffffffff861660009081526020819052604090205491906110bb565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220939093559084168152205461105d9082611102565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152602081815260409182902094909455518481529092918616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610e84565b81830381848211156110fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d7919061129c565b509392505050565b8082018281101561049257600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661118f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105d7565b60025461119c9082611102565b60025573ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020546111cf9082611102565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000815180845260005b818110156112575760208185018101518683018201520161123b565b81811115611269576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006112af6020830184611231565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461078c57600080fd5b600080604083850312156112ed57600080fd5b6112f6836112b6565b946020939093013593505050565b60008060006060848603121561131957600080fd5b611322846112b6565b9250611330602085016112b6565b9150604084013590509250925092565b60006020828403121561135257600080fd5b6112af826112b6565b60006020828403121561136d57600080fd5b5035919050565b600080600080600080600060e0888a03121561138f57600080fd5b611398886112b6565b96506113a6602089016112b6565b95506040880135945060608801359350608088013560ff811681146113ca57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156113fa57600080fd5b611403836112b6565b9150611411602084016112b6565b90509250929050565b600181811c9082168061142e57607f821691505b60208210811415611468577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082198211156114a8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220eabef41c79e988bbef5573106f3825656f6522b0a2771b005adfc744729606a364736f6c634300080a0033"],"ancestors":[],"receipts_trie":{"Digest":"0x69d2a7a1350fd9162484e14ca98016a5007d42ab6428bff8c87b15c88f77ac43"}},"commit":{"proof":["0x8f4308bc7c5e29f9164f51a51598cba1e6657e7750b7652c7acd30af5835ef1b","0xe975544167d18e47f969035178ec88e65e13b51eb7081c8d9ccd6e79add2df8b","0xfaf5e1f649c337a52c0902a23a2ac788788f857004a6058c624df264701675a8","0x02a221be610b9c4cccd3a3db952e2a0809c19378b38d0a4781af0930bd3aabca","0xa473a845e47c17961e28b6f6726a7846cd9256d5245a11d87f573f313a8b4f55","0xa4da631579493d7e16b6141d1c2a591f4f8a8b968834f7ea75cbb9137302707c","0xd4414df572b5f620fe57c3610610cb52c484815810c9ce16e17847ffb6adbfd3","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0x8fe2897e1af0ed9c7c8f2377a63a01e7bb6ca9ba76864da06d78ffbb8c271ea5","0x0000000000000000000000000000000000000000000000000000000000000000","0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0x629e964d702f65873a7a7c9d34f6fefdce7e9957d4e82e599ee89f4ec56f68a1"],"timestamp":1737478500}}} \ No newline at end of file diff --git a/crates/steel/testdata/history_input.json b/crates/steel/testdata/history_input.json index f67c0b36..2b07bfab 100644 --- a/crates/steel/testdata/history_input.json +++ b/crates/steel/testdata/history_input.json @@ -1 +1 @@ -{"History":{"input":{"header":"0xf9024aa0491a8e4b6c32ca880f1981fe728531b49e37acf68a8b22db09bcfa5688019a53a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347943826539cbd8d68dcf119e80b994557b4278cec9fa0f052cc61516fc42df094ae001bdfeb49da15806eaedeb5cec40758b322e0949aa08a3e75ca6f59879c2e2ec247a65cbb3ee361d84cefb83cb6bfc93ba3acfb8037a08c77953e9aa2af2a71fe348a17c2f34be7f0aa43fb8f269af1f055b9fc5c13b1b90100073cb054002c494801501812ae4820690091e2c91307121cb9001d1304c9c42220a2800047003990aa2a24e04c840b98349b213489105603821691c41666220a0568108801664812500e405a403ce22845448286a2068100444ac52194209ade1a0b504caa033e618f67e0c9d1205ea1080832e4208d0a180aa4aa181b619003421460101bb577686411086ae224025e80800625b4540ec0641119021605240217d84850b5087005591100c4b0a0301f11c2e0a32bd2152f41cc710701010ec110c6176b2481021237a33335aa8686b270efc90a014428062122d060844bf2402411644c430ba2e04862f35161709270c003007c0c001c8011400b01399a442a80836a93d98401c9c38083cc1b7a846723b8e080a0e78b0a3b2b8bc37ccb2fea042ea746de85e6ade32704b8e21aa8013f13c44a9788000000000000000084e64ab958a0346bbd06db5fe73280b79e976951700623d9be2fcf504c4da0d1c4654599192283080000830e0000a0dd6d380401093a7b7e1c1f5dbbea5a760fdfaab81f1d535d8faa9814c310b014","state_trie":{"Branch":[{"Digest":"0xb9eb6bc27e9be75ae7ef5c83f91aa89fe3ce24cb0331459ab5b719a4d488177d"},{"Digest":"0x122b15d66fd44300f45f250e08b62e116cef6f7d2b8fc77507cf5d6776d11824"},{"Branch":[{"Digest":"0xe5577c4afdec97c06588612657dc3ef45fd3c5ed3d8d4ace7d18b9a4c7cc7390"},{"Digest":"0x909c6b52f20546de0a2d497b88b0ad430cf299f288defb899b2690c920a0ff84"},{"Digest":"0x95b5e9df3706c11314d114a54ab058c71233ff9bb3faae71d7280896748ed1ec"},{"Digest":"0x0f662aa744e75897ec659e8fe418e83c73d1363814a3227da67e73f78ec76bb0"},{"Branch":[{"Digest":"0xd2fc19923d4acb1c55e1a05275ad0994a19ffaf8ec8b3a370ba14c8b1854ee26"},{"Digest":"0xa582cc3f062e91099143136b56fd0d2d76c084fdbc5f8b96e3d384ef2b149866"},{"Digest":"0x35740eec67b6efb2eb8bd78356df96fbe9e30a627ff3ccc2304186b4e0f202de"},{"Digest":"0x033e0ed9cf57bdd1ba657d8846a305bffaf660399fdb73ec9df767f6154e1cdc"},{"Digest":"0x9fd0b30bd848c26ce3c4a7f0e082063a47d13b313aeb976a0aec583120e8912b"},{"Digest":"0x1ec82eb4a8bfa5d1bea31a1d56caa6620165d942014c7cf4268bed60a43e0708"},{"Digest":"0x298d8c676fd7e77e1094774d2f5d90cd6bdf60f2b10644d3ddcef84b6b5a4f61"},{"Digest":"0x544ed2d5ed01c38dcc04ca4394c85c63de10137693ee6cc83a663880988ff7bb"},{"Digest":"0x30967e357ff32e33ffe3b8a705567fdb174c1612650b5eef777f4dc00827d250"},{"Digest":"0xf0fc61df701682c933d89adf374aca00b6d68a8a88e283c723703fe3669ea89f"},{"Digest":"0x7aea28fa83ab44fb60a2597a4400687357b78fad8f94e1bd3a27efbeef8d23eb"},{"Digest":"0x39543834f4c52b175af7d0797be998494b2e168aa94ae2ece7b6b1302bc2f3ee"},{"Digest":"0xf8a9a46524861464c4754a8e7da6267131a6aeb10c54f78c474ee5e156cde93f"},{"Digest":"0x7aa3de4ceb27e7cdff7c6b3d57c22232a3cef21eec1f1359ac5f0104a84d0230"},{"Digest":"0x157815c892e95e22bd16acb7fef6ecb2624e8d7f8f84513efbfb0eb12ef6d686"},{"Branch":[{"Digest":"0x4bdd900c5a3b476696b49026efda1b81dd35b0f6d423da8dd98aa5cb68641e86"},{"Digest":"0x01050ae4f6c869e5efe67c5d10c97af9504790876c2b690cab56d6e1b92e1f11"},{"Digest":"0xc256e655375e593956e51eb57355071288f044e8512bf31b8b678a019c89e6a9"},{"Digest":"0xeb7bece1ab3d9dabd26331fd68383521972e290614b76982a9bc140aa0215670"},{"Digest":"0xa22ae665fd022267222c7e3bcaae86c679a3767a2bcea4af00c974d0d83944fa"},{"Digest":"0xf2953eb078d07d986c15ac8df4ac2b8b80a8855336bc69069829185b4f42bab5"},{"Digest":"0x038bcaa36f8cbdfc9b0ee28a32fc8e3086aa3fe403730e06107266afedf7cf21"},{"Digest":"0x07258a418378444fe69599ef0a2ad6a23ce098134ba5132e727bbb2ecd4a306b"},{"Digest":"0xd46eed6156f3c251acb2bdf5ab512792632a72b54f71f26814b7dafea8afd4ac"},{"Digest":"0xdb673b96fccb158d8b591fe58370278a57323b0a39e0d32792128fc4406c3495"},{"Branch":[{"Branch":[{"Digest":"0xdb28048328251e31b2d3328dc517f370e4661cf8ce1d5fa345faa9f51ce94f9d"},{"Digest":"0x35292568f46d6bb85536804d457243974a5ef9557fd02fdd9c414150039dd570"},{"Digest":"0x547adead9dca2a0a5a68a59b0a9e15e76e03c267aa1bade08bb046f2bd4eb073"},{"Digest":"0x27d35383b43d2bd596638fd20e8dd09a6ab63c96f90ec11c6a5249bb4f4dc2eb"},{"Digest":"0x406a49a5b08edc39727921ccee69f2d8585f1658b581cc21f65349a13be8b129"},{"Digest":"0x8e3c6433db2e2b9bb76200119bf51313cb82d97200d633f988c2222980901f9a"},{"Digest":"0x1e379c0cbf9b976f7917e8dd9cd6e59314a75cff480f6a476984321794bde9d0"},{"Digest":"0x3432854290ecfba5f449eeef9f941897a935694aad97592e7b7d9d681437620f"},{"Digest":"0x644f86d76acd1f8bb5a55119608f0fa73493b2694ef0950f1a5f673e8a7e6753"},{"Digest":"0xdab646f81ca96e9244d88db3c49b36a2e1a4085a255ac571714718e1dc2505e3"},{"Digest":"0x2cf4721a99a7be43a6ed31637c001960276b54518ee3541e349aa47776752196"},{"Branch":[{"Digest":"0x8b92b40f358d29115172a38e36adc284772b7c2440b55e199e31f6d79dc52ab5"},null,null,{"Digest":"0x32e92fce0570631395ec05c62413a521ed320db25bd4a95992ccfc47c4c74a39"},null,null,{"Digest":"0xac2a299a9f99e6f0b275d38efb601ee9d1d95199b9441d46058781dd915fafe4"},null,null,null,null,{"Leaf":[[6,12,6,8,5,3,5,0,5,7,9,13,11,0,5,7,3,3,4,7,14,6,12,10,13,2,1,6,0,15,6,12,15,15,13,1,5,10,1,4,13,15,10,14,15,11,4,11,3,15,1,8,10,14,13,11,0],[248,68,1,128,160,55,119,210,214,23,29,113,66,69,233,211,98,33,29,66,5,253,147,205,185,205,52,134,172,121,35,121,39,88,103,84,66,160,173,162,122,66,135,249,23,26,77,35,164,213,151,124,154,88,61,113,137,6,246,170,45,109,127,36,115,156,57,115,6,242]]},null,null,null,null]},{"Digest":"0x6fee6a0286c5da4191cee1b6a07739758f8c96f1539a98e30627fabbe0466990"},{"Digest":"0xd6a2b5a75d24772a9e6c35cdccc8f51ac75818870ab706fef68c0e53b4aa5e40"},{"Digest":"0x2d6bae5f11cf0d8c8aa8858af8caa1a125595e8112eca81d2ca618d2d4758ec3"},{"Digest":"0x96066747f61459591574c48f97d9af2793f04d8258fe6eb7f4c1260cb2a9ed8a"}]},{"Digest":"0x1174368832cfe2745e54f285c86b1119c11c559616c7f3bf596d0de95583d625"},{"Digest":"0xafac905211b114f21670e002795d86542bd89851a38a5aabd7face23feecf318"},{"Digest":"0x87a5500f05089dbb19555530392080bb87c1635f6347fd8228bab075156953d7"},{"Digest":"0xc342bfe35d50b9fd4e369d5254d2fe75ac88c1ad9c8bdc781054e633ff4fbc9f"},{"Digest":"0x9c3c5614fb6b5bc466efb83c1f19c1aa26584caef41b2dc427cad7809e50d803"},{"Digest":"0x3874fc6d4b10550aab0f91371358ee76ec55efaa7d2dbbc620b765f01579d4fd"},{"Digest":"0x407e3fc3f77b0ad77728b9904e61f6beb8b16c1b3bf9ffdf3819e7114752b400"},{"Digest":"0xf7f6b075154e902aa4b779ea1393ac5a7496dc50c4d891cc5b7fb6bc61ddfca5"},{"Digest":"0x1eb5169b1c0c7c390ab0234f4ca897e99fa9d9d3f1ba27d0b722225874012ec2"},{"Digest":"0xd2104bd8ec17f099154fb45401b7114e068613dad16ee1f74268ad286ae7cf99"},{"Digest":"0xa8ab708ebee822eb8d9d24c5aa513adfc2175a1a6a7fa37c4c1c53d1115d55d2"},{"Digest":"0x44c7b6ae50e17f372d2f1c45eb61be10974255fdef683424179439f74c37ffd4"},{"Digest":"0x14224bc64f2c3259b64740a8d0788722e9cf529da5c777a2c356c502e89cb197"},{"Digest":"0x486bcf035980035ee0766e9c912048c22f17348a75f8e1175e6b173dabfeb517"},{"Digest":"0x5ab0db3fe574366a4bea883684c1e59b150885be66597e3716599726b7cdaf11"}]},{"Digest":"0xa360e6c29d9703d67a1c96745f1ca136083ff860acc5c33d0d0373bd627397af"},{"Digest":"0x7141105547873e6dd77bcc8c534d4f9cd0334ba051ce8ac5b1adf9855c9dd0d1"},{"Digest":"0x4126f66b37bd1e9e41b3727e42a7d9632dff18792df1007169e3589dd88eebd8"},{"Digest":"0x85643aa4f51bbd9ffeeb7e5bcf899824e2de11003eddf79116eaf35fc5b02dad"},{"Digest":"0xb5582d9e6ee9bdc6e8e7dc61516753d962b968a8cee450befdd66fe38b16a9c3"}]}]},{"Digest":"0xfbe77578d2784643c935a98e0e76b07164cfe1441086bda69f18129f2dbb80e9"},{"Digest":"0xd929d61cb21a64686da075bafb58c2148d83f4a8c6605df3f7321318521e5077"},{"Digest":"0x96f487ce902b9da46ede05b0fe655d57851331e39bc3b86d16a6f6790b146bb5"},{"Digest":"0xf5caca297dad480624262421c27204d018d65812e2752b1b7a21ae3db474ce24"},{"Digest":"0x4cfe54477473d87c2d058b22e2f69671ad7069fde2147995036d9d43b44fdf5b"},{"Digest":"0xfa63e4a218072e8265d50c86ac1e8e15f85cfdc78c3f9d4542abce4a882c1b9f"},{"Digest":"0xacd6c84b75227eb5f8996b8ee9ec424214c05b0152d37365b6557b5daa5b4be4"},{"Digest":"0xee2f78d111883bf3f4b334562f1edc89eb1ff97bf2e703a8cdd82e5ea2f62927"},{"Digest":"0xfe927d3be9e01fa8d4f23aee94f2ba4e61baeb0b88790a133cdfe30dd1d335dc"},{"Digest":"0x174e9303045989a09d14613fe8982b8198c94057e72ddc5e60800d24a3dd8b61"},{"Digest":"0xd98859085fe500957d92fe03acb308a8f88f53f118114971ddc2640b00d7aaf9"}]},{"Digest":"0xd5b792d78ca0839f8e7f2899dac5c75f9ab519a0347da16133a30febaf9a0dea"},{"Digest":"0x562ff1796fc867508eea6171a32bbe96998a4e9602ddbeff2d4fae7712c9ff3e"},{"Digest":"0x8bddaf388b3711be67c919e1ecbd4d361e46e8bd96686a75b38ee950884cae4f"},{"Digest":"0x25f1e62481fcb29aa8c9cd92e9d8b0657050d853ee430997d71ccb3f967d2b87"},{"Digest":"0x2effe1de5d98a695d2413c3137753282e5b03e6cabd86a56b4bb976934e4a851"},{"Digest":"0xbc1a3dba6367b109d269e67e80d598d9085688412c0b1191aaa0c0da835c9346"},{"Digest":"0xc8d26f4e619f84508e35b37a59556b910f1e2f053c541190206d6cec3094b218"},{"Digest":"0xe3a4c9ba29aec5118948b2e8c3c9f5ac2874338767e8d544d9692efa67294505"},{"Digest":"0x140a680cbf7197078b768a43c88277a0773bb5297647b10e3e235d1b36c2f6a7"},{"Digest":"0x113c0ad3d1b55a9fa5b6311ed87783c6d375794293001d6fb2d37bfe092305a6"},{"Digest":"0x720f077732dddc5177d8835455ec32e7e95e3fc76311a24032bc4072a9166936"},{"Digest":"0x23e28179d2072ac46982112626dc8d175e5a0971f7aedf275182b0626f4c6bf6"},{"Branch":[{"Digest":"0xd5389db13b6707e293759dd4926ed657bef29be6bf94496dc3cddc615757c044"},{"Digest":"0x7a2cfafefb898e5af3cc18917f40db4bc34904c39262bf9c43348927c4a93c26"},{"Digest":"0xb1c009da8c7e4bc8fc144f29918949a60588347d14b6c300588e424b363d6849"},{"Branch":[{"Digest":"0x06148999edfa1129572921db6428c24bbb80bb349b481df56489e4df88ccb18d"},{"Digest":"0x9d43892fc42e826c9edad87f5afda8a39c46b21d466ed06b1fd4dbe766cdfd63"},{"Digest":"0x0a2213e60ac7377cea911f310f2e04385f0f4ddea6d5b0d9619fa5e53600654f"},{"Digest":"0xb293d6376a810ecc16c479b02138f58d99277bb0cb19091c9adb60ef94072112"},{"Digest":"0xe9bb8302b43f14ec37b64f3c04142f0ba2c8d99b775d06fb16d6472a189e4a3f"},{"Digest":"0xc7ec46ccb2b365d4244dd0b02831665f33fe5cc5f935db098b5134c95087f58b"},{"Digest":"0x9fe71e8c193cf3c117099e91c59f2433b58c7a66962ec486eef6fa67426eae24"},{"Digest":"0xf3263c9621871ce05c4f177ae9a3ae814408a89afec555433d1f95959c19dfc1"},{"Digest":"0x70ad2328cee395f920f028be6daf954c2e223f5b2e8a88c0772a6eafff8d863c"},{"Digest":"0x26fc243c85b4f691a943f515b399deb144eece5661432b8a5c37e985fea72456"},{"Digest":"0xc8f82440f343b4946191f184b0703b34b24d80d294a3c11c5745782c8fdb84e1"},{"Digest":"0x19888bfea50c6b46eac601e1f3052c01d33e6a4d74d20bc7f4769bf071f95470"},{"Digest":"0x06d2bdc9a9f6c0a3517101160b81b2057d9425cf587be6adce845b2c7b59b497"},{"Branch":[{"Digest":"0x007e99d702e16d559a58524e0dd4ffa277d8e727cfdc0f7db8b5c20e41bee0b5"},{"Branch":[{"Digest":"0x35297b29e9eb8f22710f977b2853583675884ce6903aa8d69bad75e2b2d5a517"},{"Digest":"0xc71da97245fe9eae6077123ffe19a139981f2b32b1c35703ff5ac2ed7378d876"},{"Digest":"0xc4e92432586b71a98106039888b7fc6249a1e296566ee1b370a9e5383a8bab52"},{"Digest":"0x879997910c9b1369efd919164b2c1b7b8d170699bd5838857d64bd09f35277ed"},{"Digest":"0x974d9532f2644dba082a42332aa597f11dc09df738830fcec234f897ebd68e8c"},{"Digest":"0x639bc32fc28ee903dffab3f2ba2dabd52f52eff038f97b1d542a8982b0fc0385"},{"Digest":"0x34fcd5eb67c9a5f66d21ea907b7827a9c6096076748990d18f45a05761b742b7"},{"Branch":[{"Digest":"0xf9118a9542f1d128a3ea818919243b993b4969ae93738a32e254eafe5a5e1742"},{"Digest":"0xd556f84ac391250d27720d14072661f8d943fc1cdbce78be910d48769330ae6f"},{"Digest":"0x8bd7ab73a9829df8ae610cf18ab6aa5568fe21016a0f7c0eef65ab9996cf99e3"},{"Digest":"0x42c86aeb9469a10198d67d7a5702726bbc5629235be487b17e44459440ab37ed"},null,{"Digest":"0xd0bc2a62270fc35fe3aee5c38933b7371e0405bb0715ee7ef911c3dc48f444bf"},{"Digest":"0x4675b36549037cd54be78c0d2dd91b5c6beaa4fcc72f8c163c7c0074e1835fd1"},{"Digest":"0x7d585f9c072a01bb9a8cc8a7d725a4ff9071cb46c48953c8335e308d2945ff31"},{"Digest":"0x5cd62269900e92bf4c6c42a9d72683f6d7e8cbe33803356551cc478cd642067c"},{"Digest":"0x4f9e17a0091b815eea4cc5fdf9dfd6ca058704f63530e0d28e62cb092ed64010"},{"Digest":"0xbe00033c985a539420fa893598b3147f39e42a4247073dbf93cc74a2f7f59fa0"},{"Digest":"0xaf88edb76994a08a8cd7dc2af816eb7d6f0e292d9d484b8e9fb35a4404bc2d4d"},null,{"Branch":[null,{"Digest":"0x4f0ec58512839950db276341d67a8c9eb6e1ca13ca7b361462a82598b5d7da8c"},null,{"Digest":"0xfd53f8be507de3d8d640472374119fdf2cf7cd38ae17d1c9129e1e98808918f5"},null,null,null,null,null,{"Digest":"0x774b99d68677f2e87c1db96cb9a1710e4d61f1eb8f5236a7bca56b27f4f5207c"},{"Branch":[null,null,null,{"Digest":"0x1a7a7a0437eccf9be686413770e9f97ca36db202a473a1fcb79556b921fca4d4"},null,null,{"Branch":[{"Digest":"0x5fcbe7eaf578e8728028d214ee002ee6f2d85b07c8d14dc5c7542e28df17851c"},null,null,null,{"Branch":[null,null,{"Digest":"0x6b1734cc6041aaf83555ad57746aa57231a35f5fe9511cc7020421dcceb85a28"},null,null,null,null,null,null,null,null,null,{"Leaf":[[1,13,9,12,15,9,1,2,11,6,3,1,4,14,3,0,15,5,3,10,3,3,6,6,12,10,0,11,15,4,4,7,0,14,9,6,7,2,7,9,4,14,10,13,7,3,3,11,3,13,2,0,10,12],[248,78,128,138,8,99,173,96,202,124,161,146,218,54,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112]]},null,null,null]},null,null,null,null,null,null,null,null,null,null,null]},null,null,null,null,null,null,null,{"Digest":"0x86fe789644cc1e46726fd722c5ed800e75bcee9d5296a8540fc46cf133016455"},null]},null,null,null,null,null]},{"Digest":"0x184a126584f25ba8e6901480825775a5e1b9355b7d291641980b9ce2e8f5619e"},{"Digest":"0xfcfd07ca8f715589f8043a8dd7f3611bf60e2c6c16cc0675692bed6cd331924e"}]},{"Digest":"0xcb313fc9bb03bba57f9dee2abae1cf76a33699a8e93fc8e898d9fbf6d376fb94"},{"Digest":"0x4def0b21e64c75bc6a2accd215bc7119cc92db4d7ac5949a448bd289151be135"},{"Digest":"0x7486d2cf544cf2463a7a1ab2146f65962f29fd147b65158fe601275934d288ce"},{"Digest":"0x45e82d42d1e8fb132b04b30cd1e719a863d3a3bbc846673bf60a81d0aab53c21"},{"Digest":"0x9ad7a703df2d0ad2e4850d4862d38a3e13254dc3018ca687ee03d75c6d355c16"},{"Digest":"0x93aaf5788647b010b42ed5a299a9ff0769e490297fab6cd2eecae21241c26928"},{"Digest":"0x22cae78dfb10c4ca5f15b187bd31f474f1d88ee5b1619786ddc11d1fe831cd40"},{"Digest":"0xcd558349542b0921c74f8eea77039ddc54afe2ac299b846798eab9f3781be7d5"}]},{"Digest":"0xba72a0b0cdc19492a34d76f1ab6c2e4b40e91ec32b321b8926a4d4723b8f746e"},{"Digest":"0x1eccb2c7c8085bfd994226d2cfce9c3d4c9c4f36f43672bbb18c1df6313497e3"},{"Digest":"0x786a74e68ce1fdf38e1adef35dbb83e41ab190824f8dd1f10e07e70e00c28c43"},{"Digest":"0xbb866c871fed7600b0a130ac214d671ac71dea6fd40de0ff76f9674d51c4c7d9"},{"Digest":"0xa94204524b25ca5152bba13aca8b7591ca1fca2fca80c68192d5d7c1fcaab732"},{"Digest":"0xf2b015b28f74c3739b8d5512fbc569b2720ef23c16416daf75aa97a5f45f7155"},{"Digest":"0x01427d40dd8165d0abb4a828fb6fabf38ff22876816a8c01c0751eb690a27687"},{"Digest":"0xf059c99ebccf0273bfd20567b7fcfb4386dfbf8f7e97330da5d039a6961c686a"},{"Digest":"0x6f7076ae4295ae5e75af2260b3a5036fedbda005c5597aaf08ac6dc70fcffd4b"},{"Digest":"0x97dd7de9f6187b966793b1a8bbae1d1a02b7169963479d84110249d77b2035f4"},{"Digest":"0x8b48afcaa9b69cfd83e1abeba3f335136ae361f88cb8d089ed3fbf7a7ac785c2"},{"Digest":"0x02b5647116852ff9d1b1b7aec8bbadda64c40daf5c10144f83e69a1d305a62b9"},{"Digest":"0x74727c4e34a63ceaa9004d8f1a9355554141077fbb3133bedab9e865e7b62b48"},{"Digest":"0x8269d16e063f071703ece86b56b8525859938066fbec85e0d95f046212f91581"}]},{"Digest":"0x880026695c23d2aaf906cc6671b602254b006e16e42e0f99dbf355383b5f4ed5"},{"Digest":"0x9ff2c16dd18594455dd137f059eb7054e2a4b72445151d4b690f4eed305c0cce"}]},{"Digest":"0x0cd0141cec5c9c755e86a713abd57b494aab0b9c5e45be2ce3c62666868aed03"},{"Digest":"0x15bc22df4217a41431d344efccb3fe949af903cc95041e9fdeeb7c32eb8fec2a"},{"Digest":"0x7fb7a8168da1055d312e5e142483f40d7f9febb273a404ac6d63acd0451c2504"},{"Digest":"0xa75c191f6901e4abb1691053684fecb6928c054ba5495881313988a57f47083d"},{"Digest":"0x56ca9159aeec8dc2073a71b48d9211b502bbc0b12d4e3470895409d33ad93fc3"},{"Digest":"0x5821e55b8effb53df1d8733b92e5f13d58ef30c9f0733b6f19d25cd0ceba4a86"},{"Digest":"0xc8ce07470ded1fd0bdd0037a83d640653ee8ccc650f88c9bb3f13da75885d7f4"},{"Digest":"0x5d03d3f4850b559b25d0f748889541da3f8f0578e522a14a9b73786d0f25c6f4"},{"Digest":"0x237958238cda88fa7dbc11b23a93256abdbeaafe7b045f59289d3086c7b99c8f"},{"Digest":"0x310ceffdffc608f6d83f5be7848d900c636417bb48a175d28cee43f79d392966"},{"Digest":"0xbe15d411715cc18a423940babd7c2bba23b4dfaf607cfa9d94c9f0cecc85a53a"},{"Digest":"0xab5518cc2378ce874454ee1e1e75a09fa87ea369c85c44139f4302d07364b5b4"}]}]},"storage_tries":[{"Branch":[{"Digest":"0xcf5273a8819f6054dbcfe1e1bda94f9b329dffe07a79e246878a3a36007a5355"},{"Digest":"0x8e48104611ab66c172df6eaa4ea4e9fdc07497dd8f99af3ea4f45168b1721bce"},{"Digest":"0x5a62c465029febebced0fdea3c58fdd2801833d3dd3a96d6a93ca5fd1fc8e41f"},{"Digest":"0xb7a06fc90c86931b2fb97bcc755fde073ac366de2a77991cce83734a464bf385"},{"Digest":"0x7f8019aee7417d6d39d667e16d90967c14402fae1edb8b1632ae447bd5c31bc6"},{"Digest":"0x56b29dde63bed37060d39efaf69086a1b16366ade7bb9bce11e86b51c952d8d1"},{"Digest":"0x7bc6e493faf774718e00523a4b3a324daad3e720cc26a27c29a0ae20cca8408f"},{"Digest":"0x410fc008b9e51a5ac93971e596750e552ce82c2c82c1da6cd99debe9d5f5db9b"},{"Digest":"0xa76f915dccdbfd50d1dfccef64ad48a33b7e586e48d78f2995a23b764a040bf4"},{"Digest":"0xc0ec7524760d0278456192417268e9076bba9af13bd9c33d4197c557eb61612f"},{"Digest":"0xb83779e21a5cbd0a091e66fcf566b5e80b3568d43ff4492fedeed7e79e77d955"},{"Digest":"0x417e35150aad5e9f79ac5dbfd2838b591036c64f93c5ed6b2678d045341af118"},{"Digest":"0x28594fef17aa92c23917f2b9521cbc3ed86a8cfa74f48551c53b66fa9cf3e514"},{"Digest":"0x1c3949184b4eb7a907d7de8fbd2922705c2ee1823194360775842f1082da2bc5"},{"Digest":"0x129d3756c795579bdebbad3765133174bf6649af7a145470e08ee900212293e5"},{"Branch":[{"Branch":[{"Digest":"0x4c58105fc8457182b131725d845a5a48cafd91be8836cf6ac1e8d3d57f0864aa"},{"Digest":"0xb55d81a3ff4a4f592505e46cfebe2adcc6334e193f980f825b7be532dd4df98e"},{"Digest":"0x9f6e88da060cc77d253ef86ca2ea67ff300bf7d1c305d5a01e64f0c4b25c8fe3"},{"Digest":"0xa2237cdd95ec6d1a90b6f91c0ea7a1863d4889bfa6606afcc8ba49cdb9258956"},{"Digest":"0xe4ac59d7ea6fdd6e010b6248543907fd4003f314a9ae9a1c7a120661ac5ab299"},{"Digest":"0x9d84dd486094861f402aec672b68d1f0c9adc4da87e8d90584c0e81202ee95b8"},{"Digest":"0xe74c34ae4702168f184a098262ee4a4e83154a80bd7f6b7fa5e292d1736492c2"},{"Digest":"0x54ffeeb826908f18d2cab6f3de0b3337ca139c5b4c9ff1e1d9669f2f0672e084"},{"Digest":"0xecb6a637f8fe1e4e4cd6f902880f0246d73377c0329ba5ebc5955dbab1cbec40"},{"Digest":"0x0ba913221250d4227ef17c7e9fca95bfe43a200e121af635743563c4a055ed3b"},{"Digest":"0x0001f7a60b244d646976243e803758cf60a171521c1bd7fb5ca5721325851ecf"},{"Digest":"0x1eb9ce182cd5f727ae49e12320694ed298524cfd3c9f68e022b6eb85fee507d3"},{"Digest":"0xbd27be38afc6693f2fc0cd4c79b5f210a46093a4514f047687acaf594194d256"},{"Branch":[{"Digest":"0x957c5ebf39508dce06b519f3357407ce9b0c7e325a5b5baf20356802119e2a1d"},{"Digest":"0x32aabe5aa1bf8f88e391c540716064703a32bf90ee12ab8ce19af0da535d97d0"},{"Digest":"0xfe878f6d7851d2c4a89a747005f6ec12211eea53845502d577358c38d99b0540"},{"Digest":"0xba01139006d0b39ceae595d8736eeb0614536ec331df968bb7a87726d663619e"},{"Digest":"0xd835f0fb96ed233d45a950b9374600896dce6e9f9e9f415e16f56d58db6328ea"},{"Digest":"0x4e1dbbc2fb7141c60c6780e027299818036c33392a9e9fe9b752021524641a93"},{"Digest":"0x488c3ea67626988d85f3cc0e35b55198e506954f7167ac248a36441f2cd07210"},{"Digest":"0xbff83b63f63ff94b661fb0a7c3cce98b8407f55097a90e1af5351b21f649d32c"},{"Digest":"0xe0e716a063b31091e183787523f5532b2dc7ab69a1dd66cc90cfb116ad477d20"},{"Digest":"0xfe7d2af4a9f50363f9fc87756d737bd5ea2ce08079a592af54285923e44cbedd"},{"Digest":"0x9ead3ec1fa3cdcb9ba24c15460cb775117cff93e3301abfdb8afc0444bf43b89"},{"Digest":"0xed4974e0942b8c2c4c0cb67f6ff8b3acf392fb5f87750a22311117c34061a49d"},{"Digest":"0xf378325092077ca4bc0614e44fa83e756ab569606d98660d6adb51141e84c481"},{"Digest":"0x982da97762a67163d6f03c9cd0fddd75c54415859f50e8bc4291ec74d316c315"},{"Digest":"0x1ab003882db00b52c3298b9f8e5377e64facdbd98d8a31376d7f4b4f7014e11b"},{"Branch":[null,null,null,null,null,null,null,null,{"Digest":"0xf0ec532af391e6dc77f2c9867afce87e39293059a5f8ddf2b21b38d8e4dd23b6"},null,null,null,null,null,{"Digest":"0xb92295774b00d67bfc53715b07b142a21c554b7f1cce914aefc2157459fc289c"},null]}]},{"Digest":"0xf791fb03c7d02089e1b96a1d61ff74eb78ec09c376e1e8a82d52b73863ea5c8a"},{"Digest":"0xb0e10a40cc4269fa583af8d346c7a469ea8515bc92f40f47c4f7aff4433595f6"}]},{"Digest":"0xe9b51f14dcae5c60af61fe316e9f8fa624a0f78d1570e314163c99e32296fd70"},{"Digest":"0xacdc7b30958fa5e4534e1b58f26e74e3956318b1f487d447e46eb31e843d5da4"},{"Digest":"0x9db9b5cc39a6c5f9ad8cc04fa16a12516eec63fc37d36f75207a05bb1ea70cb6"},{"Digest":"0xc270ccf8208dbfb8e3c8fa0c27f5ef3a202e0af34d49484b0dd050c0b90470da"},{"Digest":"0x09ae7d7f2a79c856da90c7be1a21f9f4448b919a5f2f92e3cb6a607c810e5eee"},{"Digest":"0xacd0e9566dc3d8c75d084895dbd8f963ea1f38cb2a997b701bb96f2f381797eb"},{"Digest":"0x293228b20605b1c1be287c5dce11bb7c3b72d39d6b636529edaaba145c5be302"},{"Digest":"0x791706438954dbafe4680eb8ecfa96b795383a1c7a88e16d669d621426a8a8f5"},{"Digest":"0x1b057dce8c103d91a90b3bdfe1ae45bfb695b3c7ebb5f2d8a3da677b02a57377"},{"Digest":"0x54fe97cada63137842922520fe5421106c02376bb2c739858e5113328b669931"},{"Digest":"0x852393d2282385fc4d55e903263b4538467fac9d41609940641d93a157ffb149"},{"Digest":"0x595cd46e00be98fc4a13b93b214fad2acf164257d030dc71710e03efa49127f1"},{"Digest":"0x358972639b4991c1d711ef23d1faea75ea95face5f8dcb072657becf339993bb"},{"Digest":"0x53472a9ebb8b8ab9ba1ab55dc7f90ad65604bef2c18d8eab402ceb46ddc2fa80"},{"Digest":"0xcd469e1ec65f0f654e883a71126169b90e5f59ab76d92332dd77c4deb5a1d575"}]}]}],"contracts":["0x608060405234801561001057600080fd5b50600436106101775760003560e01c8063715018a6116100d8578063a0712d681161008c578063d505accf11610066578063d505accf14610383578063dd62ed3e14610396578063f2fde38b146103dc57600080fd5b8063a0712d681461034a578063a457c2d71461035d578063a9059cbb1461037057600080fd5b80637ecebe00116100bd5780637ecebe00146102c95780638da5cb5b146102ff57806395d89b411461034257600080fd5b8063715018a614610283578063781603761461028d57600080fd5b8063313ce5671161012f5780633950935111610114578063395093511461022757806340c10f191461023a57806370a082311461024d57600080fd5b8063313ce567146102095780633644e5151461021e57600080fd5b806318160ddd1161016057806318160ddd146101bd57806323b872dd146101cf57806330adf81f146101e257600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b6101846103ef565b604051610191919061129c565b60405180910390f35b6101ad6101a83660046112da565b610481565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101ad6101dd366004611304565b610498565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60055460405160ff9091168152602001610191565b6101c160075481565b6101ad6102353660046112da565b61050e565b6101ad6102483660046112da565b610551565b6101c161025b366004611340565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61028b6105ea565b005b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b6101c16102d7366004611340565b73ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205490565b600554610100900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101846106e5565b6101ad61035836600461135b565b6106f4565b6101ad61036b3660046112da565b610791565b6101ad61037e3660046112da565b6107ed565b61028b610391366004611374565b6107fa565b6101c16103a43660046113e7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b61028b6103ea366004611340565b610b1b565b6060600380546103fe9061141a565b80601f016020809104026020016040519081016040528092919081815260200182805461042a9061141a565b80156104775780601f1061044c57610100808354040283529160200191610477565b820191906000526020600020905b81548152906001019060200180831161045a57829003601f168201915b5050505050905090565b600061048e338484610cdd565b5060015b92915050565b60006104a5848484610e91565b61050484336104ff856040518060600160405280602881526020016114d46028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020908152604080832033845290915290205491906110bb565b610cdd565b5060019392505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161048e9185906104ff9086611102565b60055460009073ffffffffffffffffffffffffffffffffffffffff6101009091041633146105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61048e8383611112565b60055473ffffffffffffffffffffffffffffffffffffffff610100909104163314610671576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b600554604051600091610100900473ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff169055565b6060600480546103fe9061141a565b60055460009073ffffffffffffffffffffffffffffffffffffffff61010090910416331461077e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b6107883383611112565b5060015b919050565b600061048e33846104ff856040518060600160405280602581526020016114fc6025913933600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d16845290915290205491906110bb565b600061048e338484610e91565b73ffffffffffffffffffffffffffffffffffffffff8716610877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f494e56414c49445f4f574e45520000000000000000000000000000000000000060448201526064016105d7565b834211156108e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f494e56414c49445f45585049524154494f4e000000000000000000000000000060448201526064016105d7565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526006602090815260408083205460075482517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958c166060860152608085018b905260a0850181905260c08086018b90528251808703909101815260e08601909252815191909201207f19010000000000000000000000000000000000000000000000000000000000006101008501526101028401949094526101228301939093529061014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000845290830180835281905260ff8816918301919091526060820186905260808201859052915060019060a0016020604051602081039080840390855afa158015610a36573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614610ad4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f5349474e415455524500000000000000000000000000000060448201526064016105d7565b610adf82600161146e565b73ffffffffffffffffffffffffffffffffffffffff8a16600090815260066020526040902055610b10898989610cdd565b505050505050505050565b60055473ffffffffffffffffffffffffffffffffffffffff610100909104163314610ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b73ffffffffffffffffffffffffffffffffffffffff8116610c45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105d7565b60055460405173ffffffffffffffffffffffffffffffffffffffff80841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36005805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff8316610d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff8216610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610f34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff8216610fd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105d7565b611021816040518060600160405280602681526020016114ae6026913973ffffffffffffffffffffffffffffffffffffffff861660009081526020819052604090205491906110bb565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220939093559084168152205461105d9082611102565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152602081815260409182902094909455518481529092918616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610e84565b81830381848211156110fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d7919061129c565b509392505050565b8082018281101561049257600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661118f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105d7565b60025461119c9082611102565b60025573ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020546111cf9082611102565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000815180845260005b818110156112575760208185018101518683018201520161123b565b81811115611269576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006112af6020830184611231565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461078c57600080fd5b600080604083850312156112ed57600080fd5b6112f6836112b6565b946020939093013593505050565b60008060006060848603121561131957600080fd5b611322846112b6565b9250611330602085016112b6565b9150604084013590509250925092565b60006020828403121561135257600080fd5b6112af826112b6565b60006020828403121561136d57600080fd5b5035919050565b600080600080600080600060e0888a03121561138f57600080fd5b611398886112b6565b96506113a6602089016112b6565b95506040880135945060608801359350608088013560ff811681146113ca57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156113fa57600080fd5b611403836112b6565b9150611411602084016112b6565b90509250929050565b600181811c9082168061142e57607f821691505b60208210811415611468577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082198211156114a8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220eabef41c79e988bbef5573106f3825656f6522b0a2771b005adfc744729606a364736f6c634300080a0033"],"ancestors":[]},"commit":{"evm_commit":{"proof":["0x9b6a5c7b5c73cde1500ce9a44823bfabe453b00dc7dbba61067632c618591697","0x0b137fec299ac8ee20636e8c17d2e4e86bbf4d4bb5d724db064567e654a6a036","0xe81315a24d4d03ff2959c1049bb375a1736bef7e2b3f2b31f75bab44bcf6d6c0","0x2983662cfb5df58b2f424ae962bd78795615bf000c83f7c93572648da6f405c3","0xd6c884663638ecb816d966bd6ac64779c8bb943047bb849f84140f81bcd3b271","0xa41fb2fde488dfaab02a7e87bf53bfa07c908e425c873ac5db82c937257fddf3","0xe1e0ed93892f12c7f59ca93c2a3f9934fab6a56a4bcddb3b4c23dd1dcf3799e8","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0x8fe571f2d064b34440ba6e9d2347aab4f31fdb5bf018037ec4ae20a0c588e329","0x0000000000000000000000000000000000000000000000000000000000000000","0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0xda6129ac3e03990004c3b4a3c3fe2efc1dd12cdd518e6d98c846aecb692076db"],"timestamp":1730394348},"state_commits":[{"state":{"state_trie":{"Branch":[{"Digest":"0x44988c279f47ae34c9c266da6f314709adfdff987c970990503422cacc8dd436"},{"Digest":"0x344652996773a53af0e15fc054b8516252054e08e8842ed0901b00f9d8ec20ee"},{"Digest":"0x771d05f7ffcb829e0a28b04673fa18257d208be88b2a31bb8b6f49428b0f2a37"},{"Branch":[{"Digest":"0xdb2dc8d42d62f95b78f1b8bdd73f9f0a8588fb93735cf629f48491e88da21928"},{"Digest":"0x340dccaf8f6f058242f901992bf01747b6375c7862d21e285931e44f9c1393e0"},{"Digest":"0xdf81cabd4a2f448a687da946833e916c7c57f577a7084370a4b5406114992ed6"},{"Digest":"0xcf24b6fb715cf5cbd5184d3bdc88399cddf21766cbd0a600ee46ab74787f63a1"},{"Digest":"0x8b72d9d8124863c7c62cdb8db6d70947ffbcc69535afa6d92d2335d19084d9c9"},{"Digest":"0x3fabc0453a1bf02bcfdd4b428664111a75fd9940620d68ee23399c00e9ea6442"},{"Digest":"0xd0a0e03597c10edb241d61dc08257d6ccf2b373395e8baa51a90fb4fb3993684"},{"Branch":[{"Digest":"0x94fb92961c80d62fb754cf96ddb605fdb5fca1c1706f9606895c096d453800d0"},{"Digest":"0xc0f3723ac3333c9ac112ed39d0b23e4db7437c08ad5e9519c8c1f5799ba7bfdc"},{"Digest":"0x28ff5fd8f4f5be27a9adc935a1ffc7fbf924faac30f585b10516aacf81725dc4"},{"Digest":"0xa55c937856d9a004cb562f075d0c3b6b9e4ea30729359c49b7989e16f4ba175c"},{"Digest":"0x100368cdd152df9af523f227cf338204487baaf5d4bb853e5d6324cdbc773a5a"},{"Digest":"0x7eaf9a56c9010b014ce3c6b9ff1ec2521256630dd2aa5d28ebab4c8454594d4c"},{"Digest":"0x9b6fc01450fa63cd6fd4e12538722b091206db4255b3aab06b86d3ed9b29208c"},{"Digest":"0xf87447367a396f5a9cc60e14f4d922915b3dedc19af9b54e6312c48002cace34"},{"Digest":"0xb1020599c8df0ac6b2693d1805f42487408e2f632dc27ba88dd3fcf81168bfd7"},{"Digest":"0x8ac6d374fdf5fd6d67ced884340698027886da5350048ec367bfbea0182b9292"},{"Digest":"0x59106ad3cdb291785807405930f9e3ef4b9c709c6396afca28b7f8b28555cb09"},{"Digest":"0xc9a049ae9969ba4091b9c0189024de1692f1197df9364fe0d6e3fdc573d837eb"},{"Digest":"0x01513c25f6df8ea71b3cd16cecc3addfbc5126a380eea5d84ff8a5da77149049"},{"Branch":[{"Digest":"0x1ff7e2801e751c0dd18ff06189a79dd3fcc866799fd4f6b7244ff7a7b0321d9e"},{"Digest":"0x42bc5aaab3060412482e0481c842924a27d8354e9bc7bbda677247d468f910cb"},{"Digest":"0xd487960e937d4da9fa40ce3c88296deca5408f22492892f3fc317ec9ef5e0178"},{"Digest":"0x8f1e7dbb8d6e4f501e9a48f60229fde51eedc4e52ba6640c2b9f1a6e2460d37a"},{"Digest":"0x2c9d2aea671e8c3726ecf70dd1525f57cbfd3c0945bfb5f11b8aae0233b06044"},{"Digest":"0xa01dfcdaebd3560e86f94bad8d8caceb2fb9ab7c40aff5b2e14caa52e4e05d5d"},{"Branch":[{"Digest":"0xff1e3a8b9d01f3160d03af12d71423ca4b62abea0ed6e7c3765ed653054b40cc"},{"Digest":"0x280431542effab4615c71d9124d238a2d51db428915a9f0b245d98ab958a4f19"},{"Digest":"0xeedddba72f983961d2528d43e2f65d10286a3f7772b8019334cbe7a061cec01d"},{"Digest":"0x1d7c5809fdc1acf919c063c58ff129c33cf763670bbbce3623e5412375251b09"},{"Digest":"0x6587bef80995cdeffabb172342e8f06331143703be1dc3a72377139c21958b23"},{"Branch":[{"Digest":"0x2f247e5a22f0ce7198a4ad1966f23738b501aaed77d020632f52dac3a7e22a16"},{"Digest":"0xad4037ea4a3a513c45835ae9b5d852bfd30dc8f36d01a1317698140439ebbf03"},{"Digest":"0x4b3e91adde024d4afe22d0e6c074175486343ddfb8438537d6a2d7820f83df88"},{"Digest":"0x5c20dc2ccdcf1c1ce1058f7f156a73bac672e47024c9338b65e6425f3e6a3c31"},null,null,{"Digest":"0x6bc5cdca451acb08a6fed8ec2387079caa8b0be4b7cf47478b299c9a3dcfc326"},{"Digest":"0xc1b90291659b5fdfe9d6109fbe7d1385cfaf4fd5b97adea976d09673b19243e7"},{"Digest":"0xf29d63eb323d95b203dbc8937a86537fcd8a28e85d161fa9592de2966295b2fc"},{"Digest":"0x257c114cc0b35fc4b6b6b90e672c3291b4fc895ec4b71d8907d2b77f5422c81b"},{"Digest":"0x8925a22b62ba1b04f9a3e1d08e599f745b84abfcc90bcb5bdd2ab2994a53905c"},{"Digest":"0x985545ddc481849ae5ddc2cf5900bffe97f29cb15c1017719239cd5669fc297a"},{"Digest":"0xb853b8bbd201702acec567d9143a2cabfbe69b41e7e5954b7e68c2123f4ddf29"},null,{"Branch":[{"Digest":"0x1c5a4aaf9f08b6bb295daf3c7e657cb975ca7a329c66d95fab6f216add325278"},null,null,null,{"Digest":"0x1daec8ec74362454b7d8e987a1acf7cf0249a888ddb00d3f866951f99b2ce05c"},null,null,null,null,{"Digest":"0x822d4e5327518af8d2de09ac0cf21fb56b884d941ed455e07cfabd42a5b7cdc7"},{"Leaf":[[10,9,2,12,6,11,12,4,12,1,3,10,5,14,12,4,5,5,2,7,15,0,12,1,8,14,10,8,9,3,2,5,8,8,7,2,8,7,6,9,14,12,7,10,14,12,15,14,6,13,9,15,3,2,14,4,2],[248,68,1,128,160,169,117,247,76,209,9,244,87,226,101,132,56,106,192,126,94,233,244,42,224,123,234,235,166,219,221,110,153,188,93,215,61,160,245,122,205,64,37,152,114,96,109,118,25,126,240,82,243,211,85,136,218,223,145,158,225,240,227,203,155,98,211,244,176,44]]},{"Digest":"0x95800b35e85ae47744cafb4856bfdfcc6b2d13e17d265f05d9f014b038ddbdd0"},null,{"Digest":"0xc37d4e315d7d59ab68ae79c915f307165311b5278d5f1d21840a60b489209b50"},{"Digest":"0x388d852d1803e4a2b77717474b4a1585c950558fde8b753bff7b4299b9d4f697"},null]},{"Digest":"0x2273457dfcf1855fee978e95d18e0b9701adfe0b2651846a4932d9dfb00f8670"}]},{"Digest":"0xb798d7f1b72f825ae18d6a0d6868491e178515540ac17ef212dac3db906bd3ef"},{"Digest":"0xc15e1265df4b2471eae6488eba57273f4c7b550fab6f79829154a594de73dd13"},{"Digest":"0xd4b95ac57be1b9b467477051edaf102799a37a7fa68d68b5d2ab329268985f0f"},{"Digest":"0xab95cd9816b1d634a4b6f702ab9326c4ab10dab031814969a2d0ae2d44e3fd70"},{"Digest":"0x825a385467f819253205669c64adcab730a2595492f82d2953528133a384c864"},{"Digest":"0x439700ad839bc7784ad6cd872c9dd316f1613eb199e7cffd43ce059eea3ee1d2"},{"Digest":"0x1349f1faa4197817f06d0c63ef27a3bec71ef04c9b9db33e3dcef0dd73691608"},{"Digest":"0xdfa25f3c1e9c3cfd97fddcef046e5cb134caa7fed736120af02a0de5f37983d6"},{"Digest":"0xbecf259640b3a5c8a5921a5f83d75dcad800d61829d5985b9de72a8061b9d929"},{"Digest":"0xc201c0f3e23ccb3f883c7714f21d569bea8eb31dc08b3fd1fc1a5e0587a14997"}]},{"Digest":"0x9b10efb935e7ba570b191834cb4d2258fab8a6d49875a20084aa13226c4eb807"},{"Digest":"0xeb1524ed98ca904a3ccc2cdc43b654e68be6eaaef7372770fc4fc37511ee8638"},{"Digest":"0x4a64d8d9c65b4360416ad3cf80c7d61dc11c0ced174ce3b62b7cd69b44801e59"},{"Digest":"0xc63c73ac26cc676352e8210251e8f8aff0685e31e0a17d4dc21aaad6876209c2"},{"Digest":"0x60add549155dad36c51b7ceb61d6a1b62aaa6c4ae5890eb5e1e7231eaabec16a"},{"Digest":"0x51dfe2f4805cc5b3e239364ea419e39cf5227f0be4bb052aad887b7e877a9aa7"},{"Digest":"0x8d3f83c27619cfac169b3bcee8a7de5404d28b730b16af418559c5cd044ca68f"},{"Digest":"0x598e21532a531386149426a10b842aea44121e2864fcef4fa0a7dbc3585a120e"},{"Digest":"0xdee6598a4c06ba390b84b8a6ce8999793bdd2dd8498dbd2ea95687f4691b1359"}]},{"Digest":"0x37319dacc65a9bbdd0ac62169df306e3d54be7fce5f17c1039662c8baa5939fc"},{"Digest":"0x581531cdb9eeeb9225d8cef056ac8bfc2055308a2e2bc76891f2c7af4d566ef7"}]},{"Digest":"0x5c2aa19b95a749c29b91fc7f3230064e67e5fde94ce1360310944afa36d238f3"},{"Digest":"0xcec6ded42a53f4308c447b80ec5637a93e003a156205cd9cca8ab1558168f45c"},{"Digest":"0x6ccbfe692c6b042487a99875dcbafd246703f3bf6194544cee4b2b65faceec38"},{"Digest":"0x96dc83957ea2e220446c830b60f1d131735c3d9102c80d64bb2c127ecbcd68be"},{"Digest":"0xf71b0310ad2a16d2fa099b3da9f5624093b78603e9cc4f8adc6d8f9629dd915e"},{"Digest":"0x9558970b2086ca720bc5dc385f9c2ac40759044cddb1fd8608d01c86c3f72ee3"},{"Digest":"0xe39c8f005c3765f7501adebeeec8d9bd3b6e0272b3068d7ad1d5fd3a5399c837"},{"Digest":"0x04214c9b0cf46f1db5c1df74841a5c6da6f6ed2db884a43363de8d435f5dcb63"}]},{"Digest":"0xf9c2cb06158faadd603533e87585122de51ccf94e51ce11a488f86f01deccb7f"},{"Digest":"0x4cf912ec6a8ba8e2f3d959a7c8b659ca694a579e0b5a42f0d58446f616438a24"},{"Digest":"0x632a26868cc014d501a0fb4e403024ce242bc10f2ae1c9604b7f5e8482f96eea"},{"Digest":"0x3ce065111ff63b49824547d9781b29c1065df2007607fec16aa12fa38f0cba3c"},{"Digest":"0x94a3266d104e0f36affa0ec5f89f16a4dfa4ef57d8fd7b77cb5671381f903aaa"},{"Digest":"0xe96ee491abacdacbadd09891f1720a2c4570197c05043b68b17fcda9156d9555"},{"Digest":"0xee55f583ee002278dd1c305db75655c6c58e9508632048c94a16281b726c6a9f"},{"Digest":"0xba55df723a6ef2103fc5675df6d7bcb36779f2fc03a6ac7e82369f12b77d630c"},{"Digest":"0xeea1db3babe3e5f0069cb0bb1bb3ea6c55c7478aae7f88dcc45f22d2e437ec87"},{"Digest":"0x70b6a02a1758d6679812b9e0cad99264732256299615654b1581bcbe8d9082c7"},{"Digest":"0xf9d5624f56e6c6a8b4d5a51d3b730714d21e25ba3508fa55034895f8ad634b1d"},{"Digest":"0xb58c1976856fef2a567ee4aa9aa4fdf7e8c323f1fa69a23cf880f363c67d1078"}]},"storage_trie":{"Branch":[{"Digest":"0x890fc8f2f97017730f65f252f6fd3750457afa2fad45a576cfc7e1ed09668a6c"},{"Branch":[{"Digest":"0xdf4954ba0d009670d10add87345d75e4d1581c157dbb4fd68d41e44158aa2f2d"},{"Digest":"0x1815e43f5cebb8a346ba845d00f3a296a193940089b7e8118fdf7a1c52565db4"},{"Digest":"0x8004cc37db5b05006be829b396f77802b0efdfdc4eaf3dfd5821d208bfc0a6a3"},{"Digest":"0x8a3e60df6ebbda2cd02f34b2a50ef6acdfb6331961b4f5d4ae46fef64d77598f"},{"Digest":"0x941de092376adf39c394d6cd607b8b3c3f7dfd7e0974ceeae5a76706b2795b37"},{"Digest":"0x1225f07ca2eb1a87430c7fb9cae9773cc246195f26904fd9ad25b6279b85f80f"},{"Digest":"0xdd57d5787697a870a3c30b509b44cb0babeb74d260324fe81261e978cafeaff2"},{"Digest":"0xbf81735f43269458eff9604ee1dfe9c781939149bf52444d1e853f9bcd87e3f7"},{"Digest":"0x6c3e0db4e15a4b0525d71ee31c5a97a45278d286154ff8e6001488fedf4def61"},{"Digest":"0xdc105b3eb728dd9ff1e30e609c39bf797e28f8ee8930c6ee07da347b54ce6e62"},{"Digest":"0xa2edab7d7b1a2d0e8c8b9947e97ab4b12e38774ec9a5dff5fda8377ac03ac31e"},{"Digest":"0x7a9f899309b5504292d4e7ea7e12c9ea25a6849546ffb28a6339317f8ddfa2e2"},{"Digest":"0xc009d78ccc533a69be6e31177aa0dbd6c3ff1d566bba1f195d6536d461e1c535"},{"Branch":[{"Digest":"0x608f69365cc74da17e69d501de5913c22754283e24069aadbce532d1b2bed934"},{"Digest":"0xe8bc1a872e75ae73f26fa3fc7565e66f3c22cc6d171cd0fa14e383a81850293f"},{"Digest":"0x877f07ff0c64671105b00734d2ddada9a2f99ceed23017f8fb4c8f9f65720877"},{"Digest":"0x0acd037cbdf5eb7b29cf90982bb26dbec280f2c41f0e6e18dd5d10a660d2a394"},{"Digest":"0x6c644f88065f20f8a79432377a97bddaf0db6b4d31bcf531fbbc27a85b133923"},{"Digest":"0xca6820503de390e1d2de87dade8e7dc8ed70f2a043fedfd02c04449c5a1b2765"},{"Digest":"0x83320d602deb2424cfaeab18acf3f148fb137508c8951c25d41a2277d45c126c"},{"Digest":"0x1f75e9e0423d15f280ed5829eef60eeaae0dd5299fb2083149d85dbbe4bce6b2"},{"Digest":"0x38d4232c0626a243184b00f7651dadf9ff4282f070e3fa36af1b1b973d3fd10e"},{"Digest":"0xd48a781cc6f1265ae9c9d9ded9085d126023b5d7576803ca73079ddb4d1b020b"},{"Digest":"0xf32d6a75b472ec6a77ad53d1f315dc508027682ef04bbea74e62ba46c7810996"},{"Digest":"0x3cd3ae9b8b21c156f7d9ce95d38051e0548fb37a4c2af69294dc9c49f1f2a88a"},{"Leaf":[[4,3,8,3,11,8,13,2,13,7,5,14,0,8,11,5,1,2,10,13,7,5,4,7,6,9,9,14,9,0,15,15,3,13,12,2,3,2,13,0,2,15,5,3,6,0,4,6,3,9,3,7,7,12,2,2,7,3,10,5,1],[160,67,234,128,45,132,171,199,108,40,221,183,190,191,121,173,202,35,42,202,181,67,193,217,233,99,198,246,73,63,102,101,217]]},{"Digest":"0x53926616c0b07d46b4d01f959f14a740ebad2d5f8286f9911f64da7c227ff981"},{"Digest":"0x92fc3103e8cfc210999bf73ba251dc75e203c48f451089cad5af41a752c3adf9"},{"Digest":"0xeec1032e2cf664004c7d258633c72a64728e2a0599cd847af92dc3e557f83fbe"}]},{"Digest":"0x8d18ae92fd0cc05461dbba6ab76ae14a4810be165cf73c6f74521f74b58b68ba"},{"Digest":"0x4f7a27eaf822148df4df035b7a839ccc325d31288cdae582cb38e106003123ec"}]},{"Digest":"0x1cbe1bad24726f039ef2ae0c090097a606d27a463f859a749017b6cb6e8966ef"},{"Digest":"0xa88022ebd3fadd26f900d6e1b87e42929c2c5591b78e41ad149e3197033762e1"},{"Digest":"0x0b149e8fcfcad9c46c0b8668d58aac193bc0b1621c433cfcbfef212ba82a4e0d"},{"Digest":"0x14bbc37fa84e918faf198843754aafeddca735a535a76bfaedf3a1ad57174ab8"},{"Digest":"0x0627e0bbf001851c8b9cdb5d87a9c3bb5185b187f2f4a78ec4d10b2b34429a7d"},{"Digest":"0x57b52095e3593d755013693320d65d92aec7107f49071eb57f397dd6e0b25816"},{"Digest":"0x7ebc570c356155298e6e78311e373a4e1c88196ce7f950446814ec4fe1c1c394"},{"Digest":"0xdab25efb1de3678faa55a0bd3e37c5a5b9bae403c33324e9d0445e59594de7ca"},{"Digest":"0x22fd9162dcf33e45561819ba60726dfacee71afdb16aa662756474a3f369d144"},{"Digest":"0x0ed77e79cc01a481ae91ef4c15c0a97cce439f1297f2875a31ba9e9b110dd2a3"},{"Digest":"0xa3d5c6e82c8df7083564f0939f59ddcab1c7d97452b5a0c5085130d885980706"},{"Branch":[{"Digest":"0x29d27f7654a8a0155e62e61d8d71ae1e38c434ebb690f2711fe77a99b5b28e71"},{"Digest":"0x7dffaa26af1e8a6141893b7cc59fb32b4f2f92726b1e06ffe23aa0833bc2606d"},{"Digest":"0xb7eb6c00888a28a7cc07a7aa4578a915e4024b1f5e3b4323d8a462165d76328e"},{"Digest":"0xf67394cf15d9eb8da1bc57e43337c0aa31bf4805bd1c02d0e0e98da4100e56a8"},{"Branch":[{"Digest":"0x524d37cab4d45fbdfe266ba644daa6eacc5e889996e09f5319f36d557810d6a9"},{"Branch":[{"Digest":"0x7e7e73328a9bcd31ed2fe5e6f7e7af1bc20338e90ace25a792d10a5666eaabea"},null,null,{"Digest":"0x43324023ddbb07378e5bf0f8e3eafda84a0a3ea9f785e6832363644b57d8d317"},{"Branch":[null,null,null,null,null,null,{"Leaf":[[13,9,0,2,5,6,12,0,8,4,13,10,4,3,12,2,3,9,12,14,4,2,1,10,7,3,1,8,8,8,8,1,5,14,11,0,9,9,12,3,6,0,2,0,12,10,9,4,9,12,15,12,12,7,4,0,7,9,1],[132,103,35,184,236]]},null,null,null,null,null,{"Digest":"0x966735812ed4d42de4b1320ffb0cb059ac20c8682415c678a0c000ef2643375d"},null,null,null]},{"Digest":"0xb0239e602ab53507fa3e23e6663417a69c1783aa5195955a70fd4003207f5e41"},{"Digest":"0xf8284339e8912239b2cc39f9654784b4c846d60ffb7ce25c14ab6edad6ec1c21"},null,null,null,null,null,{"Digest":"0x0f7d3dee9d7d079f113f14529377f65afc66b719e41ce087f1877dcbfd14246c"},null,null,null]},{"Digest":"0xdcd0d14af8baddfed311242d3e2dacc29116f9505e2a98952270a7c9442d19bd"},{"Digest":"0xa73156b209dc1aff06b2f8a777f730a4053f1cafe29c1b136e23f61f442c24a4"},{"Digest":"0x72315e8dd64195dc281dd2198041c8aa04656b4a0edc61ef7c697aeb7e7f8c93"},{"Digest":"0x6261b4b4fee5eb5a12b1fa3f681e488422726de5431d8ef78ccf1ca0deb1a4ff"},{"Digest":"0xaf7878854810743adcfa9b2f91ebaded9cb9b95ae2dd093a0de4a528fe66f5b6"},{"Digest":"0xb3f7d94cb7ca52d484886ae76fa0c861682fa67000d89c6c0eaa23ab0f310728"},{"Digest":"0x0b8757899c349a8d4bb07b06e846e2bc83a9e7addaaf47372bdef0c36b259994"},{"Digest":"0x5e7ff8ddbb2f66ae3d4bf0a643f78611d85680fdb60009a5b59c8e86db87afd1"},{"Digest":"0xd31aa09855e7871978dfff9b6d0cdc7eda802b020a3e5456c8397f21280e42b1"},{"Digest":"0xc66fc9d7acfa0295b3c89097fe488574af968e4df59c4cbe476866bf2f9c5cec"},{"Digest":"0x1aa81288aca0c0ee0a7563874270e67bca271e8c84e7a962a49922ff1eb5fb77"},{"Digest":"0x60d644c5bd5a06b06549ab559f9408ec3c70b3262e137e70f5664eda036ecef9"},{"Digest":"0x89b6a8c9e9cbb0d90bcdedf390f76741a53933064b9ccb8a4d8be80b0db52482"},{"Digest":"0xa676192852ec80f78004e3291e6028b845708daf718a3e3699aeeb49c0a6dd84"}]},{"Digest":"0xd912b586a976421f38c43bce0ab7cb4d7c24c5b92868b945750d29a946df97bd"},{"Digest":"0x91712c3aa2feff951779ac38d3d72bcd7f482819dac8c8c7e5c777629608b40e"},{"Digest":"0x9524e2e0d7034d845c431de087cdcd38e35902c31499c5cc53930b89669692dd"},{"Digest":"0x5e74d3f0915e100226edabb0e8eb67534d801414b187ed330b4fe049d76469f6"},{"Digest":"0xf6a6f7880c23ee7deb90d4e93fe44b5bb7d7b0deae4105123be773501302438f"},{"Digest":"0x05b0b9172080e663bed86b18dcb48bf30ca88212836cfd259f1768e52be4c36c"},{"Digest":"0x76003c54f139cf0452c34652ff532ffde3fba0e288f8ea462e6f3f6c32d4b988"},{"Digest":"0xfd8a4f2de9ff2ab3f6c268fbaedf9a1ce57813422463ef81d8a5c2f425d45533"},{"Digest":"0xee12ee18a2392a5d22847d14d840714d4088b7edcf4f651e0665cf3c9d367918"},{"Digest":"0x88f35536f1528d4c540c37ec64eb0f2d15ab43c51bb9a11f89c90d3e83281a01"},{"Digest":"0x5474c61160e1e32ba06d846499c1ccae8e3d8f6103943f7863c2b5101b43fe54"}]},{"Digest":"0x1587d8954af1ef247f0dc99f66b2af957fc1c35a01a706f26bc0aa99b7659d95"},{"Digest":"0x2c288eaa925b42e9bdc10cab4be1091a1fdd7495cc3842c2bb063e96470069b1"}]}},"state_commit":{"proof":["0xd4d3ab10bc911802b0b5f290960ef684286ad08ec280adf8297fa9beec52b10b","0x4eb67de35a8017db3c07f9af57dd2521c6b39f831596acefba784d3de0011947","0xb2fc049e15715a28dfa41fea72c24b2b9cfd168194875bbf72919e1f87bc61d1","0xc3ada0341793f2f5682569650a7cc59c76157686c1d10a5f3044d0992a94e40a","0xa0a2d301812264e8c8e34ec49107360915ea82a93983958831c88a738bfe64fa","0x417ff461d13aae3f47080a08a5f8bd759d534a6b88748568e927e3af9151bfa7","0xcd1521a7c78313b1f7dc3bc1390efc3f793b61527b7654793b25bf9690c261a5","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0x8fa3b3ef1378b37c2a2642940bff690324423f7ddc94e59e5c91805f878aabf5","0x0000000000000000000000000000000000000000000000000000000000000000","0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0x10d1ab5cd0b926b280e4122ecf1f1eff38ce2e60ebf06f164aaade9b610101b5"],"timestamp":1730395068}}]}}} \ No newline at end of file +{"History":{"input":{"header":"0xf90260a0d31f749805ea5a87691b5bdc4c033b6eb05fcb023c1356e1018a9e5932ce27baa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347949b7e335088762ad8061c04d08c37902abc8acb87a0b25c7f35f8f59d541f667345743b0402017f2b9ad2e2b17ef52640a86ab14081a0395d927f25fc65f6ea1556128c9c9c3e90f7acddce3b647c89cad8f5b2ccefcca0ec20133021f4eaa7143f313bde563e8b6b5129b826fff732d53e92ab2ba64559b9010017b20a4d227a4248c815124aa6000840044bc96830938ac88b88b00653ce5012619e56c003a0335e02a20643e57c94a991d504193a55160076861e065c2c770db02c38a5280f088ee539205b300bd01214698c64b2668650b850cc349501321bbc41040d3a247111106cf40c9e4388b4f5eb0cf18e48a0c8c82d1114a1e8c8ce336200101996240d68b2881b52b82032022b6409b905229cb7454d30dc800e3d1a0fb083c06a50986e6900c6309a6cce63406229a21288289ce003fe204601a989168c6e27181a0246430abb6b230f0c6d712000e0231020c3025d20a8806421441a1fd06518900cc16ab209aa8ac004c18a00304c11224164ad192650854acc8083731191840225510083cc390c84678fcf6099d883010e0c846765746888676f312e32332e33856c696e7578a015ca96fccae5e1ecb1b4b13cde97133327db75c11edc9a4125d984ecfcdf367488000000000000000084e7dfc730a0d307a01949bf1c7a441e86170c86d5bc82ad55507a3a38b9da79358381a5a5e080839a0000a06316dd189afd2559b786c31583e7294e931d7bf2de5c28e98928af2c312d32fc","state_trie":{"Branch":[{"Digest":"0xbd36abc1e83a067e7665a1a7db2a044e4bb9d8f5121d444f614fc25b631b5d0c"},{"Digest":"0x541bf48d4b3e4558662d8e6d2834bd7181d4b6c4da70624debdaf166a263de3d"},{"Branch":[{"Digest":"0x30b5a650096bf55113ade14bf3b7392bfefd59663c0ad0ef87968f069568d6e9"},{"Digest":"0x651fe35e0169116fd90a936c8cd39a57555aa680ccd50e504e4614c98f68f9cd"},{"Digest":"0x1f3a69740811f722f5e39d7c9a09c2ee357c96067e82f76b7ddc306d2622d7e1"},{"Digest":"0x022a51d7694f2851f6cb8e1fa10041322c8cc7a78cc9f925c8e21ac3e331eb93"},{"Branch":[{"Digest":"0x5f582e6c829faba8e45af4b030e858973159c384fa1d147377e692fd73e936fb"},{"Digest":"0x061eea7c7b2b0723a5770ca2a9a111e7a61e9b89d6300013a1a7fe7807a42c01"},{"Digest":"0x8a1bfc06800ae3d05d945fc6842cd21b017ad23cf532ea11962034496cdc18ac"},{"Digest":"0x91544200377a75376c728cf079e988116916e1009625b86ecdfc7906ff67bd2b"},{"Digest":"0xd6acbf52fd7b7002acbb4f6e273b494b321a8925eb76499d0974521b0504f2dd"},{"Digest":"0xe1a3f8d0cf1a12f06505e062e44dad6182e590596670ba3c8c5703114066f64f"},{"Digest":"0x1c45977130a2289e32a0eb2f22243e195ca1bbf17680b66eb3f2d4152acff775"},{"Digest":"0xb81a4f12845c2b6c9379228a9fe834b577b3995142e0a7ff867aa5509e46706e"},{"Digest":"0x85155a997466317ae5efc39e4b11c6a493367f5148e6f322cc52a13060cb4a39"},{"Digest":"0x591e55bdce51648f02a428a1efbe39972f355c4dd86f9228d3d369f9b8e0a39c"},{"Digest":"0x3a1181cc388c227cadf367cec4893bd1080b9f70fc8d9b48b631ef7027fa3a43"},{"Digest":"0x33d7e7b27cd236414465cd4a1ffdd5c55356d01203e9af1e8528aa193d445b6e"},{"Digest":"0x346414495a92f54488096ab1490516385c3c26a012ad2c911b62c4f3f6607de5"},{"Digest":"0x149783d25ae2aec132e61b0da6217ce3a782893549efec58b029865139894937"},{"Digest":"0x494fdd61d87b0ba4d38ca7dc00bf5c8b03cdbb92c9bf8195b74c13d1ceeffcf4"},{"Branch":[{"Digest":"0x52d54434fa8694085c98cead8e5325ddca9e6d8c8bfb6a54b26a275a8d21b8e6"},{"Digest":"0x025090aded1ae4a14cc7111ce50824f88bc21f25bcb8a189c1392be4bbef8fe3"},{"Digest":"0x178c681a749035a54e8b75ead3130301e402da29d6942be6531d3baf8bdc6551"},{"Digest":"0x808ff948596d3b2eaca2ddb9bcd9558cb0d454ad6ae45c09e4c5e5cf4b179b3a"},{"Digest":"0xbb7710fdde09b0fef4b24618cb5a74ecc2384b8e78a990cb4bb7bfef554eddfc"},{"Digest":"0xe63e197caaf7220fca244ae6da7bc35b9543724123ac3a0d9b267c246f5cf97b"},{"Digest":"0x85aa900a00f3be255f953fb1a8d164f5ce69e58c943c7884b7cf21b5dafbefd0"},{"Digest":"0x4363709449bd22039d05ec13ed3049c8e6e5a72a0cc0cf758dd24e8b604e824c"},{"Digest":"0x4a2b755985c996f5c0cab76191560515222295fa6cdbd89eb2c843228b769da1"},{"Digest":"0xe29b3407f21865195d3838b3a8af3884a6a213951652dc830eeb7f11d25ac337"},{"Branch":[{"Branch":[{"Digest":"0xdb28048328251e31b2d3328dc517f370e4661cf8ce1d5fa345faa9f51ce94f9d"},{"Digest":"0x81d446edc9f6943589e0a95e027e2fc9313976a2850b249e8dbc0a36378d049a"},{"Digest":"0x547adead9dca2a0a5a68a59b0a9e15e76e03c267aa1bade08bb046f2bd4eb073"},{"Digest":"0x27d35383b43d2bd596638fd20e8dd09a6ab63c96f90ec11c6a5249bb4f4dc2eb"},{"Digest":"0x406a49a5b08edc39727921ccee69f2d8585f1658b581cc21f65349a13be8b129"},{"Digest":"0x8e3c6433db2e2b9bb76200119bf51313cb82d97200d633f988c2222980901f9a"},{"Digest":"0xb17d400444bbae6813151d24afe8fb0624b615755904c3f26f191af82df87e9a"},{"Digest":"0x6145add4d419d11c184153988c5bc5769c764ba2a7675272f6751152b69abc63"},{"Digest":"0x644f86d76acd1f8bb5a55119608f0fa73493b2694ef0950f1a5f673e8a7e6753"},{"Digest":"0xdab646f81ca96e9244d88db3c49b36a2e1a4085a255ac571714718e1dc2505e3"},{"Digest":"0x2cf4721a99a7be43a6ed31637c001960276b54518ee3541e349aa47776752196"},{"Branch":[{"Digest":"0x8b92b40f358d29115172a38e36adc284772b7c2440b55e199e31f6d79dc52ab5"},null,null,{"Digest":"0x32e92fce0570631395ec05c62413a521ed320db25bd4a95992ccfc47c4c74a39"},null,null,{"Digest":"0xac2a299a9f99e6f0b275d38efb601ee9d1d95199b9441d46058781dd915fafe4"},null,null,null,null,{"Leaf":[[6,12,6,8,5,3,5,0,5,7,9,13,11,0,5,7,3,3,4,7,14,6,12,10,13,2,1,6,0,15,6,12,15,15,13,1,5,10,1,4,13,15,10,14,15,11,4,11,3,15,1,8,10,14,13,11,0],[248,68,1,128,160,71,78,32,163,17,197,55,230,124,212,110,187,202,182,100,132,168,202,26,219,127,172,40,176,13,25,58,216,123,231,19,187,160,173,162,122,66,135,249,23,26,77,35,164,213,151,124,154,88,61,113,137,6,246,170,45,109,127,36,115,156,57,115,6,242]]},null,null,null,null]},{"Digest":"0x6fee6a0286c5da4191cee1b6a07739758f8c96f1539a98e30627fabbe0466990"},{"Digest":"0xd6a2b5a75d24772a9e6c35cdccc8f51ac75818870ab706fef68c0e53b4aa5e40"},{"Digest":"0x2d6bae5f11cf0d8c8aa8858af8caa1a125595e8112eca81d2ca618d2d4758ec3"},{"Digest":"0x96066747f61459591574c48f97d9af2793f04d8258fe6eb7f4c1260cb2a9ed8a"}]},{"Digest":"0x510fb870e6ff1af9282e7cafec6afabad92cdf02f795ee425c5dd760cbe80849"},{"Digest":"0xfae24aff7b229724462def40d3a113f8b438b2e92e9cb7e0020b5cb2ec4d5797"},{"Digest":"0x48c3d5b0bc4d23e5712c0d1d4803178175cf70650ea139f28a6fd74f33652447"},{"Digest":"0x2f6a5d7e2a1e020964d364217de929f47bd9ea6be7262323e9728fad2fab5667"},{"Digest":"0x7fdfc4eeb2b5ea8a218acb3327961ef3c3a551838f799adfad9d429f219a20e9"},{"Digest":"0xddf72c7ba849a94b74fba9ea1f8068f34445a6be789e4cecf1d421000f0ebb46"},{"Digest":"0xc77e8f9b01c01fb0f3bafe116d58fb05d7bde210b94a1eee4df5263ffae5a5ab"},{"Digest":"0x4d572d6620424e2d63f4cf6e58ad843a12a04841d2306047b810535c2cdda007"},{"Digest":"0x9d3c621f38e2c825309590531af1e86286d2d6ea5fb517ce26e619f2f7144531"},{"Digest":"0xaaf9b8b5761a356543d6c89ce90259e2360ab7edea4f0d5b53489737c064c181"},{"Digest":"0x404d28317de51dda8ff242d18501dae51c4cf0fac09241724276cc4f65a50025"},{"Digest":"0x3e9787cf06d5f388439614e469b7de7e55a26785716e5f3f484b861ba63f2409"},{"Digest":"0xc8ce4a4bd000ca801bd1effe737ffd1ac8162a24e7b154ed915d0a5773af0f3e"},{"Digest":"0x1bc26ae1ec41d087484efebc200b04fbd9fc62097773210593eaa4ffe6c9b909"},{"Digest":"0x6b0c1c1501c7ce6872fa235c4862735426758f92035f889411d4a9dcf66d338c"}]},{"Digest":"0x5831467c6bc689a0dc383da310cccd40585db93e676dd3b94c1df9e41524e7f4"},{"Digest":"0xc9800ee83d3738529b3eb97fa6b35d182379318ba194b15e584aa0fbbef2d6e5"},{"Digest":"0xbc8fd1fe0e0adb1eb1e9f8c0d42328b72143004dba1ccf6c72c4250b0d3b0c8a"},{"Digest":"0x2a287550d0c9eff316ddbda1ee77b3e4dbe398af4a8812f8da6f4818b0c68652"},{"Digest":"0x51ba137162a9599bd44fad77ce91c37fa0de35a398e305a184a8cded9c255240"}]}]},{"Digest":"0x0d74533c1a6686dd12c2c8665a7c460adfa6ed209a848c8891593209da12f4d1"},{"Digest":"0x4056b878999083e87b37da58e00ae329bb3369c5a0c2188b5dc130538e7e106c"},{"Digest":"0x007a7e1f5bf3c0759b3571c2cb9a42a01f19dc59de014f0aba7ed43e661d997b"},{"Digest":"0xb8ad17f1a5d8d4f56f0ea4a86f24e832e617f58daafda58875deb8b182fd38f9"},{"Digest":"0x47e1305cffaa4af5018f3d7e14585aa97c5e887974190a22a618ece519bbef37"},{"Digest":"0x82fa2e1e23d8f699558aba03306bc523989ccbc3db29594985f1f31a560104dc"},{"Digest":"0x35f060d9ff22c8408a512286ace082e7d809d63144c941fe02e105ae0b789c74"},{"Digest":"0x3763d3389a21d77abbff3c4aa8e5f4681fee87b49faa5958346683232029d500"},{"Digest":"0x2ff917a6c88cc54bf864351f616786efc741c7c54b203ce96cbaba2444327e57"},{"Digest":"0xb363851073cee237d43e98dc1d6011d09c5e3317ee1e40b98b44b54cce2336fa"},{"Digest":"0x215d55c881b496c75fc9abca500cd1b9e172586daad1ece0416d0911d3b95869"}]},{"Digest":"0x1aaafdf5acbc284d2a2d35f11981621be05ebbd4dd5d4c1e14fe4bab18d608de"},{"Digest":"0x4dd574a20f941e29ccb778c994286dcccd7c316d78e124a5e936fbdef765b8cb"},{"Digest":"0xa073cdfebf4935224075908ecb76ab69f7d6e9d295d594b1cbf362fb031c0484"},{"Digest":"0xcf06804831514633ae85ee30fa1f41fb280baf8cbc6721875204ce0ff0236af0"},{"Digest":"0xd195351b41cec22ec2043c58040887ff6b391963c1298db64d107f7ba79811c6"},{"Digest":"0x50ef23a5e586bd59a344d445adb35f78baeb0edb62d10e486938933b5a97f1ba"},{"Digest":"0x8fc1f329823f917fdf6f08fb6c6275902cb6afaf4e2198000c811dde3c88334c"},{"Branch":[{"Digest":"0xfbae6b9b074de2d008a4a11de98691fc233268e22eb04e82f4f2b3ae34cc94a9"},{"Digest":"0x8b22ae63762388c6475a6390e22d311de16c819b14c3f157f2a7025de68ea094"},{"Digest":"0xde66b75b2c41fdeb638f7957f744902bfc9be87ac4014fad69d610a55a2b2b42"},{"Digest":"0x440c7550f4440aa12e0e7f8de4bc3494e41aca23e6222e78f076e2efb9477fec"},{"Digest":"0x5da8f0dd1be6c56669d3476332a284618681715a6bdc89c94b806daa5a56bda5"},{"Digest":"0xa727e85ddd110b4a03fa680848fe1683d8e13e9180edb5ec98ba4e96a137c4a2"},{"Branch":[{"Digest":"0x24349fd2ac8b39a190806a081828c8c1310c4ce675ad6004851757ff34d9e655"},{"Digest":"0x60a3f3a24e3000f51630f0d4a5940972f1495a9e3d26b731f782e751ab78dc9f"},{"Digest":"0xf58a0ce405d79bacbb5fe3d4fe92d450988691ac9450c0f11f6ae9c6d6e5a18a"},{"Digest":"0x44f5993bda1129d4e15257c8119f143cb0055304f1ef2bf9d7111a12ed7e8565"},{"Digest":"0x468b04789c9686f15464a256e22f6004eb799b9a1b2a88ebd5965fef0610c12b"},{"Digest":"0x118e27f3db6645fadda58a9cbf610d0eaf2db4b09e585d8278ffa0f104bbfb6a"},{"Digest":"0x9879875449098d08ad1c2597478ef22695108cd55f1736453b05b81d54d538ae"},{"Digest":"0x9d77a56442051d5f8f209da2b6fc79bdd52272117bf91090cea4c52692431c4e"},{"Digest":"0x7eff80129a5743fccabe3b39f45a0051042ea78a668749aa7813eb6a81e0cc58"},{"Digest":"0x1ff0a41b433574872e4abcfd1e4c1fc8f821b30c4e46cd6d629d4db99aba5d94"},{"Digest":"0x6578dcc159ad1de6e0e2f49617b4524595b69825439a788a5a68cc818174f9ad"},{"Digest":"0xd24e7607cb1c73fa03bfcb143e2b3c9107ad62007f2bbcc059cad1517c316d0a"},{"Digest":"0x49a4cd436aba51082056a0772c464807b6af2dfb825f7181153bd970c7c57e4b"},{"Branch":[{"Digest":"0x0269c06d16beb1d906de1fdbfe792ced5abc17920c0b0fdc98aef74e4bd50964"},{"Digest":"0x82862e8e288882393bf50c6107c9ecceeef126529abdb7ee11c64000f763f039"},{"Digest":"0xa255fedc02db94f3ec8fc0bfe3d362cb6bea818b7d82af5130f17ae062a13f38"},{"Digest":"0x33d48b9cf3064d388fd985d628a2380ef9b2da5f2ce80af1db0df8458d9b6723"},{"Digest":"0x4492b11ca4c185526b03433a7284ef5ee418aa5abff91705008f0146b0934d9c"},{"Digest":"0x37e2dd0c2d4fe5e80cbd6570390680eb1ef3a74d2336ee4916c3c8c48dad2458"},{"Branch":[{"Digest":"0x0f593251f7dfbcaeb0276dadc5594c2f7fedc088bf0d221b82a827d75de45653"},{"Digest":"0x7b7d48d8643dbd6557d5bdaf85b8c1c5eece04d0d42b0fa38221dc7de70f1e15"},{"Digest":"0x6c5735c361a5a7f70dcb82f2a8ebf939fe31db465bd28d616371e66780fd6623"},{"Branch":[{"Digest":"0xc2461f524f09e1796b8f1d18e372cf4678f20024800baff3b4a21e946b4aea55"},{"Digest":"0xb5855d4032b529095bebbd79802e60b0b5d06275125a64ca631fe24177007224"},{"Branch":[null,{"Extension":[[8],{"Branch":[null,null,null,null,null,null,null,null,null,{"Digest":"0xd050c919c3b0719512cf480bba0588cd7182e5a0c8f53aea5a448743e715877e"},{"Branch":[null,null,null,null,{"Leaf":[[6,12,7,9,15,0,0,9,4,13,9,0,11,3,8,15,14,2,0,9,8,3,11,9,6,11,11,13,7,8,6,0,6,10,14,13,9,12,15,2,13,6,8,13,5,7,15,10,0,12,12,10,9,13],[248,78,2,138,2,135,63,140,224,198,121,247,245,53,160,86,232,31,23,27,204,85,166,255,131,69,230,146,192,248,110,91,72,224,27,153,108,173,192,1,98,47,181,227,99,180,33,160,197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112]]},null,null,null,null,null,null,null,null,null,null,{"Digest":"0xd98965485dfa507ad730bd8abdc38aaffdae9d1ca3e312c942f33be4c9cc8720"}]},null,null,null,null,null]}]},null,null,null,null,null,{"Digest":"0x3d80e008c00335733d210192e38bb1362ce31a24fa137dd961c229468f006f75"},null,null,null,{"Digest":"0xc1685c064fc07c9c34bc37e28625fa934c905c271a8890be177fd7de64e10f11"},null,null,null,null]},{"Digest":"0x58e448c3f7ef165e58708a18783e63eb413ddeba51ae8721fd6fc1bbca11fd63"},{"Digest":"0x77853b16a7e1f3f3de9d915cffa9d82bdd2bc39745eee8f16d11466391f7d13a"},{"Digest":"0x00d5ea70e653d6727602d093c0e6afd956c9a332063ef842b73a5596d6f70e13"},{"Digest":"0x1a8c748422588a9dd5fcb69ce978f1bea43fd3d5878aceab3c6744d7f3bad18a"},{"Digest":"0xb391439483570b1c227a3f565271606c4e734d83f03cb2cc887977ca54d967df"},{"Digest":"0x1e9216f562c92e557fac37255194ed0d16fdb28c6adce34e1bd43919917b3db0"},{"Digest":"0xd00efdbaffe815d660b6a6b4033a6b3b3177bd12182f293426e7e6a0b1d3e4c2"},{"Digest":"0x6f6c5bba4a69a9949d5620f394101331fbe0e01c4fd53d3f041554ff027132e4"},{"Digest":"0x7fbbe0841cb0e45d0edba32039aee359be242175d012f1f2f6301917a4688694"},{"Digest":"0x97cba2bb6da5cebbafd38c32a81f6341a1eba4aa28fcad26504db39d627174b1"},{"Digest":"0x8ec6743ba80014a45e35cb6089e5bcd9dc86a4d85e05a212a8e9309a62589ab9"},{"Digest":"0x5227c194a8a4568c0ba9ee46b6ed1d8cf178106db598b18b61e0435c6800fdd3"},{"Digest":"0xe830ec01a5e5414d65dabfb669bf73ce6ec7146f624d8effd131bba1eceba0c7"}]},{"Digest":"0xee552af19a318e5b36fcfe05dba1e76490df69becf15d8130f47618d0cfe8304"},{"Digest":"0xe0aa9ca5c20ac161be7644d027fcfd5a22cde3b20850c45af338d077af4203e3"},{"Digest":"0x770139201415c896372507b127b6e41c2a30f21d1998374ae711a8ba3b02e1bd"},{"Digest":"0x1562b4ac878245504331b62e6d629c7648e24b209831c68522ab9e9c22d055b0"},{"Digest":"0xd0133898e0e60d0a8ff2e1d02b7082580c69b74d7c905ef4c0bb1f15ced1ad3e"},{"Digest":"0x7a08b60d81e888b5a19379c7dcb434b34bf6ac50768af56142f139bf488c5130"},{"Digest":"0x09fef1afcafb900b4581851f7c5b2545a83f12150a805ddef77f359bcf558238"},{"Digest":"0xf374443d6a778a88da4b74f5ce4e99caa6e802ca4193ab5552818858bbb83734"},{"Digest":"0x7858ef577cc0e025e96a281217f6fe5d49555749b69b0b032da2c3c9a2452a8d"},{"Digest":"0x6ef98031de292d9bed83e9bf3250f019a8269c5aebdc41afd6ff56d4611e854e"},{"Digest":"0xcbae7db08e209bb79c971aa717748707550ca6eef2a9d812a724809e9484dec7"},{"Digest":"0x8d3041b0d32bdf538fe50ad19408f54ed66c61e9550f5a62c9888e42c1aba648"}]},{"Digest":"0x8e9934cc7d85267db557b19531890d4d627e7090259c678abd6ed4fe97a957fb"},{"Digest":"0x24eebbe0c8a94482a05567bd9e3dc01bb20e92f87614150896ba99a3994c1c64"},{"Digest":"0x7ad44a0baa8085a7b3f98cbb1e3a7f169996b31682f1eb8b8fb34828ed664987"},{"Digest":"0x483d701373163917bf672185ec793605d23d943239552830e22b09224eb8b680"},{"Digest":"0x1cce118ae2e8abfcc85316f495c651101eb310284b78c8a5dd2e2bbeea4b7b7d"},{"Digest":"0xe376c1c979f6c6fa04ea2c68327adc26c5424326130da1165a2212517de13692"},{"Digest":"0x91957b18d3a85aa803eb0537846341c7aed37bf7eb000e2d75be79e71a5bffdd"},{"Digest":"0x364e6dbfe95eaea8ecc78f53b1b86feedd8a21b1032733b5c574811f9e058739"},{"Digest":"0x4919f98f93dd631baf620cd573a6a8c9bc08f17a1cf88ff32e83d6decc8d6946"}]},{"Digest":"0xfb6190c96d77a0b6d14d5024ffb1de9410efdcd22076854b50c4f75344943fcb"},{"Digest":"0x6cb75de82389bfb414455cc066dbaabf509a25019272b5b72c36fe30baf58619"}]},{"Digest":"0xa0b26c94b255c5e9479be34b6c23a190ba8e028f05145b89f4e68c968b309605"},{"Digest":"0x9ab20a7f4d8e179046e873dbcd501194b4ef45018868aca35c101a402ed5797f"},{"Digest":"0x5e51af020fe8cd2a4343f933c3fb54b766b261d81dc88f5498f3ed62e1d80079"},{"Digest":"0xbc663efcc0bcbb7cbbac7b9216b90dc9b7fbfabf0c36de5a0969f7879fcf863c"},{"Digest":"0x9c905aa66adff29e955e68776f20a980d2c3539f032ab657ba9b625eaf5579dc"},{"Digest":"0x3244ac07df486fe8de28ee9ac550f0a20248473abd0bce0a84733191eb98f05a"},{"Digest":"0x97dcf0aa3a06679509e83bb7eb18468978cbf6bde77c7ced035027086d026b06"},{"Digest":"0xdb422a313f12e96b4bea7eda9a00dc526272ed220560b18b17a35928eba721d0"},{"Digest":"0x363718b53a7342981582aa2b03c167781c92045daaf3472db3a8a7403987bee5"}]},{"Digest":"0x1f9c17d37725eede53961e43867ae426cd31b30a306339cebc02a3099b2c967d"},{"Digest":"0x8d8455e38c66182876a6a9f344725ee96eb9456dfc9aee86e6722aae967be1c9"},{"Digest":"0xf384d99eb46f303804d473af8d7ba8144d2dec846014fa19fcc6c31932cdb2b9"},{"Digest":"0xce8cd44d973be4bbb2d86a0958146a076db5c258c2146423d272841e00ada4fe"},{"Digest":"0x27e9d4ca97d8dd45dbcc7b14cff211e7f0ddbd032f10f2b23cdfa7dc0cda40fb"}]},"storage_tries":[{"Branch":[{"Digest":"0xf3c49aae9ffc5c5859f82701ad88aa33c9f44ee72aa9ab50555dd27d9b46ff8e"},{"Digest":"0xb7d4c2847846a686da8209096e7900fa4dd716f0eba0e0afb7d25fdfec73e683"},{"Digest":"0x9e71f0d8512a0e6aff6ebaf65f3d2f76ca667f6284357f574550fcdf66dccb4c"},{"Digest":"0x691374e6c78757fba9010e038c4f4e0a516b939e193491974be022eecee12636"},{"Digest":"0x33d47a642805c183eea624adb5292148d548276b22f3acced79014088002a69f"},{"Digest":"0x1fae9557fc22c6f1437a05da5e7d1dd3ab1d02d76edcf69ceb4d9f556a0466e6"},{"Digest":"0xf1caeebd43b5dccae32d12e141eb10b03533f5dd8a5499b2e80b3dc33aa372b4"},{"Digest":"0x34431575930d9a0c1db72ff52bbaefb364d2ff383c50b25c9fd5b38d9362d05d"},{"Digest":"0x7c685970bdbd575e07d3ea1910dac453368acad013e82c08e9664b63040c6f1f"},{"Digest":"0x62170325c8b1c96f9765291994e56a101eb9427cb36e791f6501ec2e402febeb"},{"Digest":"0xa3c039226e6a6dda938be124b7f3fcd9fee96a4c27bb102d517b32d741337ecf"},{"Digest":"0x36c9d0be7c9f881dd7e395612c6d2680e8776ca17a5b82368528cb69a2f81fd3"},{"Digest":"0xc41b61c97d4b998b64f3adc7f5d2002f8496906802db4291231b9d4a4e2d99fb"},{"Digest":"0x878041549840cf87f28dc84036dc6546e6a9c646e5245979d0f951e369eeccbf"},{"Digest":"0x1c1b862e59bb50cd1b298986b5674db4d0aebf47a112f619899e54d6d25e726e"},{"Branch":[{"Branch":[{"Digest":"0xaffb365301da6b6a18b0d7ef4efaefff324ad65c3b57388c877d90e167a9609a"},{"Digest":"0xcaa301dfeba77405004b66b89f61853db26d981d927b2eeaeaeac8133ac20182"},{"Digest":"0x2b1fbbf1dd2930136257f164a263c467c75eef558180678b8cabf110676d74e5"},{"Digest":"0xf60d899b2db311534675632909a5ec1a5822f6517d15d2991b8814c6540587fa"},{"Digest":"0x7756d9367ccb981133ed3d4c879355c16cf2cf6bcc4972164384edb43d7d0b6b"},{"Digest":"0x4807df2cec95a95f4a733495282816388da5cd25243e666bc8cfd1fe4ef12954"},{"Digest":"0x8bcd643182696868ffe097c638367ad6ffbeb3e5b449c18546341a8652fcfd3b"},{"Digest":"0xcf32a84d4499dd2a0174286e6a361e16487ab07c1dd2b0f123e271dd1550a9ca"},{"Digest":"0x85959dda8cb42adb0d6dc37a9f515cc45f503511ea1d7d23288c93b46d7455f1"},{"Digest":"0xfe4dc360a9b7e51f860228d0f6ecd084bb4b00407a308e718f8f6c44a1bc65b0"},{"Digest":"0x70db0af24c46b0458bb32f35172080da3996d848870e521961548fea6d652c68"},{"Digest":"0x04a6db5188dcbe07aadca0d0bad9fa1715170fcef5a2ef1338055d092a30ae4c"},{"Digest":"0x49363d2a87ea8e825721c76b83b4f61b9fa5a437e91ce5c8dd0bb6bf11e7f1b7"},{"Branch":[{"Digest":"0x6f6d69fb2d68135b5ebb7b860fe9f1feea9b019a4395a8a8ad68c91f49f55ab5"},{"Digest":"0x32aabe5aa1bf8f88e391c540716064703a32bf90ee12ab8ce19af0da535d97d0"},{"Digest":"0x88130e6326f4f132ba71c5cc13cc56fe15758fe64b6bf39f096e286cdc231f5c"},{"Digest":"0xfce56c70bf134c1f93bbce177197f35d788227e0c0bbcd7c3c9d5a7cfbb1bcfb"},{"Digest":"0xaf296383d0361b96d3fba4947bda01b88525f35e07d5fe39d9d92e49f5c28237"},{"Digest":"0x4e1dbbc2fb7141c60c6780e027299818036c33392a9e9fe9b752021524641a93"},{"Digest":"0x488c3ea67626988d85f3cc0e35b55198e506954f7167ac248a36441f2cd07210"},{"Digest":"0xbff83b63f63ff94b661fb0a7c3cce98b8407f55097a90e1af5351b21f649d32c"},{"Digest":"0xa3a5c6092d7fbef03e66035b326013d54ac4c1c24e6f20b66131fc594373a2bf"},{"Digest":"0xe312443ec3a904fe56b03ac4ff12986946bb93f0dc5209fca60b22510ebca148"},{"Digest":"0xed34ca35abf8b9c0a849c6a9f8141b4b6404b661c68c3a36d4c04fb1a9ee4404"},{"Digest":"0xed4974e0942b8c2c4c0cb67f6ff8b3acf392fb5f87750a22311117c34061a49d"},{"Digest":"0x92a75579e3d7e435206711bfa34bce20989a7cd31c68f9f03484ac46271859df"},{"Digest":"0x982da97762a67163d6f03c9cd0fddd75c54415859f50e8bc4291ec74d316c315"},{"Digest":"0x1ab003882db00b52c3298b9f8e5377e64facdbd98d8a31376d7f4b4f7014e11b"},{"Branch":[null,null,null,{"Leaf":[[0,1,5,10,14,1,12,11,1,11,1,13,3,4,4,1,15,10,9,15,8,14,12,11,15,0,10,15,6,3,5,3,13,0,14,14,7,5,4,2,2,10,3,2,6,14,8,15,14,0,13,8,14,2,15,2,15,10,8],[132,1,236,139,132]]},null,null,null,null,{"Digest":"0xf0ec532af391e6dc77f2c9867afce87e39293059a5f8ddf2b21b38d8e4dd23b6"},null,null,null,null,null,{"Digest":"0xb92295774b00d67bfc53715b07b142a21c554b7f1cce914aefc2157459fc289c"},null]}]},{"Digest":"0x63c5d95b2841f2922a349e5c6b4479b62da76ee9f6c279d08d928e203710f3ec"},{"Digest":"0x30705db3c781f5e196f488ebd318ea63f734113008afcdefdf34d0d15e03c21f"}]},{"Digest":"0x87f9fcf8c604513f50a86e23f2f0989f9b96f1d3d99540a8b315a7806d07227c"},{"Digest":"0x812b731dc4f77aee3f5101bfe40193bfcca7e9cb97980098bafaa0d12bd39d16"},{"Digest":"0x9b126e01a082b7bf24e2b890f98426d5dd83193a3aae6403f2ea928f77325344"},{"Digest":"0xe493867ed492e0a552747a07c854a0e0b846b6bd62834f0d4996a42bc2e1979a"},{"Digest":"0xfcb0c15e4a3cc13df884a0b396d87a319ecf195db3d4bde4f02d1dee8210a05e"},{"Digest":"0xff8b139d44ca658e3276f749ec76164c9a07ed0e4008410bda1b2a970943a403"},{"Digest":"0x7175912619273587915d3028208d14edfc0ec4804e6ca7b8058a38af41e6ef34"},{"Digest":"0x44a96fe6833a33f89313f2b69a636c0e6040078648792f1641b125ab6ae5c2a0"},{"Digest":"0x7a55c044ebe65b274f72bd33156fa094af3126961448eb6f9657afa235528477"},{"Digest":"0x2c0dfb78537469b8908a3d3118d1079ab512af5050b2c012f72200cc99b17dfc"},{"Digest":"0xee2e5b3ea0d5856748c261b9b3d50eadf498a221cce69dde2189a806f80f0b4e"},{"Digest":"0x3c020e102cc457f636414b9999a1969ce4a92be8474a47a1320aa9ac66bc765f"},{"Digest":"0x6b61ba6119eb34dfa15b0d56e510b099067d9ea3f1c50b169db280ce8abf73ae"},{"Digest":"0xf02f56d6e0034aa24fdcecfcab208ec41317dbe79659487748d378e994a954ff"},{"Digest":"0xb9117371edb3edbdf7bcfd78a8dd35ef477651fd894b0abb1839c83f88571887"}]}]}],"contracts":["0x608060405234801561001057600080fd5b50600436106101775760003560e01c8063715018a6116100d8578063a0712d681161008c578063d505accf11610066578063d505accf14610383578063dd62ed3e14610396578063f2fde38b146103dc57600080fd5b8063a0712d681461034a578063a457c2d71461035d578063a9059cbb1461037057600080fd5b80637ecebe00116100bd5780637ecebe00146102c95780638da5cb5b146102ff57806395d89b411461034257600080fd5b8063715018a614610283578063781603761461028d57600080fd5b8063313ce5671161012f5780633950935111610114578063395093511461022757806340c10f191461023a57806370a082311461024d57600080fd5b8063313ce567146102095780633644e5151461021e57600080fd5b806318160ddd1161016057806318160ddd146101bd57806323b872dd146101cf57806330adf81f146101e257600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b6101846103ef565b604051610191919061129c565b60405180910390f35b6101ad6101a83660046112da565b610481565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101ad6101dd366004611304565b610498565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60055460405160ff9091168152602001610191565b6101c160075481565b6101ad6102353660046112da565b61050e565b6101ad6102483660046112da565b610551565b6101c161025b366004611340565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61028b6105ea565b005b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b6101c16102d7366004611340565b73ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205490565b600554610100900473ffffffffffffffffffffffffffffffffffffffff1660405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101846106e5565b6101ad61035836600461135b565b6106f4565b6101ad61036b3660046112da565b610791565b6101ad61037e3660046112da565b6107ed565b61028b610391366004611374565b6107fa565b6101c16103a43660046113e7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b61028b6103ea366004611340565b610b1b565b6060600380546103fe9061141a565b80601f016020809104026020016040519081016040528092919081815260200182805461042a9061141a565b80156104775780601f1061044c57610100808354040283529160200191610477565b820191906000526020600020905b81548152906001019060200180831161045a57829003601f168201915b5050505050905090565b600061048e338484610cdd565b5060015b92915050565b60006104a5848484610e91565b61050484336104ff856040518060600160405280602881526020016114d46028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020908152604080832033845290915290205491906110bb565b610cdd565b5060019392505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161048e9185906104ff9086611102565b60055460009073ffffffffffffffffffffffffffffffffffffffff6101009091041633146105e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61048e8383611112565b60055473ffffffffffffffffffffffffffffffffffffffff610100909104163314610671576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b600554604051600091610100900473ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580547fffffffffffffffffffffff0000000000000000000000000000000000000000ff169055565b6060600480546103fe9061141a565b60055460009073ffffffffffffffffffffffffffffffffffffffff61010090910416331461077e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b6107883383611112565b5060015b919050565b600061048e33846104ff856040518060600160405280602581526020016114fc6025913933600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d16845290915290205491906110bb565b600061048e338484610e91565b73ffffffffffffffffffffffffffffffffffffffff8716610877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f494e56414c49445f4f574e45520000000000000000000000000000000000000060448201526064016105d7565b834211156108e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f494e56414c49445f45585049524154494f4e000000000000000000000000000060448201526064016105d7565b73ffffffffffffffffffffffffffffffffffffffff87811660008181526006602090815260408083205460075482517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98186015280840196909652958c166060860152608085018b905260a0850181905260c08086018b90528251808703909101815260e08601909252815191909201207f19010000000000000000000000000000000000000000000000000000000000006101008501526101028401949094526101228301939093529061014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000845290830180835281905260ff8816918301919091526060820186905260808201859052915060019060a0016020604051602081039080840390855afa158015610a36573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614610ad4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f494e56414c49445f5349474e415455524500000000000000000000000000000060448201526064016105d7565b610adf82600161146e565b73ffffffffffffffffffffffffffffffffffffffff8a16600090815260066020526040902055610b10898989610cdd565b505050505050505050565b60055473ffffffffffffffffffffffffffffffffffffffff610100909104163314610ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105d7565b73ffffffffffffffffffffffffffffffffffffffff8116610c45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105d7565b60055460405173ffffffffffffffffffffffffffffffffffffffff80841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36005805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff8316610d7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff8216610e22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610f34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105d7565b73ffffffffffffffffffffffffffffffffffffffff8216610fd7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105d7565b611021816040518060600160405280602681526020016114ae6026913973ffffffffffffffffffffffffffffffffffffffff861660009081526020819052604090205491906110bb565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220939093559084168152205461105d9082611102565b73ffffffffffffffffffffffffffffffffffffffff8381166000818152602081815260409182902094909455518481529092918616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610e84565b81830381848211156110fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d7919061129c565b509392505050565b8082018281101561049257600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661118f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105d7565b60025461119c9082611102565b60025573ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020546111cf9082611102565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000815180845260005b818110156112575760208185018101518683018201520161123b565b81811115611269576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006112af6020830184611231565b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461078c57600080fd5b600080604083850312156112ed57600080fd5b6112f6836112b6565b946020939093013593505050565b60008060006060848603121561131957600080fd5b611322846112b6565b9250611330602085016112b6565b9150604084013590509250925092565b60006020828403121561135257600080fd5b6112af826112b6565b60006020828403121561136d57600080fd5b5035919050565b600080600080600080600060e0888a03121561138f57600080fd5b611398886112b6565b96506113a6602089016112b6565b95506040880135945060608801359350608088013560ff811681146113ca57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156113fa57600080fd5b611403836112b6565b9150611411602084016112b6565b90509250929050565b600181811c9082168061142e57607f821691505b60208210811415611468577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082198211156114a8577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b50019056fe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220eabef41c79e988bbef5573106f3825656f6522b0a2771b005adfc744729606a364736f6c634300080a0033"],"ancestors":[],"receipts_trie":{"Digest":"0xec20133021f4eaa7143f313bde563e8b6b5129b826fff732d53e92ab2ba64559"}},"commit":{"evm_commit":{"proof":["0xa2b4219661aa8437152e5e20bef60f76e6c1e906b8001ff043c5d85352a7bb68","0x85655d6022496f1c1de6532c5defe66c2e9248f37265bd93143c2608a20652c4","0xafbc94769ba03f8704f8c6a6d2533983f0af583e72724a1caf659eb5e55247ab","0x6e2ec595133be51cccc7734de154411071e888e33d9a8757b2ebd77af31903cb","0xfe2e9d85d1fd4394cd271377b10432363a92da226962bec6e42f36078ca4427b","0x4404c70f51f6ee7a3dbcf8980df31709f64a05196900b3c1f70a1510c9d8713e","0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0xd16b21c033266b8bd2791d6bd103af1dc9456ae00706fd388058598f5b6c37b1","0x0000000000000000000000000000000000000000000000000000000000000000","0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0xdd8c306a5492e3dc6f4b3d734e26553a55dc24855cab1839505ada48248f793c"],"timestamp":1737477996},"state_commits":[{"state":{"state_trie":{"Branch":[{"Digest":"0x1682d6a69aff1466836073854694713f231bf9b3a9bcbf2f0df21456f7bc161b"},{"Digest":"0x81ff2e09248ef013b446d00b3d9b687fc2158de16a6a77408a458c82d0f5766e"},{"Digest":"0x97de4c5e142bdfe12f5395c8f69abac14805b924046aebd5a2bcc6f39a159c61"},{"Branch":[{"Digest":"0x23e2d74071d10925b81e02734eb03bdad9ac8ce4bac7fce4f3079528d612e7a1"},{"Digest":"0x768062a68c6b04faf81aa2648a813b608e1eb07305ab055cd83f7a50bd79635f"},{"Digest":"0x6a8c0f205014aae9fe87f285567c3c30129611c5f74915c9e3a84165ebd5b507"},{"Digest":"0xafb985d362eba7e7f8c2f74d2ebf53dd1b83e192564de6b32b2cc2bdb06bc0ac"},{"Digest":"0xf55ed11a030413183a70473499e20012ebf1bab60535795abb4063306e4b8dbe"},{"Digest":"0x5e94e9cf8232c7c37d139a18a0b0db9024225441b39b46c9d96d2e189c42a456"},{"Digest":"0x26240ee4042e514373c1fd9261b2e9dcf3eb43e2d8191a30b102afebfe06c070"},{"Branch":[{"Digest":"0x813e88694e112c395d605c9ab52b195020fcc81d985978089b850107690b8f17"},{"Digest":"0xa8483889649928580f0e119488dd70b44e1ca90dc926e4a1586dd6643ab155ef"},{"Digest":"0x1c8dc6df4ca93ef9b3893c38690d2aea58958743bc707241551ef96cfa89b897"},{"Digest":"0x7789cca01671d1a6d727b08fede48be88e64e484f2e81e4069031abca3bf6cf1"},{"Digest":"0x426a3d9fe884fa6770c8f0f72afecb3e1c615f218c79d699ebd1a67cd574812c"},{"Digest":"0xecb4e4d06d87c4b475780001fd7690bc53462714de9d82db9a4361d031ae7f2c"},{"Digest":"0x67ab84e560431b5120f0f27d4262f3ec6f13919fc617b97293cc9b25b56da105"},{"Digest":"0xb93111371b3dcbe0ddca458ef34447cc2bfc6f33822281dc63109cf80bc86d75"},{"Digest":"0x8df729a372ad749caaf8388fb02491385dc4cf1c168eeeb76ea890d5c310b041"},{"Digest":"0x0e1feb58d8bed55ae9a2fc95c480594459499c7e7a1efe85a93537ccb982dba4"},{"Digest":"0x45ea360c6561313262a25c304dc6274bc0e3dc17c695d7d7081a3338161cbcbc"},{"Digest":"0x7d548bf4ddd76aec8d3f789cdbde01bb482b23276c6a38eeb499d715d88fbc34"},{"Digest":"0x74aa71e42fa330a58742736ad2ea83e921db9fba56c6bcd4e03b1860bbcdfaff"},{"Branch":[{"Digest":"0x00d65e2627836d01864ae9fe04c0f1e9ea92a367d24f727abe3e2d3cab12fa4d"},{"Digest":"0x322641a92a831bb28ff1117a68c08849d6da1cc40c272d394b20ca0f62dab5bb"},{"Digest":"0x332c38996195d7b21810038eb6d2b2e35b476592168d8279ea41683889c81186"},{"Digest":"0x8c71801b75d6286327e28f3721ab036728086f8c2d20cd6f3183ceaa340eef16"},{"Digest":"0x548745613d6f887333ad939883d733855fc881ac4569e99f5122f58405c24cb5"},{"Digest":"0x36108069cf8856fc682fb828423bc39cc3cfe8e14c07c3a0c4c5406f369ebdc1"},{"Branch":[{"Digest":"0x3f717187d053de7610aa750d35a11e72f5a0529de7cbecbf9b6d71347c446016"},{"Digest":"0x7b06cf0228a24123b3c960f7af8069c865c0323545f5546763c1f0125047a00b"},{"Digest":"0x6b47eb00de43a9d01a43082b5a504935e16273c53ceeacddd14dd0bea95bd6a9"},{"Digest":"0xe5e96a8eef2891372698feb338eae33d5da575cad71404500314c17d2a2cd2dd"},{"Digest":"0x1c05d1ad089b478a5797164d734f58d2c395c16274640f11056870b83fef3296"},{"Branch":[{"Digest":"0x2f247e5a22f0ce7198a4ad1966f23738b501aaed77d020632f52dac3a7e22a16"},{"Digest":"0xad4037ea4a3a513c45835ae9b5d852bfd30dc8f36d01a1317698140439ebbf03"},{"Digest":"0x4b3e91adde024d4afe22d0e6c074175486343ddfb8438537d6a2d7820f83df88"},{"Digest":"0x5c20dc2ccdcf1c1ce1058f7f156a73bac672e47024c9338b65e6425f3e6a3c31"},{"Digest":"0xd1496149b186e8b2c128bbee2506ecc759b7d26a04ed415b82a1cdedd663a767"},null,{"Digest":"0x6bc5cdca451acb08a6fed8ec2387079caa8b0be4b7cf47478b299c9a3dcfc326"},{"Digest":"0xafaaf0a61608dc252e99cc7cdaf9fcccaff2248657b27593ca9d7c3fb0658e7b"},{"Digest":"0xf29d63eb323d95b203dbc8937a86537fcd8a28e85d161fa9592de2966295b2fc"},{"Digest":"0x257c114cc0b35fc4b6b6b90e672c3291b4fc895ec4b71d8907d2b77f5422c81b"},{"Digest":"0xdad8fdc330ff654dbbd0296bb1a053575081474887da3448a1120fae380f59e2"},{"Digest":"0x985545ddc481849ae5ddc2cf5900bffe97f29cb15c1017719239cd5669fc297a"},{"Digest":"0xb853b8bbd201702acec567d9143a2cabfbe69b41e7e5954b7e68c2123f4ddf29"},null,{"Branch":[{"Digest":"0x1c5a4aaf9f08b6bb295daf3c7e657cb975ca7a329c66d95fab6f216add325278"},null,null,null,{"Digest":"0x1daec8ec74362454b7d8e987a1acf7cf0249a888ddb00d3f866951f99b2ce05c"},null,null,null,null,{"Digest":"0x822d4e5327518af8d2de09ac0cf21fb56b884d941ed455e07cfabd42a5b7cdc7"},{"Leaf":[[10,9,2,12,6,11,12,4,12,1,3,10,5,14,12,4,5,5,2,7,15,0,12,1,8,14,10,8,9,3,2,5,8,8,7,2,8,7,6,9,14,12,7,10,14,12,15,14,6,13,9,15,3,2,14,4,2],[248,68,1,128,160,180,207,193,69,214,197,61,186,60,13,169,189,200,225,119,108,188,23,201,106,245,153,18,69,128,194,86,173,52,118,212,244,160,245,122,205,64,37,152,114,96,109,118,25,126,240,82,243,211,85,136,218,223,145,158,225,240,227,203,155,98,211,244,176,44]]},{"Digest":"0x95800b35e85ae47744cafb4856bfdfcc6b2d13e17d265f05d9f014b038ddbdd0"},null,{"Digest":"0xe3c5b2e09270e962e7452c36f065423f54d5022ef8bf6f537e5a30e6bd44c3ed"},{"Digest":"0x388d852d1803e4a2b77717474b4a1585c950558fde8b753bff7b4299b9d4f697"},null]},{"Digest":"0x35232122da85d17429fd90b530c2a5fcacb9e8c8d4eda8cbd205c0ddca88f112"}]},{"Digest":"0x5765aefa1e63281afff163909df5076adb56d1cc60e8dc1a6d69603ffc443f54"},{"Digest":"0x1b69a993136c9b91de8cbe044aa1cd9d55cf06a163116dcc1b191601c12f0f7b"},{"Digest":"0xdf483184674a267c9be510dd3aaf5092906b9d0c475548262e183af6e6bba106"},{"Digest":"0x4bf0e594a7f5148becae849e9a97f6874f04a5084935f8210ecbdfcd778e00de"},{"Digest":"0xeab9e5c06c33b88f689719c13ebbe47e0a9280e39a3c1582c713eedd506678b8"},{"Digest":"0x9dccdddd3f223d8123312a2082907e46bc6ba6f00554124879d90f06d52a4574"},{"Digest":"0xd8803d474b72b031f7cb87da68ca35d76d6fc143f153ed893d1e5c58e5963173"},{"Digest":"0x8354189eca4df45be0e0c8dbb36a9ad6cf76ad57a2d0b0864b22a5bd5352756e"},{"Digest":"0xe1c1720cf05047ee0878cfe55116ab9d9bef92dfe6f6a78e89cf70971f72f953"},{"Digest":"0x59366bfef026380cc12ce446a620b771882cde11dc203085084d43c1d63e236a"}]},{"Digest":"0x81c68443d0ffa0aaf14067b4cf95ab01ec703d5cc7e888bdf2565ed7451cf5a1"},{"Digest":"0xfd6f6aaf64cfadc32012538ed38db1afcf503d819d3e58090cd114aedc02dff2"},{"Digest":"0x2e8b846abce330b1349f9408aebccaee2582a5829b47b98b38079e91c19f9848"},{"Digest":"0x3a44cabf2f028002ccc7d6b8463f357e28563eea32af4f4518995c4b55116aff"},{"Digest":"0x3455f7673616937eb3035411889c1002002208e5e68db15d49a665a614902424"},{"Digest":"0xca12170531fe35f138fc9f793bc5ed2e927d0f53cad038fdea02e7638be7dda6"},{"Digest":"0xa0d21fb59eb4f198ead0f380cca955c9cc90660a97658255ac7dc7c083e85ec6"},{"Digest":"0x30cdd6807a010c79ac6b5e76241ad3495aab6e2213f6c5d9ebf5312a059d7954"},{"Digest":"0xd258c58dfc7c89ff2c672f748f9bc5ad2b6500f6897498b29c232a704604a867"}]},{"Digest":"0x7febec264575dd0a160200273d69eaae205bd01e1667184b84a69a1b02e97b85"},{"Digest":"0x056ad7980c76e7f2c48bebc3a8922c18afd39816cf067532c7ae36b59c23bf8a"}]},{"Digest":"0x15f855a8222d5da1d239fc0f0a8cd6ae8d883d17fb08857684e4504202a449d9"},{"Digest":"0xd56540fed2a10749b023a5e1bc5d45b2755044a73ee773603f17e829cd014eaa"},{"Digest":"0x3a4a209f6b024d01dab1e04bfac431d96ac4e63e0e50dd93e5194171aa8b6393"},{"Digest":"0xc612a114a5d2698b424ed3b8ae05bc30ce0cbc45c5c5efb45b97470c6d39816e"},{"Digest":"0xc351b743b36410ce3db660cc916b2f6ba3578e20c6a63fd261001f214a5d8b19"},{"Digest":"0x07cc13215c6a802f81f2e1e8dec9a6e561f4bca8daa218e24e7a679afe6ab6f0"},{"Digest":"0x3083b9da67ac870a9bb4420a3fe7c570c1ab142309bbf468954ce2bba4272a25"},{"Digest":"0x2526b73d3fa6a930e874f56a7a398b02d4bb80e21818b03600f9732bb988db97"}]},{"Digest":"0x348c15ab43b48f674ec8dd403bda8740c251f06196ff9145f31817368203f2e9"},{"Digest":"0x9e11e9e82463a4f3e79d238aad7d65c695fed57016cf56d59507f57904b5e794"},{"Digest":"0x8f9061c2bc0a30285579321862ca2e207d240373e06fc0d2b7732542c8a97b1b"},{"Digest":"0x6af7f9830bc0be5f66579efce7da60ce941f8833e18dba9c13c39beb21e8462d"},{"Digest":"0x0c588d77e73569f7b14dbe1b062afdc7e898059514f1f26c56d1e6380cd789d0"},{"Digest":"0xa58213804832dacfa45fe5464f127a7d4d820414cf6bb03ffa8fac316e419d43"},{"Digest":"0xffe7b0830ceec874e4199d6653fa8bc4d6d84a8f960bc547472f43d80c786b87"},{"Digest":"0x4cd53c740c2b8b9dd323ef4b56ffe14eb75058366e5582a59e2c040837298695"},{"Digest":"0x1a45639fe5de0207c9fac8c0644e23528be805561a582aa15f2c55958e9b6f6e"},{"Digest":"0x189c011edfdb636a192539d212b0cdf862d2dcccf0e327245b5e52be71d1ad8b"},{"Digest":"0x0d26c5a43e0368fc03c3017e869988184ed64e51a9bf3a0ca2e42125966c606a"},{"Digest":"0xcb709504f7e1a8f78a9e70125b4413cea768b784a5176aef292963630becedb1"}]},"storage_trie":{"Branch":[{"Digest":"0x97343fab66c518117ef0bd5e560ab63b72fb2820a71e05e432ba353dddde37e0"},{"Digest":"0x60bc7235a908544a865594fd1b58572f4c78aa187abe4cee104ed3a07fb061d6"},{"Digest":"0xc19749dae622edb562f90d936428bedab34fde3a4ed4d808eb7a54313f9bd5ea"},{"Branch":[{"Digest":"0x4e8a38e16904d0ffa850ef62abc481d2ae45de256ccdc74bdf011697b3f27841"},{"Digest":"0x90a0ea9a52716db8ac5186d07c2fcd7cedce554578a466c62da7dddf00595f0e"},{"Digest":"0x398919ad8b769bc7df60e6d766013d7c76d3f99687e6c1eda48cd1fb4a5eb766"},{"Digest":"0x9bed1b15fc95c9545af1c61bcce03514b59b5b2c876d0eb954a2cc33b80898ad"},{"Branch":[{"Branch":[{"Digest":"0x20a4ccd27922e5a5c84cf31ddacd8a97db11de6b10db71d97f7b833e8237f174"},null,null,null,null,null,null,null,null,null,{"Leaf":[[13,2,7,3,1,2,2,1,9,7,12,11,10,3,13,3,15,0,0,13,3,11,9,6,13,1,12,4,5,1,8,13,14,5,13,13,12,13,5,12,7,1,15,2,11,4,6,12,1,12,5,5,13,13,13,10,5,14,6,0],[132,103,143,207,108]]},null,{"Digest":"0x84de926a9f95cd60a2755cec2dd3749ec160e9f3bea898f23a9cedfacd6b58fd"},null,null,null]},{"Digest":"0x3be03fcf85b6b23888b5077999596b16eba792c81c6d9d7e32259c5264d33962"},{"Digest":"0x3669a7bafce813e156dae4b90203f16926c6ac2f9b0078f0c4390df09993c2d9"},{"Digest":"0x0ff3462604f42f3786943bb0ea32c4df02486e7164fd44424991a7449c1d14de"},{"Digest":"0x74962aa857f381febe7dcd3d3e844f52fc821baa3da056bd7ea6c6512ca8523a"},{"Digest":"0xd6d6e2ac2e907e044af206e9eaadff8667287a716caf76761457ecd13896e745"},{"Digest":"0xd7f5002e1bcfed399a22efb281f5c93d81a233ca3e3b393626988150737d9b95"},{"Digest":"0xa83d0c6a759a0f72f8c17827bf76e88e3ec6de325bedae4685e2bfb6163ff54a"},{"Digest":"0x2bc68b9b2f22775b726fb13963d388c76b65fffcb54bd77953d170b379d8c1e0"},{"Digest":"0xb00f7f470add07e86feb9a041d2986181ec643e4f96a79ff6ded59f905616e96"},{"Digest":"0x0d5d5973f11b4636f7a3bbae9f501f9c46109edeb61facd6e3ff699bd2f8fa82"},{"Digest":"0x0d1b812488d93235b6df45ef9678b586db4b48d6b2db5c6c370c32b74cfab4fb"},{"Digest":"0xd4903fdcf57ff343cdefb0a985fe46a9bdfc3317121539f547deb87fd1956c2f"},{"Digest":"0xe1aaac1227cbe4b76b8fa2d76f9701baa4ec6d7628d0f11d7ac015735ec39a18"},{"Digest":"0xde3e12a897325de32fc8cd38697513ee5d26f2566c95b5e6ba0c76960a386afb"},{"Digest":"0xaa86e491cb65fe4925095af23e8807de1e94440bd92d12265c221eb58f276ee3"}]},{"Digest":"0x3b7ed405572b24e5311955fd498346308babf15b841e5b47bcc225d460e9ace0"},{"Digest":"0x3d8dfbc77e8e78139d8c9ee6f2beb443f432fb010baec4065c02ae7ed37189e3"},{"Digest":"0xb940579d1e659ce103e51389c55d465cfc83cfd5e7be6edad32bd77c72354c23"},{"Digest":"0xef3d0f9a9ffaadd7b4a0f91c77f0fcc02aa666994f739e70f921a7a28dfbb589"},{"Digest":"0x3bd0ff54993a118015b4370dbf74b59408dbaef3d761e64ef8cfc7766dc49876"},{"Digest":"0x12a7ed0c27df4eb9555b40d73714a486f416a4f4437e18ce513d0cd461b6b748"},{"Digest":"0x85fa8e8fb1ee7d9728862659d762910e9ee063da8736cc83fb67ba0f5880d223"},{"Digest":"0xcaa9760f0c2d0b206ac7ddb0ce5c51b93d25a93390e0c9ec98888f39c04e103a"},{"Digest":"0xae8046e75e93882944cf8500f3b481d51d271e825baed795cc45bc943465725c"},{"Digest":"0x4cec04eba711d82b38b00b017b625f89747fef8cdd615713b5577ebd8f658d02"},{"Digest":"0x6b5de212aa4b4d12d82deacbf5be28157255b39c197d6d3429195bf4b962af9c"}]},{"Digest":"0x2b6afc854a1dffd09a3eb2a2e5d8957cb8daa641fe4235d03eafe0db1f275d86"},{"Digest":"0x12577df1369d01af1b834c270ba399fe1bf4b58c87499acb2886efea765e8d24"},{"Digest":"0xe80b42ea3bee3ad87e34ccbbe62917e68a5835d2ef770d26fecc5d218820c34d"},{"Digest":"0x5d6da50ca324d435b30de80847c7bb6ada7e5fde610318443db14a4cf3c51705"},{"Branch":[{"Digest":"0xe3732333dd64d2565912fe0fe660e6a98c5162c2c6930f3774266514aa29f353"},{"Digest":"0x812c5f9792befc43cfceeacade997266dd4d60fbe115a97e990b45638cc7a9db"},{"Digest":"0x293022023d73c87d67802212872e834e7ed2149a3b90638f611ccb02500646df"},{"Digest":"0x08bb79b64b96ceb7f2899fbf8d2c22e3079c7e2c138697cde23219206d116d5a"},{"Digest":"0xdfa418e1780578897325a6acb79a30e7e18b2ef52a38c0a9b2f54dd149c4c6da"},{"Digest":"0x3004f9c6e0fe0ee4803269a2cc20cc7b63042b97980a210f459d44a029b3cc07"},{"Digest":"0x9e7fb8a4bf142c9899c9e12b41255e6098b8089ee1c525b6dfd0ce6ffb5093bd"},{"Digest":"0x623bd93c23215fdae7d627d470b7bb0302fa09340498877ecb722e1f0b66bae7"},{"Digest":"0x04bba63e43d1a68d56c2f55162e71f71b97c3b424b5505e8e9de8b1b31486f77"},{"Digest":"0xcb3fed4650c1c096b6bedd90be94ca013d5a5120ea117a4deabc6d28cf08ea0f"},{"Branch":[{"Digest":"0x8f1d0e89a35a86bdd122840b250fbb7077f58154beebb61c41c075e319bc2db2"},{"Digest":"0x872b5715f1e48119b0df6fc0f139d6b529294f42d5b948621b235c3a4bb19f96"},{"Digest":"0x84485bc5be502e78c9c64b46514dd5b46d93f6a289ff33479e20c1f033d1fe20"},{"Digest":"0x0196660547a0e8b1eca99969f3affbf8b9d8e58ff3b8a124058ef264291d4a52"},{"Digest":"0x08547492a1e70f1e47fd0854050ced8a083f2a2b65c713f855dc18cf0b3ef1ea"},{"Digest":"0x9e47fc7229d9ce77560229953cde5ede9b84d22bfc4a39a6b3d04a7ba7cc7fc1"},{"Digest":"0x5630a9fd6b9d1c160002b25490a274be3cb2e850301fd924bf19509c266e2c1b"},{"Digest":"0x6975c3248193e298d63bea6108dd9a8abae0b90d8516a3f4b6bc521ee608a8f9"},{"Digest":"0x9fc9a5af65205eb549bf64e5bb347fee45e25d652da25604cccb7f1a389df79a"},{"Digest":"0xa747621b9e1038ec1edefeba026b3c5d769f5beca90b96d01319f8d9666b8759"},{"Digest":"0x1e8f1a057c107edc8ccff1290e41016d3e5214e1a649b7756512816bf6a6dc84"},{"Digest":"0x40316584ad56679121098045b5c1c36e16e6993893ee0645896e6c47a2ad6547"},{"Branch":[null,null,null,null,null,null,{"Digest":"0xaf164cfc2da24d2706eb3ff9e602f03b28fd1cdecba41c7e267310739b92ec01"},null,null,{"Leaf":[[1,7,7,1,3,3,11,3,11,4,8,11,15,11,15,14,6,13,5,7,15,15,9,7,15,15,5,0,3,10,3,5,5,15,1,0,12,1,13,13,7,4,11,0,15,2,10,9,3,6,1,2,4,5,9,9,10,6,7,4],[160,64,195,98,6,73,21,60,146,19,231,163,6,170,30,141,84,113,251,247,139,234,17,37,139,27,229,34,204,159,53,195,9]]},null,null,null,{"Digest":"0xfae105a6affb8b0b919e2795de8ac19214efed235fa18d849fcbeb30111c493d"},null,null]},{"Digest":"0x1a823a6d6a79b94e10590836ba9f7a5c9a1143d98643e745a0a1821ff6083e0f"},{"Digest":"0x331b13e29b569f39d868abb29cd9f7ef59c65185bdbe2e1b3c619eaa5fc376a3"},{"Digest":"0x3cde8e161bddae6c22a6ef3490242058a8f52f62897f7aa6ac74e792e35218e2"}]},{"Digest":"0x73a07a91496318aa1067ecb704a3504c1b228cde2e06755fcfe0d50fb8b94e2a"},{"Digest":"0xd6fd88f9343f8403c742026d886ecc627415c4b5766a14770ab4eedf437468c4"},{"Digest":"0x59ce89290217d386929d1fc9de95fdf3f57ba35501cd20f16ad61c20a6b12839"},{"Digest":"0x5f50d0abb943f6d9ed5e77eaa12f8a63597a61c120d547dea21761111dd436d7"},{"Digest":"0xbbf9b51ad8ac565bb8fb1bd2b6b019a996842373defd0943c172d7f0bc3a81fd"}]},{"Digest":"0x57bc90f0241e936537ff4e4bac97f9bbb09490af43082091cc957806bb12a19d"},{"Digest":"0x24d2282fa97888c63359b0ce41cd7624fb5dbcfde374e4bee52013af3bea0f1e"},{"Digest":"0x15c6d2e712cff9e75722e5acb6f55180c7c874e97f26523c10f0d4262ad1f306"},{"Digest":"0xb52e01c9cf50bea1ce625f945c1f89e165a05384106ec5925b95820503790665"},{"Digest":"0xfbec43d6b77973fe6c388a4dc136dbab1bff2fd6b6a27e9dc59ea21e8df1d743"},{"Digest":"0x21ec8879796470f58d2297a13dafca2bfb8e7adfe13039cc4cf735b23255264e"},{"Digest":"0x71575df2119535c468a3857ebc665fd4bdcafcd7d29dc33a048b835507c7c0b2"}]}},"state_commit":{"proof":["0xf61625e6febc6e60a810be085e8ff1622e9f62d52ae6b79f161b4c3676f5937c","0x2cb0eb01d39b4f25bdbfa710cdb59aeef929aa105f34920e592c4d8184d353d4","0x0f89506e1dc774cf973deee0dac6b89cdb7beab37e8343806521a39783a71e47","0xab7da1269689dec7bc1d7cdfb7ee5d649695641a5e02183d769bca6a3a0606b8","0xffafd4f3151469647eb6e315b7a44ae53494f432c624e0b65a9d0e7d37e959b6","0x10aaf23a31e69a3be518650f0991813ca1797c674e57b419b4e9e06533189e92","0x5cf4da766beaed11c7f0ac71f7d57c55004ad3344768c5695e000c763d80a661","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0x684e523bd6b0bf8600fe714487f8d2e998f8e830459ce2f42d3889bb39fce296","0x0000000000000000000000000000000000000000000000000000000000000000","0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0x6368a11ecc2e7dbc4f4b85ffe5f4e92ece00baa8e06a07e4cd9f6518aa5348c5"],"timestamp":1737478584}}]}}} \ No newline at end of file diff --git a/crates/steel/tests/corruption.rs b/crates/steel/tests/corruption.rs index fbaed0f4..b8a8673f 100644 --- a/crates/steel/tests/corruption.rs +++ b/crates/steel/tests/corruption.rs @@ -421,7 +421,8 @@ mod history { use super::*; use test_log::test; - /// Creates `EthEvmInput::History` using live RPC nodes preflighting `IERC20(USDT).balanceOf(0x0)`. + /// Creates `EthEvmInput::History` using live RPC nodes preflighting + /// `IERC20(USDT).balanceOf(0x0)`. async fn rpc_usdt_history_input() -> anyhow::Result { let mut env = EthEvmEnv::builder() .rpc(RPC_URL.parse()?) diff --git a/crates/steel/tests/steel.rs b/crates/steel/tests/steel.rs index 305b76a2..7dcae197 100644 --- a/crates/steel/tests/steel.rs +++ b/crates/steel/tests/steel.rs @@ -25,7 +25,7 @@ use alloy::{ use alloy_primitives::{address, b256, bytes, hex, Address, Bytes, U256}; use alloy_sol_types::SolCall; use common::{CallOptions, ANVIL_CHAIN_SPEC}; -use risc0_steel::{ethereum::EthEvmEnv, Contract}; +use risc0_steel::{ethereum::EthEvmEnv, Contract, Event}; use sha2::{Digest, Sha256}; use test_log::test; @@ -34,19 +34,26 @@ mod common; const STEEL_TEST_CONTRACT: Address = address!("5fbdb2315678afecb367f032d93f642f64180aa3"); alloy::sol!( // docker run -i ethereum/solc:0.8.26 - --optimize --bin - #[sol(rpc, bytecode="60e060405234801561000f575f80fd5b505f60405161001d906100c4565b908152602001604051809103905ff08015801561003c573d5f803e3d5ffd5b506001600160a01b0316608052604051602a90610058906100c4565b908152602001604051809103905ff080158015610077573d5f803e3d5ffd5b506001600160a01b031660a052604051602a90610093906100c4565b908152602001604051809103905ff0801580156100b2573d5f803e3d5ffd5b506001600160a01b031660c0526100d0565b60c98061064e83390190565b60805160a05160c0516105546100fa5f395f6101b901525f61023901525f6102b901526105545ff3fe608060405234801561000f575f80fd5b50600436106100a6575f3560e01c8063413171851161006e5780634131718514610107578063445bda431461010e57806370239222146101165780637d732b5f1461011e578063ab8fd80c14610124578063d62f7a421461012f575f80fd5b80630692d13c146100aa578063163e004a146100c05780631e79fe8c146100c75780632e8bde39146100e757806330e4966314610101575b5f80fd5b5f3b5b6040519081526020015b60405180910390f35b5f546100ad565b6100da6100d53660046103f7565b610142565b6040516100b79190610465565b325b6040516001600160a01b0390911681526020016100b7565b3a6100ad565b443b6100ad565b6100ad6101b6565b6100ad610350565b466100ad565b4360ff1901406100ad565b6100e961013d36600461049a565b610392565b60605f80600a6001600160a01b031685856040516101619291906104d9565b5f60405180830381855afa9150503d805f8114610199576040519150601f19603f3d011682016040523d82523d5f602084013e61019e565b606091505b5091509150816101ac575f80fd5b9150505b92915050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610213573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023791906104e8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610293573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102b791906104e8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610313573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061033791906104e8565b61034191906104ff565b61034b91906104ff565b905090565b6040515f906002906020818481855afa15801561036f573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061034b91906104e8565b604080515f8082526020820180845287905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa1580156103e3573d5f803e3d5ffd5b5050604051601f1901519695505050505050565b5f8060208385031215610408575f80fd5b823567ffffffffffffffff81111561041e575f80fd5b8301601f8101851361042e575f80fd5b803567ffffffffffffffff811115610444575f80fd5b856020828401011115610455575f80fd5b6020919091019590945092505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f805f80608085870312156104ad575f80fd5b84359350602085013560ff811681146104c4575f80fd5b93969395505050506040820135916060013590565b818382375f9101908152919050565b5f602082840312156104f8575f80fd5b5051919050565b808201808211156101b057634e487b7160e01b5f52601160045260245ffdfea264697066735822122075dab15b6b833f12828453c07f6064f3d73d2b3056968cae053a337303dd249b64736f6c634300081a00336080604052348015600e575f80fd5b5060405160c938038060c9833981016040819052602991602f565b5f556045565b5f60208284031215603e575f80fd5b5051919050565b60798060505f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3fea2646970667358221220120e1fe19e13f245d9779578380d3ba162142d3e5bf63f5e5f83dbe878cdb44464736f6c634300081a0033")] + #[sol(rpc, bytecode="60e060405234801561000f575f80fd5b505f60405161001d906100c4565b908152602001604051809103905ff08015801561003c573d5f803e3d5ffd5b506001600160a01b0316608052604051602a90610058906100c4565b908152602001604051809103905ff080158015610077573d5f803e3d5ffd5b506001600160a01b031660a052604051602a90610093906100c4565b908152602001604051809103905ff0801580156100b2573d5f803e3d5ffd5b506001600160a01b031660c0526100d0565b60c9806106bd83390190565b60805160a05160c0516105c36100fa5f395f6101d901525f61025901525f6102d901526105c35ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c8063445bda431161006e578063445bda431461011957806370239222146101215780637d732b5f14610129578063ab8fd80c1461012f578063d62f7a421461013a578063dcd9c7fa1461014d575f80fd5b80630692d13c146100b5578063163e004a146100cb5780631e79fe8c146100d25780632e8bde39146100f257806330e496631461010c5780634131718514610112575b5f80fd5b5f3b5b6040519081526020015b60405180910390f35b5f546100b8565b6100e56100e036600461044f565b610162565b6040516100c291906104bd565b325b6040516001600160a01b0390911681526020016100c2565b3a6100b8565b443b6100b8565b6100b86101d6565b6100b8610370565b466100b8565b4360ff1901406100b8565b6100f46101483660046104f2565b6103b2565b61016061015b366004610531565b610417565b005b60605f80600a6001600160a01b03168585604051610181929190610548565b5f60405180830381855afa9150503d805f81146101b9576040519150601f19603f3d011682016040523d82523d5f602084013e6101be565b606091505b5091509150816101cc575f80fd5b9150505b92915050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610233573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102579190610557565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102b3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102d79190610557565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610333573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103579190610557565b610361919061056e565b61036b919061056e565b905090565b6040515f906002906020818481855afa15801561038f573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061036b9190610557565b604080515f8082526020820180845287905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610403573d5f803e3d5ffd5b5050604051601f1901519695505050505050565b60405181815233907ffceb437c298f40d64702ac26411b2316e79f3c28ffa60edfc891ad4fc8ab82ca9060200160405180910390a250565b5f8060208385031215610460575f80fd5b823567ffffffffffffffff811115610476575f80fd5b8301601f81018513610486575f80fd5b803567ffffffffffffffff81111561049c575f80fd5b8560208284010111156104ad575f80fd5b6020919091019590945092505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f805f8060808587031215610505575f80fd5b84359350602085013560ff8116811461051c575f80fd5b93969395505050506040820135916060013590565b5f60208284031215610541575f80fd5b5035919050565b818382375f9101908152919050565b5f60208284031215610567575f80fd5b5051919050565b808201808211156101d057634e487b7160e01b5f52601160045260245ffdfea264697066735822122068527ecb48b2f64d4c87b5c5e8547df603acc1278e655ed3ead63c589214cd7264736f6c634300081a00336080604052348015600e575f80fd5b5060405160c938038060c9833981016040819052602991602f565b5f556045565b5f60208284031215603e575f80fd5b5051919050565b60798060505f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3fea264697066735822122055ec461f1b52480526d28c3d6eead42b479b2cdb07009d195d7aee625de3073964736f6c634300081a0033")] #[derive(Debug, PartialEq, Eq)] contract SteelTest { Value internal immutable VALUE0; Value internal immutable VALUE42A; Value internal immutable VALUE42B; + event Event(address indexed from, uint256 value); + constructor() { VALUE0 = new Value(0); VALUE42A = new Value(42); VALUE42B = new Value(42); } + /// Emits a test event. + function testEvent(uint256 value) external { + emit Event(msg.sender, value); + } + /// Tests the ecRecover precompile. function testECRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) external pure returns (address) { return ecrecover(hash, v, r, s); @@ -128,6 +135,81 @@ async fn test_provider() -> impl Provider { provider } +#[test(tokio::test)] +async fn event_query_some() { + let provider = test_provider().await; + let contract = SteelTest::new(STEEL_TEST_CONTRACT, &provider); + + const VALUE: U256 = uint!(42_U256); + // send a transaction to emit an event on chain + let pending = contract.testEvent(VALUE).send().await.unwrap(); + pending.watch().await.unwrap(); + + let mut env = EthEvmEnv::builder() + .provider(provider) + .build() + .await + .unwrap() + .with_chain_spec(&ANVIL_CHAIN_SPEC); + + let preflight_logs = { + let event = Event::preflight::(&mut env).address(STEEL_TEST_CONTRACT); + event.query().await.unwrap() + }; + + let input = env.into_input().await.unwrap(); + let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); + + let logs = { + let event = Event::new::(&env).address(STEEL_TEST_CONTRACT); + event.query() + }; + assert_eq!(logs, preflight_logs, "mismatch in preflight and execution"); + assert!( + matches!( + logs.as_slice(), + [alloy_primitives::Log { + address: STEEL_TEST_CONTRACT, + data: SteelTest::Event { value: VALUE, .. }, + }] + ), + "Unexpected event logs: {:?}", + logs + ); +} + +#[test(tokio::test)] +async fn event_query_none() { + let provider = test_provider().await; + + // send a transaction to emit an event on chain + let contract = SteelTest::deploy(&provider).await.unwrap(); + let pending = contract.testEvent(U256::ZERO).send().await.unwrap(); + pending.watch().await.unwrap(); + + let mut env = EthEvmEnv::builder() + .provider(provider) + .build() + .await + .unwrap() + .with_chain_spec(&ANVIL_CHAIN_SPEC); + + let preflight_logs = { + let event = Event::preflight::(&mut env).address(STEEL_TEST_CONTRACT); + event.query().await.unwrap() + }; + + let input = env.into_input().await.unwrap(); + let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); + + let logs = { + let event = Event::new::(&env).address(STEEL_TEST_CONTRACT); + event.query() + }; + assert_eq!(logs, preflight_logs, "mismatch in preflight and execution"); + assert!(logs.is_empty()); +} + #[test(tokio::test)] async fn ec_recover() { let result = common::eth_call( From 5bfd6d9fc29b17cb0a809126adc4d6854e0f3819 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 22 Jan 2025 20:47:38 +0100 Subject: [PATCH 02/14] improve documentation --- crates/steel/src/event.rs | 43 +++++++++++++++++++++++++++++++++++++++ crates/steel/src/state.rs | 12 +++++------ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/crates/steel/src/event.rs b/crates/steel/src/event.rs index d4289531..1164fb7c 100644 --- a/crates/steel/src/event.rs +++ b/crates/steel/src/event.rs @@ -21,6 +21,48 @@ use alloy_sol_types::SolEvent; use std::marker::PhantomData; /// Represents an Ethereum event query. +/// +/// ### Usage +/// - **Preflight calls on the Host:** To prepare calls on the host environment and build the +/// necessary proof, use [Event::preflight]. +/// - **Calls in the Guest:** To initialize the contract in the guest environment, use [Event::new]. +/// See [Contract] for more details. +/// +/// ### Examples +/// ```rust,no_run +/// # use risc0_steel::{ethereum::EthEvmEnv, Event}; +/// # use alloy_primitives::address; +/// # use alloy_sol_types::sol; +/// +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() -> anyhow::Result<()> { +/// let contract_address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); +/// sol! { +/// # #[derive(Debug)] +/// interface IERC20 { +/// event Transfer(address indexed from, address indexed to, uint256 value); +/// } +/// } +/// +/// // Host: +/// let url = "https://ethereum-rpc.publicnode.com".parse()?; +/// let mut env = EthEvmEnv::builder().rpc(url).build().await?; +/// let event = Event::preflight::(&mut env).address(contract_address); +/// event.query().await?; +/// +/// let evm_input = env.into_input().await?; +/// +/// // Guest: +/// let env = evm_input.into_env(); +/// let event = Event::new::(&env).address(contract_address); +/// let logs = event.query(); +/// # dbg!(logs); +/// +/// # Ok(()) +/// # } +/// ``` +/// +/// [Contract]: crate::Contract pub struct Event { filter: Filter, env: E, @@ -105,6 +147,7 @@ mod host { /// /// [EvmEnv::into_input]: crate::EvmEnv::into_input /// [EvmEnv]: crate::EvmEnv + /// [Provider]: alloy::providers::Provider pub fn preflight( env: &mut HostEvmEnv, ) -> Event> { diff --git a/crates/steel/src/state.rs b/crates/steel/src/state.rs index 24c8f6a6..44c2c5ed 100644 --- a/crates/steel/src/state.rs +++ b/crates/steel/src/state.rs @@ -12,22 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{convert::Infallible, rc::Rc}; +pub use alloy_consensus::Account as StateAccount; -use crate::mpt::MerkleTrie; +use crate::{event, mpt::MerkleTrie, EvmBlockHeader, EvmDatabase}; use alloy_primitives::{ keccak256, map::{AddressHashMap, B256HashMap, HashMap}, Address, Bytes, Log, Sealed, B256, U256, }; +use alloy_rpc_types::{Filter, FilteredParams}; use revm::{ primitives::{AccountInfo, Bytecode}, Database as RevmDatabase, }; - -use crate::{event, EvmBlockHeader}; -pub use alloy_consensus::Account as StateAccount; -use alloy_rpc_types::{Filter, FilteredParams}; +use std::{convert::Infallible, rc::Rc}; /// A simple MPT-based read-only EVM database implementation. /// @@ -195,7 +193,7 @@ impl RevmDatabase for WrapStateDb<'_, H> { } } -impl crate::EvmDatabase for WrapStateDb<'_, H> { +impl EvmDatabase for WrapStateDb<'_, H> { fn logs(&mut self, filter: Filter) -> Result, ::Error> { assert_eq!(filter.get_block_hash(), Some(self.header.seal())); From a09842247b8ad1cc1476df15667e479125fc2e13 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 10:59:16 +0100 Subject: [PATCH 03/14] fix serialization --- crates/steel/src/block.rs | 17 +-- crates/steel/src/event.rs | 1 + crates/steel/src/lib.rs | 1 + crates/steel/src/serde.rs | 222 ++++++++++++++++++++++++++++++-------- crates/steel/src/state.rs | 11 +- 5 files changed, 193 insertions(+), 59 deletions(-) diff --git a/crates/steel/src/block.rs b/crates/steel/src/block.rs index 6a3b13c7..3fb98d1b 100644 --- a/crates/steel/src/block.rs +++ b/crates/steel/src/block.rs @@ -13,12 +13,11 @@ // limitations under the License. use crate::{ - config::ChainSpec, state::StateDb, BlockHeaderCommit, Commitment, CommitmentVersion, - EvmBlockHeader, EvmEnv, GuestEvmEnv, MerkleTrie, + config::ChainSpec, serde::Eip2718Wrapper, state::StateDb, BlockHeaderCommit, Commitment, + CommitmentVersion, EvmBlockHeader, EvmEnv, GuestEvmEnv, MerkleTrie, }; use ::serde::{Deserialize, Serialize}; use alloy_consensus::ReceiptEnvelope; -use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{map::HashMap, Bytes, Sealed, B256}; /// Input committing to the corresponding execution block hash. @@ -29,7 +28,7 @@ pub struct BlockInput { storage_tries: Vec, contracts: Vec, ancestors: Vec, - receipts: Option>, + receipts: Option>>, } /// Implement [BlockHeaderCommit] for the unit type. @@ -77,14 +76,12 @@ impl BlockInput { // verify the root hash of the included receipts and extract their logs let logs = self.receipts.map(|receipts| { - let root = alloy_trie::root::ordered_trie_root_with_encoder(&receipts, |r, buf| { - r.encode_2718(buf); - }); + let root = alloy_trie::root::ordered_trie_root(&receipts); assert_eq!(header.receipts_root(), &root, "Receipts root mismatch"); receipts .into_iter() - .flat_map(|envelope| match envelope { + .flat_map(|wrapper| match wrapper.into_inner() { ReceiptEnvelope::Legacy(t) => t.receipt.logs, ReceiptEnvelope::Eip2930(t) => t.receipt.logs, ReceiptEnvelope::Eip1559(t) => t.receipt.logs, @@ -117,6 +114,7 @@ pub mod host { use super::BlockInput; use crate::{ host::db::{AlloyDb, ProofDb, ProviderDb}, + serde::Eip2718Wrapper, EvmBlockHeader, }; use alloy::{ @@ -161,6 +159,9 @@ pub mod host { } let receipts = db.receipt_proof().await?; + // wrap the receipts so that they can be serialized + let receipts = + receipts.map(|receipts| receipts.into_iter().map(Eip2718Wrapper::new).collect()); debug!("state size: {}", state_trie.size()); debug!("storage tries: {}", storage_tries.len()); diff --git a/crates/steel/src/event.rs b/crates/steel/src/event.rs index 1164fb7c..9527f709 100644 --- a/crates/steel/src/event.rs +++ b/crates/steel/src/event.rs @@ -26,6 +26,7 @@ use std::marker::PhantomData; /// - **Preflight calls on the Host:** To prepare calls on the host environment and build the /// necessary proof, use [Event::preflight]. /// - **Calls in the Guest:** To initialize the contract in the guest environment, use [Event::new]. +/// /// See [Contract] for more details. /// /// ### Examples diff --git a/crates/steel/src/lib.rs b/crates/steel/src/lib.rs index e2f6579b..a5f0b4d0 100644 --- a/crates/steel/src/lib.rs +++ b/crates/steel/src/lib.rs @@ -174,6 +174,7 @@ impl EvmEnv { self.db.as_ref().unwrap() } + #[cfg(feature = "host")] pub(crate) fn db_mut(&mut self) -> &mut D { // safe unwrap: self cannot be borrowed without a DB self.db.as_mut().unwrap() diff --git a/crates/steel/src/serde.rs b/crates/steel/src/serde.rs index 3da9d249..3a40007a 100644 --- a/crates/steel/src/serde.rs +++ b/crates/steel/src/serde.rs @@ -13,11 +13,14 @@ // limitations under the License. //! Serde related helpers. -use std::fmt::{self, Debug}; - -use alloy_primitives::{hex, keccak256, Sealable, Sealed, B256}; +use alloy_eips::eip2718::{Eip2718Envelope, Encodable2718}; +use alloy_primitives::{bytes::BufMut, hex, keccak256, Sealable, Sealed, B256}; use alloy_rlp::{Decodable, Encodable}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use std::{ + fmt::{self, Debug}, + ops, +}; /// An efficient wrapper for header types that do not support serde serialization. /// @@ -26,15 +29,15 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; #[derive(Clone, Debug)] pub struct RlpHeader { inner: H, - rlp: Option>, + rlp: Option>, } -impl std::ops::Deref for RlpHeader { +impl ops::Deref for RlpHeader { type Target = H; #[inline] fn deref(&self) -> &Self::Target { - self.inner() + &self.inner } } @@ -44,10 +47,12 @@ impl RlpHeader { pub const fn new(inner: H) -> Self { Self { inner, rlp: None } } + #[inline] pub fn inner(&self) -> &H { &self.inner } + #[inline] pub fn inner_mut(&mut self) -> &mut H { &mut self.inner @@ -55,7 +60,6 @@ impl RlpHeader { } impl Sealable for RlpHeader { - /// Calculate the seal hash, this may be slow. #[inline] fn hash_slow(&self) -> B256 { match &self.rlp { @@ -74,10 +78,11 @@ impl Sealable for RlpHeader { impl Serialize for RlpHeader { #[inline] fn serialize(&self, serializer: S) -> Result { + let encoded = alloy_rlp::encode(&self.inner); if serializer.is_human_readable() { - hex::serialize(alloy_rlp::encode(&self.inner), serializer) + hex::serialize(&encoded, serializer) } else { - serializer.serialize_bytes(&alloy_rlp::encode(&self.inner)) + serializer.serialize_bytes(&encoded) } } } @@ -85,46 +90,16 @@ impl Serialize for RlpHeader { impl<'de, H: Encodable + Decodable> Deserialize<'de> for RlpHeader { #[inline] fn deserialize>(deserializer: D) -> Result { - struct BytesVisitor; - - impl<'de> de::Visitor<'de> for BytesVisitor { - type Value = Vec; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("bytes represented as a hex string, sequence or raw bytes") - } - - fn visit_str(self, v: &str) -> Result { - hex::decode(v).map_err(de::Error::custom) - } - fn visit_bytes(self, v: &[u8]) -> Result { - Ok(v.to_vec()) - } - fn visit_byte_buf(self, v: Vec) -> Result { - Ok(v) - } - fn visit_seq>(self, mut seq: A) -> Result { - let mut values = Vec::with_capacity(seq.size_hint().unwrap_or(0)); - while let Some(value) = seq.next_element()? { - values.push(value); - } - Ok(values) - } - } - - // deserialize the byte vector let rlp = if deserializer.is_human_readable() { deserializer.deserialize_any(BytesVisitor)? } else { deserializer.deserialize_byte_buf(BytesVisitor)? }; - // the RLP-encoding is not malleable, as long as we make sure that there are no additional - // bytes after the RLP-encoded data let inner = alloy_rlp::decode_exact(&rlp).map_err(de::Error::custom)?; Ok(RlpHeader { inner, - rlp: Some(rlp), + rlp: Some(rlp.into_boxed_slice()), }) } } @@ -140,31 +115,188 @@ where } } +/// An efficient wrapper for [Eip2718Envelope] types that do not support serde serialization. +/// +/// It implements deserialization using the EIP-2718 RLP encoding and does not discard the RLP data +/// after decoding, instead keeping it for faster RLP encoding of the deserialized type. +#[derive(Clone, Debug)] +pub struct Eip2718Wrapper { + inner: T, + encoding: Option>, +} + +impl Eip2718Wrapper { + #[must_use] + #[inline] + pub const fn new(inner: T) -> Self { + Self { + inner, + encoding: None, + } + } + + #[inline] + pub fn inner(&self) -> &T { + &self.inner + } + + #[inline] + pub fn into_inner(self) -> T { + self.inner + } +} + +impl ops::Deref for Eip2718Wrapper { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl Encodable for Eip2718Wrapper { + #[inline] + fn encode(&self, out: &mut dyn BufMut) { + self.encode_2718(out); + } + + #[inline] + fn length(&self) -> usize { + self.encode_2718_len() + } +} + +impl Encodable2718 for Eip2718Wrapper { + fn type_flag(&self) -> Option { + self.inner.type_flag() + } + + fn encode_2718_len(&self) -> usize { + match &self.encoding { + None => self.inner.encode_2718_len(), + Some(bytes) => bytes.len(), + } + } + + fn encode_2718(&self, out: &mut dyn BufMut) { + match &self.encoding { + Some(bytes) => out.put_slice(bytes), + None => self.inner.encode_2718(out), + } + } +} + +impl Serialize for Eip2718Wrapper { + #[inline] + fn serialize(&self, serializer: S) -> Result { + let encoded = self.inner.encoded_2718(); + if serializer.is_human_readable() { + hex::serialize(&encoded, serializer) + } else { + serializer.serialize_bytes(&encoded) + } + } +} + +impl<'de, T: Eip2718Envelope> Deserialize<'de> for Eip2718Wrapper { + #[inline] + fn deserialize>(deserializer: D) -> Result { + let bytes = if deserializer.is_human_readable() { + deserializer.deserialize_any(BytesVisitor)? + } else { + deserializer.deserialize_byte_buf(BytesVisitor)? + }; + let mut buf = bytes.as_slice(); + let inner = T::decode_2718(&mut buf).map_err(de::Error::custom)?; + if !buf.is_empty() { + return Err(de::Error::custom("invalid rlp length")); + } + + Ok(Eip2718Wrapper { + inner, + encoding: Some(bytes.into_boxed_slice()), + }) + } +} + +struct BytesVisitor; + +impl<'de> de::Visitor<'de> for BytesVisitor { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("bytes represented as a hex string, sequence or raw bytes") + } + + fn visit_str(self, v: &str) -> Result { + hex::decode(v).map_err(de::Error::custom) + } + + fn visit_bytes(self, v: &[u8]) -> Result { + Ok(v.to_vec()) + } + + fn visit_byte_buf(self, v: Vec) -> Result { + Ok(v) + } + + fn visit_seq>(self, mut seq: A) -> Result { + let mut values = Vec::with_capacity(seq.size_hint().unwrap_or(0)); + while let Some(value) = seq.next_element()? { + values.push(value); + } + Ok(values) + } +} + #[cfg(test)] mod tests { use super::*; - + use alloy_consensus::{Header, ReceiptEnvelope}; use alloy_primitives::Sealable; #[test] fn bincode_rlp_header() { - let value = RlpHeader::new(alloy_consensus::Header::default()); + let value = RlpHeader::new(Header::default()); assert_eq!(value.hash_slow(), value.inner().hash_slow()); let bin = bincode::serialize(&value).unwrap(); - let de: RlpHeader = bincode::deserialize(&bin).unwrap(); + let de: RlpHeader
= bincode::deserialize(&bin).unwrap(); assert_eq!(de.inner(), value.inner()); assert_eq!(de.hash_slow(), value.inner().hash_slow()); } #[test] fn serde_rlp_header() { - let value = RlpHeader::new(alloy_consensus::Header::default()); + let value = RlpHeader::new(Header::default()); assert_eq!(value.hash_slow(), value.inner().hash_slow()); let json = serde_json::to_string(&value).unwrap(); - let de: RlpHeader = serde_json::from_str(&json).unwrap(); + let de: RlpHeader
= serde_json::from_str(&json).unwrap(); assert_eq!(de.inner(), value.inner()); assert_eq!(de.hash_slow(), value.inner().hash_slow()); } + + #[test] + fn bincode_eip2718_wrapper() { + let value = Eip2718Wrapper::new(ReceiptEnvelope::Eip2930(Default::default())); + assert_eq!(value.encoded_2718(), value.inner().encoded_2718()); + + let bin = bincode::serialize(&value).unwrap(); + let de: Eip2718Wrapper = bincode::deserialize(&bin).unwrap(); + assert_eq!(de.inner(), value.inner()); + assert_eq!(de.encoded_2718(), value.inner().encoded_2718()); + } + + #[test] + fn serde_eip2718_wrapper() { + let value = Eip2718Wrapper::new(ReceiptEnvelope::Eip2930(Default::default())); + assert_eq!(value.encoded_2718(), value.inner().encoded_2718()); + + let json = serde_json::to_string(&value).unwrap(); + let de: Eip2718Wrapper = serde_json::from_str(&json).unwrap(); + assert_eq!(de.inner(), value.inner()); + assert_eq!(de.encoded_2718(), value.inner().encoded_2718()); + } } diff --git a/crates/steel/src/state.rs b/crates/steel/src/state.rs index 44c2c5ed..5bf8811f 100644 --- a/crates/steel/src/state.rs +++ b/crates/steel/src/state.rs @@ -207,12 +207,11 @@ impl EvmDatabase for WrapStateDb<'_, H> { }; let params = FilteredParams::new(Some(filter)); - let mut filtered = Vec::new(); - for log in logs { - if params.filter_address(&log.address) && params.filter_topics(log.topics()) { - filtered.push(log.clone()); - } - } + let filtered = logs + .iter() + .filter(|log| params.filter_address(&log.address) && params.filter_topics(log.topics())) + .cloned() + .collect(); Ok(filtered) } From 4ba0ddcd2f8e121c15689a0b177794f2879c28a0 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 13:22:24 +0100 Subject: [PATCH 04/14] add USDT event example --- crates/steel/src/block.rs | 7 +- crates/steel/src/serde.rs | 21 +--- examples/events/Cargo.toml | 36 +++++++ examples/events/host/Cargo.toml | 17 ++++ examples/events/host/src/main.rs | 112 ++++++++++++++++++++++ examples/events/methods/Cargo.toml | 10 ++ examples/events/methods/build.rs | 17 ++++ examples/events/methods/guest/Cargo.toml | 19 ++++ examples/events/methods/guest/src/main.rs | 71 ++++++++++++++ examples/events/methods/src/lib.rs | 15 +++ 10 files changed, 307 insertions(+), 18 deletions(-) create mode 100644 examples/events/Cargo.toml create mode 100644 examples/events/host/Cargo.toml create mode 100644 examples/events/host/src/main.rs create mode 100644 examples/events/methods/Cargo.toml create mode 100644 examples/events/methods/build.rs create mode 100644 examples/events/methods/guest/Cargo.toml create mode 100644 examples/events/methods/guest/src/main.rs create mode 100644 examples/events/methods/src/lib.rs diff --git a/crates/steel/src/block.rs b/crates/steel/src/block.rs index 3fb98d1b..483561e4 100644 --- a/crates/steel/src/block.rs +++ b/crates/steel/src/block.rs @@ -18,6 +18,7 @@ use crate::{ }; use ::serde::{Deserialize, Serialize}; use alloy_consensus::ReceiptEnvelope; +use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{map::HashMap, Bytes, Sealed, B256}; /// Input committing to the corresponding execution block hash. @@ -76,7 +77,9 @@ impl BlockInput { // verify the root hash of the included receipts and extract their logs let logs = self.receipts.map(|receipts| { - let root = alloy_trie::root::ordered_trie_root(&receipts); + let root = alloy_trie::root::ordered_trie_root_with_encoder(&receipts, |r, out| { + r.encode_2718(out) + }); assert_eq!(header.receipts_root(), &root, "Receipts root mismatch"); receipts @@ -169,9 +172,9 @@ pub mod host { "total storage size: {}", storage_tries.iter().map(|t| t.size()).sum::() ); - debug!("receipts: {}", receipts.as_ref().map_or(0, Vec::len)); debug!("contracts: {}", contracts.len()); debug!("ancestor blocks: {}", ancestors.len()); + debug!("receipts: {:?}", receipts.as_ref().map(Vec::len)); let input = BlockInput { header: header.into_inner(), diff --git a/crates/steel/src/serde.rs b/crates/steel/src/serde.rs index 3a40007a..4d75f3d5 100644 --- a/crates/steel/src/serde.rs +++ b/crates/steel/src/serde.rs @@ -35,7 +35,6 @@ pub struct RlpHeader { impl ops::Deref for RlpHeader { type Target = H; - #[inline] fn deref(&self) -> &Self::Target { &self.inner } @@ -43,20 +42,21 @@ impl ops::Deref for RlpHeader { impl RlpHeader { #[must_use] - #[inline] pub const fn new(inner: H) -> Self { Self { inner, rlp: None } } - #[inline] pub fn inner(&self) -> &H { &self.inner } - #[inline] pub fn inner_mut(&mut self) -> &mut H { &mut self.inner } + + pub fn into_inner(self) -> H { + self.inner + } } impl Sealable for RlpHeader { @@ -109,7 +109,6 @@ impl From> for RlpHeader where I: Encodable + Decodable + From, { - #[inline] fn from(value: alloy::rpc::types::Header) -> Self { Self::new(value.inner.into()) } @@ -127,7 +126,6 @@ pub struct Eip2718Wrapper { impl Eip2718Wrapper { #[must_use] - #[inline] pub const fn new(inner: T) -> Self { Self { inner, @@ -135,12 +133,10 @@ impl Eip2718Wrapper { } } - #[inline] pub fn inner(&self) -> &T { &self.inner } - #[inline] pub fn into_inner(self) -> T { self.inner } @@ -149,19 +145,16 @@ impl Eip2718Wrapper { impl ops::Deref for Eip2718Wrapper { type Target = T; - #[inline] fn deref(&self) -> &Self::Target { &self.inner } } impl Encodable for Eip2718Wrapper { - #[inline] fn encode(&self, out: &mut dyn BufMut) { self.encode_2718(out); } - #[inline] fn length(&self) -> usize { self.encode_2718_len() } @@ -210,7 +203,7 @@ impl<'de, T: Eip2718Envelope> Deserialize<'de> for Eip2718Wrapper { let mut buf = bytes.as_slice(); let inner = T::decode_2718(&mut buf).map_err(de::Error::custom)?; if !buf.is_empty() { - return Err(de::Error::custom("invalid rlp length")); + return Err(de::Error::custom("unexpected length")); } Ok(Eip2718Wrapper { @@ -228,19 +221,15 @@ impl<'de> de::Visitor<'de> for BytesVisitor { fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("bytes represented as a hex string, sequence or raw bytes") } - fn visit_str(self, v: &str) -> Result { hex::decode(v).map_err(de::Error::custom) } - fn visit_bytes(self, v: &[u8]) -> Result { Ok(v.to_vec()) } - fn visit_byte_buf(self, v: Vec) -> Result { Ok(v) } - fn visit_seq>(self, mut seq: A) -> Result { let mut values = Vec::with_capacity(seq.size_hint().unwrap_or(0)); while let Some(value) = seq.next_element()? { diff --git a/examples/events/Cargo.toml b/examples/events/Cargo.toml new file mode 100644 index 00000000..f13597d6 --- /dev/null +++ b/examples/events/Cargo.toml @@ -0,0 +1,36 @@ +[workspace] +resolver = "2" +members = ["host", "methods"] + +[workspace.dependencies] +# Intra-workspace dependencies +risc0-steel = { path = "../../crates/steel" } + +# risc0 monorepo dependencies. +risc0-build = { git = "https://github.com/risc0/risc0", branch = "main" } +risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false } +risc0-zkp = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false } + +alloy-primitives = { version = "0.8" } +alloy-sol-types = { version = "0.8" } +anyhow = "1.0" +clap = { version = "4.5", features = ["derive", "env"] } +events-methods = { path = "methods" } +tokio = { version = "1.39", features = ["full"] } +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +url = { version = "2.5" } +log = { version = "0.4" } + +# Always optimize; building and running the guest takes much longer without optimization. +[profile.dev] +opt-level = 3 + +[profile.dev.build-override] +opt-level = 3 + +[profile.release] +debug = 1 +lto = true + +[profile.release.build-override] +opt-level = 3 diff --git a/examples/events/host/Cargo.toml b/examples/events/host/Cargo.toml new file mode 100644 index 00000000..e3cf95b7 --- /dev/null +++ b/examples/events/host/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "host" +version = "0.1.0" +edition = "2021" + +[dependencies] +alloy-primitives = { workspace = true } +alloy-sol-types = { workspace = true } +anyhow = { workspace = true } +clap = { workspace = true } +events-methods = { workspace = true } +log = { workspace = true } +risc0-steel = { workspace = true, features = ["host"] } +risc0-zkvm = { workspace = true, features = ["client"] } +tokio = { workspace = true } +tracing-subscriber = { workspace = true } +url = { workspace = true } diff --git a/examples/events/host/src/main.rs b/examples/events/host/src/main.rs new file mode 100644 index 00000000..2a206d56 --- /dev/null +++ b/examples/events/host/src/main.rs @@ -0,0 +1,112 @@ +// Copyright 2024 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use alloy_primitives::{address, Address}; +use alloy_sol_types::{sol, SolEvent, SolValue}; +use anyhow::{Context, Result}; +use clap::Parser; +use events_methods::EVENTS_GUEST_ELF; +use risc0_steel::{ + ethereum::{EthEvmEnv, ETH_SEPOLIA_CHAIN_SPEC}, + Commitment, Event, +}; +use risc0_zkvm::{default_executor, ExecutorEnv}; +use tokio::task; +use tracing_subscriber::EnvFilter; +use url::Url; + +sol! { + /// ERC-20 transfer event signature. + /// This must match the signature in the guest. + #[derive(Debug)] + interface IERC20 { + event Transfer(address indexed from, address indexed to, uint256 value); + } +} + +/// Address of the deployed contract to call the function on (USDT contract on Mainnet). +const CONTRACT: Address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); + +sol! { + /// ABI-encodable journal. + struct Journal { + Commitment commitment; + bytes32 blockHash; + uint256 value; + } +} + +/// Simple program to show the use of Ethereum contract data inside the guest. +#[derive(Parser, Debug)] +#[command(about, long_about = None)] +struct Args { + /// URL of the RPC endpoint + #[arg(short, long, env = "RPC_URL")] + rpc_url: Url, +} + +#[tokio::main] +async fn main() -> Result<()> { + // Initialize tracing. In order to view logs, run `RUST_LOG=info cargo run` + tracing_subscriber::fmt() + .with_env_filter(EnvFilter::from_default_env()) + .init(); + // Parse the command line arguments. + let args = Args::parse(); + + // Create an EVM environment from an RPC endpoint defaulting to the latest block. + let mut env = EthEvmEnv::builder().rpc(args.rpc_url).build().await?; + // The `with_chain_spec` method is used to specify the chain configuration. + env = env.with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); + + // Preflight the event query to prepare the input that is required to execute the function in + // the guest without RPC access. + let event = Event::preflight::(&mut env); + let logs = event.address(CONTRACT).query().await?; + log::info!( + "Contract {} emitted {} events with signature: {}", + CONTRACT, + logs.len(), + IERC20::Transfer::SIGNATURE, + ); + + // Finally, construct the input from the environment. + let evm_input = env.into_input().await?; + + let session_info = task::spawn_blocking(move || { + let env = ExecutorEnv::builder() + .write(&evm_input) + .context("failed to encode input")? + .build() + .context("failed to build env")?; + let exec = default_executor(); + exec.execute(env, EVENTS_GUEST_ELF) + .context("failed to run executor") + }) + .await? + .context("failed to execute guest")?; + + // The journal should be the ABI encoded commitment. + let journal = Journal::abi_decode(session_info.journal.as_ref(), true) + .context("failed to decode journal")?; + log::debug!("Steel commitment: {:?}", journal.commitment); + + log::info!( + "Total USDT transferred in block {}: {}", + journal.blockHash, + journal.value, + ); + + Ok(()) +} diff --git a/examples/events/methods/Cargo.toml b/examples/events/methods/Cargo.toml new file mode 100644 index 00000000..269052c9 --- /dev/null +++ b/examples/events/methods/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "events-methods" +version = "0.1.0" +edition = "2021" + +[build-dependencies] +risc0-build = { workspace = true, features = ["unstable"] } + +[package.metadata.risc0] +methods = ["guest"] diff --git a/examples/events/methods/build.rs b/examples/events/methods/build.rs new file mode 100644 index 00000000..a4aa2563 --- /dev/null +++ b/examples/events/methods/build.rs @@ -0,0 +1,17 @@ +// Copyright 2024 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +fn main() { + risc0_build::embed_methods(); +} diff --git a/examples/events/methods/guest/Cargo.toml b/examples/events/methods/guest/Cargo.toml new file mode 100644 index 00000000..987e7707 --- /dev/null +++ b/examples/events/methods/guest/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "events-guest" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +alloy-primitives = { version = "0.8" } +alloy-sol-types = { version = "0.8" } +risc0-steel = { path = "../../../../crates/steel" } +risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false, features = ["std", "unstable"] } + +[patch.crates-io] +# use optimized risc0 circuit +crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.5-risczero.0" } +k256 = { git = "https://github.com/risc0/RustCrypto-elliptic-curves", tag = "k256/v0.13.3-risczero.1" } +sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" } +tiny-keccak = { git = "https://github.com/risc0/tiny-keccak", tag = "tiny-keccak/v2.0.2-risczero.0" } diff --git a/examples/events/methods/guest/src/main.rs b/examples/events/methods/guest/src/main.rs new file mode 100644 index 00000000..d26b6db8 --- /dev/null +++ b/examples/events/methods/guest/src/main.rs @@ -0,0 +1,71 @@ +// Copyright 2024 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![allow(unused_doc_comments)] +#![no_main] + +use alloy_primitives::{address, Address, U256}; +use alloy_sol_types::{sol, SolValue}; +use risc0_steel::{ + ethereum::{EthEvmInput, ETH_SEPOLIA_CHAIN_SPEC}, + Commitment, Event, +}; +use risc0_zkvm::guest::env; + +risc0_zkvm::guest::entry!(main); + +/// Specify the event to query using the [`sol!`] macro. +sol! { + /// ERC-20 transfer event signature. + interface IERC20 { + event Transfer(address indexed from, address indexed to, uint256 value); + } +} + +sol! { + /// ABI-encodable journal. + struct Journal { + Commitment commitment; + bytes32 blockHash; + uint256 value; + } +} + +/// Address of the deployed contract to call the function on (USDT contract on Mainnet). +const CONTRACT: Address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); + +fn main() { + // Read the input from the guest environment. + let input: EthEvmInput = env::read(); + + // Converts the input into a `EvmEnv` for execution. + // The `with_chain_spec` method is used to specify the chain configuration. + let env = input.into_env().with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); + let block_hash = env.header().seal(); + + // Query all `Transfer` events of the USDT contract. + let event = Event::new::(&env); + let logs = event.address(CONTRACT).query(); + + // Process the events. + let value = logs.iter().map(|log| log.data.value).sum::(); + + // This commits the sum of all USDT transfers in the current block into the journal. + let journal = Journal { + commitment: env.into_commitment(), + blockHash: block_hash, + value, + }; + env::commit_slice(&journal.abi_encode()); +} diff --git a/examples/events/methods/src/lib.rs b/examples/events/methods/src/lib.rs new file mode 100644 index 00000000..ae9d61e6 --- /dev/null +++ b/examples/events/methods/src/lib.rs @@ -0,0 +1,15 @@ +// Copyright 2024 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +include!(concat!(env!("OUT_DIR"), "/methods.rs")); From 02b344ea74b9b225fef2e1ea4e0aa86cc103a706 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 15:53:41 +0100 Subject: [PATCH 05/14] add workaround of Ethereum only receipts --- crates/steel/docs/steel-commitments.md | 2 +- crates/steel/src/block.rs | 17 ++++---- crates/steel/src/host/db/proof.rs | 60 ++++++++++++++++++++------ 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/crates/steel/docs/steel-commitments.md b/crates/steel/docs/steel-commitments.md index d747b0c4..83d77392 100644 --- a/crates/steel/docs/steel-commitments.md +++ b/crates/steel/docs/steel-commitments.md @@ -12,7 +12,7 @@ Steel uses [revm] to generate an EVM execution environment, `EvmEnv` within the // Create an EVM environment from that provider let mut env = EthEvmEnv::builder() .provider(provider.clone()) - .BLOCK_NUMBER(20842508) + .block_number(20842508) .build() .await?; ``` diff --git a/crates/steel/src/block.rs b/crates/steel/src/block.rs index 483561e4..1628a5da 100644 --- a/crates/steel/src/block.rs +++ b/crates/steel/src/block.rs @@ -120,26 +120,25 @@ pub mod host { serde::Eip2718Wrapper, EvmBlockHeader, }; - use alloy::{ - network::{Ethereum, Network}, - providers::Provider, - transports::Transport, - }; + use alloy::{network::Network, providers::Provider, transports::Transport}; use alloy_primitives::Sealed; use anyhow::{anyhow, ensure}; use log::debug; + use std::fmt::Display; impl BlockInput { /// Creates the `BlockInput` containing the necessary EVM state that can be verified against /// the block hash. - pub(crate) async fn from_proof_db( - mut db: ProofDb>, + pub(crate) async fn from_proof_db( + mut db: ProofDb>, header: Sealed, ) -> anyhow::Result where T: Transport + Clone, - P: Provider, - H: EvmBlockHeader + From<::HeaderResponse>, + N: Network, + P: Provider, + H: EvmBlockHeader + TryFrom<::HeaderResponse>, + ::HeaderResponse>>::Error: Display, { assert_eq!(db.inner().block_hash(), header.seal(), "DB block mismatch"); diff --git a/crates/steel/src/host/db/proof.rs b/crates/steel/src/host/db/proof.rs index 39db54f5..f8ec6a90 100644 --- a/crates/steel/src/host/db/proof.rs +++ b/crates/steel/src/host/db/proof.rs @@ -17,12 +17,13 @@ use crate::{event, MerkleTrie}; use alloy::{ consensus::BlockHeader, eips::eip2930::{AccessList, AccessListItem}, - network::{primitives::BlockTransactionsKind, BlockResponse, Ethereum, Network}, + network::{primitives::BlockTransactionsKind, BlockResponse, Network}, providers::Provider, rpc::types::EIP1186AccountProofResponse, transports::Transport, }; use alloy_consensus::{Receipt, ReceiptEnvelope, ReceiptWithBloom, TxReceipt}; +use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{ map::{hash_map, AddressHashMap, B256HashMap, B256HashSet, HashSet}, Address, BlockNumber, Bytes, Log, StorageKey, StorageValue, B256, U256, @@ -222,38 +223,40 @@ impl> ProofDb> ProofDb> { pub async fn receipt_proof(&self) -> Result>> { if self.logs.is_empty() { return Ok(None); } + let provider = self.inner.provider(); let block_hash = self.inner.block_hash(); - let block = self - .inner - .provider() + + let block = provider .get_block_by_hash(block_hash, BlockTransactionsKind::Hashes) .await .context("eth_getBlockByNumber failed")? .with_context(|| format!("block {} not found", block_hash))?; + let header = block.header(); + // we don't need to include any receipts, if the Bloom filter proves the exclusion let bloom_match = self .logs .iter() - .any(|filter| event::matches_filter(block.header.logs_bloom, filter)); + .any(|filter| event::matches_filter(header.logs_bloom(), filter)); if !bloom_match { return Ok(None); } - let tx_receipts = self - .inner - .provider() + let rpc_receipts = provider .get_block_receipts(block_hash.into()) - .await? + .await + .context("eth_getBlockReceipts failed")? .with_context(|| format!("block {} not found", block_hash))?; - let receipts = tx_receipts.into_iter().map(simplify_receipt).collect(); + + // convert the receipts so that they can be RLP-encoded + let receipts = convert_rpc_receipts::(rpc_receipts, header.receipts_root()) + .context("invalid receipts; inconsistent API response or incompatible response type")?; Ok(Some(receipts)) } @@ -308,7 +311,7 @@ impl RevmDatabase for ProofDb { impl crate::EvmDatabase for ProofDb { fn logs(&mut self, filter: Filter) -> Result, ::Error> { - log::trace!("LOGS: signatures={:?}", filter.topics[0]); + log::trace!("LOGS: filter={:?}", &filter); let logs = self.inner.logs(filter.clone())?; self.logs.push(filter); @@ -364,7 +367,36 @@ fn add_proof( Ok(()) } -fn simplify_receipt(tx_receipt: TransactionReceipt) -> ReceiptEnvelope { +/// Converts an API ReceiptResponse into a vector of ReceiptEnvelope. +fn convert_rpc_receipts( + rpc_receipts: impl IntoIterator::ReceiptResponse>, + receipts_root: B256, +) -> Result> { + let receipts = rpc_receipts + .into_iter() + .map(|rpc_receipt| { + // Unfortunately ReceiptResponse does not implement ReceiptEnvelope, so we have to + // manually convert it. We convert to a TransactionReceipt which is the default and + // works for Ethereum-compatible networks. + // Use serde here for the conversion as it is much safer than mem::transmute. + // TODO(https://github.com/alloy-rs/alloy/issues/854): use ReceiptEnvelope directly + let json = serde_json::to_value(rpc_receipt).context("failed to serialize")?; + let tx_receipt: TransactionReceipt = serde_json::from_value(json) + .context("failed to parse as Ethereum transaction receipt")?; + + Ok(tx_receipt_to_envelope(tx_receipt)) + }) + .collect::>>()?; + + // in case the conversion did not work correctly, we check the receipts root in the header + let root = + alloy_trie::root::ordered_trie_root_with_encoder(&receipts, |r, out| r.encode_2718(out)); + ensure!(root == receipts_root, "receipts root mismatch"); + + Ok(receipts) +} + +fn tx_receipt_to_envelope(tx_receipt: TransactionReceipt) -> ReceiptEnvelope { fn simplify_receipt(t: ReceiptWithBloom>) -> ReceiptWithBloom { ReceiptWithBloom::new( Receipt { From 87f5dede02cb4e0c5e972731979cd885c589cc3e Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 16:03:53 +0100 Subject: [PATCH 06/14] cleanups --- crates/steel/src/host/mod.rs | 10 +++--- crates/steel/src/mpt.rs | 60 ++---------------------------------- crates/steel/src/serde.rs | 13 +++++--- 3 files changed, 17 insertions(+), 66 deletions(-) diff --git a/crates/steel/src/host/mod.rs b/crates/steel/src/host/mod.rs index a191088a..01aa2def 100644 --- a/crates/steel/src/host/mod.rs +++ b/crates/steel/src/host/mod.rs @@ -133,7 +133,7 @@ pub struct HostCommit { impl HostEvmEnv where - D: crate::EvmDatabase + Send + 'static, + D: Send + 'static, { /// Runs the provided closure that requires mutable access to the database on a thread where /// blocking is acceptable. @@ -176,11 +176,13 @@ impl HostEvmEnv { } } -impl HostEvmEnv, H, ()> +impl HostEvmEnv, H, ()> where T: Transport + Clone, - P: Provider, - H: EvmBlockHeader + From<::HeaderResponse>, + N: Network, + P: Provider, + H: EvmBlockHeader + TryFrom<::HeaderResponse>, + ::HeaderResponse>>::Error: Display, { /// Converts the environment into a [EvmInput] committing to an execution block hash. pub async fn into_input(self) -> Result> { diff --git a/crates/steel/src/mpt.rs b/crates/steel/src/mpt.rs index cfb1206c..25eeb659 100644 --- a/crates/steel/src/mpt.rs +++ b/crates/steel/src/mpt.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{fmt, fmt::Debug}; +use std::fmt::Debug; use alloy_primitives::{b256, keccak256, map::B256HashMap, B256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header, PayloadView, EMPTY_STRING_CODE}; @@ -67,12 +67,6 @@ impl MerkleTrie { } } - /// Gets an iterator over the values of the trie, sorted by key. - #[inline] - pub fn values(&self) -> Iter { - Iter::new(&self.0) - } - /// Creates a new trie from the given RLP encoded nodes. /// /// The first node provided must always be the root node. The remaining nodes can be in any @@ -310,52 +304,6 @@ impl Encodable for NodeRef<'_> { } } -/// An iterator over the entries of a `MerkleTrie`. -/// -/// This `struct` is created by the [`values`] method on [`MerkleTrie`]. See its -/// documentation for more. -/// -/// [`values`]: MerkleTrie::values -#[derive(Clone, Default)] -#[must_use = "iterators are lazy and do nothing unless consumed"] -pub struct Iter<'a> { - stack: Vec<&'a Node>, -} - -impl Debug for Iter<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_list().entries(self.clone()).finish() - } -} - -impl<'a> Iter<'a> { - fn new(root: &'a Node) -> Self { - Self { stack: vec![root] } - } -} - -impl<'a> Iterator for Iter<'a> { - type Item = &'a [u8]; - - fn next(&mut self) -> Option { - while let Some(node) = self.stack.pop() { - match node { - Node::Null | Node::Digest(_) => {} - Node::Leaf(_, value) => return Some(value), - Node::Extension(_, child) => self.stack.push(child), - Node::Branch(children) => { - for child in children.iter().rev().flatten() { - if !matches!(**child, Node::Null | Node::Digest(_)) { - self.stack.push(child); - } - } - } - } - } - None - } -} - #[inline] fn encode_list_header(payload_length: usize) -> Vec { debug_assert!(payload_length > 0); @@ -598,9 +546,7 @@ mod tests { // generate proofs only for every second leaf let proof_keys = leaves.keys().step_by(2).cloned().collect(); let mut hasher = HashBuilder::default().with_proof_retainer(proof_keys); - leaves - .iter() - .for_each(|(k, v)| hasher.add_leaf(k.clone(), v)); + leaves.into_iter().for_each(|(k, v)| hasher.add_leaf(k, &v)); let exp_hash = hasher.root(); // reconstruct the trie from the RLP encoded proofs and verify the root hash @@ -613,8 +559,6 @@ mod tests { ) .unwrap(); assert_eq!(mpt.hash_slow(), exp_hash); - - assert!(mpt.values().eq(leaves.values().step_by(2))); } #[test] diff --git a/crates/steel/src/serde.rs b/crates/steel/src/serde.rs index 4d75f3d5..502ff2f6 100644 --- a/crates/steel/src/serde.rs +++ b/crates/steel/src/serde.rs @@ -35,6 +35,7 @@ pub struct RlpHeader { impl ops::Deref for RlpHeader { type Target = H; + #[inline] fn deref(&self) -> &Self::Target { &self.inner } @@ -105,12 +106,15 @@ impl<'de, H: Encodable + Decodable> Deserialize<'de> for RlpHeader { } #[cfg(feature = "host")] -impl From> for RlpHeader +impl TryFrom> for RlpHeader where - I: Encodable + Decodable + From, + I: Encodable + Decodable + TryFrom, { - fn from(value: alloy::rpc::types::Header) -> Self { - Self::new(value.inner.into()) + type Error = >::Error; + + #[inline] + fn try_from(value: alloy::rpc::types::Header) -> Result { + Ok(Self::new(value.inner.try_into()?)) } } @@ -145,6 +149,7 @@ impl Eip2718Wrapper { impl ops::Deref for Eip2718Wrapper { type Target = T; + #[inline] fn deref(&self) -> &Self::Target { &self.inner } From cc965be9491e00eef1d5307b5287a1ee9cf25c41 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 17:18:34 +0100 Subject: [PATCH 07/14] hide event support behind unstable feature --- crates/steel/Cargo.toml | 2 + crates/steel/src/block.rs | 10 +- crates/steel/src/ethereum.rs | 6 +- crates/steel/src/event.rs | 12 +- crates/steel/src/host/db/proof.rs | 16 +-- crates/steel/src/host/mod.rs | 3 +- crates/steel/src/lib.rs | 16 ++- crates/steel/src/state.rs | 17 ++- crates/steel/tests/steel.rs | 155 ++++++++++++----------- examples/events/Cargo.toml | 2 +- examples/events/methods/guest/Cargo.toml | 2 +- 11 files changed, 135 insertions(+), 106 deletions(-) diff --git a/crates/steel/Cargo.toml b/crates/steel/Cargo.toml index 1a8926d4..e149c78d 100644 --- a/crates/steel/Cargo.toml +++ b/crates/steel/Cargo.toml @@ -33,6 +33,7 @@ stability = { workspace = true } thiserror = { workspace = true, features = ["default"] } tokio = { workspace = true, optional = true } url = { workspace = true, optional = true } +cfg-if = "1.0.0" [dev-dependencies] alloy = { workspace = true, features = ["contract", "node-bindings"] } @@ -52,5 +53,6 @@ host = [ "dep:tokio", "dep:url", ] +unstable-event = [] unstable-history = [] unstable-verifier = [] diff --git a/crates/steel/src/block.rs b/crates/steel/src/block.rs index 1628a5da..da7a5c89 100644 --- a/crates/steel/src/block.rs +++ b/crates/steel/src/block.rs @@ -18,7 +18,6 @@ use crate::{ }; use ::serde::{Deserialize, Serialize}; use alloy_consensus::ReceiptEnvelope; -use alloy_eips::eip2718::Encodable2718; use alloy_primitives::{map::HashMap, Bytes, Sealed, B256}; /// Input committing to the corresponding execution block hash. @@ -75,10 +74,17 @@ impl BlockInput { previous_header = ancestor; } + #[cfg(not(feature = "unstable-event"))] + // there must not be any receipts, if events are not supported + let logs = { + assert!(self.receipts.is_none(), "Receipts not supported"); + None + }; + #[cfg(feature = "unstable-event")] // verify the root hash of the included receipts and extract their logs let logs = self.receipts.map(|receipts| { let root = alloy_trie::root::ordered_trie_root_with_encoder(&receipts, |r, out| { - r.encode_2718(out) + alloy_eips::eip2718::Encodable2718::encode_2718(r, out) }); assert_eq!(header.receipts_root(), &root, "Receipts root mismatch"); diff --git a/crates/steel/src/ethereum.rs b/crates/steel/src/ethereum.rs index 4d281efa..646f237c 100644 --- a/crates/steel/src/ethereum.rs +++ b/crates/steel/src/ethereum.rs @@ -20,7 +20,7 @@ use crate::{ serde::RlpHeader, EvmBlockHeader, EvmEnv, EvmInput, }; -use alloy_primitives::{BlockNumber, Bloom, B256, U256}; +use alloy_primitives::{BlockNumber, B256, U256}; use revm::primitives::{BlockEnv, SpecId}; /// The Ethereum Sepolia [ChainSpec]. @@ -79,12 +79,14 @@ impl EvmBlockHeader for EthBlockHeader { fn state_root(&self) -> &B256 { &self.inner().state_root } + #[cfg(feature = "unstable-event")] #[inline] fn receipts_root(&self) -> &B256 { &self.inner().receipts_root } + #[cfg(feature = "unstable-event")] #[inline] - fn logs_bloom(&self) -> &Bloom { + fn logs_bloom(&self) -> &alloy_primitives::Bloom { &self.inner().logs_bloom } diff --git a/crates/steel/src/event.rs b/crates/steel/src/event.rs index 9527f709..65d98f94 100644 --- a/crates/steel/src/event.rs +++ b/crates/steel/src/event.rs @@ -15,8 +15,8 @@ pub use alloy_rpc_types::{Topic, ValueOrArray}; use crate::{state::WrapStateDb, EvmBlockHeader, EvmDatabase, GuestEvmEnv}; -use alloy_primitives::{Address, Bloom, Log, Sealed}; -use alloy_rpc_types::{Filter, FilteredParams}; +use alloy_primitives::{Address, Log, Sealed}; +use alloy_rpc_types::Filter; use alloy_sol_types::SolEvent; use std::marker::PhantomData; @@ -81,6 +81,7 @@ impl Event<(), &GuestEvmEnv> { } } +#[cfg(feature = "unstable-event")] impl Event> { /// Executes the query and returns the matching logs and panics on failure. /// @@ -190,10 +191,3 @@ fn event_filter(header: &Sealed) -> Filter { .event_signature(S::SIGNATURE_HASH) .at_block_hash(header.seal()) } - -/// Checks if a bloom filter matches the given filter parameters. -#[inline] -pub(crate) fn matches_filter(bloom: Bloom, filter: &Filter) -> bool { - FilteredParams::matches_address(bloom, &FilteredParams::address_filter(&filter.address)) - && FilteredParams::matches_topics(bloom, &FilteredParams::topics_filter(&filter.topics)) -} diff --git a/crates/steel/src/host/db/proof.rs b/crates/steel/src/host/db/proof.rs index f8ec6a90..d0b2df04 100644 --- a/crates/steel/src/host/db/proof.rs +++ b/crates/steel/src/host/db/proof.rs @@ -13,7 +13,7 @@ // limitations under the License. use super::{provider::ProviderDb, AlloyDb}; -use crate::{event, MerkleTrie}; +use crate::MerkleTrie; use alloy::{ consensus::BlockHeader, eips::eip2930::{AccessList, AccessListItem}, @@ -40,7 +40,7 @@ pub struct ProofDb { accounts: AddressHashMap, contracts: B256HashMap, block_hash_numbers: HashSet, - logs: Vec, + log_filters: Vec, proofs: AddressHashMap, inner: D, } @@ -66,7 +66,7 @@ impl ProofDb { accounts: Default::default(), contracts: Default::default(), block_hash_numbers: Default::default(), - logs: Default::default(), + log_filters: Default::default(), proofs: Default::default(), inner: db, } @@ -147,7 +147,7 @@ impl> ProofDb> ProofDb Result>> { - if self.logs.is_empty() { + if self.log_filters.is_empty() { return Ok(None); } @@ -241,9 +241,9 @@ impl> ProofDb crate::EvmDatabase for ProofDb { log::trace!("LOGS: filter={:?}", &filter); let logs = self.inner.logs(filter.clone())?; - self.logs.push(filter); + self.log_filters.push(filter); Ok(logs) } diff --git a/crates/steel/src/host/mod.rs b/crates/steel/src/host/mod.rs index 01aa2def..c4829c51 100644 --- a/crates/steel/src/host/mod.rs +++ b/crates/steel/src/host/mod.rs @@ -142,6 +142,7 @@ where /// This function is necessary because mutable references to the database cannot be passed /// directly to `tokio::task::spawn_blocking`. Instead, the database is temporarily taken out of /// the `HostEvmEnv`, moved into the blocking task, and then restored after the task completes. + #[allow(dead_code)] pub(crate) async fn spawn_with_db(&mut self, f: F) -> R where F: FnOnce(&mut ProofDb) -> R + Send + 'static, @@ -150,7 +151,7 @@ where // as mutable references are not possible, the DB must be moved in and out of the task let mut db = self.db.take().unwrap(); - let (result, db) = tokio::task::spawn_blocking(|| (f(&mut db), db)) + let (result, db) = tokio::task::spawn_blocking(move || (f(&mut db), db)) .await .expect("DB execution panicked"); diff --git a/crates/steel/src/lib.rs b/crates/steel/src/lib.rs index a5f0b4d0..2b2234e6 100644 --- a/crates/steel/src/lib.rs +++ b/crates/steel/src/lib.rs @@ -25,7 +25,7 @@ pub use alloy; use ::serde::{Deserialize, Serialize}; use alloy_primitives::{uint, BlockNumber, Bloom, Log, Sealable, Sealed, B256, U256}; -use alloy_rpc_types::Filter; +use alloy_rpc_types::{Filter, FilteredParams}; use alloy_sol_types::SolValue; use config::ChainSpec; use revm::{ @@ -38,6 +38,7 @@ mod block; pub mod config; mod contract; pub mod ethereum; +#[cfg(feature = "unstable-event")] mod event; #[cfg(feature = "unstable-history")] pub mod history; @@ -55,10 +56,11 @@ mod verifier; pub use beacon::BeaconInput; pub use block::BlockInput; pub use contract::{CallBuilder, Contract}; -pub use event::Event; pub use mpt::MerkleTrie; pub use state::{StateAccount, StateDb}; +#[cfg(feature = "unstable-event")] +pub use event::Event; #[cfg(feature = "unstable-history")] pub use history::HistoryInput; #[cfg(not(feature = "unstable-history"))] @@ -137,6 +139,14 @@ pub trait EvmDatabase: RevmDatabase { fn logs(&mut self, filter: Filter) -> Result, ::Error>; } +/// Checks if a bloom filter matches the given filter parameters. +// TODO: Move to `event` once no longer unstable +#[inline] +pub(crate) fn matches_filter(bloom: Bloom, filter: &Filter) -> bool { + FilteredParams::matches_address(bloom, &FilteredParams::address_filter(&filter.address)) + && FilteredParams::matches_topics(bloom, &FilteredParams::topics_filter(&filter.topics)) +} + /// Alias for readability, do not make public. pub(crate) type GuestEvmEnv = EvmEnv; @@ -218,8 +228,10 @@ pub trait EvmBlockHeader: Sealable { fn timestamp(&self) -> u64; /// Returns the state root hash. fn state_root(&self) -> &B256; + #[cfg(feature = "unstable-event")] /// Returns the receipts root hash of the block. fn receipts_root(&self) -> &B256; + #[cfg(feature = "unstable-event")] /// Returns the logs bloom filter of the block fn logs_bloom(&self) -> &Bloom; diff --git a/crates/steel/src/state.rs b/crates/steel/src/state.rs index 5bf8811f..c49962d4 100644 --- a/crates/steel/src/state.rs +++ b/crates/steel/src/state.rs @@ -14,13 +14,12 @@ pub use alloy_consensus::Account as StateAccount; -use crate::{event, mpt::MerkleTrie, EvmBlockHeader, EvmDatabase}; +use crate::{mpt::MerkleTrie, EvmBlockHeader}; use alloy_primitives::{ keccak256, map::{AddressHashMap, B256HashMap, HashMap}, Address, Bytes, Log, Sealed, B256, U256, }; -use alloy_rpc_types::{Filter, FilteredParams}; use revm::{ primitives::{AccountInfo, Bytecode}, Database as RevmDatabase, @@ -47,7 +46,7 @@ pub struct StateDb { contracts: B256HashMap, /// Block hashes by their number. block_hashes: HashMap, - + /// All the logs for this block. logs: Option>, } @@ -193,20 +192,24 @@ impl RevmDatabase for WrapStateDb<'_, H> { } } -impl EvmDatabase for WrapStateDb<'_, H> { - fn logs(&mut self, filter: Filter) -> Result, ::Error> { +#[cfg(feature = "unstable-event")] +impl crate::EvmDatabase for WrapStateDb<'_, H> { + fn logs( + &mut self, + filter: alloy_rpc_types::Filter, + ) -> Result, ::Error> { assert_eq!(filter.get_block_hash(), Some(self.header.seal())); let Some(logs) = self.inner.logs.as_ref() else { // if no logs are stored in the DB, check that the Bloom filter proves non-existence assert!( - !event::matches_filter(*self.header.logs_bloom(), &filter), + !crate::matches_filter(*self.header.logs_bloom(), &filter), "No logs for matching filter" ); return Ok(vec![]); }; - let params = FilteredParams::new(Some(filter)); + let params = alloy_rpc_types::FilteredParams::new(Some(filter)); let filtered = logs .iter() .filter(|log| params.filter_address(&log.address) && params.filter_topics(log.topics())) diff --git a/crates/steel/tests/steel.rs b/crates/steel/tests/steel.rs index 7dcae197..7cab00c1 100644 --- a/crates/steel/tests/steel.rs +++ b/crates/steel/tests/steel.rs @@ -25,7 +25,7 @@ use alloy::{ use alloy_primitives::{address, b256, bytes, hex, Address, Bytes, U256}; use alloy_sol_types::SolCall; use common::{CallOptions, ANVIL_CHAIN_SPEC}; -use risc0_steel::{ethereum::EthEvmEnv, Contract, Event}; +use risc0_steel::{ethereum::EthEvmEnv, Contract}; use sha2::{Digest, Sha256}; use test_log::test; @@ -135,79 +135,88 @@ async fn test_provider() -> impl Provider { provider } -#[test(tokio::test)] -async fn event_query_some() { - let provider = test_provider().await; - let contract = SteelTest::new(STEEL_TEST_CONTRACT, &provider); - - const VALUE: U256 = uint!(42_U256); - // send a transaction to emit an event on chain - let pending = contract.testEvent(VALUE).send().await.unwrap(); - pending.watch().await.unwrap(); - - let mut env = EthEvmEnv::builder() - .provider(provider) - .build() - .await - .unwrap() - .with_chain_spec(&ANVIL_CHAIN_SPEC); - - let preflight_logs = { - let event = Event::preflight::(&mut env).address(STEEL_TEST_CONTRACT); - event.query().await.unwrap() - }; - - let input = env.into_input().await.unwrap(); - let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); - - let logs = { - let event = Event::new::(&env).address(STEEL_TEST_CONTRACT); - event.query() - }; - assert_eq!(logs, preflight_logs, "mismatch in preflight and execution"); - assert!( - matches!( - logs.as_slice(), - [alloy_primitives::Log { - address: STEEL_TEST_CONTRACT, - data: SteelTest::Event { value: VALUE, .. }, - }] - ), - "Unexpected event logs: {:?}", - logs - ); -} - -#[test(tokio::test)] -async fn event_query_none() { - let provider = test_provider().await; - - // send a transaction to emit an event on chain - let contract = SteelTest::deploy(&provider).await.unwrap(); - let pending = contract.testEvent(U256::ZERO).send().await.unwrap(); - pending.watch().await.unwrap(); - - let mut env = EthEvmEnv::builder() - .provider(provider) - .build() - .await - .unwrap() - .with_chain_spec(&ANVIL_CHAIN_SPEC); - - let preflight_logs = { - let event = Event::preflight::(&mut env).address(STEEL_TEST_CONTRACT); - event.query().await.unwrap() - }; - - let input = env.into_input().await.unwrap(); - let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); +#[cfg(feature = "unstable-event")] +mod event { + use super::*; + use risc0_steel::Event; + use test_log::test; + + #[test(tokio::test)] + async fn event_query_some() { + let provider = test_provider().await; + let contract = SteelTest::new(STEEL_TEST_CONTRACT, &provider); + + const VALUE: U256 = uint!(42_U256); + // send a transaction to emit an event on chain + let pending = contract.testEvent(VALUE).send().await.unwrap(); + pending.watch().await.unwrap(); + + let mut env = EthEvmEnv::builder() + .provider(provider) + .build() + .await + .unwrap() + .with_chain_spec(&ANVIL_CHAIN_SPEC); + + let preflight_logs = { + let event = risc0_steel::Event::preflight::(&mut env) + .address(STEEL_TEST_CONTRACT); + event.query().await.unwrap() + }; + + let input = env.into_input().await.unwrap(); + let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); + + let logs = { + let event = + risc0_steel::Event::new::(&env).address(STEEL_TEST_CONTRACT); + event.query() + }; + assert_eq!(logs, preflight_logs, "mismatch in preflight and execution"); + assert!( + matches!( + logs.as_slice(), + [alloy_primitives::Log { + address: STEEL_TEST_CONTRACT, + data: SteelTest::Event { value: VALUE, .. }, + }] + ), + "Unexpected event logs: {:?}", + logs + ); + } - let logs = { - let event = Event::new::(&env).address(STEEL_TEST_CONTRACT); - event.query() - }; - assert_eq!(logs, preflight_logs, "mismatch in preflight and execution"); - assert!(logs.is_empty()); + #[test(tokio::test)] + async fn event_query_none() { + let provider = test_provider().await; + + // send a transaction to emit an event on chain + let contract = SteelTest::deploy(&provider).await.unwrap(); + let pending = contract.testEvent(U256::ZERO).send().await.unwrap(); + pending.watch().await.unwrap(); + + let mut env = EthEvmEnv::builder() + .provider(provider) + .build() + .await + .unwrap() + .with_chain_spec(&ANVIL_CHAIN_SPEC); + + let preflight_logs = { + let event = Event::preflight::(&mut env).address(STEEL_TEST_CONTRACT); + event.query().await.unwrap() + }; + + let input = env.into_input().await.unwrap(); + let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); + + let logs = { + let event = Event::new::(&env).address(STEEL_TEST_CONTRACT); + event.query() + }; + assert_eq!(logs, preflight_logs, "mismatch in preflight and execution"); + assert!(logs.is_empty()); + } } #[test(tokio::test)] diff --git a/examples/events/Cargo.toml b/examples/events/Cargo.toml index f13597d6..b1a0c4c2 100644 --- a/examples/events/Cargo.toml +++ b/examples/events/Cargo.toml @@ -4,7 +4,7 @@ members = ["host", "methods"] [workspace.dependencies] # Intra-workspace dependencies -risc0-steel = { path = "../../crates/steel" } +risc0-steel = { path = "../../crates/steel", features = ["unstable-event"] } # risc0 monorepo dependencies. risc0-build = { git = "https://github.com/risc0/risc0", branch = "main" } diff --git a/examples/events/methods/guest/Cargo.toml b/examples/events/methods/guest/Cargo.toml index 987e7707..021b433f 100644 --- a/examples/events/methods/guest/Cargo.toml +++ b/examples/events/methods/guest/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] alloy-primitives = { version = "0.8" } alloy-sol-types = { version = "0.8" } -risc0-steel = { path = "../../../../crates/steel" } +risc0-steel = { path = "../../../../crates/steel", features = ["unstable-event"] } risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false, features = ["std", "unstable"] } [patch.crates-io] From 9fe8326f2c890b3193004bc36f93f4abec9aad1d Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 18:17:25 +0100 Subject: [PATCH 08/14] fix --- crates/op-steel/Cargo.toml | 1 + crates/op-steel/src/optimism/mod.rs | 11 +++++++++++ crates/steel/Cargo.toml | 1 - 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/op-steel/Cargo.toml b/crates/op-steel/Cargo.toml index 25cec2c8..1c43fc29 100644 --- a/crates/op-steel/Cargo.toml +++ b/crates/op-steel/Cargo.toml @@ -33,3 +33,4 @@ risc0-op-steel = { workspace = true, features = ["host"] } [features] default = [] host = ["dep:alloy", "dep:tokio", "dep:url", "risc0-steel/host", "alloy-primitives/rand"] +unstable-event = [] diff --git a/crates/op-steel/src/optimism/mod.rs b/crates/op-steel/src/optimism/mod.rs index 5550c1ed..29524139 100644 --- a/crates/op-steel/src/optimism/mod.rs +++ b/crates/op-steel/src/optimism/mod.rs @@ -13,6 +13,7 @@ // limitations under the License. use crate::game::DisputeGameInput; +use alloy_primitives::Bloom; use op_alloy_network::{Network, Optimism}; use revm::{ precompile::B256, @@ -98,6 +99,16 @@ impl EvmBlockHeader for OpBlockHeader { fn state_root(&self) -> &B256 { &self.0.inner().state_root } + #[cfg(feature = "unstable-event")] + #[inline] + fn receipts_root(&self) -> &B256 { + &self.0.inner().receipts_root + } + #[cfg(feature = "unstable-event")] + #[inline] + fn logs_bloom(&self) -> &Bloom { + &self.0.inner().logs_bloom + } #[inline] fn fill_block_env(&self, blk_env: &mut BlockEnv) { diff --git a/crates/steel/Cargo.toml b/crates/steel/Cargo.toml index e149c78d..af06080c 100644 --- a/crates/steel/Cargo.toml +++ b/crates/steel/Cargo.toml @@ -33,7 +33,6 @@ stability = { workspace = true } thiserror = { workspace = true, features = ["default"] } tokio = { workspace = true, optional = true } url = { workspace = true, optional = true } -cfg-if = "1.0.0" [dev-dependencies] alloy = { workspace = true, features = ["contract", "node-bindings"] } From 682a211d50359af1e51c0b881c9770095993056d Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 18:20:09 +0100 Subject: [PATCH 09/14] update license header --- examples/events/host/src/main.rs | 2 +- examples/events/methods/build.rs | 2 +- examples/events/methods/guest/src/main.rs | 2 +- examples/events/methods/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/events/host/src/main.rs b/examples/events/host/src/main.rs index 2a206d56..fe49dd30 100644 --- a/examples/events/host/src/main.rs +++ b/examples/events/host/src/main.rs @@ -1,4 +1,4 @@ -// Copyright 2024 RISC Zero, Inc. +// Copyright 2025 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/examples/events/methods/build.rs b/examples/events/methods/build.rs index a4aa2563..0daaafc8 100644 --- a/examples/events/methods/build.rs +++ b/examples/events/methods/build.rs @@ -1,4 +1,4 @@ -// Copyright 2024 RISC Zero, Inc. +// Copyright 2025 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/examples/events/methods/guest/src/main.rs b/examples/events/methods/guest/src/main.rs index d26b6db8..74de59f7 100644 --- a/examples/events/methods/guest/src/main.rs +++ b/examples/events/methods/guest/src/main.rs @@ -1,4 +1,4 @@ -// Copyright 2024 RISC Zero, Inc. +// Copyright 2025 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/examples/events/methods/src/lib.rs b/examples/events/methods/src/lib.rs index ae9d61e6..af77b3e6 100644 --- a/examples/events/methods/src/lib.rs +++ b/examples/events/methods/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2024 RISC Zero, Inc. +// Copyright 2025 RISC Zero, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 3bda990795865f36c1a87f478b8e7da292f03a84 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 18:29:28 +0100 Subject: [PATCH 10/14] fix warnings --- crates/op-steel/src/optimism/mod.rs | 3 +-- crates/steel/src/state.rs | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/op-steel/src/optimism/mod.rs b/crates/op-steel/src/optimism/mod.rs index 29524139..62ea5f5c 100644 --- a/crates/op-steel/src/optimism/mod.rs +++ b/crates/op-steel/src/optimism/mod.rs @@ -13,7 +13,6 @@ // limitations under the License. use crate::game::DisputeGameInput; -use alloy_primitives::Bloom; use op_alloy_network::{Network, Optimism}; use revm::{ precompile::B256, @@ -106,7 +105,7 @@ impl EvmBlockHeader for OpBlockHeader { } #[cfg(feature = "unstable-event")] #[inline] - fn logs_bloom(&self) -> &Bloom { + fn logs_bloom(&self) -> &alloy_primitives::Bloom { &self.0.inner().logs_bloom } diff --git a/crates/steel/src/state.rs b/crates/steel/src/state.rs index c49962d4..f40483f2 100644 --- a/crates/steel/src/state.rs +++ b/crates/steel/src/state.rs @@ -47,6 +47,7 @@ pub struct StateDb { /// Block hashes by their number. block_hashes: HashMap, /// All the logs for this block. + #[allow(dead_code)] logs: Option>, } @@ -114,6 +115,7 @@ impl StateDb { /// account. pub struct WrapStateDb<'a, H> { inner: &'a StateDb, + #[allow(dead_code)] header: &'a Sealed, account_storage: AddressHashMap>>, } From 369c8b38ea4e8461009c3d226f2531c08d101f4e Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 18:39:23 +0100 Subject: [PATCH 11/14] fix warning --- crates/steel/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/steel/src/lib.rs b/crates/steel/src/lib.rs index 2b2234e6..35c76f01 100644 --- a/crates/steel/src/lib.rs +++ b/crates/steel/src/lib.rs @@ -141,6 +141,7 @@ pub trait EvmDatabase: RevmDatabase { /// Checks if a bloom filter matches the given filter parameters. // TODO: Move to `event` once no longer unstable +#[allow(dead_code)] #[inline] pub(crate) fn matches_filter(bloom: Bloom, filter: &Filter) -> bool { FilteredParams::matches_address(bloom, &FilteredParams::address_filter(&filter.address)) From 38985d145199d8985be36889d5303daf82c1a4f5 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 18:49:06 +0100 Subject: [PATCH 12/14] add README --- examples/README.md | 5 +++++ examples/events/README.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 examples/events/README.md diff --git a/examples/README.md b/examples/README.md index 8d64f685..c4eafddc 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,6 +12,11 @@ Explore a more advanced interaction between [Steel] and a custom Ethereum smart - Verify ERC20 token ownership (minimum 1 token required) before incrementing. - Leverage RISC Zero as a [coprocessor] for efficient proof generation and verification. +## [Event Query](./events/README.md) + +This example illustrates how to use [Steel] to query and process events. +This example computes the total USDT transferred in a block by evaluating the ERC20 `Transfer` event emitted by the corresponding contract. + ## [Compound Token Stats (APR Proof)](./token-stats/README.md) This example shows how the [Steel] library can be used to call multiple view functions of a contract. diff --git a/examples/events/README.md b/examples/events/README.md new file mode 100644 index 00000000..366aabd4 --- /dev/null +++ b/examples/events/README.md @@ -0,0 +1,31 @@ +# Events Example + +**An example that computes the total USDT transferred in a block by evaluating the ERC20 `Transfer` event emitted by the corresponding contract.** + +## Prerequisites + +To get started, you need to have Rust installed. If you haven't done so, follow the instructions [here][install-rust]. + +Next, you will also need to have the `cargo-risczero` tool installed following the instructions [here][install-risczero]. + +You'll also need access to an Ethereum Mainnet RPC endpoint. You can for example use [ethereum-rpc.publicnode.com](https://ethereum-rpc.publicnode.com/) or a commercial RPC provider like [Alchemy](https://www.alchemy.com/). + +## Run the example + +To run the example, which computes the total USDT transferred in the latest block on Ethereum, execute the following command: + +```bash +RPC_URL=https://ethereum-rpc.publicnode.com RUST_LOG=info cargo run --release +``` + +The output should resemble the following: + +```text +2025-01-23T17:45:09.325435Z INFO risc0_steel::host::builder: Environment initialized with block 21688768 (0x74886aafc56111558c80aad6d998f214fb3f3fc70bd65164a81eb89c6aafaba6) +2025-01-23T17:45:09.404058Z INFO host: Contract 0xdAC17F958D2ee523a2206206994597C13D831ec7 emitted 13 events with signature: Transfer(address,address,uint256) +2025-01-23T17:45:09.797803Z INFO risc0_zkvm::host::server::exec::executor: execution time: 95.332417ms +2025-01-23T17:45:09.801306Z INFO host: Total USDT transferred in block 0x74886aafc56111558c80aad6d998f214fb3f3fc70bd65164a81eb89c6aafaba6: 505404191183 +``` + +[install-rust]: https://doc.rust-lang.org/cargo/getting-started/installation.html +[install-risczero]: https://dev.risczero.com/api/zkvm/install From 2c1e5489c83ff58ff6d5a05fb07f10ad6ef462ae Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 23 Jan 2025 19:04:11 +0100 Subject: [PATCH 13/14] add CHANGELOG --- crates/steel/CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/steel/CHANGELOG.md b/crates/steel/CHANGELOG.md index 663a370e..abe0045d 100644 --- a/crates/steel/CHANGELOG.md +++ b/crates/steel/CHANGELOG.md @@ -4,8 +4,11 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - -## [1.3.0] +### ⚡️ Features + +- Introduce the capability to query Ethereum events. The new `Event` allows to query events of a specific type in Steel. Its usage is very similar to the existing `Contract`, during the preflight step and in the guest. This functionality is currently marked unstable and must be enabled using the `unstable-event` feature. + +## [1.3.0](https://github.com/risc0/risc0-ethereum/releases/tag/v1.3.0) ### ⚡️ Features From 0226b3158e5a44bc97d51a117f2ff5f7bcc23bfd Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Fri, 24 Jan 2025 15:36:50 +0100 Subject: [PATCH 14/14] minor fixes --- crates/steel/src/event.rs | 29 ++++++++++++++--------------- crates/steel/src/lib.rs | 2 +- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/crates/steel/src/event.rs b/crates/steel/src/event.rs index 65d98f94..166fb5fa 100644 --- a/crates/steel/src/event.rs +++ b/crates/steel/src/event.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Types related to event queries. pub use alloy_rpc_types::{Topic, ValueOrArray}; use crate::{state::WrapStateDb, EvmBlockHeader, EvmDatabase, GuestEvmEnv}; @@ -20,14 +21,12 @@ use alloy_rpc_types::Filter; use alloy_sol_types::SolEvent; use std::marker::PhantomData; -/// Represents an Ethereum event query. +/// Represents an EVM event query. /// /// ### Usage -/// - **Preflight calls on the Host:** To prepare calls on the host environment and build the -/// necessary proof, use [Event::preflight]. -/// - **Calls in the Guest:** To initialize the contract in the guest environment, use [Event::new]. -/// -/// See [Contract] for more details. +/// - **Preflight calls on the Host:** To prepare the event query on the host environment and build +/// the necessary proof, use [Event::preflight]. +/// - **Calls in the Guest:** To initialize the event query in the guest, use [Event::new]. /// /// ### Examples /// ```rust,no_run @@ -39,7 +38,6 @@ use std::marker::PhantomData; /// # async fn main() -> anyhow::Result<()> { /// let contract_address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); /// sol! { -/// # #[derive(Debug)] /// interface IERC20 { /// event Transfer(address indexed from, address indexed to, uint256 value); /// } @@ -57,7 +55,6 @@ use std::marker::PhantomData; /// let env = evm_input.into_env(); /// let event = Event::new::(&env).address(contract_address); /// let logs = event.query(); -/// # dbg!(logs); /// /// # Ok(()) /// # } @@ -132,16 +129,16 @@ impl Event { mod host { use super::*; use crate::host::HostEvmEnv; - use anyhow::{anyhow, Result}; + use anyhow::{Context, Result}; use revm::Database as RevmDatabase; - use std::fmt::Display; + use std::error::Error as StdError; impl Event<(), &mut HostEvmEnv> where D: EvmDatabase + Send + 'static, - ::Error: Display + Send + 'static, + ::Error: StdError + Send + Sync + 'static, { - /// Constructor for preflighting an event query for a specific Solidity event. + /// Constructor for preflighting an event query for a specific EVM event. /// /// Initializes the environment for event queries, fetching necessary data via the /// [Provider], and generating a storage proof for any accessed elements using @@ -164,7 +161,7 @@ mod host { impl Event> where D: EvmDatabase + Send + 'static, - ::Error: Display + Send + 'static, + ::Error: StdError + Send + Sync + 'static, { /// Executes the event query using an [EvmEnv] constructed with [Event::preflight]. /// @@ -172,11 +169,13 @@ mod host { /// /// [EvmEnv]: crate::EvmEnv pub async fn query(self) -> Result>> { + log::info!("Executing preflight querying event '{}'", S::SIGNATURE); + let logs = self .env .spawn_with_db(move |db| db.logs(self.filter)) .await - .map_err(|err| anyhow!("querying '{}' failed: {}", S::SIGNATURE, err))?; + .with_context(|| format!("querying logs for '{}' failed", S::SIGNATURE))?; logs.iter() .map(|log| Ok(S::decode_log(log, false)?)) .collect() @@ -184,7 +183,7 @@ mod host { } } -/// Creates an event filter for a specific Solidity event and block header. +/// Creates an event filter for a specific event and block header. fn event_filter(header: &Sealed) -> Filter { assert!(!S::ANONYMOUS, "Anonymous events not supported"); Filter::new() diff --git a/crates/steel/src/lib.rs b/crates/steel/src/lib.rs index 35c76f01..264b37b2 100644 --- a/crates/steel/src/lib.rs +++ b/crates/steel/src/lib.rs @@ -39,7 +39,7 @@ pub mod config; mod contract; pub mod ethereum; #[cfg(feature = "unstable-event")] -mod event; +pub mod event; #[cfg(feature = "unstable-history")] pub mod history; #[cfg(not(feature = "unstable-history"))]