From b30672cb2a16aa26c84e879f4d542cd01ad08218 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 24 Jul 2024 17:43:43 +0200 Subject: [PATCH 01/30] switch Steel to alloy --- Cargo.toml | 10 +- examples/erc20-counter/Cargo.toml | 7 +- examples/erc20-counter/apps/Cargo.toml | 9 +- examples/erc20-counter/apps/README.md | 14 +- .../erc20-counter/apps/src/bin/publisher.rs | 129 +++--- examples/erc20-counter/apps/src/lib.rs | 60 --- .../methods/guest/src/bin/balance_of.rs | 7 +- .../erc20-counter/test-local-deployment.sh | 1 - examples/erc20/Cargo.toml | 13 +- examples/erc20/host/Cargo.toml | 2 + examples/erc20/host/src/main.rs | 32 +- examples/erc20/methods/Cargo.toml | 2 +- examples/erc20/rust-toolchain.toml | 2 +- examples/token-stats/Cargo.toml | 14 +- examples/token-stats/host/Cargo.toml | 2 + examples/token-stats/host/src/main.rs | 48 +- examples/token-stats/methods/Cargo.toml | 2 +- examples/token-stats/rust-toolchain.toml | 4 + rust-toolchain.toml | 2 +- steel/Cargo.toml | 15 +- steel/README.md | 15 +- steel/src/contract.rs | 98 +++-- steel/src/ethereum.rs | 68 +-- steel/src/host/db.rs | 187 -------- steel/src/host/db/alloy.rs | 164 +++++++ steel/src/host/db/mod.rs | 23 + steel/src/host/db/trace.rs | 91 ++++ steel/src/host/mod.rs | 121 ++++-- steel/src/host/provider/ethers.rs | 234 ---------- steel/src/host/provider/file.rs | 311 ------------- steel/src/host/provider/mod.rs | 110 ----- steel/src/lib.rs | 4 +- steel/tests/eth_call.rs | 409 ++++++++---------- 33 files changed, 808 insertions(+), 1402 deletions(-) delete mode 100644 examples/erc20-counter/apps/src/lib.rs create mode 100644 examples/token-stats/rust-toolchain.toml delete mode 100644 steel/src/host/db.rs create mode 100644 steel/src/host/db/alloy.rs create mode 100644 steel/src/host/db/mod.rs create mode 100644 steel/src/host/db/trace.rs delete mode 100644 steel/src/host/provider/ethers.rs delete mode 100644 steel/src/host/provider/file.rs delete mode 100644 steel/src/host/provider/mod.rs diff --git a/Cargo.toml b/Cargo.toml index c86fdc69..4fb301df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,16 +21,20 @@ risc0-build = { git = "https://github.com/risc0/risc0", branch = "main", default risc0-zkp = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false } risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false } +# Alloy guest dependencies +alloy-consensus = { git = "https://github.com/alloy-rs/alloy.git" } alloy-primitives = { version = "0.7", features = ["serde", "rlp", "std"] } alloy-rlp = { version = "0.3.7", default-features = false } alloy-rlp-derive = { version = "0.3.7", default-features = false } alloy-sol-types = { version = "0.7" } + +# Alloy host dependencies +alloy = { git = "https://github.com/alloy-rs/alloy.git", features = ["full"] } alloy-trie = { version = "0.4.0" } + anyhow = { version = "1.0" } bincode = { version = "1.3" } clap = { version = "4.5", features = ["derive", "env"] } -ethers-core = "2.0" -ethers-providers = "2.0" log = "0.4" nybbles = { version = "0.2.1", features = ["serde"] } once_cell = "1.19" @@ -41,3 +45,5 @@ test-log = "0.2.15" thiserror = "1.0" tokio = { version = "1.35" } tracing-subscriber = { version = "0.3", features = ["env-filter"] } +url = { version = "2.5" } +wiremock = { version = "0.6" } diff --git a/examples/erc20-counter/Cargo.toml b/examples/erc20-counter/Cargo.toml index adf99978..b18d1475 100644 --- a/examples/erc20-counter/Cargo.toml +++ b/examples/erc20-counter/Cargo.toml @@ -18,17 +18,20 @@ risc0-build = { git = "https://github.com/risc0/risc0", branch = "main", feature 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.7", default-features = false, features = ["rlp", "serde", "std"] } +alloy = { git = "https://github.com/alloy-rs/alloy.git", features = ["full"] } +alloy-primitives = { version = "0.7", features = ["rlp", "serde", "std"] } alloy-sol-types = { version = "0.7" } anyhow = { version = "1.0.75" } bincode = { version = "1.3" } bytemuck = { version = "1.14" } +clap = { version = "4.5" } ethers = { version = "2.0" } hex = { version = "0.4" } -log = { version = "0.4" } erc20-counter-methods = { path = "./methods" } serde = { version = "1.0", features = ["derive", "std"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } +tokio = { version = "1.39", features = ["full"] } +url = { version = "2.5" } [profile.release] debug = 1 diff --git a/examples/erc20-counter/apps/Cargo.toml b/examples/erc20-counter/apps/Cargo.toml index cdae974f..747f179b 100644 --- a/examples/erc20-counter/apps/Cargo.toml +++ b/examples/erc20-counter/apps/Cargo.toml @@ -4,15 +4,14 @@ version = { workspace = true } edition = { workspace = true } [dependencies] +alloy = { workspace = true } alloy-primitives = { workspace = true } -alloy-sol-types = { workspace = true } anyhow = { workspace = true } -clap = { version = "4.0", features = ["derive", "env"] } +clap = { workspace = true, features = ["derive", "env"] } erc20-counter-methods = { workspace = true } -ethers = { workspace = true } -log = { workspace = true } risc0-ethereum-contracts = { workspace = true } risc0-steel = { workspace = true, features = ["host"] } risc0-zkvm = { workspace = true, features = ["client"] } -tokio = { version = "1.35", features = ["full"] } +tokio = { workspace = true } tracing-subscriber = { workspace = true } +url = { workspace = true } diff --git a/examples/erc20-counter/apps/README.md b/examples/erc20-counter/apps/README.md index f02eab6c..08f8c22c 100644 --- a/examples/erc20-counter/apps/README.md +++ b/examples/erc20-counter/apps/README.md @@ -15,17 +15,17 @@ cargo run --bin publisher ```text $ cargo run --bin publisher -- --help -Usage: publisher --chain-id --eth-wallet-private-key --rpc-url --contract --account +Usage: publisher --eth-wallet-private-key --rpc-url --contract --token --account Options: - --chain-id - Ethereum chain ID --eth-wallet-private-key - Ethereum Node endpoint [env: ETH_WALLET_PRIVATE_KEY=0x2a5369d12693b5a8c4e1d0e85788bea5ccb1c90fb6f82bb33a25a216e6cce071] + Ethereum Node endpoint [env: ETH_WALLET_PRIVATE_KEY=] --rpc-url Ethereum Node endpoint [env: RPC_URL=] --contract Counter's contract address on Ethereum + --token + ERC20 contract address on Ethereum --account Account address to read the balance_of on Ethereum -h, --help @@ -34,11 +34,5 @@ Options: Print version ``` -## Library - -We provide a small rust [library] containing utility functions to help with sending -transactions to a deployed app contract on Ethereum. - [publisher]: ./src/bin/publisher.rs -[library]: ./src/lib.rs [Counter]: ../contracts/Counter.sol diff --git a/examples/erc20-counter/apps/src/bin/publisher.rs b/examples/erc20-counter/apps/src/bin/publisher.rs index 2066d886..42aee5dd 100644 --- a/examples/erc20-counter/apps/src/bin/publisher.rs +++ b/examples/erc20-counter/apps/src/bin/publisher.rs @@ -16,18 +16,26 @@ // to the Bonsai proving service and publish the received proofs directly // to your deployed app contract. +use std::time::Duration; + +use alloy::{ + network::EthereumWallet, providers::ProviderBuilder, signers::local::PrivateKeySigner, + sol_types::SolCall, +}; use alloy_primitives::Address; -use alloy_sol_types::{sol, SolCall}; -use anyhow::Result; -use apps::TxSender; +use anyhow::{ensure, Context, Result}; use clap::Parser; use erc20_counter_methods::BALANCE_OF_ELF; use risc0_ethereum_contracts::groth16::encode; -use risc0_steel::{config::ETH_SEPOLIA_CHAIN_SPEC, ethereum::EthEvmEnv, Contract, EvmBlockHeader}; +use risc0_steel::{ + config::ETH_SEPOLIA_CHAIN_SPEC, ethereum::EthEvmEnv, host::BlockNumberOrTag, Contract, +}; use risc0_zkvm::{default_prover, ExecutorEnv, ProverOpts, VerifierContext}; +use tokio::task; use tracing_subscriber::EnvFilter; +use url::Url; -sol! { +alloy::sol! { /// ERC-20 balance function signature. /// This must match the signature in the guest. interface IERC20 { @@ -35,23 +43,22 @@ sol! { } } -sol!("../contracts/ICounter.sol"); +alloy::sol!( + #[sol(rpc)] + "../contracts/ICounter.sol" +); /// Arguments of the publisher CLI. #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] struct Args { - /// Ethereum chain ID - #[clap(long)] - chain_id: u64, - /// Ethereum Node endpoint. #[clap(long, env)] - eth_wallet_private_key: String, + eth_wallet_private_key: PrivateKeySigner, /// Ethereum Node endpoint. #[clap(long, env)] - rpc_url: String, + rpc_url: Url, /// Counter's contract address on Ethereum #[clap(long)] @@ -66,18 +73,24 @@ struct Args { account: Address, } -fn main() -> Result<()> { +#[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 + // Parse the command line arguments. let args = Args::parse(); - // Create an EVM environment from an RPC endpoint and a block number. If no block number is - // provided, the latest block is used. - let mut env = EthEvmEnv::from_rpc(&args.rpc_url, None)?; + // Create an alloy provider for that private key and URL. + let wallet = EthereumWallet::from(args.eth_wallet_private_key); + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .wallet(wallet) + .on_http(args.rpc_url); + + // Create an EVM environment from that provider and a block number. + let mut env = EthEvmEnv::from_provider(provider.clone(), BlockNumberOrTag::Latest).await?; // The `with_chain_spec` method is used to specify the chain configuration. env = env.with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); @@ -86,58 +99,62 @@ fn main() -> Result<()> { account: args.account, }; - // Preflight the call to execute the function in the guest. + // Preflight the call to prepare the input that is required to execute the function in + // the guest without RPC access. It also returns the result of the call. let mut contract = Contract::preflight(args.token, &mut env); - let returns = contract.call_builder(&call).call()?; + let returns = contract.call_builder(&call).call().await?; println!( - "For block {} calling `{}` on {} returns: {}", - env.header().number(), + "Call {} Function on {:#} returns: {}", IERC20::balanceOfCall::SIGNATURE, args.token, returns._0 ); - println!("proving..."); - let view_call_input = env.into_input()?; - let env = ExecutorEnv::builder() - .write(&view_call_input)? - .write(&args.token)? - .write(&args.account)? - .build()?; + // Finally, construct the input from the environment. + let view_call_input = env.into_input().await?; + + println!("Creating proof for the constructed input..."); + let prove_info = task::spawn_blocking(move || { + let env = ExecutorEnv::builder() + .write(&view_call_input)? + .write(&args.token)? + .write(&args.account)? + .build() + .unwrap(); - let receipt = default_prover() - .prove_with_ctx( + default_prover().prove_with_ctx( env, &VerifierContext::default(), BALANCE_OF_ELF, &ProverOpts::groth16(), - )? - .receipt; - println!("proving...done"); - - // Create a new `TxSender`. - let tx_sender = TxSender::new( - args.chain_id, - &args.rpc_url, - &args.eth_wallet_private_key, - &args.contract.to_string(), - )?; - - // Encode the groth16 seal with the selector - let seal = encode(receipt.inner.groth16()?.seal.clone())?; + ) + }) + .await? + .context("failed to create proof")?; + let receipt = prove_info.receipt; - // Encode the function call for `ICounter.increment(journal, seal)`. - let calldata = ICounter::incrementCall { - journalData: receipt.journal.bytes.into(), - seal: seal.into(), - } - .abi_encode(); + // Create an alloy instance of the Counter contract. + let contract = ICounter::new(args.contract, provider); + + // Encode the groth16 seal with the selector and call the increment function of the contract. + let seal = encode(receipt.inner.groth16()?.seal.clone())?; - // Send the calldata to Ethereum. - println!("sending tx..."); - let runtime = tokio::runtime::Runtime::new()?; - runtime.block_on(tx_sender.send(calldata))?; - println!("sending tx...done"); + // Call the increment function of the contract and wait for confirmation. + println!( + "Sending Tx calling {} Function of {:#}...", + ICounter::incrementCall::SIGNATURE, + contract.address() + ); + let call_builder = contract.increment(receipt.journal.bytes.into(), seal.into()); + let pending_tx = call_builder.send().await?; + let receipt = pending_tx + .with_timeout(Some(Duration::from_secs(60))) + .get_receipt() + .await?; + ensure!(receipt.status(), "transaction failed"); + + let value = contract.get().call().await?._0; + println!("New value of Counter: {}", value); Ok(()) } diff --git a/examples/erc20-counter/apps/src/lib.rs b/examples/erc20-counter/apps/src/lib.rs deleted file mode 100644 index 4b154739..00000000 --- a/examples/erc20-counter/apps/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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. - -// The following library provides utility functions to help with sending -// transactions to a deployed app contract on Ethereum. - -use anyhow::Result; -use ethers::prelude::*; - -/// Wrapper of a `SignerMiddleware` client to send transactions to the given -/// contract's `Address`. -pub struct TxSender { - chain_id: u64, - client: SignerMiddleware, Wallet>, - contract: Address, -} - -impl TxSender { - /// Creates a new `TxSender`. - pub fn new(chain_id: u64, rpc_url: &str, private_key: &str, contract: &str) -> Result { - let provider = Provider::::try_from(rpc_url)?; - let wallet: LocalWallet = private_key.parse::()?.with_chain_id(chain_id); - let client = SignerMiddleware::new(provider.clone(), wallet.clone()); - let contract = contract.parse::
()?; - - Ok(TxSender { - chain_id, - client, - contract, - }) - } - - /// Send a transaction with the given calldata. - pub async fn send(&self, calldata: Vec) -> Result> { - let tx = TransactionRequest::new() - .chain_id(self.chain_id) - .to(self.contract) - .from(self.client.address()) - .data(calldata); - - log::info!("Transaction request: {:?}", &tx); - - let tx = self.client.send_transaction(tx, None).await?.await?; - - log::info!("Transaction receipt: {:?}", &tx); - - Ok(tx) - } -} diff --git a/examples/erc20-counter/methods/guest/src/bin/balance_of.rs b/examples/erc20-counter/methods/guest/src/bin/balance_of.rs index 58e16920..751a9be3 100644 --- a/examples/erc20-counter/methods/guest/src/bin/balance_of.rs +++ b/examples/erc20-counter/methods/guest/src/bin/balance_of.rs @@ -41,9 +41,12 @@ sol! { fn main() { // Read the input from the guest environment. + println!("Reading input"); let input: EthEvmInput = env::read(); - let contract: Address = env::read(); - let account: Address = env::read(); + let contract: Address = Address::ZERO; // env::read(); + let account: Address = Address::ZERO; // env::read(); + + println!("Reading input done"); // Converts the input into a `EvmEnv` for execution. The `with_chain_spec` method is used // to specify the chain configuration. It checks that the state matches the state root in the diff --git a/examples/erc20-counter/test-local-deployment.sh b/examples/erc20-counter/test-local-deployment.sh index 9abaacc5..9caba335 100755 --- a/examples/erc20-counter/test-local-deployment.sh +++ b/examples/erc20-counter/test-local-deployment.sh @@ -48,7 +48,6 @@ echo "Counter Address: $COUNTER_ADDRESS" # Publish a new state echo "Publishing a new state..." cargo run --bin publisher -- \ - --chain-id=31337 \ --rpc-url=http://localhost:8545 \ --contract=${COUNTER_ADDRESS:?} \ --token=${TOYKEN_ADDRESS:?} \ diff --git a/examples/erc20/Cargo.toml b/examples/erc20/Cargo.toml index fd4eabb1..a25f7c04 100644 --- a/examples/erc20/Cargo.toml +++ b/examples/erc20/Cargo.toml @@ -3,6 +3,16 @@ resolver = "2" members = ["host", "methods"] [workspace.dependencies] +# Intra-workspace dependencies +risc0-build-ethereum = { path = "../../build" } +risc0-ethereum-contracts = { path = "../../contracts" } +risc0-steel = { path = "../../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.7", features = ["serde", "rlp", "std"] } alloy-rlp = { version = "0.3.4", default-features = false } alloy-rlp-derive = { version = "0.3.4", default-features = false } @@ -16,13 +26,12 @@ erc20-methods = { path = "methods" } nybbles = { version = "0.2.1", features = ["serde"] } once_cell = "1.19" revm = { version = "9.0", default-features = false, features = ["std"] } -risc0-steel = { path = "../../steel" } -risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false } rlp = "0.5.2" serde = "1.0" thiserror = "1.0" tokio = { version = "1.35" } tracing-subscriber = { version = "0.3", features = ["env-filter"] } +url = { version = "2.5" } # Always optimize; building and running the guest takes much longer without optimization. [profile.dev] diff --git a/examples/erc20/host/Cargo.toml b/examples/erc20/host/Cargo.toml index df70faad..d33d3ebd 100644 --- a/examples/erc20/host/Cargo.toml +++ b/examples/erc20/host/Cargo.toml @@ -11,4 +11,6 @@ clap = { workspace = true } erc20-methods = { workspace = true } risc0-steel = { path = "../../../steel", features = ["host"] } risc0-zkvm = { workspace = true, features = ["client"] } +tokio = { workspace = true, features = ["rt-multi-thread"] } tracing-subscriber = { workspace = true } +url = { workspace = true } diff --git a/examples/erc20/host/src/main.rs b/examples/erc20/host/src/main.rs index 77858de9..c36418b7 100644 --- a/examples/erc20/host/src/main.rs +++ b/examples/erc20/host/src/main.rs @@ -17,9 +17,12 @@ use alloy_sol_types::{sol, SolCall, SolValue}; use anyhow::{Context, Result}; use clap::Parser; use erc20_methods::ERC20_GUEST_ELF; -use risc0_steel::{config::ETH_SEPOLIA_CHAIN_SPEC, ethereum::EthEvmEnv, Contract, EvmBlockHeader}; +use risc0_steel::{ + config::ETH_SEPOLIA_CHAIN_SPEC, ethereum::EthEvmEnv, host::BlockNumberOrTag, Contract, +}; use risc0_zkvm::{default_executor, ExecutorEnv}; use tracing_subscriber::EnvFilter; +use url::Url; sol! { /// ERC-20 balance function signature. @@ -45,10 +48,11 @@ const CALLER: Address = address!("f08A50178dfcDe18524640EA6618a1f965821715"); struct Args { /// URL of the RPC endpoint #[arg(short, long, env = "RPC_URL")] - rpc_url: String, + rpc_url: Url, } -fn main() -> Result<()> { +#[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()) @@ -56,35 +60,35 @@ fn main() -> Result<()> { // Parse the command line arguments. let args = Args::parse(); - // Create an EVM environment from an RPC endpoint and a block number. If no block number is - // provided, the latest block is used. - let mut env = EthEvmEnv::from_rpc(&args.rpc_url, None)?; + // Create an EVM environment from an RPC endpoint and a block number or tag. + let mut env = EthEvmEnv::from_rpc(args.rpc_url, BlockNumberOrTag::Latest).await?; // The `with_chain_spec` method is used to specify the chain configuration. env = env.with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); - let commitment = env.block_commitment(); - // Preflight the call to prepare the input that is required to execute the function in // the guest without RPC access. It also returns the result of the call. let mut contract = Contract::preflight(CONTRACT, &mut env); - let returns = contract.call_builder(&CALL).from(CALLER).call()?; + let returns = contract.call_builder(&CALL).from(CALLER).call().await?; println!( - "For block {} `{}` returns: {}", - env.header().number(), + "Call {} Function by {:#} on {:#} returns: {}", IERC20::balanceOfCall::SIGNATURE, + CALLER, + CONTRACT, returns._0 ); + // Get the commitment to verify execution later. + let commitment = env.block_commitment(); // Finally, construct the input from the environment. - let input = env.into_input()?; + let input = env.into_input().await?; - println!("Running the guest with the constructed input:"); + println!("Running the guest with the constructed input..."); let session_info = { let env = ExecutorEnv::builder() .write(&input) .unwrap() .build() - .context("Failed to build exec env")?; + .context("failed to build executor env")?; let exec = default_executor(); exec.execute(env, ERC20_GUEST_ELF) .context("failed to run executor")? diff --git a/examples/erc20/methods/Cargo.toml b/examples/erc20/methods/Cargo.toml index bee6d029..0a6056a3 100644 --- a/examples/erc20/methods/Cargo.toml +++ b/examples/erc20/methods/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [build-dependencies] -risc0-build = { git = "https://github.com/risc0/risc0", branch = "main" } +risc0-build = { workspace = true } [package.metadata.risc0] methods = ["guest"] diff --git a/examples/erc20/rust-toolchain.toml b/examples/erc20/rust-toolchain.toml index b58c6b90..36614c30 100644 --- a/examples/erc20/rust-toolchain.toml +++ b/examples/erc20/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.75" +channel = "stable" components = ["rustfmt", "rust-src"] profile = "minimal" diff --git a/examples/token-stats/Cargo.toml b/examples/token-stats/Cargo.toml index dd874148..198aaa5e 100644 --- a/examples/token-stats/Cargo.toml +++ b/examples/token-stats/Cargo.toml @@ -3,6 +3,14 @@ resolver = "2" members = ["core", "host", "methods"] [workspace.dependencies] +# Intra-workspace dependencies +risc0-steel = { path = "../../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.7", features = ["serde", "rlp", "std"] } alloy-rlp = { version = "0.3", default-features = false } alloy-rlp-derive = { version = "0.3", default-features = false } @@ -13,16 +21,14 @@ ethers-core = "2.0" ethers-providers = "2.0" log = "0.4" methods = { path = "methods" } -nybbles = { version = "0.2.1", features = ["serde"] } once_cell = "1.19" revm = { version = "9.0", default-features = false, features = ["std"] } -risc0-steel = { path = "../../steel" } -risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false } rlp = "0.5.2" serde = "1.0" thiserror = "1.0" -tokio = { version = "1.35" } +tokio = { version = "1.35", features = ["full"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } +url = { version = "2.5" } # Always optimize; building and running the guest takes much longer without optimization. [profile.dev] diff --git a/examples/token-stats/host/Cargo.toml b/examples/token-stats/host/Cargo.toml index 95b297eb..4f6469d7 100644 --- a/examples/token-stats/host/Cargo.toml +++ b/examples/token-stats/host/Cargo.toml @@ -11,4 +11,6 @@ core = { path = "../core" } methods = { 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/token-stats/host/src/main.rs b/examples/token-stats/host/src/main.rs index f68981a1..be30750e 100644 --- a/examples/token-stats/host/src/main.rs +++ b/examples/token-stats/host/src/main.rs @@ -12,14 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use alloy_sol_types::SolValue; +use alloy_sol_types::{SolCall, SolValue}; use anyhow::{Context, Result}; use clap::Parser; use core::{APRCommitment, CometMainInterface, CONTRACT}; use methods::TOKEN_STATS_ELF; -use risc0_steel::{config::ETH_MAINNET_CHAIN_SPEC, ethereum::EthEvmEnv, Contract}; +use risc0_steel::{ + config::ETH_MAINNET_CHAIN_SPEC, ethereum::EthEvmEnv, host::BlockNumberOrTag, Contract, +}; use risc0_zkvm::{default_executor, ExecutorEnv}; use tracing_subscriber::EnvFilter; +use url::Url; // Simple program to show the use of Ethereum contract data inside the guest. #[derive(Parser, Debug)] @@ -27,10 +30,11 @@ use tracing_subscriber::EnvFilter; struct Args { /// URL of the RPC endpoint #[arg(short, long, env = "RPC_URL")] - rpc_url: String, + rpc_url: Url, } -fn main() -> Result<()> { +#[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()) @@ -38,27 +42,41 @@ fn main() -> Result<()> { // Parse the command line arguments. let args = Args::parse(); - // Create an EVM environment from an RPC endpoint and a block number. If no block number is - // provided, the latest block is used. - let mut env = EthEvmEnv::from_rpc(&args.rpc_url, None)?; + // Create an EVM environment from an RPC endpoint and a block number. + let mut env = EthEvmEnv::from_rpc(args.rpc_url, BlockNumberOrTag::Latest).await?; // The `with_chain_spec` method is used to specify the chain configuration. env = env.with_chain_spec(Ð_MAINNET_CHAIN_SPEC); - let block_commitment = env.block_commitment(); - // Preflight the call to prepare the input that is required to execute the function in // the guest without RPC access. It also returns the result of the call. let mut contract = Contract::preflight(CONTRACT, &mut env); let utilization = contract .call_builder(&CometMainInterface::getUtilizationCall {}) - .call()? + .call() + .await? ._0; - contract + println!( + "Call {} Function on {:#} returns: {}", + CometMainInterface::getUtilizationCall::SIGNATURE, + CONTRACT, + utilization + ); + let rate = contract .call_builder(&CometMainInterface::getSupplyRateCall { utilization }) - .call()?; + .call() + .await? + ._0; + println!( + "Call {} Function on {:#} returns: {}", + CometMainInterface::getSupplyRateCall::SIGNATURE, + CONTRACT, + rate + ); + // Get the commitment to verify execution later. + let commitment = env.block_commitment(); // Finally, construct the input from the environment. - let input = env.into_input()?; + let input = env.into_input().await?; println!("Running the guest with the constructed input:"); let session_info = { @@ -66,7 +84,7 @@ fn main() -> Result<()> { .write(&input) .unwrap() .build() - .context("Failed to build exec env")?; + .context("failed to build executor env")?; let exec = default_executor(); exec.execute(env, TOKEN_STATS_ELF) .context("failed to run executor")? @@ -74,7 +92,7 @@ fn main() -> Result<()> { let apr_commit = APRCommitment::abi_decode(&session_info.journal.bytes, true) .context("failed to decode journal")?; - assert_eq!(block_commitment, apr_commit.commitment); + assert_eq!(apr_commit.commitment, commitment); // Calculation is handling `/ 10^18 * 100` to match precision for a percentage. let apr = apr_commit.annualSupplyRate as f64 / 10f64.powi(16); diff --git a/examples/token-stats/methods/Cargo.toml b/examples/token-stats/methods/Cargo.toml index 15079482..6de3c23b 100644 --- a/examples/token-stats/methods/Cargo.toml +++ b/examples/token-stats/methods/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [build-dependencies] -risc0-build = { git = "https://github.com/risc0/risc0", branch = "main" } +risc0-build = { workspace = true } [package.metadata.risc0] methods = ["guest"] diff --git a/examples/token-stats/rust-toolchain.toml b/examples/token-stats/rust-toolchain.toml new file mode 100644 index 00000000..6c18dfcd --- /dev/null +++ b/examples/token-stats/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "stable" +components = ["rustfmt", "rust-src"] +profile = "minimal" \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 588d1b9b..f61bf150 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.75" +channel = "1.76" components = ["clippy", "rustfmt", "rust-src"] targets = [] profile = "minimal" diff --git a/steel/Cargo.toml b/steel/Cargo.toml index e99c5823..e67e7631 100644 --- a/steel/Cargo.toml +++ b/steel/Cargo.toml @@ -12,13 +12,13 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] +alloy = { workspace = true, optional = true } +alloy-consensus = { workspace = true, features = ["serde"] } alloy-primitives = { workspace = true } alloy-rlp = { workspace = true } alloy-rlp-derive = { workspace = true } alloy-sol-types = { workspace = true } anyhow = { workspace = true } -ethers-core = { workspace = true, optional = true } -ethers-providers = { workspace = true, optional = true } log = { workspace = true, optional = true } nybbles = { workspace = true } once_cell = { workspace = true } @@ -27,19 +27,14 @@ serde = { workspace = true } serde_json = { workspace = true, optional = true } thiserror = { workspace = true } tokio = { workspace = true, optional = true } +url = { workspace = true } [dev-dependencies] +alloy = { workspace = true, features = ["node-bindings"] } alloy-trie = { workspace = true } risc0-steel = { path = ".", features = ["host"] } test-log = { workspace = true } [features] default = [] -host = [ - "dep:ethers-core", - "dep:ethers-providers", - "dep:log", - "dep:serde_json", - "dep:tokio", - "revm/ethersdb", -] +host = ["dep:alloy", "dep:log", "dep:serde_json", "dep:tokio"] diff --git a/steel/README.md b/steel/README.md index e9a8304d..72d39501 100644 --- a/steel/README.md +++ b/steel/README.md @@ -60,17 +60,18 @@ fn main() { Here is a snippet to the [relevant code](../examples/erc20/host/src/main.rs) on the host, it requires the same arguments as the guest: ```rust -// Create a view call environment from an RPC endpoint and a block number. If no block number is -// provided, the latest block is used. -let mut env = EthViewCallEnv::from_rpc(&args.rpc_url, None)?; +// Create an EVM environment from an RPC endpoint and a block number or tag. +let mut env = EthEvmEnv::from_rpc(args.rpc_url, BlockNumberOrTag::Latest).await?; // The `with_chain_spec` method is used to specify the chain configuration. env = env.with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); -// Preflight the call to construct the input that is required to execute the function in -// the guest. It also returns the result of the call. +// Preflight the call to prepare the input that is required to execute the function in +// the guest without RPC access. It also returns the result of the call. let mut contract = Contract::preflight(CONTRACT, &mut env); -let returns = contract.call_builder(&CALL).from(CALLER).call()?; -let input = env.into_input()?; +let returns = contract.call_builder(&CALL).from(CALLER).call().await?; + +// Finally, construct the input from the environment. +let input = env.into_input().await?; ``` ## Ethereum integration diff --git a/steel/src/contract.rs b/steel/src/contract.rs index f4a19250..a773cdbc 100644 --- a/steel/src/contract.rs +++ b/steel/src/contract.rs @@ -13,9 +13,9 @@ // limitations under the License. #[cfg(feature = "host")] -use crate::host::{provider::Provider, HostEvmEnv}; +use crate::host::HostEvmEnv; use crate::{EvmBlockHeader, GuestEvmEnv, MerkleTrie, StateDb}; -use alloy_primitives::{keccak256, Address, Sealed, TxKind, B256, U256}; +use alloy_primitives::{keccak256, Address, TxKind, B256, U256}; use alloy_sol_types::{SolCall, SolType}; use revm::{ primitives::{ @@ -24,7 +24,7 @@ use revm::{ }, Database, Evm, }; -use std::{convert::Infallible, fmt::Debug, marker::PhantomData, mem, rc::Rc}; +use std::{borrow::Borrow, convert::Infallible, fmt::Debug, marker::PhantomData, mem, rc::Rc}; /// Represents a contract that is initialized with a specific environment and contract address. /// @@ -40,11 +40,12 @@ use std::{convert::Infallible, fmt::Debug, marker::PhantomData, mem, rc::Rc}; /// /// ### Examples /// ```rust no_run -/// # use risc0_steel::{ethereum::EthEvmEnv, Contract}; +/// # use risc0_steel::{ethereum::EthEvmEnv, Contract, host::BlockNumberOrTag}; /// # use alloy_primitives::{address}; /// # use alloy_sol_types::sol; /// -/// # fn main() -> anyhow::Result<()> { +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() -> anyhow::Result<()> { /// let contract_address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); /// sol! { /// interface IERC20 { @@ -57,11 +58,12 @@ use std::{convert::Infallible, fmt::Debug, marker::PhantomData, mem, rc::Rc}; /// }; /// /// // Host: -/// let mut env = EthEvmEnv::from_rpc("https://ethereum-rpc.publicnode.com", None)?; +/// let url = "https://ethereum-rpc.publicnode.com".parse()?; +/// let mut env = EthEvmEnv::from_rpc(url, BlockNumberOrTag::Latest).await?; /// let mut contract = Contract::preflight(contract_address, &mut env); -/// contract.call_builder(&get_balance).call()?; +/// contract.call_builder(&get_balance).call().await?; /// -/// let evm_input = env.into_input()?; +/// let evm_input = env.into_input().await?; /// /// // Guest: /// let evm_env = evm_input.into_env(); @@ -93,9 +95,9 @@ impl<'a, H> Contract<&'a GuestEvmEnv> { } #[cfg(feature = "host")] -impl<'a, P, H> Contract<&'a mut HostEvmEnv> +impl<'a, D, H> Contract<&'a mut HostEvmEnv> where - P: Provider, + D: Database, { /// Constructor for preflighting calls to an Ethereum contract on the host. /// @@ -103,15 +105,15 @@ where /// necessary data via the [Provider], and generating a storage proof for any accessed /// elements using [EvmEnv::into_input]. /// - /// [Provider]: crate::host::provider::Provider + /// [Provider]: alloy::providers::Provider /// [EvmEnv::into_input]: crate::EvmEnv::into_input /// [EvmEnv]: crate::EvmEnv - pub fn preflight(address: Address, env: &'a mut HostEvmEnv) -> Self { + pub fn preflight(address: Address, env: &'a mut HostEvmEnv) -> Self { Self { address, env } } /// Initializes a call builder to execute a call on the contract. - pub fn call_builder(&mut self, call: &C) -> CallBuilder> { + pub fn call_builder(&mut self, call: &C) -> CallBuilder> { CallBuilder::new(self.env, self.address, call) } } @@ -173,24 +175,40 @@ impl CallBuilder { } #[cfg(feature = "host")] -impl<'a, C, P, H> CallBuilder> +impl<'a, C, D, H> CallBuilder> where - C: SolCall, - P: Provider, - H: EvmBlockHeader, + C: SolCall + Send + 'static, + ::Return: Send, + D: Database + Send + 'static, + ::Error: Debug, + H: EvmBlockHeader + Clone + Send + 'static, { /// Executes the call with a [EvmEnv] constructed with [Contract::preflight]. /// /// [EvmEnv]: crate::EvmEnv - pub fn call(self) -> anyhow::Result { + pub async fn call(self) -> anyhow::Result { log::info!( "Executing preflight for '{}' on contract {}", C::SIGNATURE, self.tx.to ); - let evm = new_evm(&mut self.env.db, self.env.cfg_env.clone(), &self.env.header); - self.tx.transact(evm).map_err(|err| anyhow::anyhow!(err)) + let cfg = self.env.cfg_env.clone(); + let header = self.env.header.inner().clone(); + let db = self.env.db.take().unwrap(); + + let (res, db) = tokio::task::spawn_blocking(move || { + let mut evm = new_evm(db, cfg, header); + let res = self.tx.transact(&mut evm); + let (db, _) = evm.into_db_and_env_with_handler_cfg(); + + (res, db) + }) + .await?; + + self.env.db = Some(db); + + res.map_err(|err| anyhow::anyhow!(err)) } } @@ -203,12 +221,13 @@ where /// /// [EvmEnv]: crate::EvmEnv pub fn call(self) -> C::Return { - let evm = new_evm( - WrapStateDb::new(&self.env.db), + let state_db = self.env.db.as_ref().unwrap(); + let mut evm = new_evm::<_, H>( + WrapStateDb::new(state_db), self.env.cfg_env.clone(), - &self.env.header, + self.env.header.inner(), ); - self.tx.transact(evm).unwrap() + self.tx.transact(&mut evm).unwrap() } } @@ -232,7 +251,7 @@ impl CallTxData { ); /// Executes the call in the provided [Evm]. - fn transact(self, mut evm: Evm<'_, (), DB>) -> Result + fn transact(self, evm: &mut Evm<'_, EXT, DB>) -> Result where DB: Database, ::Error: Debug, @@ -251,17 +270,18 @@ impl CallTxData { let ResultAndState { result, .. } = evm .transact_preverified() .map_err(|err| format!("Call '{}' failed: {:?}", C::SIGNATURE, err))?; - let ExecutionResult::Success { reason, output, .. } = result else { - return Err(format!("Call '{}' failed", C::SIGNATURE)); - }; - // there must be a return value to decode - if reason != SuccessReason::Return { - return Err(format!( - "Call '{}' did not return: {:?}", - C::SIGNATURE, - reason - )); - } + let output = match result { + ExecutionResult::Success { reason, output, .. } => { + // there must be a return value to decode + if reason != SuccessReason::Return { + Err(format!("Did not return: {:?}", reason)) + } else { + Ok(output) + } + } + ExecutionResult::Revert { output, .. } => Err(format!("Reverted: {}", output)), + ExecutionResult::Halt { reason, .. } => Err(format!("Halted: {:?}", reason)), + }?; let returns = C::abi_decode_returns(&output.into_data(), true).map_err(|err| { format!( "Call '{}' returned invalid type; expected '{}': {:?}", @@ -275,15 +295,15 @@ impl CallTxData { } } -fn new_evm<'a, DB, H>(db: DB, cfg: CfgEnvWithHandlerCfg, header: &Sealed) -> Evm<'a, (), DB> +fn new_evm<'a, D, H>(db: D, cfg: CfgEnvWithHandlerCfg, header: impl Borrow) -> Evm<'a, (), D> where - DB: Database, + D: Database, H: EvmBlockHeader, { Evm::builder() .with_db(db) .with_cfg_env_with_handler_cfg(cfg) - .modify_block_env(|blk_env| header.fill_block_env(blk_env)) + .modify_block_env(|blk_env| header.borrow().fill_block_env(blk_env)) .build() } diff --git a/steel/src/ethereum.rs b/steel/src/ethereum.rs index 41edee15..231c3305 100644 --- a/steel/src/ethereum.rs +++ b/steel/src/ethereum.rs @@ -16,12 +16,8 @@ use crate::EvmEnv; use super::{EvmBlockHeader, EvmInput}; -use alloy_primitives::{ - keccak256, Address, BlockHash, BlockNumber, Bloom, Bytes, Sealable, B256, B64, U256, -}; -use alloy_rlp_derive::RlpEncodable; +use alloy_primitives::{BlockNumber, B256, U256}; use revm::primitives::BlockEnv; -use serde::{Deserialize, Serialize}; /// [EvmEnv] for Ethereum. pub type EthEvmEnv = EvmEnv; @@ -29,58 +25,8 @@ pub type EthEvmEnv = EvmEnv; /// [EvmInput] for Ethereum. pub type EthEvmInput = EvmInput; -/// Ethereum post-merge block header. -#[derive(Debug, Clone, Serialize, Deserialize, RlpEncodable)] -#[rlp(trailing)] -pub struct EthBlockHeader { - /// Hash of the parent block's header. - pub parent_hash: BlockHash, - /// Unused 256-bit hash; always the hash of the empty list. - pub ommers_hash: B256, - /// Address that receives the priority fees of each transaction in the block. - pub beneficiary: Address, - /// Root hash of the state trie after all transactions in the block are executed. - pub state_root: B256, - /// Root hash of the trie containing all transactions in the block. - pub transactions_root: B256, - /// Root hash of the trie containing the receipts of each transaction in the block. - pub receipts_root: B256, - /// Bloom filter for log entries in the block. - pub logs_bloom: Bloom, - /// Always set to `0` as it's unused. - pub difficulty: U256, - /// The block number in the chain. - pub number: BlockNumber, - /// Maximum amount of gas consumed by the transactions within the block. - pub gas_limit: u64, - /// Total amount of gas used by all transactions in this block. - pub gas_used: u64, - /// Value corresponding to the seconds since Epoch at this block's inception. - pub timestamp: u64, - /// Arbitrary byte array containing extra data related to the block. - pub extra_data: Bytes, - /// Hash previously used for the PoW now containing the RANDAO value. - pub mix_hash: B256, - /// Unused 64-bit hash, always zero. - pub nonce: B64, - /// Base fee paid by all transactions in the block. - pub base_fee_per_gas: U256, - /// Root hash of the trie containing all withdrawals in the block. - pub withdrawals_root: Option, - /// Total amount of blob gas consumed by the transactions within the block. - pub blob_gas_used: Option, - /// Running total of blob gas consumed in excess of the target, prior to the block. - pub excess_blob_gas: Option, - /// Hash tree root of the parent beacon block for the given execution block. - pub parent_beacon_block_root: Option, -} - -impl Sealable for EthBlockHeader { - #[inline] - fn hash_slow(&self) -> B256 { - keccak256(alloy_rlp::encode(self)) - } -} +/// [EvmBlockHeader] for Ethereum. +pub type EthBlockHeader = alloy_consensus::Header; impl EvmBlockHeader for EthBlockHeader { #[inline] @@ -105,9 +51,13 @@ impl EvmBlockHeader for EthBlockHeader { blk_env.number = U256::from(self.number); blk_env.coinbase = self.beneficiary; blk_env.timestamp = U256::from(self.timestamp); + blk_env.gas_limit = U256::from(self.gas_limit); + blk_env.basefee = U256::from(self.base_fee_per_gas.unwrap_or_default()); blk_env.difficulty = self.difficulty; + // technically, this is only valid after EIP-4399 but revm makes sure it is not used before blk_env.prevrandao = Some(self.mix_hash); - blk_env.basefee = self.base_fee_per_gas; - blk_env.gas_limit = U256::from(self.gas_limit); + if let Some(excess_blob_gas) = self.excess_blob_gas { + blk_env.set_blob_excess_gas_and_price(excess_blob_gas.try_into().unwrap()) + }; } } diff --git a/steel/src/host/db.rs b/steel/src/host/db.rs deleted file mode 100644 index 960169a5..00000000 --- a/steel/src/host/db.rs +++ /dev/null @@ -1,187 +0,0 @@ -// 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 super::provider::Provider; -use alloy_primitives::{Address, Bytes, Sealable, B256, U256}; -use revm::{ - primitives::{AccountInfo, Bytecode, HashMap, HashSet, KECCAK_EMPTY}, - Database, -}; -use std::fmt::Debug; -use thiserror::Error; - -/// Error type for the [ProviderDb]. -#[derive(Error, Debug)] -pub enum ProviderDbError { - #[error("provider error")] - Provider(#[from] E), - #[error("invalid block number: {0}")] - InvalidBlockNumber(U256), - #[error("hash missing for block: {0}")] - BlockHashMissing(U256), -} - -/// A revm [Database] backed by a [Provider]. -pub struct ProviderDb

{ - provider: P, - block_number: u64, - - /// Cache for code hashes to contract addresses. - code_hashes: HashMap, -} - -impl ProviderDb

{ - /// Creates a new [ProviderDb] with the given provider and block number. - pub fn new(provider: P, block_number: u64) -> Self { - Self { - provider, - block_number, - code_hashes: HashMap::new(), - } - } -} - -impl Database for ProviderDb

{ - type Error = ProviderDbError; - - fn basic(&mut self, address: Address) -> Result, Self::Error> { - // use `eth_getProof` to get all the account info with a single call - let proof = self - .provider - .get_proof(address, vec![], self.block_number)?; - // for non-existent accounts, the code hash is zero - // see https://github.com/ethereum/go-ethereum/issues/28441 - if proof.code_hash == B256::ZERO { - return Ok(None); - } - // cache the code hash to address mapping, so we can later retrieve the code - self.code_hashes - .insert(proof.code_hash.0.into(), proof.address); - - Ok(Some(AccountInfo { - nonce: proof.nonce, - balance: proof.balance, - code_hash: proof.code_hash, - code: None, - })) - } - - fn code_by_hash(&mut self, code_hash: B256) -> Result { - // avoid querying the RPC if the code hash is empty - if code_hash == KECCAK_EMPTY { - return Ok(Bytecode::new()); - } - - // this works because we always call `basic_ref` first - let contract_address = *self - .code_hashes - .get(&code_hash) - .expect("`basic` must be called first for the corresponding account"); - let code = self - .provider - .get_code(contract_address, self.block_number) - .map_err(ProviderDbError::Provider)?; - - Ok(Bytecode::new_raw(code.0.into())) - } - - fn storage(&mut self, address: Address, index: U256) -> Result { - let storage = self - .provider - .get_storage_at(address, index.into(), self.block_number) - .map_err(ProviderDbError::Provider)?; - - Ok(storage) - } - - fn block_hash(&mut self, number: U256) -> Result { - let block_number: u64 = number - .try_into() - .map_err(|_| ProviderDbError::InvalidBlockNumber(number))?; - let header = self - .provider - .get_block_header(block_number)? - .ok_or(ProviderDbError::InvalidBlockNumber(number))?; - - Ok(header.hash_slow()) - } -} - -/// A revm [Database] backed by a [Provider] that caches all queries needed for a state proof. -pub struct ProofDb

{ - accounts: HashMap>, - contracts: HashMap, - block_hash_numbers: HashSet, - - db: ProviderDb

, -} - -impl ProofDb

{ - pub fn new(provider: P, block_number: u64) -> Self { - Self { - accounts: HashMap::new(), - contracts: HashMap::new(), - block_hash_numbers: HashSet::new(), - db: ProviderDb::new(provider, block_number), - } - } - - pub fn provider(&self) -> &P { - &self.db.provider - } - pub fn block_number(&self) -> u64 { - self.db.block_number - } - pub fn accounts(&self) -> &HashMap> { - &self.accounts - } - pub fn contracts(&self) -> &HashMap { - &self.contracts - } - pub fn block_hash_numbers(&self) -> &HashSet { - &self.block_hash_numbers - } -} - -impl Database for ProofDb

{ - type Error = as Database>::Error; - - fn basic(&mut self, address: Address) -> Result, Self::Error> { - let basic = self.db.basic(address)?; - self.accounts.entry(address).or_default(); - - Ok(basic) - } - - fn code_by_hash(&mut self, code_hash: B256) -> Result { - let code = self.db.code_by_hash(code_hash)?; - self.contracts.insert(code_hash, code.original_bytes()); - - Ok(code) - } - - fn storage(&mut self, address: Address, index: U256) -> Result { - let storage = self.db.storage(address, index)?; - self.accounts.entry(address).or_default().insert(index); - - Ok(storage) - } - - fn block_hash(&mut self, number: U256) -> Result { - let block_hash = self.db.block_hash(number)?; - self.block_hash_numbers.insert(number); - - Ok(block_hash) - } -} diff --git a/steel/src/host/db/alloy.rs b/steel/src/host/db/alloy.rs new file mode 100644 index 00000000..1ae2595c --- /dev/null +++ b/steel/src/host/db/alloy.rs @@ -0,0 +1,164 @@ +// 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 std::{future::IntoFuture, marker::PhantomData}; + +use alloy::{ + network::Network, + providers::Provider, + transports::{Transport, TransportError}, +}; +use alloy_primitives::{Address, BlockNumber, B256, U256}; +use revm::{ + primitives::{AccountInfo, Bytecode, HashMap, KECCAK_EMPTY}, + Database, +}; +use tokio::runtime::{self, Handle, Runtime}; + +/// A revm [Database] 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 +/// must *not* be executed inside an async runtime, or it will panic when trying to block. If the +/// immediate context is only synchronous, but a transitive caller is async, use +/// [tokio::task::spawn_blocking] around the calls that need to be blocked. +pub struct AlloyDb> { + /// The provider to fetch the data from. + provider: P, + /// The block number on which the queries will be based on. + block_number: BlockNumber, + /// handle to the tokio runtime + runtime_handle: HandleOrRuntime, + /// Cache for code hashes to contract addresses. + code_hashes: HashMap, + + _marker: PhantomData (T, N)>, +} + +/// Holds a tokio runtime handle or full runtime +#[derive(Debug)] +enum HandleOrRuntime { + Handle(Handle), + Runtime(Runtime), +} + +impl> AlloyDb { + pub fn new(provider: P, block_number: BlockNumber) -> Self { + let runtime_handle = match Handle::try_current() { + Ok(handle) => HandleOrRuntime::Handle(handle), + Err(_) => { + let runtime = runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + HandleOrRuntime::Runtime(runtime) + } + }; + + Self { + provider, + block_number, + runtime_handle, + code_hashes: HashMap::new(), + _marker: PhantomData, + } + } + + pub(crate) fn provider(&self) -> &P { + &self.provider + } + pub(crate) fn block_number(&self) -> BlockNumber { + self.block_number + } + + /// internal utility function to call tokio feature and wait for output + #[inline] + fn block_on(&self, f: F) -> F::Output { + match &self.runtime_handle { + HandleOrRuntime::Handle(handle) => handle.block_on(f), + HandleOrRuntime::Runtime(rt) => rt.block_on(f), + } + } +} + +impl> Database for AlloyDb { + type Error = TransportError; + + fn basic(&mut self, address: Address) -> Result, Self::Error> { + // use `eth_getProof` to get all the account info with a single call + let proof = self.block_on( + self.provider + .get_proof(address, vec![]) + .number(self.block_number) + .into_future(), + )?; + // for non-existent accounts, the code hash is zero + // see https://github.com/ethereum/go-ethereum/issues/28441 + if proof.code_hash == B256::ZERO { + return Ok(None); + } + // cache the code hash to address mapping, so we can later retrieve the code + self.code_hashes + .insert(proof.code_hash.0.into(), proof.address); + + Ok(Some(AccountInfo { + nonce: proof.nonce, + balance: proof.balance, + code_hash: proof.code_hash, + code: None, + })) + } + + fn code_by_hash(&mut self, code_hash: B256) -> Result { + // avoid querying the RPC if the code hash is empty + if code_hash == KECCAK_EMPTY { + return Ok(Bytecode::new()); + } + + // this works because we always call `basic` first + let contract_address = *self + .code_hashes + .get(&code_hash) + .expect("`basic` must be called first for the corresponding account"); + let code = self.block_on( + self.provider + .get_code_at(contract_address) + .number(self.block_number) + .into_future(), + )?; + + Ok(Bytecode::new_raw(code.0.into())) + } + + fn storage(&mut self, address: Address, index: U256) -> Result { + let storage = self.block_on( + self.provider + .get_storage_at(address, index) + .number(self.block_number) + .into_future(), + )?; + + Ok(storage) + } + + fn block_hash(&mut self, number: U256) -> Result { + // SAFETY: We know number <= u64::MAX, so we can safely convert it to u64 + let block = self.block_on( + self.provider + .get_block_by_number(number.to::().into(), false), + )?; + let header = block.unwrap().header; + Ok(header.hash.unwrap()) + } +} diff --git a/steel/src/host/db/mod.rs b/steel/src/host/db/mod.rs new file mode 100644 index 00000000..509cf3e0 --- /dev/null +++ b/steel/src/host/db/mod.rs @@ -0,0 +1,23 @@ +// 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. + +//! [Database] implementations. +//! +//! [Database]: revm::Database + +mod alloy; +mod trace; + +pub use alloy::AlloyDb; +pub use trace::TraceDb; diff --git a/steel/src/host/db/trace.rs b/steel/src/host/db/trace.rs new file mode 100644 index 00000000..f3cb098e --- /dev/null +++ b/steel/src/host/db/trace.rs @@ -0,0 +1,91 @@ +// 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, Bytes, B256, U256}; +use revm::{ + primitives::{AccountInfo, Bytecode, HashMap, HashSet}, + Database, +}; + +/// A simple revm [Database] wrapper that records all DB queries. +pub struct TraceDb { + accounts: HashMap>, + contracts: HashMap, + block_hash_numbers: HashSet, + + inner: D, +} + +impl TraceDb { + pub fn new(db: D) -> Self { + Self { + accounts: HashMap::new(), + contracts: HashMap::new(), + block_hash_numbers: HashSet::new(), + inner: db, + } + } + + /// Returns all the queried account addresses with their queried storage keys. + pub fn accounts(&self) -> &HashMap> { + &self.accounts + } + /// Returns a map of the bytecode of the contracts queried by their code hash. + pub fn contracts(&self) -> &HashMap { + &self.contracts + } + /// Returns all the queried block numbers. + pub fn block_hash_numbers(&self) -> &HashSet { + &self.block_hash_numbers + } + + pub fn inner(&self) -> &D { + &self.inner + } + pub fn into_inner(self) -> D { + self.inner + } +} + +impl Database for TraceDb { + type Error = DB::Error; + + fn basic(&mut self, address: Address) -> Result, Self::Error> { + let basic = self.inner.basic(address)?; + self.accounts.entry(address).or_default(); + + Ok(basic) + } + + fn code_by_hash(&mut self, code_hash: B256) -> Result { + let code = self.inner.code_by_hash(code_hash)?; + self.contracts.insert(code_hash, code.original_bytes()); + + Ok(code) + } + + fn storage(&mut self, address: Address, index: U256) -> Result { + let storage = self.inner.storage(address, index)?; + self.accounts.entry(address).or_default().insert(index); + + Ok(storage) + } + + fn block_hash(&mut self, number: U256) -> Result { + let block_hash = self.inner.block_hash(number)?; + self.block_hash_numbers.insert(number); + + Ok(block_hash) + } +} diff --git a/steel/src/host/mod.rs b/steel/src/host/mod.rs index bf18e0b6..b20aeb98 100644 --- a/steel/src/host/mod.rs +++ b/steel/src/host/mod.rs @@ -14,75 +14,93 @@ //! Functionality that is only needed for the host and not the guest. -use self::{ - db::ProofDb, - provider::{EthersProvider, Provider}, -}; +use std::fmt::Debug; + use crate::{ethereum::EthEvmEnv, EvmBlockHeader, EvmEnv, EvmInput, MerkleTrie}; -use alloy_primitives::{Sealable, B256}; -use anyhow::{ensure, Context}; -use ethers_providers::{Http, RetryClient}; +use alloy::{ + network::{Ethereum, Network}, + providers::{Provider, ProviderBuilder, RootProvider}, + rpc::types::Header as RpcHeader, + transports::{ + http::{Client, Http}, + Transport, + }, +}; +use alloy_primitives::{Sealable, StorageKey}; +use anyhow::{anyhow, ensure, Context}; +use db::{AlloyDb, TraceDb}; use log::debug; use revm::primitives::HashMap; +use url::Url; pub mod db; -pub mod provider; -/// Alias for readability, do not make public. -pub(crate) type HostEvmEnv = EvmEnv, H>; +/// A block number (or tag - "latest", "earliest", "pending"). +pub type BlockNumberOrTag = alloy::rpc::types::BlockNumberOrTag; -/// The Ethers client type. -pub type EthersClient = ethers_providers::Provider>; +/// Alias for readability, do not make public. +pub(crate) type HostEvmEnv = EvmEnv, H>; -impl EthEvmEnv>> { +impl EthEvmEnv, Ethereum, RootProvider>>>> { /// Creates a new provable [EvmEnv] for Ethereum from an RPC endpoint. - pub fn from_rpc(url: &str, block_number: Option) -> anyhow::Result { - let client = EthersClient::new_client(url, 3, 500)?; - let provider = EthersProvider::new(client); - - // get the latest block number if none is provided - let block_number = match block_number { - Some(n) => n, - None => provider.get_block_number()?, - }; - - EvmEnv::from_provider(provider, block_number) + pub async fn from_rpc(url: Url, number: BlockNumberOrTag) -> anyhow::Result { + let provider = ProviderBuilder::new().on_http(url); + EvmEnv::from_provider(provider, number).await } } -impl EvmEnv, P::Header> { - /// Creates a new provable [EvmEnv] from a [Provider]. - pub fn from_provider(provider: P, block_number: u64) -> anyhow::Result { - let header = provider - .get_block_header(block_number)? - .with_context(|| format!("block {block_number} not found"))?; - - // create a new database backed by the provider - let db = ProofDb::new(provider, block_number); +impl EvmEnv>, ::Header> +where + T: Transport + Clone, + N: Network, + P: Provider, + ::Header: EvmBlockHeader + TryFrom, + <::Header as TryFrom>::Error: Debug, +{ + /// Creates a new provable [EvmEnv] from an alloy [Provider]. + pub async fn from_provider(provider: P, number: BlockNumberOrTag) -> anyhow::Result { + let rpc_block = provider + .get_block_by_number(number, false) + .await? + .with_context(|| format!("block {number} not found"))?; + let header: ::Header = try_into_header(rpc_block.header)?; + log::info!("Environment initialized for block {}", header.number()); + + let db = TraceDb::new(AlloyDb::new(provider, header.number())); Ok(EvmEnv::new(db, header.seal_slow())) } } -impl EvmEnv, P::Header> { +impl EvmEnv>, ::Header> +where + T: Transport + Clone, + N: Network, + ::Header: EvmBlockHeader + TryFrom, + <::Header as TryFrom>::Error: Debug, + P: Provider, +{ /// Converts the environment into a [EvmInput]. /// /// The resulting input contains inclusion proofs for all the required chain state data. It can /// therefore be used to execute the same calls in a verifiable way in the zkVM. - pub fn into_input(self) -> anyhow::Result> { - let db = &self.db; + pub async fn into_input(self) -> anyhow::Result::Header>> { + let db = &self.db.unwrap(); // use the same provider as the database - let provider = db.provider(); + let provider = db.inner().provider(); + let block_number = db.inner().block_number(); // retrieve EIP-1186 proofs for all accounts let mut proofs = Vec::new(); for (address, storage_keys) in db.accounts() { - let proof = provider.get_proof( - *address, - storage_keys.iter().map(|v| B256::from(*v)).collect(), - db.block_number(), - )?; + let proof = provider + .get_proof( + *address, + storage_keys.iter().map(|v| StorageKey::from(*v)).collect(), + ) + .number(block_number) + .await?; proofs.push(proof); } @@ -117,10 +135,12 @@ impl EvmEnv, P::Header> { let mut ancestors = Vec::new(); if let Some(block_hash_min_number) = db.block_hash_numbers().iter().min() { let block_hash_min_number: u64 = block_hash_min_number.to(); - for number in (block_hash_min_number..db.block_number()).rev() { - let header = provider - .get_block_header(number)? + for number in (block_hash_min_number..block_number).rev() { + let rpc_block = provider + .get_block_by_number(number.into(), false) + .await? .with_context(|| format!("block {number} not found"))?; + let header: ::Header = try_into_header(rpc_block.header)?; ancestors.push(header); } } @@ -144,3 +164,14 @@ impl EvmEnv, P::Header> { }) } } + +fn try_into_header>( + rpc_header: RpcHeader, +) -> anyhow::Result +where + >::Error: Debug, +{ + rpc_header + .try_into() + .map_err(|err| anyhow!("invalid header {err:?}")) +} diff --git a/steel/src/host/provider/ethers.rs b/steel/src/host/provider/ethers.rs deleted file mode 100644 index 52811995..00000000 --- a/steel/src/host/provider/ethers.rs +++ /dev/null @@ -1,234 +0,0 @@ -// 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 super::{EIP1186Proof, Provider, StorageProof}; -use crate::ethereum::EthBlockHeader; -use ethers_core::types::{Block, Bytes, H160, H256, U256}; -use ethers_providers::{Middleware, MiddlewareError}; -use thiserror::Error; -use tokio::runtime::{Handle, Runtime}; - -/// An error that can occur when interacting with the provider. -#[derive(Error, Debug)] -pub enum EthersProviderError { - #[error("middleware error")] - MiddlewareError(#[from] M), - #[error("block conversion error: {0}")] - BlockConversionError(String), -} - -/// A provider that fetches data from an Ethereum node using the ethers crate. -pub struct EthersProvider { - client: M, - runtime_handle: (Handle, Option), -} - -impl EthersProvider { - pub fn new(client: M) -> Self { - // if we are not in a tokio runtime, we need to create a new handle - let runtime_handle = match Handle::try_current() { - Ok(handle) => (handle, None), - Err(_) => { - let runtime = Runtime::new().unwrap(); - (runtime.handle().clone(), Some(runtime)) - } - }; - - Self { - client, - runtime_handle, - } - } - - /// Fetches the current block number. - pub fn get_block_number(&self) -> Result { - Ok(self.block_on(self.client.get_block_number())?.as_u64()) - } - - /// internal utility function to call tokio feature and wait for output - fn block_on(&self, f: F) -> F::Output { - self.runtime_handle.0.block_on(f) - } -} - -impl Provider for EthersProvider -where - M::Error: 'static, -{ - type Error = EthersProviderError; - type Header = EthBlockHeader; - - fn get_block_header( - &self, - block: alloy_primitives::BlockNumber, - ) -> Result, Self::Error> { - let block = self.block_on(self.client.get_block(block))?; - match block { - Some(block) => Ok(Some( - block - .try_into() - .map_err(EthersProviderError::BlockConversionError)?, - )), - None => Ok(None), - } - } - - fn get_transaction_count( - &self, - address: alloy_primitives::Address, - block: alloy_primitives::BlockNumber, - ) -> Result { - let address = to_ethers_h160(address); - let count = self - .block_on( - self.client - .get_transaction_count(address, Some(block.into())), - ) - .map(from_ethers_u256)?; - Ok(count.to()) - } - - fn get_balance( - &self, - address: alloy_primitives::Address, - block: alloy_primitives::BlockNumber, - ) -> Result { - let address = to_ethers_h160(address); - Ok(from_ethers_u256(self.block_on( - self.client.get_balance(address, Some(block.into())), - )?)) - } - - fn get_code( - &self, - address: alloy_primitives::Address, - block: alloy_primitives::BlockNumber, - ) -> Result { - let address = to_ethers_h160(address); - Ok(from_ethers_bytes(self.block_on( - self.client.get_code(address, Some(block.into())), - )?)) - } - - fn get_storage_at( - &self, - address: alloy_primitives::Address, - key: alloy_primitives::StorageKey, - block: alloy_primitives::BlockNumber, - ) -> Result { - let address = to_ethers_h160(address); - let key = to_ethers_h256(key); - let value = self.block_on(self.client.get_storage_at(address, key, Some(block.into())))?; - - Ok(from_ethers_h256(value).into()) - } - - fn get_proof( - &self, - address: alloy_primitives::Address, - storage_keys: Vec, - block: alloy_primitives::BlockNumber, - ) -> Result { - let address = to_ethers_h160(address); - let storage_keys = storage_keys.into_iter().map(to_ethers_h256).collect(); - let proof = self.block_on(self.client.get_proof( - address, - storage_keys, - Some(block.into()), - ))?; - - Ok(EIP1186Proof { - address: address.0.into(), - balance: from_ethers_u256(proof.balance), - code_hash: from_ethers_h256(proof.code_hash), - nonce: proof.nonce.as_u64(), - storage_hash: from_ethers_h256(proof.storage_hash), - account_proof: proof - .account_proof - .into_iter() - .map(from_ethers_bytes) - .collect(), - storage_proof: proof - .storage_proof - .into_iter() - .map(|p| StorageProof { - key: from_ethers_u256(p.key).to_be_bytes().into(), - proof: p.proof.into_iter().map(from_ethers_bytes).collect(), - value: from_ethers_u256(p.value), - }) - .collect(), - }) - } -} - -impl TryFrom> for EthBlockHeader { - type Error = String; - - fn try_from(block: Block) -> Result { - Ok(EthBlockHeader { - parent_hash: from_ethers_h256(block.parent_hash), - ommers_hash: from_ethers_h256(block.uncles_hash), - beneficiary: block.author.ok_or("author missing")?.0.into(), - state_root: from_ethers_h256(block.state_root), - transactions_root: from_ethers_h256(block.transactions_root), - receipts_root: from_ethers_h256(block.receipts_root), - logs_bloom: alloy_primitives::Bloom::from_slice( - block.logs_bloom.ok_or("bloom missing")?.as_bytes(), - ), - difficulty: from_ethers_u256(block.difficulty), - number: block.number.ok_or("number is missing")?.as_u64(), - gas_limit: block - .gas_limit - .try_into() - .map_err(|_| "invalid gas limit")?, - gas_used: block.gas_used.try_into().map_err(|_| "invalid gas used")?, - timestamp: block - .timestamp - .try_into() - .map_err(|_| "invalid timestamp")?, - extra_data: block.extra_data.0.into(), - mix_hash: from_ethers_h256(block.mix_hash.ok_or("mix_hash is missing")?), - nonce: block.nonce.ok_or("nonce is missing")?.0.into(), - base_fee_per_gas: from_ethers_u256( - block - .base_fee_per_gas - .ok_or("base_fee_per_gas is missing")?, - ), - withdrawals_root: block.withdrawals_root.map(from_ethers_h256), - blob_gas_used: block.blob_gas_used.map(|x| x.try_into().unwrap()), - excess_blob_gas: block.excess_blob_gas.map(|x| x.try_into().unwrap()), - parent_beacon_block_root: block.parent_beacon_block_root.map(from_ethers_h256), - }) - } -} - -fn from_ethers_bytes(v: Bytes) -> alloy_primitives::Bytes { - v.0.into() -} - -fn to_ethers_h256(v: alloy_primitives::B256) -> H256 { - v.0.into() -} - -fn from_ethers_h256(v: H256) -> alloy_primitives::B256 { - v.0.into() -} - -fn from_ethers_u256(v: U256) -> alloy_primitives::U256 { - alloy_primitives::U256::from_limbs(v.0) -} - -fn to_ethers_h160(v: alloy_primitives::Address) -> H160 { - v.into_array().into() -} diff --git a/steel/src/host/provider/file.rs b/steel/src/host/provider/file.rs deleted file mode 100644 index 4868a558..00000000 --- a/steel/src/host/provider/file.rs +++ /dev/null @@ -1,311 +0,0 @@ -// 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 super::{EIP1186Proof, NullProvider, Provider}; -use crate::{ethereum::EthBlockHeader, EvmBlockHeader}; -use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, StorageValue, TxNumber, U256}; -use anyhow::Context; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::{ - cell::RefCell, - collections::{hash_map::Entry, BTreeSet, HashMap}, - fs::{self, File}, - io::{BufReader, BufWriter}, - marker::PhantomData, - path::PathBuf, -}; - -/// A provider that caches responses from an underlying provider in a JSON file. -/// Queries are first checked against the cache, and if not found, the provider is invoked. -/// The cache is saved when the provider is dropped. -pub struct CachedProvider -where - P::Header: Clone + Serialize + DeserializeOwned, -{ - inner: P, - cache: RefCell>, -} - -impl CachedProvider

-where - P::Header: Clone + Serialize + DeserializeOwned, -{ - /// Creates a new [CachedProvider]. If the cache file exists, it will be read and deserialized. - /// Otherwise, a new file will be created when dropped. - pub fn new(cache_path: PathBuf, provider: P) -> anyhow::Result { - let cache = match JsonCache::from_file(cache_path.clone()) { - Ok(cache) => cache, - Err(err) => match err.downcast_ref::() { - Some(io_err) if io_err.kind() == std::io::ErrorKind::NotFound => { - // create the file and directory if it doesn't exist - if let Some(parent) = cache_path.parent() { - fs::create_dir_all(parent).context("failed to create directory")?; - } - JsonCache::empty(cache_path) - } - _ => return Err(err), - }, - }; - - Ok(Self { - inner: provider, - cache: RefCell::new(cache), - }) - } -} - -/// [FileProvider] for Ethereum. -pub type EthFileProvider = FileProvider; - -/// A provider returning responses cached in a file. -/// It panics if queries are not found in the cache. -pub type FileProvider = CachedProvider>; - -impl FileProvider -where - H: EvmBlockHeader + Clone + Serialize + DeserializeOwned, -{ - /// Creates a new [FileProvider] loading the given file. - pub fn from_file(file_path: &PathBuf) -> anyhow::Result { - let cache = JsonCache::load(file_path)?; - Ok(Self { - inner: NullProvider(PhantomData), - cache: RefCell::new(cache), - }) - } -} - -impl Provider for CachedProvider

-where - P::Header: Clone + Serialize + DeserializeOwned, -{ - type Error = P::Error; - type Header = P::Header; - - fn get_block_header(&self, block: BlockNumber) -> Result, Self::Error> { - match self - .cache - .borrow_mut() - .partial_blocks - .entry(BlockQuery { block_no: block }) - { - Entry::Occupied(entry) => Ok(entry.get().clone()), - Entry::Vacant(entry) => Ok(entry.insert(self.inner.get_block_header(block)?).clone()), - } - } - - fn get_transaction_count( - &self, - address: Address, - block: BlockNumber, - ) -> Result { - match self - .cache - .borrow_mut() - .transaction_count - .entry(AccountQuery { - block_no: block, - address, - }) { - Entry::Occupied(entry) => Ok(*entry.get()), - Entry::Vacant(entry) => { - let count = self.inner.get_transaction_count(address, block)?; - Ok(*entry.insert(count)) - } - } - } - - fn get_balance(&self, address: Address, block: BlockNumber) -> Result { - match self.cache.borrow_mut().balance.entry(AccountQuery { - block_no: block, - address, - }) { - Entry::Occupied(entry) => Ok(*entry.get()), - Entry::Vacant(entry) => { - let balance = self.inner.get_balance(address, block)?; - Ok(*entry.insert(balance)) - } - } - } - - fn get_code(&self, address: Address, block: BlockNumber) -> Result { - match self.cache.borrow_mut().code.entry(AccountQuery { - block_no: block, - address, - }) { - Entry::Occupied(entry) => Ok(entry.get().clone()), - Entry::Vacant(entry) => { - let code = self.inner.get_code(address, block)?; - Ok(entry.insert(code).clone()) - } - } - } - - fn get_storage_at( - &self, - address: Address, - key: StorageKey, - block: BlockNumber, - ) -> Result { - match self.cache.borrow_mut().storage.entry(StorageQuery { - block_no: block, - address, - key, - }) { - Entry::Occupied(entry) => Ok(*entry.get()), - Entry::Vacant(entry) => { - let storage = self.inner.get_storage_at(address, key, block)?; - Ok(*entry.insert(storage)) - } - } - } - - fn get_proof( - &self, - address: Address, - storage_keys: Vec, - block: BlockNumber, - ) -> Result { - match self.cache.borrow_mut().proofs.entry(ProofQuery { - block_no: block, - address, - storage_keys: storage_keys.iter().cloned().collect(), - }) { - Entry::Occupied(entry) => Ok(entry.get().clone()), - Entry::Vacant(entry) => { - let proof = self.inner.get_proof(address, storage_keys, block)?; - Ok(entry.insert(proof).clone()) - } - } - } -} - -/// A simple JSON cache for storing responses from a provider. -#[derive(Debug, Deserialize, Serialize)] -struct JsonCache { - #[serde(skip)] - file_path: Option, - - #[serde(with = "ordered_map")] - partial_blocks: HashMap>, - #[serde(with = "ordered_map")] - proofs: HashMap, - #[serde(with = "ordered_map")] - transaction_count: HashMap, - #[serde(with = "ordered_map")] - balance: HashMap, - #[serde(with = "ordered_map")] - code: HashMap, - #[serde(with = "ordered_map")] - storage: HashMap, -} - -impl JsonCache { - /// Creates a new empty cache. It will be saved to the given file when dropped. - fn empty(file_path: PathBuf) -> Self { - Self { - file_path: Some(file_path), - partial_blocks: HashMap::new(), - proofs: HashMap::new(), - transaction_count: HashMap::new(), - balance: HashMap::new(), - code: HashMap::new(), - storage: HashMap::new(), - } - } - - /// Creates a new cache backed by the given file. It updates the file when dropped. - fn from_file(file_path: PathBuf) -> anyhow::Result { - Self::load(&file_path).map(|mut cache| { - cache.file_path = Some(file_path); - cache - }) - } - - /// Loads a cache from a file. Nothing is saved when the cache is dropped. - fn load(file_path: &PathBuf) -> anyhow::Result { - let file = File::open(file_path).context("failed to open cache file")?; - let reader = BufReader::new(file); - serde_json::from_reader(reader).context("failed to deserialize cache") - } - - /// Saves the cache to the file. - fn save(&self) -> anyhow::Result<()> { - if let Some(file_path) = &self.file_path { - let file = File::create(file_path).context("failed to create cache file")?; - let writer = BufWriter::new(file); - serde_json::to_writer_pretty(writer, self).context("failed to serialize cache")?; - } - Ok(()) - } -} - -impl Drop for JsonCache { - fn drop(&mut self) { - self.save().expect("failed to save cache"); - } -} - -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] -struct AccountQuery { - block_no: BlockNumber, - address: Address, -} - -#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Deserialize, Serialize)] -struct BlockQuery { - block_no: BlockNumber, -} - -#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Deserialize, Serialize)] -struct ProofQuery { - block_no: BlockNumber, - address: Address, - storage_keys: BTreeSet, -} - -#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Deserialize, Serialize)] -struct StorageQuery { - block_no: BlockNumber, - address: Address, - key: StorageKey, -} - -/// A serde helper to serialize a HashMap into a vector sorted by key -mod ordered_map { - use std::{collections::HashMap, hash::Hash}; - - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - - pub fn serialize(map: &HashMap, serializer: S) -> Result - where - S: Serializer, - K: Ord + Serialize, - V: Serialize, - { - let mut vec: Vec<(_, _)> = map.iter().collect(); - vec.sort_unstable_by_key(|&(k, _)| k); - vec.serialize(serializer) - } - - pub fn deserialize<'de, D, K, V>(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - K: Eq + Hash + Deserialize<'de>, - V: Deserialize<'de>, - { - let vec = Vec::<(_, _)>::deserialize(deserializer)?; - Ok(vec.into_iter().collect()) - } -} diff --git a/steel/src/host/provider/mod.rs b/steel/src/host/provider/mod.rs deleted file mode 100644 index 2e07459a..00000000 --- a/steel/src/host/provider/mod.rs +++ /dev/null @@ -1,110 +0,0 @@ -// 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 crate::EvmBlockHeader; -use alloy_primitives::{ - Address, BlockNumber, Bytes, StorageKey, StorageValue, TxNumber, B256, U256, -}; -use serde::{Deserialize, Serialize}; -use std::{convert::Infallible, error::Error as StdError, fmt::Debug, marker::PhantomData}; - -mod ethers; -mod file; - -pub use ethers::EthersProvider; -pub use file::{CachedProvider, EthFileProvider, FileProvider}; - -/// A trait for providers that fetch data from the Ethereum blockchain. -pub trait Provider { - type Error: StdError + Send + Sync + 'static; - type Header: EvmBlockHeader; - - fn get_block_header(&self, block: BlockNumber) -> Result, Self::Error>; - fn get_transaction_count( - &self, - address: Address, - block: BlockNumber, - ) -> Result; - fn get_balance(&self, address: Address, block: BlockNumber) -> Result; - fn get_code(&self, address: Address, block: BlockNumber) -> Result; - fn get_storage_at( - &self, - address: Address, - key: StorageKey, - block: BlockNumber, - ) -> Result; - fn get_proof( - &self, - address: Address, - storage_keys: Vec, - block: BlockNumber, - ) -> Result; -} - -/// Data structure with proof for one single storage-entry -#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)] -pub struct StorageProof { - pub key: StorageKey, - pub proof: Vec, - pub value: StorageValue, -} - -/// Response for EIP-1186 account proof `eth_getProof` -#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)] -pub struct EIP1186Proof { - pub address: Address, - pub balance: U256, - pub code_hash: B256, - pub nonce: TxNumber, - pub storage_hash: B256, - pub account_proof: Vec, - pub storage_proof: Vec, -} - -/// A simple provider that panics on all queries. -pub struct NullProvider(PhantomData); - -impl Provider for NullProvider { - type Error = Infallible; - type Header = H; - - fn get_block_header(&self, _: BlockNumber) -> Result, Self::Error> { - panic!("Unexpected provider call") - } - fn get_transaction_count(&self, _: Address, _: BlockNumber) -> Result { - panic!("Unexpected provider call") - } - fn get_balance(&self, _: Address, _: BlockNumber) -> Result { - panic!("Unexpected provider call") - } - fn get_code(&self, _: Address, _: BlockNumber) -> Result { - panic!("Unexpected provider call") - } - fn get_storage_at( - &self, - _: Address, - _: StorageKey, - _: BlockNumber, - ) -> Result { - panic!("Unexpected provider call") - } - fn get_proof( - &self, - _: Address, - _: Vec, - _: BlockNumber, - ) -> Result { - panic!("Unexpected provider call") - } -} diff --git a/steel/src/lib.rs b/steel/src/lib.rs index 8d633d46..547ceed4 100644 --- a/steel/src/lib.rs +++ b/steel/src/lib.rs @@ -105,7 +105,7 @@ pub(crate) type GuestEvmEnv = EvmEnv; /// The environment to execute the contract calls in. pub struct EvmEnv { - db: D, + db: Option, cfg_env: CfgEnvWithHandlerCfg, header: Sealed, } @@ -117,7 +117,7 @@ impl EvmEnv { let cfg_env = CfgEnvWithHandlerCfg::new_with_spec_id(Default::default(), SpecId::LATEST); Self { - db, + db: Some(db), cfg_env, header, } diff --git a/steel/tests/eth_call.rs b/steel/tests/eth_call.rs index 99cde4cd..7c6d77d8 100644 --- a/steel/tests/eth_call.rs +++ b/steel/tests/eth_call.rs @@ -14,149 +14,47 @@ #![cfg(feature = "host")] +use alloy::{ + network::{Ethereum, EthereumWallet}, + providers::{ + ext::AnvilApi, + fillers::{FillProvider, JoinFill, RecommendedFiller, WalletFiller}, + layers::AnvilProvider, + ProviderBuilder, RootProvider, + }, + rpc::types::BlockNumberOrTag, + transports::http::{Client, Http}, +}; use alloy_primitives::{address, b256, uint, Address, U256}; -use alloy_sol_types::{sol, SolCall}; +use alloy_sol_types::SolCall; +use once_cell::sync::Lazy; +use revm::primitives::SpecId; use risc0_steel::{ - config::{ChainSpec, ETH_MAINNET_CHAIN_SPEC, ETH_SEPOLIA_CHAIN_SPEC}, + config::{ChainSpec, EIP1559_CONSTANTS_DEFAULT}, ethereum::EthEvmEnv, - host, CallBuilder, Contract, + CallBuilder, Contract, EvmBlockHeader, }; use std::fmt::Debug; use test_log::test; -macro_rules! provider { - () => { - test_provider!() - // use the following to fill the cache file - // test_provider!("") - }; -} - -const RPC_CACHE_FILE: &str = "testdata/rpc_cache.json"; - -// Create a file provider or a cached Ethers provider when an URL is specified. -macro_rules! test_provider { - () => { - host::provider::EthFileProvider::from_file(&RPC_CACHE_FILE.into()).unwrap() - }; - ($url:tt) => {{ - let client = host::EthersClient::new_client($url, 3, 500).unwrap(); - let provider = host::provider::EthersProvider::new(client); - host::provider::CachedProvider::new(RPC_CACHE_FILE.into(), provider).unwrap() - }}; -} - -const ERC20_TEST_CONTRACT: Address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); // USDT -const ERC20_TEST_BLOCK: u64 = 19493153; -sol! { +const STEEL_TEST_CONTRACT: Address = address!("5fbdb2315678afecb367f032d93f642f64180aa3"); +alloy::sol!( + #[sol(rpc, bytecode="60e060405234801561000f575f80fd5b505f60405161001d906100c4565b908152602001604051809103905ff08015801561003c573d5f803e3d5ffd5b506001600160a01b0316608052604051602a90610058906100c4565b908152602001604051809103905ff080158015610077573d5f803e3d5ffd5b506001600160a01b031660a052604051602a90610093906100c4565b908152602001604051809103905ff0801580156100b2573d5f803e3d5ffd5b506001600160a01b031660c0526100d0565b60c98061041e83390190565b60805160a05160c0516103256100f95f395f60de01525f61015e01525f6101de01526103255ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063445bda4311610058578063445bda43146100ba5780637d732b5f146100c25780639f6f32aa146100c8578063ab8fd80c146100d0575f80fd5b80630692d13c146100895780632e8bde391461009f57806330e49663146100ad57806341317185146100b3575b5f80fd5b5f3b5b6040519081526020015b60405180910390f35b604051328152602001610096565b3a61008c565b443b61008c565b61008c6100db565b4661008c565b61008c610275565b4360fe19014061008c565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610138573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061015c91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101dc91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610238573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025c91906102b3565b61026691906102ca565b61027091906102ca565b905090565b6040515f906002906020818481855afa158015610294573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061027091905b5f602082840312156102c3575f80fd5b5051919050565b808201808211156102e957634e487b7160e01b5f52601160045260245ffd5b9291505056fea264697066735822122017cd88097c7ec4827d02d5b993a5a0735d07aaa06059c5e6c23f0ee89f66264b64736f6c634300081900336080604052348015600e575f80fd5b5060405160c938038060c9833981016040819052602991602f565b5f556045565b5f60208284031215603e575f80fd5b5051919050565b60798060505f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3fea2646970667358221220fb757efaa1a5b5711adfcca5d02365b7e8408bfa6624b2b9bf549a8fa2f4f1fc64736f6c63430008190033")] #[derive(Debug, PartialEq, Eq)] - interface IERC20 { - function balanceOf(address account) external view returns (uint); - } -} - -#[test] -fn erc20_balance_of() { - let call = IERC20::balanceOfCall { - account: address!("F977814e90dA44bFA03b6295A0616a897441aceC"), // Binance 8 - }; - - let result = eth_call( - call, - ERC20_TEST_CONTRACT, - BuilderOverrides::default(), - ERC20_TEST_BLOCK, - Ð_MAINNET_CHAIN_SPEC, - ); - assert_eq!(result._0, uint!(3000000000000000_U256)); -} - -#[test] -fn erc20_multi_balance_of() { - let call1 = IERC20::balanceOfCall { - account: address!("F977814e90dA44bFA03b6295A0616a897441aceC"), - }; - let call2 = IERC20::balanceOfCall { - account: address!("5a52E96BAcdaBb82fd05763E25335261B270Efcb"), - }; - - let mut env = EthEvmEnv::from_provider(provider!(), ERC20_TEST_BLOCK) - .unwrap() - .with_chain_spec(Ð_MAINNET_CHAIN_SPEC); - let mut contract = Contract::preflight(ERC20_TEST_CONTRACT, &mut env); - contract.call_builder(&call1).call().unwrap(); - contract.call_builder(&call2).call().unwrap(); - let input = env.into_input().unwrap(); - - // execute the call - let env = input.into_env().with_chain_spec(Ð_MAINNET_CHAIN_SPEC); - let contract = Contract::new(ERC20_TEST_CONTRACT, &env); - let result1 = contract.call_builder(&call1).call(); - let result2 = contract.call_builder(&call2).call(); - assert_eq!(result1._0, uint!(3000000000000000_U256)); - assert_eq!(result2._0, uint!(0x38d7ea4c68000_U256)); -} - -#[test] -fn uniswap_exact_output_single() { - // mimic tx 0x241c81c3aa4c68cd07ae03a756050fc47fd91918a710250453d34c6db9d11997 - let block = 19493153; - let caller = address!("f5213a6a2f0890321712520b8048D9886c1A9900"); - let contract = address!("E592427A0AEce92De3Edee1F18E0157C05861564"); // Uniswap V3 - sol! { - #[derive(Debug, PartialEq, Eq)] - interface ISwapRouter { - struct ExactOutputSingleParams { - address tokenIn; - address tokenOut; - uint24 fee; - address recipient; - uint256 deadline; - uint256 amountOut; - uint256 amountInMaximum; - uint160 sqrtPriceLimitX96; - } - function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); + contract SteelTest { + Value internal immutable VALUE0; + Value internal immutable VALUE42A; + Value internal immutable VALUE42B; + + constructor() { + VALUE0 = new Value(0); + VALUE42A = new Value(42); + VALUE42B = new Value(42); } - } - - // swap USDT for 34.1973 WETH - let call = ISwapRouter::exactOutputSingleCall { - params: ISwapRouter::ExactOutputSingleParams { - tokenIn: address!("dAC17F958D2ee523a2206206994597C13D831ec7"), // USDT - tokenOut: address!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), // WETH - fee: 500, - recipient: caller, - deadline: uint!(1711146836_U256), - amountOut: uint!(34197300000000000000_U256), - amountInMaximum: U256::MAX, - sqrtPriceLimitX96: U256::ZERO, - }, - }; - - let result = eth_call( - call, - contract, - BuilderOverrides { - from: Some(caller), - ..Default::default() - }, - block, - Ð_MAINNET_CHAIN_SPEC, - ); - assert_eq!(result.amountIn, uint!(112537714517_U256)); -} -const VIEW_CALL_TEST_CONTRACT: Address = address!("C5096d96dbC7594B3d0Ba50e708ba654A7ae1F3E"); -const VIEW_CALL_TEST_BLOCK: u64 = 5702743; -sol!( - #[derive(Debug, PartialEq, Eq)] - contract ViewCallTest { /// Tests the SHA256 precompile. - function testPrecompile() external view returns (bytes32) { - (bool ok, bytes memory out) = address(0x02).staticcall(""); - require(ok); - return abi.decode(out, (bytes32)); + function testPrecompile() external pure returns (bytes32) { + return sha256(""); } /// Tests accessing the code of a nonexistent account. @@ -171,8 +69,8 @@ sol!( } /// Tests the blockhash opcode. - function testBlockhash() external view returns (bytes32) { - return blockhash(block.number - 2); + function testBlockhash() external view returns (bytes32 h) { + assembly { h := blockhash(sub(number(), 255)) } } /// Tests retrieving the chain ID. @@ -180,6 +78,11 @@ sol!( return block.chainid; } + /// Tests retrieving the address of the sender of the transaction. + function testOrigin() external view returns (address) { + return tx.origin; + } + /// Tests retrieving the gas price. function testGasprice() external view returns (uint256) { return tx.gasprice; @@ -187,126 +90,185 @@ sol!( /// Tests calling multiple contracts with the same and different storage. function testMuliContractCalls() external view returns (uint256) { - return VALUE0.value() + VALUE42_a.value() + VALUE42_b.value(); + return VALUE0.value() + VALUE42A.value() + VALUE42B.value(); } } ); -#[test] -fn precompile() { +static ANVIL_CHAIN_SPEC: Lazy = + Lazy::new(|| ChainSpec::new_single(31337, SpecId::CANCUN, EIP1559_CONSTANTS_DEFAULT)); + +type TestProvider = FillProvider< + JoinFill>, + AnvilProvider>, Http>, + Http, + Ethereum, +>; + +async fn test_provider() -> TestProvider { + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .on_anvil_with_wallet_and_config(|anvil| anvil.args(["--hardfork", "cancun"])); + let node_info = provider.anvil_node_info().await.unwrap(); + log::info!("Anvil started: {:?}", node_info); + let instance = SteelTest::deploy(&provider).await.unwrap(); + assert_eq!(*instance.address(), STEEL_TEST_CONTRACT); + provider + .anvil_mine(Some(U256::from(254)), None) + .await + .unwrap(); + + provider +} + +#[tokio::test] +async fn precompile() { let result = eth_call( - ViewCallTest::testPrecompileCall {}, - VIEW_CALL_TEST_CONTRACT, - BuilderOverrides::default(), - VIEW_CALL_TEST_BLOCK, - Ð_SEPOLIA_CHAIN_SPEC, - ); + test_provider().await, + SteelTest::testPrecompileCall {}, + STEEL_TEST_CONTRACT, + CallBuilderOverrides::empty(), + ) + .await; assert_eq!( result._0, b256!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") ); } -#[test] -fn nonexistent_account() { +#[tokio::test] +async fn nonexistent_account() { let result = eth_call( - ViewCallTest::testNonexistentAccountCall {}, - VIEW_CALL_TEST_CONTRACT, - BuilderOverrides::default(), - VIEW_CALL_TEST_BLOCK, - Ð_SEPOLIA_CHAIN_SPEC, - ); + test_provider().await, + SteelTest::testNonexistentAccountCall {}, + STEEL_TEST_CONTRACT, + CallBuilderOverrides::empty(), + ) + .await; assert_eq!(result.size, uint!(0_U256)); } -#[test] -fn eoa_account() { +#[tokio::test] +async fn eoa_account() { let result = eth_call( - ViewCallTest::testEoaAccountCall {}, - VIEW_CALL_TEST_CONTRACT, - BuilderOverrides::default(), - VIEW_CALL_TEST_BLOCK, - Ð_SEPOLIA_CHAIN_SPEC, - ); + test_provider().await, + SteelTest::testEoaAccountCall {}, + STEEL_TEST_CONTRACT, + CallBuilderOverrides::empty(), + ) + .await; assert_eq!(result.size, uint!(0_U256)); } -#[test] -fn blockhash() { +#[test(tokio::test)] +async fn blockhash() { + let provider = test_provider().await; + let block_hash = provider.anvil_node_info().await.unwrap().current_block_hash; + // mine more blocks to assure that the chain is long enough + provider + .anvil_mine(Some(U256::from(255)), None) + .await + .unwrap(); + let result = eth_call( - ViewCallTest::testBlockhashCall {}, - VIEW_CALL_TEST_CONTRACT, - BuilderOverrides::default(), - VIEW_CALL_TEST_BLOCK, - Ð_SEPOLIA_CHAIN_SPEC, - ); - assert_eq!( - result._0, - b256!("7703fe4a3d6031a579d52ce9e493e7907d376cfc3b41f9bc7710b0dae8c67f68") - ); + provider, + SteelTest::testBlockhashCall {}, + STEEL_TEST_CONTRACT, + CallBuilderOverrides::empty(), + ) + .await; + assert_eq!(result.h, block_hash); } -#[test] -fn chainid() { +#[tokio::test] +async fn chainid() { let result = eth_call( - ViewCallTest::testChainidCall {}, - VIEW_CALL_TEST_CONTRACT, - BuilderOverrides::default(), - VIEW_CALL_TEST_BLOCK, - Ð_SEPOLIA_CHAIN_SPEC, - ); - assert_eq!(result._0, uint!(11155111_U256)); + test_provider().await, + SteelTest::testChainidCall {}, + STEEL_TEST_CONTRACT, + CallBuilderOverrides::empty(), + ) + .await; + assert_eq!(result._0, uint!(31337_U256)); +} + +#[tokio::test] +async fn origin() { + let from = address!("0000000000000000000000000000000000000042"); + let result = eth_call( + test_provider().await, + SteelTest::testOriginCall {}, + STEEL_TEST_CONTRACT, + CallBuilderOverrides::from(from), + ) + .await; + assert_eq!(result._0, from); } -#[test] -fn gasprice() { +#[tokio::test] +async fn gasprice() { let gas_price = uint!(42_U256); let result = eth_call( - ViewCallTest::testGaspriceCall {}, - VIEW_CALL_TEST_CONTRACT, - BuilderOverrides { - gas_price: Some(gas_price), - ..Default::default() - }, - VIEW_CALL_TEST_BLOCK, - Ð_SEPOLIA_CHAIN_SPEC, - ); + test_provider().await, + SteelTest::testGaspriceCall {}, + STEEL_TEST_CONTRACT, + CallBuilderOverrides::gas_price(gas_price), + ) + .await; assert_eq!(result._0, gas_price); } -#[test] -fn multi_contract_calls() { +#[test(tokio::test)] +async fn multi_contract_calls() { let result = eth_call( - ViewCallTest::testMuliContractCallsCall {}, - VIEW_CALL_TEST_CONTRACT, - BuilderOverrides::default(), - VIEW_CALL_TEST_BLOCK, - Ð_SEPOLIA_CHAIN_SPEC, - ); + test_provider().await, + SteelTest::testMuliContractCallsCall {}, + STEEL_TEST_CONTRACT, + CallBuilderOverrides::empty(), + ) + .await; assert_eq!(result._0, uint!(84_U256)); } -#[test] -fn call_eoa() { - let mut env = EthEvmEnv::from_provider(provider!(), VIEW_CALL_TEST_BLOCK) +#[test(tokio::test)] +async fn call_eoa() { + let mut env = EthEvmEnv::from_provider(test_provider().await, BlockNumberOrTag::Latest) + .await .unwrap() - .with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); + .with_chain_spec(&ANVIL_CHAIN_SPEC); let mut contract = Contract::preflight(Address::ZERO, &mut env); contract - .call_builder(&ViewCallTest::testBlockhashCall {}) + .call_builder(&SteelTest::testBlockhashCall {}) .call() + .await .expect_err("calling an EOA should fail"); } /// Simple struct to operate over different [CallBuilder] types. #[derive(Debug, Default)] -struct BuilderOverrides { +struct CallBuilderOverrides { gas_price: Option, from: Option

, } -impl BuilderOverrides { - fn override_builder(&self, mut builder: CallBuilder) -> CallBuilder { +impl CallBuilderOverrides { + fn empty() -> Self { + CallBuilderOverrides::default() + } + fn from(from: Address) -> Self { + Self { + from: Some(from), + ..Default::default() + } + } + fn gas_price(gas_price: U256) -> Self { + Self { + gas_price: Some(gas_price), + ..Default::default() + } + } + + fn set(&self, mut builder: CallBuilder) -> CallBuilder { if let Some(gas_price) = self.gas_price { builder = builder.gas_price(gas_price); } @@ -317,34 +279,39 @@ impl BuilderOverrides { } } -fn eth_call( +async fn eth_call( + provider: TestProvider, call: C, address: Address, - call_overrides: BuilderOverrides, - block: u64, - chain_spec: &ChainSpec, + call_overrides: CallBuilderOverrides, ) -> C::Return where - C: SolCall, - ::Return: PartialEq + Debug, + C: SolCall + Send + 'static, + ::Return: PartialEq + Debug + Send, { - let mut env = EthEvmEnv::from_provider(provider!(), block) + let mut env = EthEvmEnv::from_provider(provider, BlockNumberOrTag::Latest) + .await .unwrap() - .with_chain_spec(chain_spec); + .with_chain_spec(&ANVIL_CHAIN_SPEC); + let block_hash = env.header().hash_slow(); + let block_number = U256::from(env.header().number()); let mut preflight = Contract::preflight(address, &mut env); let preflight_result = call_overrides - .override_builder(preflight.call_builder(&call)) + .set(preflight.call_builder(&call)) .call() + .await .unwrap(); - let input = env.into_input().unwrap(); + let input = env.into_input().await.unwrap(); + + let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); + let commitment = env.block_commitment(); + assert_eq!(commitment.blockHash, block_hash, "invalid commitment"); + assert_eq!(commitment.blockNumber, block_number, "invalid commitment"); - let env = input.into_env().with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); let contract = Contract::new(address, &env); - let result = call_overrides - .override_builder(contract.call_builder(&call)) - .call(); + let result = call_overrides.set(contract.call_builder(&call)).call(); assert_eq!( result, preflight_result, "mismatch in preflight and execution" From fcd859a0492bf8b2b19a3d6ccbda258f9a423cda Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 24 Jul 2024 17:46:24 +0200 Subject: [PATCH 02/30] remove ethers dependencies --- examples/erc20-counter/Cargo.toml | 1 - examples/erc20/Cargo.toml | 2 -- examples/token-stats/Cargo.toml | 2 -- 3 files changed, 5 deletions(-) diff --git a/examples/erc20-counter/Cargo.toml b/examples/erc20-counter/Cargo.toml index b18d1475..8d539c85 100644 --- a/examples/erc20-counter/Cargo.toml +++ b/examples/erc20-counter/Cargo.toml @@ -25,7 +25,6 @@ anyhow = { version = "1.0.75" } bincode = { version = "1.3" } bytemuck = { version = "1.14" } clap = { version = "4.5" } -ethers = { version = "2.0" } hex = { version = "0.4" } erc20-counter-methods = { path = "./methods" } serde = { version = "1.0", features = ["derive", "std"] } diff --git a/examples/erc20/Cargo.toml b/examples/erc20/Cargo.toml index a25f7c04..a52aa903 100644 --- a/examples/erc20/Cargo.toml +++ b/examples/erc20/Cargo.toml @@ -19,8 +19,6 @@ alloy-rlp-derive = { version = "0.3.4", default-features = false } alloy-sol-types = { version = "0.7" } anyhow = "1.0" clap = { version = "4.4", features = ["derive", "env"] } -ethers-core = "2.0" -ethers-providers = "2.0" log = "0.4" erc20-methods = { path = "methods" } nybbles = { version = "0.2.1", features = ["serde"] } diff --git a/examples/token-stats/Cargo.toml b/examples/token-stats/Cargo.toml index 198aaa5e..465c48e5 100644 --- a/examples/token-stats/Cargo.toml +++ b/examples/token-stats/Cargo.toml @@ -17,8 +17,6 @@ alloy-rlp-derive = { version = "0.3", default-features = false } alloy-sol-types = { version = "0.7" } anyhow = "1.0" clap = { version = "4.4", features = ["derive", "env"] } -ethers-core = "2.0" -ethers-providers = "2.0" log = "0.4" methods = { path = "methods" } once_cell = "1.19" From 90f76f35ebd57f3f932558f73d346c548c965653 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 24 Jul 2024 17:52:19 +0200 Subject: [PATCH 03/30] cleanup Cargo.toml --- examples/erc20/Cargo.toml | 17 +++-------------- examples/erc20/host/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/examples/erc20/Cargo.toml b/examples/erc20/Cargo.toml index a52aa903..4d7a1a1f 100644 --- a/examples/erc20/Cargo.toml +++ b/examples/erc20/Cargo.toml @@ -4,8 +4,6 @@ members = ["host", "methods"] [workspace.dependencies] # Intra-workspace dependencies -risc0-build-ethereum = { path = "../../build" } -risc0-ethereum-contracts = { path = "../../contracts" } risc0-steel = { path = "../../steel" } # risc0 monorepo dependencies. @@ -13,21 +11,12 @@ 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.7", features = ["serde", "rlp", "std"] } -alloy-rlp = { version = "0.3.4", default-features = false } -alloy-rlp-derive = { version = "0.3.4", default-features = false } +alloy-primitives = { version = "0.7" } alloy-sol-types = { version = "0.7" } anyhow = "1.0" -clap = { version = "4.4", features = ["derive", "env"] } -log = "0.4" +clap = { version = "4.5", features = ["derive", "env"] } erc20-methods = { path = "methods" } -nybbles = { version = "0.2.1", features = ["serde"] } -once_cell = "1.19" -revm = { version = "9.0", default-features = false, features = ["std"] } -rlp = "0.5.2" -serde = "1.0" -thiserror = "1.0" -tokio = { version = "1.35" } +tokio = { version = "1.39", features = ["full"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } url = { version = "2.5" } diff --git a/examples/erc20/host/Cargo.toml b/examples/erc20/host/Cargo.toml index d33d3ebd..0f714f2e 100644 --- a/examples/erc20/host/Cargo.toml +++ b/examples/erc20/host/Cargo.toml @@ -11,6 +11,6 @@ clap = { workspace = true } erc20-methods = { workspace = true } risc0-steel = { path = "../../../steel", features = ["host"] } risc0-zkvm = { workspace = true, features = ["client"] } -tokio = { workspace = true, features = ["rt-multi-thread"] } +tokio = { workspace = true } tracing-subscriber = { workspace = true } url = { workspace = true } From 0996262797e2f59db9bbe42eefdf7da226705b8b Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 25 Jul 2024 20:21:46 +0200 Subject: [PATCH 04/30] fix serde --- Cargo.toml | 4 +- examples/erc20-counter/Cargo.toml | 2 +- .../methods/guest/src/bin/balance_of.rs | 7 +- steel/Cargo.toml | 1 + steel/src/ethereum.rs | 30 ++-- steel/src/host/mod.rs | 20 +-- steel/src/lib.rs | 17 +- steel/src/serde.rs | 161 ++++++++++++++++++ steel/tests/eth_call.rs | 8 +- 9 files changed, 204 insertions(+), 46 deletions(-) create mode 100644 steel/src/serde.rs diff --git a/Cargo.toml b/Cargo.toml index 4fb301df..a50c3510 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,14 +22,14 @@ risc0-zkp = { git = "https://github.com/risc0/risc0", branch = "main", default-f risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false } # Alloy guest dependencies -alloy-consensus = { git = "https://github.com/alloy-rs/alloy.git" } +alloy-consensus = { git = "https://github.com/alloy-rs/alloy.git", rev = "067cc464bd1357e745653709db051707b949cc6b" } alloy-primitives = { version = "0.7", features = ["serde", "rlp", "std"] } alloy-rlp = { version = "0.3.7", default-features = false } alloy-rlp-derive = { version = "0.3.7", default-features = false } alloy-sol-types = { version = "0.7" } # Alloy host dependencies -alloy = { git = "https://github.com/alloy-rs/alloy.git", features = ["full"] } +alloy = { git = "https://github.com/alloy-rs/alloy.git", rev = "067cc464bd1357e745653709db051707b949cc6b", features = ["full"] } alloy-trie = { version = "0.4.0" } anyhow = { version = "1.0" } diff --git a/examples/erc20-counter/Cargo.toml b/examples/erc20-counter/Cargo.toml index 8d539c85..f7e02c17 100644 --- a/examples/erc20-counter/Cargo.toml +++ b/examples/erc20-counter/Cargo.toml @@ -18,7 +18,7 @@ risc0-build = { git = "https://github.com/risc0/risc0", branch = "main", feature 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 = { git = "https://github.com/alloy-rs/alloy.git", features = ["full"] } +alloy = { git = "https://github.com/alloy-rs/alloy.git", rev = "067cc464bd1357e745653709db051707b949cc6b", features = ["full"] } alloy-primitives = { version = "0.7", features = ["rlp", "serde", "std"] } alloy-sol-types = { version = "0.7" } anyhow = { version = "1.0.75" } diff --git a/examples/erc20-counter/methods/guest/src/bin/balance_of.rs b/examples/erc20-counter/methods/guest/src/bin/balance_of.rs index 751a9be3..58e16920 100644 --- a/examples/erc20-counter/methods/guest/src/bin/balance_of.rs +++ b/examples/erc20-counter/methods/guest/src/bin/balance_of.rs @@ -41,12 +41,9 @@ sol! { fn main() { // Read the input from the guest environment. - println!("Reading input"); let input: EthEvmInput = env::read(); - let contract: Address = Address::ZERO; // env::read(); - let account: Address = Address::ZERO; // env::read(); - - println!("Reading input done"); + let contract: Address = env::read(); + let account: Address = env::read(); // Converts the input into a `EvmEnv` for execution. The `with_chain_spec` method is used // to specify the chain configuration. It checks that the state matches the state root in the diff --git a/steel/Cargo.toml b/steel/Cargo.toml index e67e7631..602ea7ed 100644 --- a/steel/Cargo.toml +++ b/steel/Cargo.toml @@ -32,6 +32,7 @@ url = { workspace = true } [dev-dependencies] alloy = { workspace = true, features = ["node-bindings"] } alloy-trie = { workspace = true } +bincode = { workspace = true } risc0-steel = { path = ".", features = ["host"] } test-log = { workspace = true } diff --git a/steel/src/ethereum.rs b/steel/src/ethereum.rs index 231c3305..82cbc513 100644 --- a/steel/src/ethereum.rs +++ b/steel/src/ethereum.rs @@ -13,7 +13,7 @@ // limitations under the License. //! Type aliases for Ethereum. -use crate::EvmEnv; +use crate::{serde::RlpHeader, EvmEnv}; use super::{EvmBlockHeader, EvmInput}; use alloy_primitives::{BlockNumber, B256, U256}; @@ -26,37 +26,39 @@ pub type EthEvmEnv = EvmEnv; pub type EthEvmInput = EvmInput; /// [EvmBlockHeader] for Ethereum. -pub type EthBlockHeader = alloy_consensus::Header; +pub type EthBlockHeader = RlpHeader; impl EvmBlockHeader for EthBlockHeader { #[inline] fn parent_hash(&self) -> &B256 { - &self.parent_hash + &self.inner().parent_hash } #[inline] fn number(&self) -> BlockNumber { - self.number + self.inner().number } #[inline] fn timestamp(&self) -> u64 { - self.timestamp + self.inner().timestamp } #[inline] fn state_root(&self) -> &B256 { - &self.state_root + &self.inner().state_root } #[inline] fn fill_block_env(&self, blk_env: &mut BlockEnv) { - blk_env.number = U256::from(self.number); - blk_env.coinbase = self.beneficiary; - blk_env.timestamp = U256::from(self.timestamp); - blk_env.gas_limit = U256::from(self.gas_limit); - blk_env.basefee = U256::from(self.base_fee_per_gas.unwrap_or_default()); - blk_env.difficulty = self.difficulty; + let header = self.inner(); + + blk_env.number = U256::from(header.number); + blk_env.coinbase = header.beneficiary; + blk_env.timestamp = U256::from(header.timestamp); + blk_env.gas_limit = U256::from(header.gas_limit); + blk_env.basefee = U256::from(header.base_fee_per_gas.unwrap_or_default()); + blk_env.difficulty = header.difficulty; // technically, this is only valid after EIP-4399 but revm makes sure it is not used before - blk_env.prevrandao = Some(self.mix_hash); - if let Some(excess_blob_gas) = self.excess_blob_gas { + blk_env.prevrandao = Some(header.mix_hash); + if let Some(excess_blob_gas) = header.excess_blob_gas { blk_env.set_blob_excess_gas_and_price(excess_blob_gas.try_into().unwrap()) }; } diff --git a/steel/src/host/mod.rs b/steel/src/host/mod.rs index b20aeb98..ed8cc39a 100644 --- a/steel/src/host/mod.rs +++ b/steel/src/host/mod.rs @@ -26,7 +26,7 @@ use alloy::{ Transport, }, }; -use alloy_primitives::{Sealable, StorageKey}; +use alloy_primitives::StorageKey; use anyhow::{anyhow, ensure, Context}; use db::{AlloyDb, TraceDb}; use log::debug; @@ -49,13 +49,13 @@ impl EthEvmEnv, Ethereum, RootProvider } } -impl EvmEnv>, ::Header> +impl EvmEnv>, H> where T: Transport + Clone, N: Network, P: Provider, - ::Header: EvmBlockHeader + TryFrom, - <::Header as TryFrom>::Error: Debug, + H: EvmBlockHeader + TryFrom, + >::Error: Debug, { /// Creates a new provable [EvmEnv] from an alloy [Provider]. pub async fn from_provider(provider: P, number: BlockNumberOrTag) -> anyhow::Result { @@ -63,7 +63,7 @@ where .get_block_by_number(number, false) .await? .with_context(|| format!("block {number} not found"))?; - let header: ::Header = try_into_header(rpc_block.header)?; + let header: H = try_into_header(rpc_block.header)?; log::info!("Environment initialized for block {}", header.number()); let db = TraceDb::new(AlloyDb::new(provider, header.number())); @@ -72,19 +72,19 @@ where } } -impl EvmEnv>, ::Header> +impl EvmEnv>, H> where T: Transport + Clone, N: Network, - ::Header: EvmBlockHeader + TryFrom, - <::Header as TryFrom>::Error: Debug, P: Provider, + H: EvmBlockHeader + TryFrom, + >::Error: Debug, { /// Converts the environment into a [EvmInput]. /// /// The resulting input contains inclusion proofs for all the required chain state data. It can /// therefore be used to execute the same calls in a verifiable way in the zkVM. - pub async fn into_input(self) -> anyhow::Result::Header>> { + pub async fn into_input(self) -> anyhow::Result> { let db = &self.db.unwrap(); // use the same provider as the database @@ -140,7 +140,7 @@ where .get_block_by_number(number.into(), false) .await? .with_context(|| format!("block {number} not found"))?; - let header: ::Header = try_into_header(rpc_block.header)?; + let header: H = try_into_header(rpc_block.header)?; ancestors.push(header); } } diff --git a/steel/src/lib.rs b/steel/src/lib.rs index 547ceed4..b679f7d3 100644 --- a/steel/src/lib.rs +++ b/steel/src/lib.rs @@ -15,14 +15,14 @@ #![cfg_attr(not(doctest), doc = include_str!("../README.md"))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +use std::{fmt::Debug, rc::Rc}; + +use ::serde::{Deserialize, Serialize}; use alloy_primitives::{ b256, keccak256, Address, BlockNumber, Bytes, Sealable, Sealed, TxNumber, B256, U256, }; use alloy_rlp_derive::{RlpDecodable, RlpEncodable}; - use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg, HashMap, SpecId}; -use serde::{Deserialize, Serialize}; -use std::{fmt::Debug, rc::Rc}; pub mod config; mod contract; @@ -30,6 +30,7 @@ pub mod ethereum; #[cfg(feature = "host")] pub mod host; mod mpt; +pub mod serde; pub use contract::{CallBuilder, Contract}; pub use mpt::MerkleTrie; @@ -37,11 +38,11 @@ pub use mpt::MerkleTrie; /// The serializable input to derive and validate a [EvmEnv]. #[derive(Debug, Serialize, Deserialize)] pub struct EvmInput { - pub header: H, - pub state_trie: MerkleTrie, - pub storage_tries: Vec, - pub contracts: Vec, - pub ancestors: Vec, + header: H, + state_trie: MerkleTrie, + storage_tries: Vec, + contracts: Vec, + ancestors: Vec, } impl EvmInput { diff --git a/steel/src/serde.rs b/steel/src/serde.rs new file mode 100644 index 00000000..e8cb184e --- /dev/null +++ b/steel/src/serde.rs @@ -0,0 +1,161 @@ +// 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::{keccak256, Sealable, Sealed, B256}; +use alloy_rlp::{Decodable, Encodable}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +pub mod rlp { + use core::{fmt, marker::PhantomData}; + + use alloy_rlp::{Decodable, Encodable}; + use serde::de::{Error, Visitor}; + use serde::{Deserializer, Serializer}; + + struct RlpVisitor(PhantomData); + + impl<'de, T: Decodable> Visitor<'de> for RlpVisitor { + type Value = T; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("RLP-encodes bytes") + } + + #[inline] + fn visit_bytes(self, mut v: &[u8]) -> Result { + T::decode(&mut v).map_err(Error::custom) + } + } + + pub fn serialize(source: &T, serializer: S) -> Result + where + T: Encodable, + S: Serializer, + { + let rlp = alloy_rlp::encode(source); + serializer.serialize_bytes(&rlp) + } + + pub fn deserialize<'de, T, D>(deserializer: D) -> Result + where + T: Decodable, + D: Deserializer<'de>, + { + deserializer.deserialize_bytes(RlpVisitor(PhantomData)) + } +} + +/// A simple wrapper to serialize a header using the RLP-encoding. +#[derive(Clone)] +pub struct RlpHeader { + inner: H, + rlp: Option>, +} + +impl RlpHeader { + pub fn new(inner: H) -> Self { + Self { inner, rlp: None } + } + #[inline] + pub fn inner(&self) -> &H { + &self.inner + } +} + +impl Sealable for RlpHeader { + /// Calculate the seal hash, this may be slow. + #[inline] + fn hash_slow(&self) -> B256 { + match &self.rlp { + Some(rlp) => keccak256(rlp), + None => keccak256(alloy_rlp::encode(&self.inner)), + } + } + + #[inline] + fn seal_unchecked(mut self, seal: B256) -> Sealed { + self.rlp = None; + Sealed::new_unchecked(self, seal) + } +} + +impl Serialize for RlpHeader { + fn serialize(&self, serializer: S) -> Result { + let rlp = alloy_rlp::encode(&self.inner).into_boxed_slice(); + rlp.serialize(serializer) + } +} + +impl<'de, H: Encodable + Decodable> Deserialize<'de> for RlpHeader { + fn deserialize>(deserializer: D) -> Result { + let rlp = >::deserialize(deserializer)?; + let header = H::decode(&mut rlp.as_ref()).map_err(serde::de::Error::custom)?; + Ok(RlpHeader { + inner: header, + rlp: Some(rlp), + }) + } +} + +#[cfg(feature = "host")] +impl TryFrom for RlpHeader +where + H: Encodable + Decodable + TryFrom, +{ + type Error = >::Error; + + fn try_from(value: alloy::rpc::types::Header) -> Result { + let header = value.try_into()?; + Ok(Self { + inner: header, + rlp: None, + }) + } +} + +#[cfg(test)] +mod tests { + use alloy_primitives::U256; + use serde::{Deserialize, Serialize}; + + use crate::serde::RlpHeader; + + #[test] + fn serde_with() { + #[derive(Debug, PartialEq, Serialize, Deserialize)] + struct T { + #[serde(with = "super::rlp")] + uint: U256, + } + let t = T { + uint: U256::from(42), + }; + + let bin = bincode::serialize(&t).unwrap(); + assert_eq!(bincode::deserialize::(&bin).unwrap(), t); + } + + #[test] + fn rlp_header_roundtrip() { + let value = RlpHeader::new(alloy_consensus::Header::default()); + + let bin = bincode::serialize(&value).unwrap(); + assert_eq!( + bincode::deserialize::>(&bin) + .unwrap() + .inner(), + value.inner() + ); + } +} diff --git a/steel/tests/eth_call.rs b/steel/tests/eth_call.rs index 7c6d77d8..c27fdda0 100644 --- a/steel/tests/eth_call.rs +++ b/steel/tests/eth_call.rs @@ -25,7 +25,7 @@ use alloy::{ rpc::types::BlockNumberOrTag, transports::http::{Client, Http}, }; -use alloy_primitives::{address, b256, uint, Address, U256}; +use alloy_primitives::{address, b256, uint, Address, Sealable, U256}; use alloy_sol_types::SolCall; use once_cell::sync::Lazy; use revm::primitives::SpecId; @@ -113,10 +113,6 @@ async fn test_provider() -> TestProvider { log::info!("Anvil started: {:?}", node_info); let instance = SteelTest::deploy(&provider).await.unwrap(); assert_eq!(*instance.address(), STEEL_TEST_CONTRACT); - provider - .anvil_mine(Some(U256::from(254)), None) - .await - .unwrap(); provider } @@ -160,7 +156,7 @@ async fn eoa_account() { assert_eq!(result.size, uint!(0_U256)); } -#[test(tokio::test)] +#[tokio::test] async fn blockhash() { let provider = test_provider().await; let block_hash = provider.anvil_node_info().await.unwrap().current_block_hash; From 8e595c3fd545d5697162a99c8aa9d3c206487c6f Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Fri, 26 Jul 2024 13:46:15 +0200 Subject: [PATCH 05/30] improve RlpHeader performance --- steel/src/serde.rs | 153 +++++++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 76 deletions(-) diff --git a/steel/src/serde.rs b/steel/src/serde.rs index e8cb184e..9992ab4a 100644 --- a/steel/src/serde.rs +++ b/steel/src/serde.rs @@ -12,58 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -use alloy_primitives::{keccak256, Sealable, Sealed, B256}; -use alloy_rlp::{Decodable, Encodable}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -pub mod rlp { - use core::{fmt, marker::PhantomData}; - - use alloy_rlp::{Decodable, Encodable}; - use serde::de::{Error, Visitor}; - use serde::{Deserializer, Serializer}; - - struct RlpVisitor(PhantomData); +use std::fmt; - impl<'de, T: Decodable> Visitor<'de> for RlpVisitor { - type Value = T; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("RLP-encodes bytes") - } - - #[inline] - fn visit_bytes(self, mut v: &[u8]) -> Result { - T::decode(&mut v).map_err(Error::custom) - } - } - - pub fn serialize(source: &T, serializer: S) -> Result - where - T: Encodable, - S: Serializer, - { - let rlp = alloy_rlp::encode(source); - serializer.serialize_bytes(&rlp) - } - - pub fn deserialize<'de, T, D>(deserializer: D) -> Result - where - T: Decodable, - D: Deserializer<'de>, - { - deserializer.deserialize_bytes(RlpVisitor(PhantomData)) - } -} +use alloy_primitives::{hex, keccak256, Sealable, Sealed, B256}; +use alloy_rlp::{Decodable, Encodable}; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; -/// A simple wrapper to serialize a header using the RLP-encoding. +/// An efficient wrapper for header types that do not support serde serialization. +/// +/// It implements deserialization using RLP encoding and does not discard the RLP data after +/// decoding, instead keeping it for faster hash computation. #[derive(Clone)] -pub struct RlpHeader { +pub struct RlpHeader { inner: H, - rlp: Option>, + rlp: Option>, } -impl RlpHeader { +impl RlpHeader { pub fn new(inner: H) -> Self { Self { inner, rlp: None } } @@ -73,7 +38,7 @@ impl RlpHeader { } } -impl Sealable for RlpHeader { +impl Sealable for RlpHeader { /// Calculate the seal hash, this may be slow. #[inline] fn hash_slow(&self) -> B256 { @@ -90,17 +55,61 @@ impl Sealable for RlpHeader { } } -impl Serialize for RlpHeader { +impl Serialize for RlpHeader { + #[inline] fn serialize(&self, serializer: S) -> Result { - let rlp = alloy_rlp::encode(&self.inner).into_boxed_slice(); - rlp.serialize(serializer) + if serializer.is_human_readable() { + hex::serialize(alloy_rlp::encode(&self.inner), serializer) + } else { + serializer.serialize_bytes(&alloy_rlp::encode(&self.inner)) + } } } impl<'de, H: Encodable + Decodable> Deserialize<'de> for RlpHeader { + #[inline] fn deserialize>(deserializer: D) -> Result { - let rlp = >::deserialize(deserializer)?; - let header = H::decode(&mut rlp.as_ref()).map_err(serde::de::Error::custom)?; + 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 mut buf = rlp.as_slice(); + let header = H::decode(&mut buf).map_err(de::Error::custom)?; + if !buf.is_empty() { + return Err(de::Error::custom("trailing bytes")); + } + Ok(RlpHeader { inner: header, rlp: Some(rlp), @@ -116,9 +125,8 @@ where type Error = >::Error; fn try_from(value: alloy::rpc::types::Header) -> Result { - let header = value.try_into()?; Ok(Self { - inner: header, + inner: value.try_into()?, rlp: None, }) } @@ -126,36 +134,29 @@ where #[cfg(test)] mod tests { - use alloy_primitives::U256; - use serde::{Deserialize, Serialize}; + use super::*; - use crate::serde::RlpHeader; + use alloy_primitives::Sealable; #[test] - fn serde_with() { - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct T { - #[serde(with = "super::rlp")] - uint: U256, - } - let t = T { - uint: U256::from(42), - }; + fn bincode_rlp_header() { + let value = RlpHeader::new(alloy_consensus::Header::default()); + assert_eq!(value.hash_slow(), value.inner().hash_slow()); - let bin = bincode::serialize(&t).unwrap(); - assert_eq!(bincode::deserialize::(&bin).unwrap(), t); + let bin = bincode::serialize(&value).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 rlp_header_roundtrip() { + fn serde_rlp_header() { let value = RlpHeader::new(alloy_consensus::Header::default()); + assert_eq!(value.hash_slow(), value.inner().hash_slow()); - let bin = bincode::serialize(&value).unwrap(); - assert_eq!( - bincode::deserialize::>(&bin) - .unwrap() - .inner(), - value.inner() - ); + let json = serde_json::to_string(&value).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()); } } From 3c2093e0559d56d8ce766254c0df586edf102d42 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Mon, 29 Jul 2024 12:45:13 +0200 Subject: [PATCH 06/30] minor refactoring --- steel/src/config.rs | 92 ++++------------- steel/src/contract.rs | 119 +++++---------------- steel/src/ethereum.rs | 47 ++++++++- steel/src/host/db/mod.rs | 1 - steel/src/host/db/trace.rs | 10 +- steel/src/host/mod.rs | 29 +++--- steel/src/lib.rs | 101 +----------------- steel/src/mpt.rs | 11 +- steel/src/serde.rs | 1 + steel/src/state.rs | 207 +++++++++++++++++++++++++++++++++++++ steel/tests/eth_call.rs | 22 ++-- 11 files changed, 339 insertions(+), 301 deletions(-) create mode 100644 steel/src/state.rs diff --git a/steel/src/config.rs b/steel/src/config.rs index babad1e1..2be675ca 100644 --- a/steel/src/config.rs +++ b/steel/src/config.rs @@ -17,42 +17,9 @@ use std::collections::BTreeMap; use alloy_primitives::{BlockNumber, ChainId}; use anyhow::bail; -use once_cell::sync::Lazy; use revm::primitives::SpecId; use serde::{Deserialize, Serialize}; -/// The Ethereum Mainnet specification. -pub static ETH_MAINNET_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { - chain_id: 1, - max_spec_id: SpecId::CANCUN, - hard_forks: BTreeMap::from([ - (SpecId::MERGE, ForkCondition::Block(15537394)), - (SpecId::SHANGHAI, ForkCondition::Timestamp(1681338455)), - (SpecId::CANCUN, ForkCondition::Timestamp(1710338135)), - ]), - gas_constants: BTreeMap::from([(SpecId::LONDON, EIP1559_CONSTANTS_DEFAULT)]), -}); - -/// The Ethereum Sepolia specification. -pub static ETH_SEPOLIA_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { - chain_id: 11155111, - max_spec_id: SpecId::CANCUN, - hard_forks: BTreeMap::from([ - (SpecId::MERGE, ForkCondition::Block(1735371)), - (SpecId::SHANGHAI, ForkCondition::Timestamp(1677557088)), - (SpecId::CANCUN, ForkCondition::Timestamp(1706655072)), - ]), - gas_constants: BTreeMap::from([(SpecId::LONDON, EIP1559_CONSTANTS_DEFAULT)]), -}); - -/// The gas constants as defined in [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). -pub const EIP1559_CONSTANTS_DEFAULT: Eip1559Constants = Eip1559Constants { - base_fee_change_denominator: 8, - base_fee_max_increase_denominator: 8, - base_fee_max_decrease_denominator: 8, - elasticity_multiplier: 2, -}; - /// The condition at which a fork is activated. #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub enum ForkCondition { @@ -67,6 +34,7 @@ pub enum ForkCondition { impl ForkCondition { /// Returns whether the condition has been met. + #[inline] pub fn active(&self, block_number: BlockNumber, timestamp: u64) -> bool { match self { ForkCondition::Block(block) => *block <= block_number, @@ -76,36 +44,24 @@ impl ForkCondition { } } -/// [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) parameters. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)] -pub struct Eip1559Constants { - pub base_fee_change_denominator: u64, - pub base_fee_max_increase_denominator: u64, - pub base_fee_max_decrease_denominator: u64, - pub elasticity_multiplier: u64, -} - /// Specification of a specific chain. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ChainSpec { - chain_id: ChainId, - max_spec_id: SpecId, - hard_forks: BTreeMap, - gas_constants: BTreeMap, + /// Chain identifier. + pub chain_id: ChainId, + /// ID of the latest supported revm specification. + pub max_spec_id: SpecId, + /// Map revm specification IDs to their respective activation condition. + pub hard_forks: BTreeMap, } impl ChainSpec { /// Creates a new configuration consisting of only one specification ID. - pub fn new_single( - chain_id: ChainId, - spec_id: SpecId, - eip_1559_constants: Eip1559Constants, - ) -> Self { + pub fn new_single(chain_id: ChainId, spec_id: SpecId) -> Self { ChainSpec { chain_id, max_spec_id: spec_id, hard_forks: BTreeMap::from([(spec_id, ForkCondition::Block(0))]), - gas_constants: BTreeMap::from([(spec_id, eip_1559_constants)]), } } /// Returns the network chain ID. @@ -137,13 +93,6 @@ impl ChainSpec { None => bail!("no supported fork for block {}", block_number), } } - /// Returns the Eip1559 constants for a given [SpecId]. - pub fn gas_constants(&self, spec_id: SpecId) -> Option<&Eip1559Constants> { - self.gas_constants - .range(..=spec_id) - .next_back() - .map(|(_, v)| v) - } fn spec_id(&self, block_number: BlockNumber, timestamp: u64) -> Option { for (spec_id, fork) in self.hard_forks.iter().rev() { @@ -159,6 +108,18 @@ impl ChainSpec { mod tests { use super::*; + use once_cell::sync::Lazy; + + static ETH_MAINNET_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { + chain_id: 1, + max_spec_id: SpecId::CANCUN, + hard_forks: BTreeMap::from([ + (SpecId::MERGE, ForkCondition::Block(15537394)), + (SpecId::SHANGHAI, ForkCondition::Timestamp(1681338455)), + (SpecId::CANCUN, ForkCondition::Timestamp(1710338135)), + ]), + }); + #[test] fn spec_id() { assert_eq!(ETH_MAINNET_CHAIN_SPEC.spec_id(15537393, 0), None); @@ -175,17 +136,4 @@ mod tests { Some(SpecId::SHANGHAI) ); } - - #[test] - fn gas_constants() { - assert_eq!(ETH_MAINNET_CHAIN_SPEC.gas_constants(SpecId::BERLIN), None); - assert_eq!( - ETH_MAINNET_CHAIN_SPEC.gas_constants(SpecId::MERGE), - Some(&EIP1559_CONSTANTS_DEFAULT) - ); - assert_eq!( - ETH_MAINNET_CHAIN_SPEC.gas_constants(SpecId::SHANGHAI), - Some(&EIP1559_CONSTANTS_DEFAULT) - ); - } } diff --git a/steel/src/contract.rs b/steel/src/contract.rs index a773cdbc..e4179eb7 100644 --- a/steel/src/contract.rs +++ b/steel/src/contract.rs @@ -12,19 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{ + borrow::Borrow, + fmt::{Debug, Display}, + marker::PhantomData, + mem, +}; + #[cfg(feature = "host")] use crate::host::HostEvmEnv; -use crate::{EvmBlockHeader, GuestEvmEnv, MerkleTrie, StateDb}; -use alloy_primitives::{keccak256, Address, TxKind, B256, U256}; +use crate::{state::WrapStateDb, EvmBlockHeader, GuestEvmEnv}; +use alloy_primitives::{Address, TxKind, U256}; use alloy_sol_types::{SolCall, SolType}; use revm::{ - primitives::{ - AccountInfo, Bytecode, CfgEnvWithHandlerCfg, ExecutionResult, HashMap, ResultAndState, - SuccessReason, - }, + primitives::{CfgEnvWithHandlerCfg, ExecutionResult, ResultAndState, SuccessReason}, Database, Evm, }; -use std::{borrow::Borrow, convert::Infallible, fmt::Debug, marker::PhantomData, mem, rc::Rc}; /// Represents a contract that is initialized with a specific environment and contract address. /// @@ -41,7 +44,7 @@ use std::{borrow::Borrow, convert::Infallible, fmt::Debug, marker::PhantomData, /// ### Examples /// ```rust no_run /// # use risc0_steel::{ethereum::EthEvmEnv, Contract, host::BlockNumberOrTag}; -/// # use alloy_primitives::{address}; +/// # use alloy_primitives::address; /// # use alloy_sol_types::sol; /// /// # #[tokio::main(flavor = "current_thread")] @@ -180,21 +183,24 @@ where C: SolCall + Send + 'static, ::Return: Send, D: Database + Send + 'static, - ::Error: Debug, + ::Error: Display, H: EvmBlockHeader + Clone + Send + 'static, { /// Executes the call with a [EvmEnv] constructed with [Contract::preflight]. /// + /// This uses [tokio::task::spawn_blocking] to run the blocking revm execution. + /// /// [EvmEnv]: crate::EvmEnv pub async fn call(self) -> anyhow::Result { log::info!( - "Executing preflight for '{}' on contract {}", + "Executing preflight calling '{}' on {}", C::SIGNATURE, self.tx.to ); let cfg = self.env.cfg_env.clone(); let header = self.env.header.inner().clone(); + // we cannot clone the database, so it gets moved in and out of the task let db = self.env.db.take().unwrap(); let (res, db) = tokio::task::spawn_blocking(move || { @@ -208,7 +214,7 @@ where self.env.db = Some(db); - res.map_err(|err| anyhow::anyhow!(err)) + res.map_err(|err| anyhow::anyhow!("call '{}' failed: {}", C::SIGNATURE, err)) } } @@ -254,7 +260,7 @@ impl CallTxData { fn transact(self, evm: &mut Evm<'_, EXT, DB>) -> Result where DB: Database, - ::Error: Debug, + ::Error: Display, { #[allow(clippy::let_unit_value)] let _ = Self::RETURNS; @@ -269,23 +275,22 @@ impl CallTxData { let ResultAndState { result, .. } = evm .transact_preverified() - .map_err(|err| format!("Call '{}' failed: {:?}", C::SIGNATURE, err))?; + .map_err(|err| format!("EVM error: {}", err))?; let output = match result { ExecutionResult::Success { reason, output, .. } => { // there must be a return value to decode if reason != SuccessReason::Return { - Err(format!("Did not return: {:?}", reason)) + Err(format!("did not return: {:?}", reason)) } else { Ok(output) } } - ExecutionResult::Revert { output, .. } => Err(format!("Reverted: {}", output)), - ExecutionResult::Halt { reason, .. } => Err(format!("Halted: {:?}", reason)), + ExecutionResult::Revert { output, .. } => Err(format!("reverted: {}", output)), + ExecutionResult::Halt { reason, .. } => Err(format!("halted: {:?}", reason)), }?; let returns = C::abi_decode_returns(&output.into_data(), true).map_err(|err| { format!( - "Call '{}' returned invalid type; expected '{}': {:?}", - C::SIGNATURE, + "return type invalid; expected '{}': {}", as SolType>::SOL_NAME, err ) @@ -306,81 +311,3 @@ where .modify_block_env(|blk_env| header.borrow().fill_block_env(blk_env)) .build() } - -struct WrapStateDb<'a> { - inner: &'a StateDb, - account_storage: HashMap>>, -} - -impl<'a> WrapStateDb<'a> { - /// Creates a new [Database] from the given [StateDb]. - pub(crate) fn new(inner: &'a StateDb) -> Self { - Self { - inner, - account_storage: HashMap::new(), - } - } -} - -impl Database for WrapStateDb<'_> { - /// The database does not return any errors. - type Error = Infallible; - - /// Get basic account information. - #[inline] - fn basic(&mut self, address: Address) -> Result, Self::Error> { - let account = self.inner.account(address); - match account { - Some(account) => { - // link storage trie to the account, if it exists - if let Some(storage_trie) = self.inner.storage_trie(&account.storage_root) { - self.account_storage - .insert(address, Some(storage_trie.clone())); - } - - Ok(Some(AccountInfo { - balance: account.balance, - nonce: account.nonce, - code_hash: account.code_hash, - code: None, // we don't need the code here, `code_by_hash` will be used instead - })) - } - None => { - self.account_storage.insert(address, None); - - Ok(None) - } - } - } - - /// Get account code by its hash. - #[inline] - fn code_by_hash(&mut self, code_hash: B256) -> Result { - let code = self.inner.code_by_hash(code_hash); - Ok(Bytecode::new_raw(code.clone())) - } - - /// Get storage value of address at index. - #[inline] - fn storage(&mut self, address: Address, index: U256) -> Result { - let storage = self - .account_storage - .get(&address) - .unwrap_or_else(|| panic!("storage not found: {:?}", address)); - match storage { - Some(storage) => { - let val = storage - .get_rlp(keccak256(index.to_be_bytes::<32>())) - .expect("invalid storage value"); - Ok(val.unwrap_or_default()) - } - None => Ok(U256::ZERO), - } - } - - /// Get block hash by block number. - #[inline] - fn block_hash(&mut self, number: U256) -> Result { - Ok(self.inner.block_hash(number)) - } -} diff --git a/steel/src/ethereum.rs b/steel/src/ethereum.rs index 82cbc513..1d9e3e7f 100644 --- a/steel/src/ethereum.rs +++ b/steel/src/ethereum.rs @@ -12,12 +12,51 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Type aliases for Ethereum. -use crate::{serde::RlpHeader, EvmEnv}; +//! Type aliases and specifications for Ethereum. +use std::collections::BTreeMap; -use super::{EvmBlockHeader, EvmInput}; +use crate::{ + config::{ChainSpec, ForkCondition}, + serde::RlpHeader, + EvmBlockHeader, EvmEnv, EvmInput, +}; use alloy_primitives::{BlockNumber, B256, U256}; -use revm::primitives::BlockEnv; +use once_cell::sync::Lazy; +use revm::primitives::{BlockEnv, SpecId}; + +/// The Ethereum Sepolia [ChainSpec]. +pub static ETH_SEPOLIA_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { + chain_id: 11155111, + max_spec_id: SpecId::CANCUN, + hard_forks: BTreeMap::from([ + (SpecId::LONDON, ForkCondition::Block(0)), + (SpecId::MERGE, ForkCondition::Block(1735371)), + (SpecId::SHANGHAI, ForkCondition::Timestamp(1677557088)), + (SpecId::CANCUN, ForkCondition::Timestamp(1706655072)), + ]), +}); + +/// The Ethereum Holešky [ChainSpec]. +pub static ETH_HOLESKY_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { + chain_id: 17000, + max_spec_id: SpecId::CANCUN, + hard_forks: BTreeMap::from([ + (SpecId::MERGE, ForkCondition::Block(0)), + (SpecId::SHANGHAI, ForkCondition::Timestamp(1696000704)), + (SpecId::CANCUN, ForkCondition::Timestamp(1707305664)), + ]), +}); + +/// The Ethereum Mainnet [ChainSpec]. +pub static ETH_MAINNET_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { + chain_id: 1, + max_spec_id: SpecId::CANCUN, + hard_forks: BTreeMap::from([ + (SpecId::MERGE, ForkCondition::Block(15537394)), + (SpecId::SHANGHAI, ForkCondition::Timestamp(1681338455)), + (SpecId::CANCUN, ForkCondition::Timestamp(1710338135)), + ]), +}); /// [EvmEnv] for Ethereum. pub type EthEvmEnv = EvmEnv; diff --git a/steel/src/host/db/mod.rs b/steel/src/host/db/mod.rs index 509cf3e0..1dc15957 100644 --- a/steel/src/host/db/mod.rs +++ b/steel/src/host/db/mod.rs @@ -15,7 +15,6 @@ //! [Database] implementations. //! //! [Database]: revm::Database - mod alloy; mod trace; diff --git a/steel/src/host/db/trace.rs b/steel/src/host/db/trace.rs index f3cb098e..a4c3f2fc 100644 --- a/steel/src/host/db/trace.rs +++ b/steel/src/host/db/trace.rs @@ -62,20 +62,23 @@ impl Database for TraceDb { type Error = DB::Error; fn basic(&mut self, address: Address) -> Result, Self::Error> { + log::trace!("BASIC: address={}", address); let basic = self.inner.basic(address)?; self.accounts.entry(address).or_default(); Ok(basic) } - fn code_by_hash(&mut self, code_hash: B256) -> Result { - let code = self.inner.code_by_hash(code_hash)?; - self.contracts.insert(code_hash, code.original_bytes()); + fn code_by_hash(&mut self, hash: B256) -> Result { + log::trace!("CODE: hash={}", hash); + let code = self.inner.code_by_hash(hash)?; + self.contracts.insert(hash, code.original_bytes()); Ok(code) } fn storage(&mut self, address: Address, index: U256) -> Result { + log::trace!("STORAGE: address={}, index={}", address, index); let storage = self.inner.storage(address, index)?; self.accounts.entry(address).or_default().insert(index); @@ -83,6 +86,7 @@ impl Database for TraceDb { } fn block_hash(&mut self, number: U256) -> Result { + log::trace!("BLOCK: number={}", number); let block_hash = self.inner.block_hash(number)?; self.block_hash_numbers.insert(number); diff --git a/steel/src/host/mod.rs b/steel/src/host/mod.rs index ed8cc39a..e5261dc0 100644 --- a/steel/src/host/mod.rs +++ b/steel/src/host/mod.rs @@ -13,8 +13,7 @@ // limitations under the License. //! Functionality that is only needed for the host and not the guest. - -use std::fmt::Debug; +use std::fmt::Display; use crate::{ethereum::EthEvmEnv, EvmBlockHeader, EvmEnv, EvmInput, MerkleTrie}; use alloy::{ @@ -55,14 +54,15 @@ where N: Network, P: Provider, H: EvmBlockHeader + TryFrom, - >::Error: Debug, + >::Error: Display, { /// Creates a new provable [EvmEnv] from an alloy [Provider]. pub async fn from_provider(provider: P, number: BlockNumberOrTag) -> anyhow::Result { let rpc_block = provider .get_block_by_number(number, false) - .await? - .with_context(|| format!("block {number} not found"))?; + .await + .context("eth_getBlockByNumber failed")? + .with_context(|| format!("block {} not found", number))?; let header: H = try_into_header(rpc_block.header)?; log::info!("Environment initialized for block {}", header.number()); @@ -78,7 +78,7 @@ where N: Network, P: Provider, H: EvmBlockHeader + TryFrom, - >::Error: Debug, + >::Error: Display, { /// Converts the environment into a [EvmInput]. /// @@ -100,14 +100,14 @@ where storage_keys.iter().map(|v| StorageKey::from(*v)).collect(), ) .number(block_number) - .await?; + .await + .context("eth_getProof failed")?; proofs.push(proof); } // build the sparse MPT for the state and verify against the header let state_nodes = proofs.iter().flat_map(|p| p.account_proof.iter()); - let state_trie = - MerkleTrie::from_rlp_nodes(state_nodes).context("invalid account proof")?; + let state_trie = MerkleTrie::from_rlp_nodes(state_nodes).context("accountProof invalid")?; ensure!( self.header.state_root() == &state_trie.hash_slow(), "root of the state trie does not match the header" @@ -123,7 +123,7 @@ where let storage_nodes = proof.storage_proof.iter().flat_map(|p| p.proof.iter()); let storage_trie = - MerkleTrie::from_rlp_nodes(storage_nodes).context("invalid storage proof")?; + MerkleTrie::from_rlp_nodes(storage_nodes).context("storageProof invalid")?; storage_tries.insert(storage_trie.hash_slow(), storage_trie); } let storage_tries: Vec<_> = storage_tries.into_values().collect(); @@ -138,8 +138,9 @@ where for number in (block_hash_min_number..block_number).rev() { let rpc_block = provider .get_block_by_number(number.into(), false) - .await? - .with_context(|| format!("block {number} not found"))?; + .await + .context("eth_getBlockByNumber failed")? + .with_context(|| format!("block {} not found", number))?; let header: H = try_into_header(rpc_block.header)?; ancestors.push(header); } @@ -169,9 +170,9 @@ fn try_into_header>( rpc_header: RpcHeader, ) -> anyhow::Result where - >::Error: Debug, + >::Error: Display, { rpc_header .try_into() - .map_err(|err| anyhow!("invalid header {err:?}")) + .map_err(|err| anyhow!("header invalid: {}", err)) } diff --git a/steel/src/lib.rs b/steel/src/lib.rs index b679f7d3..a90b2b93 100644 --- a/steel/src/lib.rs +++ b/steel/src/lib.rs @@ -15,13 +15,10 @@ #![cfg_attr(not(doctest), doc = include_str!("../README.md"))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -use std::{fmt::Debug, rc::Rc}; +use std::fmt::Debug; use ::serde::{Deserialize, Serialize}; -use alloy_primitives::{ - b256, keccak256, Address, BlockNumber, Bytes, Sealable, Sealed, TxNumber, B256, U256, -}; -use alloy_rlp_derive::{RlpDecodable, RlpEncodable}; +use alloy_primitives::{BlockNumber, Bytes, Sealable, Sealed, B256, U256}; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg, HashMap, SpecId}; pub mod config; @@ -31,6 +28,7 @@ pub mod ethereum; pub mod host; mod mpt; pub mod serde; +mod state; pub use contract::{CallBuilder, Contract}; pub use mpt::MerkleTrie; @@ -100,6 +98,7 @@ mod private { /// Solidity struct representing the committed block used for validation. pub use private::Commitment as SolCommitment; +use state::StateDb; /// Alias for readability, do not make public. pub(crate) type GuestEvmEnv = EvmEnv; @@ -142,102 +141,12 @@ impl EvmEnv { } /// Returns the header of the environment. + #[inline] pub fn header(&self) -> &H { self.header.inner() } } -/// A simple read-only EVM database. -/// -/// It is backed by a single [MerkleTrie] for the accounts and one [MerkleTrie] each for the -/// accounts' storages. It panics when data is queried that is not contained in the tries. -pub struct StateDb { - state_trie: MerkleTrie, - storage_tries: HashMap>, - contracts: HashMap, - block_hashes: HashMap, -} - -impl StateDb { - /// Creates a new state database from the given tries. - pub fn new( - state_trie: MerkleTrie, - storage_tries: impl IntoIterator, - contracts: impl IntoIterator, - block_hashes: HashMap, - ) -> Self { - let contracts = contracts - .into_iter() - .map(|code| (keccak256(&code), code)) - .collect(); - let storage_tries = storage_tries - .into_iter() - .map(|trie| (trie.hash_slow(), Rc::new(trie))) - .collect(); - Self { - state_trie, - contracts, - storage_tries, - block_hashes, - } - } - - fn account(&self, address: Address) -> Option { - self.state_trie - .get_rlp(keccak256(address)) - .expect("invalid state value") - } - - fn code_by_hash(&self, hash: B256) -> &Bytes { - self.contracts - .get(&hash) - .unwrap_or_else(|| panic!("code not found: {}", hash)) - } - - fn block_hash(&self, number: U256) -> B256 { - // block number is never bigger then u64::MAX - let number: u64 = number.to(); - let hash = self - .block_hashes - .get(&number) - .unwrap_or_else(|| panic!("block not found: {}", number)); - *hash - } - - fn storage_trie(&self, root: &B256) -> Option<&Rc> { - self.storage_tries.get(root) - } -} - -/// Hash of an empty byte array, i.e. `keccak256([])`. -pub const KECCAK_EMPTY: B256 = - b256!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); - -/// Represents an account within the state trie. -#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)] -struct StateAccount { - /// The number of transactions sent from this account's address. - pub nonce: TxNumber, - /// The number of Wei owned by this account's address. - pub balance: U256, - /// The root of the account's storage trie. - pub storage_root: B256, - /// The hash of the EVM code of this account. - pub code_hash: B256, -} - -impl Default for StateAccount { - /// Provides default values for a [StateAccount]. - fn default() -> Self { - Self { - nonce: 0, - balance: U256::ZERO, - storage_root: mpt::EMPTY_ROOT_HASH, - code_hash: KECCAK_EMPTY, - } - } -} - /// An EVM abstraction of a block header. pub trait EvmBlockHeader: Sealable { /// Returns the hash of the parent block's header. diff --git a/steel/src/mpt.rs b/steel/src/mpt.rs index 7eb841f5..62346d78 100644 --- a/steel/src/mpt.rs +++ b/steel/src/mpt.rs @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::fmt::Debug; + use alloy_primitives::{b256, keccak256, B256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header, PayloadView, EMPTY_STRING_CODE}; use nybbles::Nibbles; use revm::primitives::HashMap; use serde::{Deserialize, Serialize}; -use std::fmt::Debug; use thiserror::Error as ThisError; /// Root hash of an empty Merkle Patricia trie, i.e. `keccak256(RLP(""))`. @@ -374,8 +375,9 @@ fn resolve_trie(root: Node, nodes_by_hash: &HashMap) -> Node { #[cfg(test)] mod tests { + use crate::state::StateAccount; + use super::*; - use crate::StateAccount; use alloy_primitives::{address, uint, Bytes, U256}; use alloy_trie::HashBuilder; use serde_json::json; @@ -393,6 +395,11 @@ mod tests { out } + #[test] + pub fn empty_root_hash() { + assert_eq!(EMPTY_ROOT_HASH, keccak256(Node::Null.rlp_encoded())); + } + #[test] pub fn mpt_null() { let mpt = MerkleTrie(Node::Null); diff --git a/steel/src/serde.rs b/steel/src/serde.rs index 9992ab4a..5fc8aa19 100644 --- a/steel/src/serde.rs +++ b/steel/src/serde.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Serde related helpers. use std::fmt; use alloy_primitives::{hex, keccak256, Sealable, Sealed, B256}; diff --git a/steel/src/state.rs b/steel/src/state.rs new file mode 100644 index 00000000..408c2c8f --- /dev/null +++ b/steel/src/state.rs @@ -0,0 +1,207 @@ +// 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 std::{convert::Infallible, fmt::Debug, rc::Rc}; + +use crate::mpt::{MerkleTrie, EMPTY_ROOT_HASH}; +use alloy_primitives::{keccak256, Address, Bytes, TxNumber, B256, U256}; +use alloy_rlp_derive::{RlpDecodable, RlpEncodable}; +use revm::{ + primitives::{AccountInfo, Bytecode, HashMap, KECCAK_EMPTY}, + Database, +}; + +/// A simple MPT-based read-only EVM database implementation. +/// +/// It is backed by a single [MerkleTrie] for the accounts and one [MerkleTrie] each for the +/// accounts' stores. It panics when querying data not contained in the tries. This design allows +/// storage keys to be queried by storage trie root hash, but not by account, which is required to +/// implement [revm::DatabaseRef]. Thus, in order to use [StateDb] in revm, [WrapStateDb] must be +/// used, which caches the appropriate storage trie root for each basic account query, thus +/// requiring mutability. +pub struct StateDb { + /// State MPT. + state_trie: MerkleTrie, + /// Storage MPTs to their root hash. + /// [Rc] is used fore MPT deduplication. + storage_tries: HashMap>, + /// Contracts by their hash. + contracts: HashMap, + /// Block hashes by their number. + block_hashes: HashMap, +} + +impl StateDb { + /// Creates a new state database from the given tries. + pub fn new( + state_trie: MerkleTrie, + storage_tries: impl IntoIterator, + contracts: impl IntoIterator, + block_hashes: HashMap, + ) -> Self { + let contracts = contracts + .into_iter() + .map(|code| (keccak256(&code), code)) + .collect(); + let storage_tries = storage_tries + .into_iter() + .map(|trie| (trie.hash_slow(), Rc::new(trie))) + .collect(); + Self { + state_trie, + contracts, + storage_tries, + block_hashes, + } + } + + #[inline] + fn account(&self, address: Address) -> Option { + self.state_trie + .get_rlp(keccak256(address)) + .expect("invalid state value") + } + + #[inline] + fn code_by_hash(&self, hash: B256) -> &Bytes { + self.contracts + .get(&hash) + .unwrap_or_else(|| panic!("code not found: {}", hash)) + } + + #[inline] + fn block_hash(&self, number: U256) -> B256 { + // block number is never bigger then u64::MAX + let number: u64 = number.to(); + let hash = self + .block_hashes + .get(&number) + .unwrap_or_else(|| panic!("block not found: {}", number)); + *hash + } + + #[inline] + fn storage_trie(&self, root: &B256) -> Option<&Rc> { + self.storage_tries.get(root) + } +} + +/// A simple wrapper for [StateDb] to implement the [Database] trait. +/// +/// In addition to translating the actual [Database] queries into MPT calls, it also maps account +/// 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> { + inner: &'a StateDb, + account_storage: HashMap>>, +} + +impl<'a> WrapStateDb<'a> { + /// Creates a new [Database] from the given [StateDb]. + pub fn new(inner: &'a StateDb) -> Self { + Self { + inner, + account_storage: HashMap::new(), + } + } +} + +impl Database for WrapStateDb<'_> { + /// The [StateDb] does not return any errors. + type Error = Infallible; + + /// Get basic account information. + #[inline] + fn basic(&mut self, address: Address) -> Result, Self::Error> { + let account = self.inner.account(address); + match account { + Some(account) => { + // link storage trie to the account, if it exists + if let Some(storage_trie) = self.inner.storage_trie(&account.storage_root) { + self.account_storage + .insert(address, Some(storage_trie.clone())); + } + + Ok(Some(AccountInfo { + balance: account.balance, + nonce: account.nonce, + code_hash: account.code_hash, + code: None, // we don't need the code here, `code_by_hash` will be used instead + })) + } + None => { + self.account_storage.insert(address, None); + + Ok(None) + } + } + } + + /// Get account code by its hash. + #[inline] + fn code_by_hash(&mut self, code_hash: B256) -> Result { + let code = self.inner.code_by_hash(code_hash); + Ok(Bytecode::new_raw(code.clone())) + } + + /// Get storage value of address at index. + #[inline] + fn storage(&mut self, address: Address, index: U256) -> Result { + let storage = self + .account_storage + .get(&address) + .unwrap_or_else(|| panic!("storage not found: {:?}", address)); + match storage { + Some(storage) => { + let val = storage + .get_rlp(keccak256(index.to_be_bytes::<32>())) + .expect("invalid storage value"); + Ok(val.unwrap_or_default()) + } + None => Ok(U256::ZERO), + } + } + + /// Get block hash by block number. + #[inline] + fn block_hash(&mut self, number: U256) -> Result { + Ok(self.inner.block_hash(number)) + } +} + +/// Represents an account within the state trie. +#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable, RlpDecodable)] +pub struct StateAccount { + /// The number of transactions sent from this account's address. + pub nonce: TxNumber, + /// The number of Wei owned by this account's address. + pub balance: U256, + /// The root of the account's storage trie. + pub storage_root: B256, + /// The hash of the EVM code of this account. + pub code_hash: B256, +} + +impl Default for StateAccount { + /// Provides default values for a [StateAccount]. + fn default() -> Self { + Self { + nonce: 0, + balance: U256::ZERO, + storage_root: EMPTY_ROOT_HASH, + code_hash: KECCAK_EMPTY, + } + } +} diff --git a/steel/tests/eth_call.rs b/steel/tests/eth_call.rs index c27fdda0..7679d45b 100644 --- a/steel/tests/eth_call.rs +++ b/steel/tests/eth_call.rs @@ -29,11 +29,7 @@ use alloy_primitives::{address, b256, uint, Address, Sealable, U256}; use alloy_sol_types::SolCall; use once_cell::sync::Lazy; use revm::primitives::SpecId; -use risc0_steel::{ - config::{ChainSpec, EIP1559_CONSTANTS_DEFAULT}, - ethereum::EthEvmEnv, - CallBuilder, Contract, EvmBlockHeader, -}; +use risc0_steel::{config::ChainSpec, ethereum::EthEvmEnv, CallBuilder, Contract, EvmBlockHeader}; use std::fmt::Debug; use test_log::test; @@ -96,7 +92,7 @@ alloy::sol!( ); static ANVIL_CHAIN_SPEC: Lazy = - Lazy::new(|| ChainSpec::new_single(31337, SpecId::CANCUN, EIP1559_CONSTANTS_DEFAULT)); + Lazy::new(|| ChainSpec::new_single(31337, SpecId::CANCUN)); type TestProvider = FillProvider< JoinFill>, @@ -117,7 +113,7 @@ async fn test_provider() -> TestProvider { provider } -#[tokio::test] +#[test(tokio::test)] async fn precompile() { let result = eth_call( test_provider().await, @@ -132,7 +128,7 @@ async fn precompile() { ); } -#[tokio::test] +#[test(tokio::test)] async fn nonexistent_account() { let result = eth_call( test_provider().await, @@ -144,7 +140,7 @@ async fn nonexistent_account() { assert_eq!(result.size, uint!(0_U256)); } -#[tokio::test] +#[test(tokio::test)] async fn eoa_account() { let result = eth_call( test_provider().await, @@ -156,7 +152,7 @@ async fn eoa_account() { assert_eq!(result.size, uint!(0_U256)); } -#[tokio::test] +#[tokio::test] // Anvil crashes, if logging is enabled async fn blockhash() { let provider = test_provider().await; let block_hash = provider.anvil_node_info().await.unwrap().current_block_hash; @@ -176,7 +172,7 @@ async fn blockhash() { assert_eq!(result.h, block_hash); } -#[tokio::test] +#[test(tokio::test)] async fn chainid() { let result = eth_call( test_provider().await, @@ -188,7 +184,7 @@ async fn chainid() { assert_eq!(result._0, uint!(31337_U256)); } -#[tokio::test] +#[test(tokio::test)] async fn origin() { let from = address!("0000000000000000000000000000000000000042"); let result = eth_call( @@ -201,7 +197,7 @@ async fn origin() { assert_eq!(result._0, from); } -#[tokio::test] +#[test(tokio::test)] async fn gasprice() { let gas_price = uint!(42_U256); let result = eth_call( From e4384582b80d83002363bf63ed217c4828321620 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Mon, 29 Jul 2024 19:01:21 +0200 Subject: [PATCH 07/30] add ERC20 tests back --- steel/src/host/db/trace.rs | 8 +- steel/tests/common/mod.rs | 109 ++++++++++++++++ steel/tests/erc20.rs | 95 ++++++++++++++ steel/tests/{eth_call.rs => individual.rs} | 143 +++++---------------- 4 files changed, 243 insertions(+), 112 deletions(-) create mode 100644 steel/tests/common/mod.rs create mode 100644 steel/tests/erc20.rs rename steel/tests/{eth_call.rs => individual.rs} (74%) diff --git a/steel/src/host/db/trace.rs b/steel/src/host/db/trace.rs index a4c3f2fc..79594a12 100644 --- a/steel/src/host/db/trace.rs +++ b/steel/src/host/db/trace.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use alloy_primitives::{Address, Bytes, B256, U256}; +use alloy_primitives::{Address, Bytes, StorageKey, B256, U256}; use revm::{ primitives::{AccountInfo, Bytecode, HashMap, HashSet}, Database, @@ -78,7 +78,11 @@ impl Database for TraceDb { } fn storage(&mut self, address: Address, index: U256) -> Result { - log::trace!("STORAGE: address={}, index={}", address, index); + log::trace!( + "STORAGE: address={}, index={}", + address, + StorageKey::from(index) + ); let storage = self.inner.storage(address, index)?; self.accounts.entry(address).or_default().insert(index); diff --git a/steel/tests/common/mod.rs b/steel/tests/common/mod.rs new file mode 100644 index 00000000..489e25c9 --- /dev/null +++ b/steel/tests/common/mod.rs @@ -0,0 +1,109 @@ +// 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 std::fmt::Debug; + +use alloy::{network::Ethereum, providers::Provider, transports::Transport}; +use alloy_primitives::{Address, Sealable, U256}; +use alloy_sol_types::SolCall; +use once_cell::sync::Lazy; +use revm::primitives::SpecId; +use risc0_steel::{ + config::ChainSpec, ethereum::EthEvmEnv, host::BlockNumberOrTag, CallBuilder, Contract, + EvmBlockHeader, +}; + +pub static ANVIL_CHAIN_SPEC: Lazy = + Lazy::new(|| ChainSpec::new_single(31337, SpecId::CANCUN)); + +/// Executes a new [SolCall] using steel. +pub async fn eth_call( + provider: P, + address: Address, + call: C, + options: CallOptions, +) -> C::Return +where + T: Transport + Clone, + P: Provider + 'static, + C: SolCall + Send + 'static, + C::Return: PartialEq + Debug + Send, +{ + let mut env = EthEvmEnv::from_provider(provider, BlockNumberOrTag::Latest) + .await + .unwrap() + .with_chain_spec(&ANVIL_CHAIN_SPEC); + let block_hash = env.header().hash_slow(); + let block_number = U256::from(env.header().number()); + + let preflight_result = { + let mut preflight = Contract::preflight(address, &mut env); + let call_builder = preflight.call_builder(&call); + options.apply(call_builder).call().await.unwrap() + }; + + let input = env.into_input().await.unwrap(); + let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); + + let commitment = env.block_commitment(); + assert_eq!(commitment.blockHash, block_hash, "invalid commitment"); + assert_eq!(commitment.blockNumber, block_number, "invalid commitment"); + + let result = { + let contract = Contract::new(address, &env); + options.apply(contract.call_builder(&call)).call() + }; + assert_eq!( + result, preflight_result, + "mismatch in preflight and execution" + ); + + result +} + +/// Simple struct to operate over different [CallBuilder] types. +#[derive(Debug, Default)] +pub struct CallOptions { + gas_price: Option, + from: Option
, +} + +#[allow(dead_code)] +impl CallOptions { + pub fn new() -> Self { + Self::default() + } + pub fn with_from(from: Address) -> Self { + Self { + from: Some(from), + ..Default::default() + } + } + pub fn with_gas_price(gas_price: U256) -> Self { + Self { + gas_price: Some(gas_price), + ..Default::default() + } + } + + fn apply(&self, mut builder: CallBuilder) -> CallBuilder { + if let Some(gas_price) = self.gas_price { + builder = builder.gas_price(gas_price); + } + if let Some(from) = self.from { + builder = builder.from(from); + } + builder + } +} diff --git a/steel/tests/erc20.rs b/steel/tests/erc20.rs new file mode 100644 index 00000000..5ac88947 --- /dev/null +++ b/steel/tests/erc20.rs @@ -0,0 +1,95 @@ +// 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. + +#![cfg(feature = "host")] + +use alloy::{ + providers::{ext::AnvilApi, ProviderBuilder}, + uint, +}; +use alloy_primitives::{address, Address}; +use common::CallOptions; +use test_log::test; + +mod common; + +const USDT_MAINNET_ADDRESS: Address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); +alloy::sol!( + #[sol(rpc, deployed_bytecode="0x606060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461019b5780630753c30c14610229578063095ea7b3146102625780630e136b19146102a45780630ecb93c0146102d157806318160ddd1461030a57806323b872dd1461033357806326976e3f1461039457806327e235e3146103e9578063313ce56714610436578063353907141461045f5780633eaaf86b146104885780633f4ba83a146104b157806359bf1abe146104c65780635c658165146105175780635c975abb1461058357806370a08231146105b05780638456cb59146105fd578063893d20e8146106125780638da5cb5b1461066757806395d89b41146106bc578063a9059cbb1461074a578063c0324c771461078c578063cc872b66146107b8578063db006a75146107db578063dd62ed3e146107fe578063dd644f721461086a578063e47d606014610893578063e4997dc5146108e4578063e5b5019a1461091d578063f2fde38b14610946578063f3bdc2281461097f575b600080fd5b34156101a657600080fd5b6101ae6109b8565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101ee5780820151818401526020810190506101d3565b50505050905090810190601f16801561021b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561023457600080fd5b610260600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a56565b005b341561026d57600080fd5b6102a2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b73565b005b34156102af57600080fd5b6102b7610cc1565b604051808215151515815260200191505060405180910390f35b34156102dc57600080fd5b610308600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cd4565b005b341561031557600080fd5b61031d610ded565b6040518082815260200191505060405180910390f35b341561033e57600080fd5b610392600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610ebd565b005b341561039f57600080fd5b6103a761109d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f457600080fd5b610420600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506110c3565b6040518082815260200191505060405180910390f35b341561044157600080fd5b6104496110db565b6040518082815260200191505060405180910390f35b341561046a57600080fd5b6104726110e1565b6040518082815260200191505060405180910390f35b341561049357600080fd5b61049b6110e7565b6040518082815260200191505060405180910390f35b34156104bc57600080fd5b6104c46110ed565b005b34156104d157600080fd5b6104fd600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506111ab565b604051808215151515815260200191505060405180910390f35b341561052257600080fd5b61056d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611201565b6040518082815260200191505060405180910390f35b341561058e57600080fd5b610596611226565b604051808215151515815260200191505060405180910390f35b34156105bb57600080fd5b6105e7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611239565b6040518082815260200191505060405180910390f35b341561060857600080fd5b610610611348565b005b341561061d57600080fd5b610625611408565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561067257600080fd5b61067a611431565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156106c757600080fd5b6106cf611456565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561070f5780820151818401526020810190506106f4565b50505050905090810190601f16801561073c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561075557600080fd5b61078a600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506114f4565b005b341561079757600080fd5b6107b6600480803590602001909190803590602001909190505061169e565b005b34156107c357600080fd5b6107d96004808035906020019091905050611783565b005b34156107e657600080fd5b6107fc600480803590602001909190505061197a565b005b341561080957600080fd5b610854600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611b0d565b6040518082815260200191505060405180910390f35b341561087557600080fd5b61087d611c52565b6040518082815260200191505060405180910390f35b341561089e57600080fd5b6108ca600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611c58565b604051808215151515815260200191505060405180910390f35b34156108ef57600080fd5b61091b600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611c78565b005b341561092857600080fd5b610930611d91565b6040518082815260200191505060405180910390f35b341561095157600080fd5b61097d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611db5565b005b341561098a57600080fd5b6109b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611e8a565b005b60078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a4e5780601f10610a2357610100808354040283529160200191610a4e565b820191906000526020600020905b815481529060010190602001808311610a3157829003601f168201915b505050505081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ab157600080fd5b6001600a60146101000a81548160ff02191690831515021790555080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcc358699805e9a8b7f77b522628c7cb9abd07d9efb86b6fb616af1609036a99e81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b604060048101600036905010151515610b8b57600080fd5b600a60149054906101000a900460ff1615610cb157600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663aee92d333385856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1515610c9857600080fd5b6102c65a03f11515610ca957600080fd5b505050610cbc565b610cbb838361200e565b5b505050565b600a60149054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d2f57600080fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f42e160154868087d6bfdc0ca23d96a1c1cfa32f1b72ba9ba27b69b98a0d819dc81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b6000600a60149054906101000a900460ff1615610eb457600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610e9257600080fd5b6102c65a03f11515610ea357600080fd5b505050604051805190509050610eba565b60015490505b90565b600060149054906101000a900460ff16151515610ed957600080fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610f3257600080fd5b600a60149054906101000a900460ff161561108c57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638b477adb338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050600060405180830381600087803b151561107357600080fd5b6102c65a03f1151561108457600080fd5b505050611098565b6110978383836121ab565b5b505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60026020528060005260406000206000915090505481565b60095481565b60045481565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561114857600080fd5b600060149054906101000a900460ff16151561116357600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6005602052816000526040600020602052806000526040600020600091509150505481565b600060149054906101000a900460ff1681565b6000600a60149054906101000a900460ff161561133757600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561131557600080fd5b6102c65a03f1151561132657600080fd5b505050604051805190509050611343565b61134082612652565b90505b919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113a357600080fd5b600060149054906101000a900460ff161515156113bf57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60088054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114ec5780601f106114c1576101008083540402835291602001916114ec565b820191906000526020600020905b8154815290600101906020018083116114cf57829003601f168201915b505050505081565b600060149054906101000a900460ff1615151561151057600080fd5b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561156957600080fd5b600a60149054906101000a900460ff161561168f57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e18980a3384846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b151561167657600080fd5b6102c65a03f1151561168757600080fd5b50505061169a565b611699828261269b565b5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116f957600080fd5b60148210151561170857600080fd5b60328110151561171757600080fd5b81600381905550611736600954600a0a82612a0390919063ffffffff16565b6004819055507fb044a1e409eac5c48e5af22d4af52670dd1a99059537a78b31b48c6500a6354e600354600454604051808381526020018281526020019250505060405180910390a15050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156117de57600080fd5b60015481600154011115156117f257600080fd5b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011115156118c257600080fd5b80600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550806001600082825401925050819055507fcb8241adb0c3fdb35b70c24ce35c5eb0c17af7431c99f827d44a445ca624176a816040518082815260200191505060405180910390a150565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156119d557600080fd5b80600154101515156119e657600080fd5b80600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515611a5557600080fd5b8060016000828254039250508190555080600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507f702d5967f45f6513a38ffc42d6ba9bf230bd40e8f53b16363c7eb4fd2deb9a44816040518082815260200191505060405180910390a150565b6000600a60149054906101000a900460ff1615611c3f57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b1515611c1d57600080fd5b6102c65a03f11515611c2e57600080fd5b505050604051805190509050611c4c565b611c498383612a3e565b90505b92915050565b60035481565b60066020528060005260406000206000915054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611cd357600080fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fd7e9ec6e6ecd65492dce6bf513cd6867560d49544421d0783ddf06e76c24470c81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611e1057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515611e8757806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611ee757600080fd5b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611f3f57600080fd5b611f4882611239565b90506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550806001600082825403925050819055507f61e6e66b0d6339b2980aecc6ccc0039736791f0ccde9ed512e789a7fbdd698c68282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15050565b60406004810160003690501015151561202657600080fd5b600082141580156120b457506000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b1515156120c057600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a3505050565b60008060006060600481016000369050101515156121c857600080fd5b600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054935061227061271061226260035488612a0390919063ffffffff16565b612ac590919063ffffffff16565b92506004548311156122825760045492505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84101561233e576122bd8585612ae090919063ffffffff16565b600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6123518386612ae090919063ffffffff16565b91506123a585600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ae090919063ffffffff16565b600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061243a82600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008311156125e4576124f983600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000806040600481016000369050101515156126b657600080fd5b6126df6127106126d160035487612a0390919063ffffffff16565b612ac590919063ffffffff16565b92506004548311156126f15760045492505b6127048385612ae090919063ffffffff16565b915061275884600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ae090919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506127ed82600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000831115612997576128ac83600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a35050505050565b6000806000841415612a185760009150612a37565b8284029050828482811515612a2957fe5b04141515612a3357fe5b8091505b5092915050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000808284811515612ad357fe5b0490508091505092915050565b6000828211151515612aee57fe5b818303905092915050565b6000808284019050838110151515612b0d57fe5b80915050929150505600a165627a7a72305820645ee12d73db47fd78ba77fa1f824c3c8f9184061b3b10386beb4dc9236abb280029")] + #[derive(Debug, PartialEq, Eq)] + interface IERC20 { + function balanceOf(address account) external view returns (uint256); + } +); + +#[test(tokio::test)] +async fn usdt_mainnet() { + let provider = ProviderBuilder::new() + .with_recommended_fillers() + .on_anvil_with_wallet_and_config(|anvil| anvil.args(["--hardfork", "cancun"])); + let node_info = provider.anvil_node_info().await.unwrap(); + log::info!("Anvil started: {:?}", node_info); + + // unfortunately, we do not know the private key of the USDT owner, so we have to mock it + provider + .anvil_set_code(USDT_MAINNET_ADDRESS, IERC20::DEPLOYED_BYTECODE.clone()) + .await + .unwrap(); + provider + .anvil_set_storage_at(USDT_MAINNET_ADDRESS, uint!(0x0a_U256), uint!(0_U256).into()) + .await + .unwrap(); + provider + .anvil_set_storage_at( + USDT_MAINNET_ADDRESS, + uint!(0xbe16d71963429204d70543701f859c43526c316ac005c10114f4694ca405f36_U256), + uint!(4000000052090000_U256).into(), + ) + .await + .unwrap(); + provider + .anvil_set_storage_at( + USDT_MAINNET_ADDRESS, + uint!(0x01c6cc8cc023571df8a8b69db8ed5e9b181bff6746532684be35308ac4e4a3e2_U256), + uint!(2640479813824172_U256).into(), + ) + .await + .unwrap(); + // mine a new block containing those state changes + provider.evm_mine(None).await.unwrap(); + + // query Binance 8 + let result = common::eth_call( + provider.clone(), + USDT_MAINNET_ADDRESS, + IERC20::balanceOfCall { + account: address!("F977814e90dA44bFA03b6295A0616a897441aceC"), + }, + CallOptions::new(), + ) + .await; + assert_eq!(result._0, uint!(4000000052090000_U256)); + + // query Arbitrum One: L1 Arb - Custom Gateway + let result = common::eth_call( + provider.clone(), + USDT_MAINNET_ADDRESS, + IERC20::balanceOfCall { + account: address!("cEe284F754E854890e311e3280b767F80797180d"), + }, + CallOptions::new(), + ) + .await; + assert_eq!(result._0, uint!(2640479813824172_U256)); +} diff --git a/steel/tests/eth_call.rs b/steel/tests/individual.rs similarity index 74% rename from steel/tests/eth_call.rs rename to steel/tests/individual.rs index 7679d45b..795a3682 100644 --- a/steel/tests/eth_call.rs +++ b/steel/tests/individual.rs @@ -14,6 +14,8 @@ #![cfg(feature = "host")] +use std::fmt::Debug; + use alloy::{ network::{Ethereum, EthereumWallet}, providers::{ @@ -22,17 +24,16 @@ use alloy::{ layers::AnvilProvider, ProviderBuilder, RootProvider, }, - rpc::types::BlockNumberOrTag, transports::http::{Client, Http}, + uint, }; -use alloy_primitives::{address, b256, uint, Address, Sealable, U256}; -use alloy_sol_types::SolCall; -use once_cell::sync::Lazy; -use revm::primitives::SpecId; -use risc0_steel::{config::ChainSpec, ethereum::EthEvmEnv, CallBuilder, Contract, EvmBlockHeader}; -use std::fmt::Debug; +use alloy_primitives::{address, b256, Address, U256}; +use common::{CallOptions, ANVIL_CHAIN_SPEC}; +use risc0_steel::{ethereum::EthEvmEnv, host::BlockNumberOrTag, Contract}; use test_log::test; +mod common; + const STEEL_TEST_CONTRACT: Address = address!("5fbdb2315678afecb367f032d93f642f64180aa3"); alloy::sol!( #[sol(rpc, bytecode="60e060405234801561000f575f80fd5b505f60405161001d906100c4565b908152602001604051809103905ff08015801561003c573d5f803e3d5ffd5b506001600160a01b0316608052604051602a90610058906100c4565b908152602001604051809103905ff080158015610077573d5f803e3d5ffd5b506001600160a01b031660a052604051602a90610093906100c4565b908152602001604051809103905ff0801580156100b2573d5f803e3d5ffd5b506001600160a01b031660c0526100d0565b60c98061041e83390190565b60805160a05160c0516103256100f95f395f60de01525f61015e01525f6101de01526103255ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063445bda4311610058578063445bda43146100ba5780637d732b5f146100c25780639f6f32aa146100c8578063ab8fd80c146100d0575f80fd5b80630692d13c146100895780632e8bde391461009f57806330e49663146100ad57806341317185146100b3575b5f80fd5b5f3b5b6040519081526020015b60405180910390f35b604051328152602001610096565b3a61008c565b443b61008c565b61008c6100db565b4661008c565b61008c610275565b4360fe19014061008c565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610138573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061015c91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101dc91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610238573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025c91906102b3565b61026691906102ca565b61027091906102ca565b905090565b6040515f906002906020818481855afa158015610294573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061027091905b5f602082840312156102c3575f80fd5b5051919050565b808201808211156102e957634e487b7160e01b5f52601160045260245ffd5b9291505056fea264697066735822122017cd88097c7ec4827d02d5b993a5a0735d07aaa06059c5e6c23f0ee89f66264b64736f6c634300081900336080604052348015600e575f80fd5b5060405160c938038060c9833981016040819052602991602f565b5f556045565b5f60208284031215603e575f80fd5b5051919050565b60798060505f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3fea2646970667358221220fb757efaa1a5b5711adfcca5d02365b7e8408bfa6624b2b9bf549a8fa2f4f1fc64736f6c63430008190033")] @@ -91,9 +92,6 @@ alloy::sol!( } ); -static ANVIL_CHAIN_SPEC: Lazy = - Lazy::new(|| ChainSpec::new_single(31337, SpecId::CANCUN)); - type TestProvider = FillProvider< JoinFill>, AnvilProvider>, Http>, @@ -101,6 +99,7 @@ type TestProvider = FillProvider< Ethereum, >; +/// Returns an Anvil provider with the deployed [SteelTest] contract. async fn test_provider() -> TestProvider { let provider = ProviderBuilder::new() .with_recommended_fillers() @@ -115,11 +114,11 @@ async fn test_provider() -> TestProvider { #[test(tokio::test)] async fn precompile() { - let result = eth_call( + let result = common::eth_call( test_provider().await, - SteelTest::testPrecompileCall {}, STEEL_TEST_CONTRACT, - CallBuilderOverrides::empty(), + SteelTest::testPrecompileCall {}, + CallOptions::new(), ) .await; assert_eq!( @@ -130,11 +129,11 @@ async fn precompile() { #[test(tokio::test)] async fn nonexistent_account() { - let result = eth_call( + let result = common::eth_call( test_provider().await, - SteelTest::testNonexistentAccountCall {}, STEEL_TEST_CONTRACT, - CallBuilderOverrides::empty(), + SteelTest::testNonexistentAccountCall {}, + CallOptions::new(), ) .await; assert_eq!(result.size, uint!(0_U256)); @@ -142,11 +141,11 @@ async fn nonexistent_account() { #[test(tokio::test)] async fn eoa_account() { - let result = eth_call( + let result = common::eth_call( test_provider().await, - SteelTest::testEoaAccountCall {}, STEEL_TEST_CONTRACT, - CallBuilderOverrides::empty(), + SteelTest::testEoaAccountCall {}, + CallOptions::new(), ) .await; assert_eq!(result.size, uint!(0_U256)); @@ -162,11 +161,11 @@ async fn blockhash() { .await .unwrap(); - let result = eth_call( + let result = common::eth_call( provider, - SteelTest::testBlockhashCall {}, STEEL_TEST_CONTRACT, - CallBuilderOverrides::empty(), + SteelTest::testBlockhashCall {}, + CallOptions::new(), ) .await; assert_eq!(result.h, block_hash); @@ -174,11 +173,11 @@ async fn blockhash() { #[test(tokio::test)] async fn chainid() { - let result = eth_call( + let result = common::eth_call( test_provider().await, - SteelTest::testChainidCall {}, STEEL_TEST_CONTRACT, - CallBuilderOverrides::empty(), + SteelTest::testChainidCall {}, + CallOptions::new(), ) .await; assert_eq!(result._0, uint!(31337_U256)); @@ -187,11 +186,11 @@ async fn chainid() { #[test(tokio::test)] async fn origin() { let from = address!("0000000000000000000000000000000000000042"); - let result = eth_call( + let result = common::eth_call( test_provider().await, - SteelTest::testOriginCall {}, STEEL_TEST_CONTRACT, - CallBuilderOverrides::from(from), + SteelTest::testOriginCall {}, + CallOptions::with_from(from), ) .await; assert_eq!(result._0, from); @@ -200,11 +199,11 @@ async fn origin() { #[test(tokio::test)] async fn gasprice() { let gas_price = uint!(42_U256); - let result = eth_call( + let result = common::eth_call( test_provider().await, - SteelTest::testGaspriceCall {}, STEEL_TEST_CONTRACT, - CallBuilderOverrides::gas_price(gas_price), + SteelTest::testGaspriceCall {}, + CallOptions::with_gas_price(gas_price), ) .await; assert_eq!(result._0, gas_price); @@ -212,11 +211,11 @@ async fn gasprice() { #[test(tokio::test)] async fn multi_contract_calls() { - let result = eth_call( + let result = common::eth_call( test_provider().await, - SteelTest::testMuliContractCallsCall {}, STEEL_TEST_CONTRACT, - CallBuilderOverrides::empty(), + SteelTest::testMuliContractCallsCall {}, + CallOptions::new(), ) .await; assert_eq!(result._0, uint!(84_U256)); @@ -235,79 +234,3 @@ async fn call_eoa() { .await .expect_err("calling an EOA should fail"); } - -/// Simple struct to operate over different [CallBuilder] types. -#[derive(Debug, Default)] -struct CallBuilderOverrides { - gas_price: Option, - from: Option
, -} - -impl CallBuilderOverrides { - fn empty() -> Self { - CallBuilderOverrides::default() - } - fn from(from: Address) -> Self { - Self { - from: Some(from), - ..Default::default() - } - } - fn gas_price(gas_price: U256) -> Self { - Self { - gas_price: Some(gas_price), - ..Default::default() - } - } - - fn set(&self, mut builder: CallBuilder) -> CallBuilder { - if let Some(gas_price) = self.gas_price { - builder = builder.gas_price(gas_price); - } - if let Some(from) = self.from { - builder = builder.from(from); - } - builder - } -} - -async fn eth_call( - provider: TestProvider, - call: C, - address: Address, - call_overrides: CallBuilderOverrides, -) -> C::Return -where - C: SolCall + Send + 'static, - ::Return: PartialEq + Debug + Send, -{ - let mut env = EthEvmEnv::from_provider(provider, BlockNumberOrTag::Latest) - .await - .unwrap() - .with_chain_spec(&ANVIL_CHAIN_SPEC); - let block_hash = env.header().hash_slow(); - let block_number = U256::from(env.header().number()); - - let mut preflight = Contract::preflight(address, &mut env); - let preflight_result = call_overrides - .set(preflight.call_builder(&call)) - .call() - .await - .unwrap(); - - let input = env.into_input().await.unwrap(); - - let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); - let commitment = env.block_commitment(); - assert_eq!(commitment.blockHash, block_hash, "invalid commitment"); - assert_eq!(commitment.blockNumber, block_number, "invalid commitment"); - - let contract = Contract::new(address, &env); - let result = call_overrides.set(contract.call_builder(&call)).call(); - assert_eq!( - result, preflight_result, - "mismatch in preflight and execution" - ); - - result -} From 4c66d065d07ded4515d0eafaaa88b43721c1693f Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 30 Jul 2024 13:30:41 +0200 Subject: [PATCH 08/30] add more RPC checks --- steel/src/host/mod.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/steel/src/host/mod.rs b/steel/src/host/mod.rs index e5261dc0..d593983e 100644 --- a/steel/src/host/mod.rs +++ b/steel/src/host/mod.rs @@ -15,7 +15,9 @@ //! Functionality that is only needed for the host and not the guest. use std::fmt::Display; -use crate::{ethereum::EthEvmEnv, EvmBlockHeader, EvmEnv, EvmInput, MerkleTrie}; +use crate::{ + ethereum::EthEvmEnv, state::StateAccount, EvmBlockHeader, EvmEnv, EvmInput, MerkleTrie, +}; use alloy::{ network::{Ethereum, Network}, providers::{Provider, ProviderBuilder, RootProvider}, @@ -25,7 +27,7 @@ use alloy::{ Transport, }, }; -use alloy_primitives::StorageKey; +use alloy_primitives::{keccak256, StorageKey}; use anyhow::{anyhow, ensure, Context}; use db::{AlloyDb, TraceDb}; use log::debug; @@ -105,12 +107,12 @@ where proofs.push(proof); } - // build the sparse MPT for the state and verify against the header + // build the sparse MPT for the state and verify it against the header let state_nodes = proofs.iter().flat_map(|p| p.account_proof.iter()); let state_trie = MerkleTrie::from_rlp_nodes(state_nodes).context("accountProof invalid")?; ensure!( self.header.state_root() == &state_trie.hash_slow(), - "root of the state trie does not match the header" + "accountProof root does not match header's stateRoot" ); // build the sparse MPT for account storages and filter duplicates @@ -121,10 +123,23 @@ where continue; } + // build the sparse MPT for that account's storage by iterating over all storage proofs let storage_nodes = proof.storage_proof.iter().flat_map(|p| p.proof.iter()); let storage_trie = MerkleTrie::from_rlp_nodes(storage_nodes).context("storageProof invalid")?; - storage_tries.insert(storage_trie.hash_slow(), storage_trie); + let storage_root_hash = storage_trie.hash_slow(); + // verify it against the state trie + let account: StateAccount = state_trie + .get_rlp(keccak256(proof.address)) + .with_context(|| format!("invalid RLP value in state trie for {}", proof.address))? + .unwrap_or_default(); + ensure!( + account.storage_root == storage_root_hash, + "storageProof of {} does not match storageRoot in the state", + proof.address + ); + + storage_tries.insert(storage_root_hash, storage_trie); } let storage_tries: Vec<_> = storage_tries.into_values().collect(); From 1b0109b2424412b5d021efc553244bcb79d211d4 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 30 Jul 2024 13:31:40 +0200 Subject: [PATCH 09/30] minor test cleanups --- steel/tests/common/mod.rs | 18 ++++++++++++++---- steel/tests/erc20.rs | 5 ++--- steel/tests/{individual.rs => steel.rs} | 0 3 files changed, 16 insertions(+), 7 deletions(-) rename steel/tests/{individual.rs => steel.rs} (100%) diff --git a/steel/tests/common/mod.rs b/steel/tests/common/mod.rs index 489e25c9..ce4c189e 100644 --- a/steel/tests/common/mod.rs +++ b/steel/tests/common/mod.rs @@ -75,8 +75,9 @@ where /// Simple struct to operate over different [CallBuilder] types. #[derive(Debug, Default)] pub struct CallOptions { - gas_price: Option, from: Option
, + gas: Option, + gas_price: Option, } #[allow(dead_code)] @@ -90,6 +91,12 @@ impl CallOptions { ..Default::default() } } + pub fn with_gas(gas: u64) -> Self { + Self { + gas: Some(gas), + ..Default::default() + } + } pub fn with_gas_price(gas_price: U256) -> Self { Self { gas_price: Some(gas_price), @@ -98,12 +105,15 @@ impl CallOptions { } fn apply(&self, mut builder: CallBuilder) -> CallBuilder { - if let Some(gas_price) = self.gas_price { - builder = builder.gas_price(gas_price); - } if let Some(from) = self.from { builder = builder.from(from); } + if let Some(gas) = self.gas { + builder = builder.gas(gas); + } + if let Some(gas_price) = self.gas_price { + builder = builder.gas_price(gas_price); + } builder } } diff --git a/steel/tests/erc20.rs b/steel/tests/erc20.rs index 5ac88947..1357ffad 100644 --- a/steel/tests/erc20.rs +++ b/steel/tests/erc20.rs @@ -35,9 +35,8 @@ alloy::sol!( #[test(tokio::test)] async fn usdt_mainnet() { - let provider = ProviderBuilder::new() - .with_recommended_fillers() - .on_anvil_with_wallet_and_config(|anvil| anvil.args(["--hardfork", "cancun"])); + let provider = + ProviderBuilder::new().on_anvil_with_config(|anvil| anvil.args(["--hardfork", "cancun"])); let node_info = provider.anvil_node_info().await.unwrap(); log::info!("Anvil started: {:?}", node_info); diff --git a/steel/tests/individual.rs b/steel/tests/steel.rs similarity index 100% rename from steel/tests/individual.rs rename to steel/tests/steel.rs From ce727d0ab7d109002b48d942fadd86fc41a0a85a Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 30 Jul 2024 13:32:11 +0200 Subject: [PATCH 10/30] remove unused dependencies --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a50c3510..f6312013 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,4 +46,3 @@ thiserror = "1.0" tokio = { version = "1.35" } tracing-subscriber = { version = "0.3", features = ["env-filter"] } url = { version = "2.5" } -wiremock = { version = "0.6" } From 4de4a97062760cdea048f66a438d485a3239cc15 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 30 Jul 2024 19:50:56 +0200 Subject: [PATCH 11/30] fix examples --- examples/erc20-counter/apps/src/bin/publisher.rs | 4 +++- examples/erc20-counter/methods/guest/src/bin/balance_of.rs | 5 ++++- examples/erc20/host/src/main.rs | 4 +++- examples/erc20/methods/guest/src/main.rs | 5 ++++- examples/token-stats/host/src/main.rs | 4 +++- examples/token-stats/methods/guest/src/main.rs | 5 ++++- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/examples/erc20-counter/apps/src/bin/publisher.rs b/examples/erc20-counter/apps/src/bin/publisher.rs index 42aee5dd..25298452 100644 --- a/examples/erc20-counter/apps/src/bin/publisher.rs +++ b/examples/erc20-counter/apps/src/bin/publisher.rs @@ -28,7 +28,9 @@ use clap::Parser; use erc20_counter_methods::BALANCE_OF_ELF; use risc0_ethereum_contracts::groth16::encode; use risc0_steel::{ - config::ETH_SEPOLIA_CHAIN_SPEC, ethereum::EthEvmEnv, host::BlockNumberOrTag, Contract, + ethereum::{EthEvmEnv, ETH_SEPOLIA_CHAIN_SPEC}, + host::BlockNumberOrTag, + Contract, }; use risc0_zkvm::{default_prover, ExecutorEnv, ProverOpts, VerifierContext}; use tokio::task; diff --git a/examples/erc20-counter/methods/guest/src/bin/balance_of.rs b/examples/erc20-counter/methods/guest/src/bin/balance_of.rs index 58e16920..747f33b0 100644 --- a/examples/erc20-counter/methods/guest/src/bin/balance_of.rs +++ b/examples/erc20-counter/methods/guest/src/bin/balance_of.rs @@ -17,7 +17,10 @@ use alloy_primitives::{Address, U256}; use alloy_sol_types::{sol, SolValue}; -use risc0_steel::{config::ETH_SEPOLIA_CHAIN_SPEC, ethereum::EthEvmInput, Contract, SolCommitment}; +use risc0_steel::{ + ethereum::{EthEvmInput, ETH_SEPOLIA_CHAIN_SPEC}, + Contract, SolCommitment, +}; use risc0_zkvm::guest::env; risc0_zkvm::guest::entry!(main); diff --git a/examples/erc20/host/src/main.rs b/examples/erc20/host/src/main.rs index c36418b7..39aeda24 100644 --- a/examples/erc20/host/src/main.rs +++ b/examples/erc20/host/src/main.rs @@ -18,7 +18,9 @@ use anyhow::{Context, Result}; use clap::Parser; use erc20_methods::ERC20_GUEST_ELF; use risc0_steel::{ - config::ETH_SEPOLIA_CHAIN_SPEC, ethereum::EthEvmEnv, host::BlockNumberOrTag, Contract, + ethereum::{EthEvmEnv, ETH_SEPOLIA_CHAIN_SPEC}, + host::BlockNumberOrTag, + Contract, }; use risc0_zkvm::{default_executor, ExecutorEnv}; use tracing_subscriber::EnvFilter; diff --git a/examples/erc20/methods/guest/src/main.rs b/examples/erc20/methods/guest/src/main.rs index d63b4317..99b6d141 100644 --- a/examples/erc20/methods/guest/src/main.rs +++ b/examples/erc20/methods/guest/src/main.rs @@ -17,7 +17,10 @@ use alloy_primitives::{address, Address}; use alloy_sol_types::{sol, SolValue}; -use risc0_steel::{config::ETH_SEPOLIA_CHAIN_SPEC, ethereum::EthEvmInput, Contract}; +use risc0_steel::{ + ethereum::{EthEvmInput, ETH_SEPOLIA_CHAIN_SPEC}, + Contract, +}; use risc0_zkvm::guest::env; risc0_zkvm::guest::entry!(main); diff --git a/examples/token-stats/host/src/main.rs b/examples/token-stats/host/src/main.rs index be30750e..602d41e1 100644 --- a/examples/token-stats/host/src/main.rs +++ b/examples/token-stats/host/src/main.rs @@ -18,7 +18,9 @@ use clap::Parser; use core::{APRCommitment, CometMainInterface, CONTRACT}; use methods::TOKEN_STATS_ELF; use risc0_steel::{ - config::ETH_MAINNET_CHAIN_SPEC, ethereum::EthEvmEnv, host::BlockNumberOrTag, Contract, + ethereum::{EthEvmEnv, ETH_MAINNET_CHAIN_SPEC}, + host::BlockNumberOrTag, + Contract, }; use risc0_zkvm::{default_executor, ExecutorEnv}; use tracing_subscriber::EnvFilter; diff --git a/examples/token-stats/methods/guest/src/main.rs b/examples/token-stats/methods/guest/src/main.rs index ba8a7ce8..bbe876d7 100644 --- a/examples/token-stats/methods/guest/src/main.rs +++ b/examples/token-stats/methods/guest/src/main.rs @@ -14,7 +14,10 @@ use alloy_sol_types::SolValue; use core::{APRCommitment, CometMainInterface, CONTRACT}; -use risc0_steel::{config::ETH_MAINNET_CHAIN_SPEC, ethereum::EthEvmInput, Contract}; +use risc0_steel::{ + ethereum::{EthEvmInput, ETH_MAINNET_CHAIN_SPEC}, + Contract, +}; use risc0_zkvm::guest::env; const SECONDS_PER_YEAR: u64 = 60 * 60 * 24 * 365; From 609fc391b581eee03ea4401f7d3830d9fff4fd5e Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 30 Jul 2024 19:56:13 +0200 Subject: [PATCH 12/30] Paris oldest supported version --- steel/src/ethereum.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/steel/src/ethereum.rs b/steel/src/ethereum.rs index 1d9e3e7f..2dc7bfd8 100644 --- a/steel/src/ethereum.rs +++ b/steel/src/ethereum.rs @@ -29,7 +29,6 @@ pub static ETH_SEPOLIA_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { chain_id: 11155111, max_spec_id: SpecId::CANCUN, hard_forks: BTreeMap::from([ - (SpecId::LONDON, ForkCondition::Block(0)), (SpecId::MERGE, ForkCondition::Block(1735371)), (SpecId::SHANGHAI, ForkCondition::Timestamp(1677557088)), (SpecId::CANCUN, ForkCondition::Timestamp(1706655072)), From fa7e48a7d7a5ce2121e96e33d8017d5a5b646e1d Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 31 Jul 2024 10:20:58 +0200 Subject: [PATCH 13/30] fix steel tests --- steel/testdata/rpc_cache.json | 1250 --------------------------------- steel/tests/steel.rs | 6 +- 2 files changed, 3 insertions(+), 1253 deletions(-) delete mode 100644 steel/testdata/rpc_cache.json diff --git a/steel/testdata/rpc_cache.json b/steel/testdata/rpc_cache.json deleted file mode 100644 index 148fd5c7..00000000 --- a/steel/testdata/rpc_cache.json +++ /dev/null @@ -1,1250 +0,0 @@ -{ - "partial_blocks": [ - [ - { - "block_no": 5702741 - }, - { - "parent_hash": "0x977c30034d1e773ff880fee14a2e7c97972426b337e68db83c03263689cb30f3", - "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "beneficiary": "0x3826539cbd8d68dcf119e80b994557b4278cec9f", - "state_root": "0xecfcc84b0709daea00a7480076073bd6d716633276931424e9a379d41a78a1d5", - "transactions_root": "0x740f0e2fa99f59bb6cfbca3b59f06ff4f6ee0f303cdede90ab8a1c9651decb31", - "receipts_root": "0xf45f876553500ee11092eb62fff2a3d1d109e75d3b6e83a6cd0905d1403b89b9", - "logs_bloom": "0xa80e024ac50a424221d0822a35dc022ea201f400108a000802915049c31bc01021000a15680112046eb081200f0cc4d20a2118c40a2020041645d915b1b504281074a0080c65256a41a0001a116d9803148b20921b444808600a401380a068e0080420c66230471320950c0510520b91807801c5011004d0c242a01c62088a406f4a00e4221009662f0001a04c1021a304718a892808451861c552109578420067686a4240220bdac501b2912c08510a05d10a80014041e00ce6610e02946800c917586b84401a20413307848a3624011e20003491400460c31091060063e82214101201ec870858000230003494011000109040493e20465a4030a083d95803", - "difficulty": "0x0", - "number": 5702741, - "gas_limit": 30000000, - "gas_used": 15597620, - "timestamp": 1713175236, - "extra_data": "0x", - "mix_hash": "0x8cb34d0c1ef320ae4a9f65092f7779c9e326d09722225b3541bf8b7af2d955fc", - "nonce": "0x0000000000000000", - "base_fee_per_gas": "0x3d07820b", - "withdrawals_root": "0x699b371f14ac5647e2bc4a9a03c9067187e3bad70be6eba4d76a8164b1c1905c", - "blob_gas_used": 262144, - "excess_blob_gas": 83230720, - "parent_beacon_block_root": "0x23f380f7992f5c64dbfc68b5a2bfa904fe47d56b56fba256b127448f4766084c" - } - ], - [ - { - "block_no": 5702742 - }, - { - "parent_hash": "0x7703fe4a3d6031a579d52ce9e493e7907d376cfc3b41f9bc7710b0dae8c67f68", - "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "beneficiary": "0xff58d746a67c2e42bcc07d6b3f58406e8837e883", - "state_root": "0x90adfc0b42bf187912cac64b991b7a5c0609053ce43e9b3453b9967cd3b26011", - "transactions_root": "0x92fae0f834ab74b2767e8acf6952a499ba7cc52fd50c04e88cbb1b341fd59508", - "receipts_root": "0x1689e7e464f842a92a557afcf2063be805a397ee53e41d16b3303c9eb44b593e", - "logs_bloom": "0x6900050a1c4140200710823308981068004344028000442442901008848a8058100104454800000008300188000c4086500008804b24910607f051001234200100449812022f0b084112409a0500c0040421221218076168300300408080caa32b108082060340430884104401080d82540848c2d22004054088a01c0508004022a45904c0105c2c64201300342a43211c074a6140028cf07171b09805403280222a0884b0002906608100040004028c3040021801008000c0a108aa12806089e100b0620a242300804105118b1a44460c206200904848004290850409002221101230c84254000822043200244d010414004b1008a100c348125aa008230004", - "difficulty": "0x0", - "number": 5702742, - "gas_limit": 30000000, - "gas_used": 16478701, - "timestamp": 1713175248, - "extra_data": "0x476f65726c69205365706f6c69612d4265706f6c696120513966", - "mix_hash": "0x9915d504a10c513da03d54fac9546ca7c1375e3ed3e09f3f0c23e550be3f596b", - "nonce": "0x0000000000000000", - "base_fee_per_gas": "0x3d5550ce", - "withdrawals_root": "0x3fb533ba8dff76e3bd3b27492252ef8f8308f1857d0320e082d3854e03bc0efb", - "blob_gas_used": 262144, - "excess_blob_gas": 83099648, - "parent_beacon_block_root": "0xb6860316e19573a9a47a4887a54c181f19b8c35605bbe3e90acc70a885118a12" - } - ], - [ - { - "block_no": 5702743 - }, - { - "parent_hash": "0x42973629a9c092ed0688547fdf95f029e3cc5066a0501f2f64db474682d7692f", - "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "beneficiary": "0x455e5aa18469bc6ccef49594645666c587a3a71b", - "state_root": "0x5b0175eb7c1e10cbc00ac4e75586526760ea6b222d2cc1be6fdb83c518a69936", - "transactions_root": "0xf6822df5304f2c267d83a81c53bfb62d150e771223415f943e34ca6fc921c22b", - "receipts_root": "0xe969c3cf27b0833c7159e3796176943ad98236d5c5070b852c25f9d75e5edcb3", - "logs_bloom": "0x8900c88a040a68c021108273b95142283053010024000084828013c440c8005819848060102004204020018010048b9208084e200aa0481406981800823c28014024880900252b185282101a0400c295cc21829202926009606a206080c4d2820a0220a02603444b4004156580b80982549801e582000c150100b038200a024062048140bf024c20e800030214604f940e084a4b0024c460b009b05004442008222cca2a802288064805818c0105528c42540080204280885ce948031280020799009063028003a8c00025078806d10002244900c8c980408210900c09b07080149e224c40061802021ba02064440104d40300004ca0824b42029880c9294104", - "difficulty": "0x0", - "number": 5702743, - "gas_limit": 30000000, - "gas_used": 11186926, - "timestamp": 1713175260, - "extra_data": "0xd883010d0e846765746888676f312e32312e37856c696e7578", - "mix_hash": "0x0c6b2728c387f3bda543bbc8db0214b86e9eeca256d0680ede6d995570998e36", - "nonce": "0x0000000000000000", - "base_fee_per_gas": "0x3e16cb94", - "withdrawals_root": "0xb18a9f78fd77aace088c2e1f519eb60dcb1d5f9a653dfefa0ec45234c6e20c46", - "blob_gas_used": 262144, - "excess_blob_gas": 82968576, - "parent_beacon_block_root": "0xe3d95ea165e4ef5ef8c7108c6e822cfb438bb9451f0d0baccccd3f8d6c37a1df" - } - ], - [ - { - "block_no": 19493153 - }, - { - "parent_hash": "0x60bbba1163ed4a5e00294a62bf8347b61177eb862344a38441c1a2b663f28c6e", - "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "beneficiary": "0x388c818ca8b9251b393131c08a736a67ccb19297", - "state_root": "0xa05c68711ea0a14cfe4f326221a9debb632bf85699e4295d9fdac7b668e15e7c", - "transactions_root": "0x2a6273be38e1c8917d63b4db9fd79fcb227459f51a9940c7d62975775c00e3ef", - "receipts_root": "0xb067f5748e021f07ad95f47da2785b73f8e7f670a025c3f803f62652c5bcce67", - "logs_bloom": "0x59eb645267c97d5510fc16f2848d102531cb8029ec66008ad099a9a7573f4e9d78f779cac0f9aa954f5f7b42e0db0b677b2bc00dfb6f68ed3e1c09a001ea6ea84512d5dc64e08ce9c84b683b9c434ae7791712c216e029143cc21c52cc627aecdeca4d8ce244edb9051d9d7468182c7306b284e940584514b65d2a966d0ab88efc8bbe7681e19df4014d9349170e877eb403d671dbb91e5e7e2162fa741f203a77bf597b5381a21e5a1771e0e9b36dc31d59f49ada3249882abc047294abc874d5f236bf8ef86e4f4c609e0609f990c6f8e01ab2d27bd8fd039472cbcb2b61cb1dbd72553db14d3ad4b535a970e7d30486a3d0617b2835d8209fa9b0d818f747", - "difficulty": "0x0", - "number": 19493153, - "gas_limit": 29970705, - "gas_used": 14726603, - "timestamp": 1711146719, - "extra_data": "0x546974616e2028746974616e6275696c6465722e78797a29", - "mix_hash": "0x3bfd2dc3f7fdd6a434d1848e46f7b55091fc15f583b15b573fd78d08ba5ba62d", - "nonce": "0x0000000000000000", - "base_fee_per_gas": "0x500385d77", - "withdrawals_root": "0xd6ff600419d5bda1803316212a0a523a0d5dfb17f93a7ad7de3ad9e5d93d608e", - "blob_gas_used": 0, - "excess_blob_gas": 0, - "parent_beacon_block_root": "0x47a9ffb86b1d46b39c1d7d5ad7f3705b6abfc8d57f73f1e5a7e195f25d6960bf" - } - ] - ], - "proofs": [ - [ - { - "block_no": 5702743, - "address": "0x0000000000000000000000000000000000000000", - "storage_keys": [] - }, - { - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x1830e66656d6c3870771", - "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "nonce": 0, - "storage_hash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a0826cd2334d1b5982bb3db5128c7d7a2f3a9c72a007d3d730b9c5b235de45e3bda06ff728d9c6bc6ed19233baba82a385afe4b301557b79170f0afbe60ad7327854a04af2e2d23a59a7a98c46631e0f5bf395d505e521020c4481285a6e4cced510e4a0b586f1676383d62ec99886ea5f4fab14acc6b1c56c8c7d16c2530817039d1a6ca022284bfab7b5968e861418fa5783d58afe3cc3ca2bd2c1635b5eb8b2f00a78a6a0e2766f88fb084cfc410e0a8e95c4adf042903904b0a585bf2be03b0202bd1955a07ea5ca40594cc7899d4d8c98665fd98b7e74f814e199a339f848df0ef0bf2907a0d06744eb6b1648ad4276fc1f1534615ead34f044d5f197e0876e0b57d91bf454a0d83247b6c859de0e881c08bc9ecb182219ba90d16dfd8c2f731d35b44e08e8f0a0f5204869c0f85e2278c617657fb31a8e0683d8f3f402c4ed4f344edaf4e6ffa0a019788e655b0533fb22b7871d33985dd01fe27b117a18b6f79e09a29195657dd2a0f8c16586725526ab0416e49e050d513a66338660290b8dfe0bb9237c698a7851a0b50b7032c6619f1557c9646d431f65a2404a1d909910268b4efd5b30400997c8a0adab837a0d3984b0dcdfcbf31b856df1cc2ed978dd8717f007c8b1154287d916a048ac09d06852c82d52ed06124228782f0dc011cffef354a10f3ebfa6627f167aa0d6c6480def7b086a5a7e42f67cb033fd98ba59990a577581cdb1f27e23ff7d1e80", - "0xf90211a038cf0040e608a3eaca581795528dee879008496134919de7748743ead04232f4a01c770293af22ca80c62ab694333cfe8bfad978908bb18b0473b2b1c91ce29c90a0db9c08056f4677b539a6dce73a04241ce68f8f79f26a99bc935b553b7d3f158ca0ed9d1552064d11f2542a8e884acbf272439a20776d868d1d587dfd4e58b7d096a0a306a642c17a8987ec0ce73a83d1e79b4fd5d513b4ca90b8b70bcc96adbeab2ca0019889fe9509a52cc6c57ad9b627769a0e5d0e975674a086610c7648c0a7d2daa0c0bde0b2ffdff64ff7b0a9fb364ed236fa23b174daf4712b60594a8f43e82cefa0b8ef39c2829b5091d1f538ba3a065f25f8cb32378c7617ccea024b7c001eff4ea0b8b2f06e43dba44b1a83408894bca779b13642821bc7b8eea4542bf7fd08ad7fa0810b116ee6f6e2b152338b917550832f4ee6c9258fd7b94406adb545a25ccaa6a0012760ea89336ac02e07947f8729ae47c636e1a2d01a409cd87f36ba781664b0a034c4414bca2baf9d2ed46241b4aef8c7a19766ae7ea0011af77bf56103d21920a04f50af185480ab410ff907f52da3ec4416d1bb00c36e7e86bb82f1dff070588ea00143f885b2c89580b6389a236fca819ad3673b719c9126e86b97c64494ad4cd3a0b8308384ec62647d09ffbabc1e91e9fcb3202bf68e76b4ad22927a6b7a3b9a21a0472fc9826a62bf6f9e0270ab38071d8ed03b64d757ab7fe204a0c7c6aad4deaf80", - "0xf90211a0206962283f65b42132116ad644cf6a39884f957f06eca2da7ae364c8d8ff211aa0ba03f89a92df4aaa41c2b83ae9c36280e3adc60692aa6e817dfb9cf8d90cb4bda0bc09ac92fcf00688d036165282798557871b4299549e159a25d481980b50ac8ba071512259c8424b4c523224f49f6631952c68f44a4a12c884fe05274c9868b083a0220188899bbfd2c6117eceef1d57ad541053d7e1fc968c28ca402f90659b460da05c88d6e27289d30bf0729664218ee48bbb2ed277af0762c73952b6fba3f13c9fa0370cc6719788789ca0a79dc2bf79f41adbdfb359de070b3fed02660738aa8e27a0a8b14c9c0c5feee29d468a79194ea29c140ebcf618209240c705e1656f84beaba0fe0e3b45f74e698dd0282e14befa67be6907b50651cf33e5c0e2fab841f56251a0562cec6f55170c63886cd71a9f238a3feb0c6292b8757b1ec6697bccc827c7b2a0bda3aea6c305dc421bdded2deb8e49d6c8636212f15d177bfaff6d3bfab9bd5ba04f8841a18cc459d1240d012f20c7053ccdf4fd7c88c77e1cb838e33499d6a19fa062410a0dc2893a3c7dce42d584a61986924469b357f166e726854c02416f67aba041af8cf49989895f49e1dfcbd370561650d03427a8c73d37acfa1a375b2307d5a01d4c297e4f2afcd0de118e0913321b2041b67bd17eb80dfd6028056c73256124a0fdf6d2d72eff0ca7e9340b1b28136ec3c0551c7cf294bc3295ca2be60146009c80", - "0xf90211a0769fd7544111f4f937556323489c5609f989cbeb1de438e5a95cf52cb080778fa0c9f58903daca0a0f19571e50104fd5f3aa9152e4b73b88fdab04f8b8bd0bfa0ca021f90eab6f5a6d3ad11bd53348cfdeb4e12a0178cfba5355462a4e27cee3a581a0350854f1c5a932468d3bbc93b1244a0212b57b53d90868010db5012f4ee3c707a05d54900fae4a4fd728c85937ac5a2c5e80aa5b59d2f862d29588394ecc3763aba09fde8e94d942eeda4a40e1247f7c790c657fe5d6c9e93e24ae242e9b0d38ea04a0995cc1c47544ce229a754601033e61fa691ad29b396f3988433d1eaa87cbd571a0807f7322a5f20d5b2c4780e3929b0f2dfe05200d2ceedaf977b03a9a8f6754d1a0787eca702c16dd6358a737733c650bfa46e96d45c363bec41797f391b2563297a0ed33522403db6c10067f5ed83105fcea3ef4b69175f864445c8f2ccbb876b714a038a14cfe2401b60702cd378821dc2b9d0db5ed883e9a8f79821b53c5e22d37fca0bd2e173acee2e04c03d4639766007189abf07e37a8be309b93f75c087a4cd1f3a0dc8c0144345749c908eb5c75ac3f38f76f711a16e66f383d2d88564fac88909da0bf69c74c889cba88a94d5c03099f71886bd8c201d09391cc793dccd6fa496322a0a876d78598c4559b191642460332b6fccafb599c59f31e48741ca350afaacd97a0d249b2987a9a9d4d459f2636827060e74e58979ea697af7d7ebca376db43eb3d80", - "0xf901f1a00604d6f7d7bad1c73872796360c75e84bb9a33af5a7ee731358e4922bb82b79fa083db0f00db4e9c3f10a74475b9b38449a08b3d6c943964d845815e896028d7cda09c9e745cedb5bc847c25a6b6fe2a4a221f4d4463bc39a2c0e1008d1615c2553da0ca5e5054ae0ff29b7791ffd3c3b8e692ca163c307a0c144f9521ad00f151c2dca02467996df5686ed91bea333ab6f68164d968852459e494cc35982a933d5ba445a01d20130117d040a978eda747a2de40c318d2e4c42aeeffd7fec513b130f71f2da0c56a8992c8b3340907bbb91e96192c30dd793506e8c3185d516bd4e11d12c174a0a46a65230b1f1fa8a0b6d22d1fcc41bd64068558b27cd2925981eaf0b6e17959a050112db382afd7a3da486dc54d610e73049a428dad6c5db87a978400e6a76e90a0c85d8fa58f5d90c85de511b7a27858614fbbd3831dd06c1c78d8bf83fc86f0f0a080ef0141630d3cad60bd4bff8e1f1837656c147fb3993176adf534d2e0e967f5a02f0dc0c919e9d75870ca213d88550ca899d9d3c5dd63e58c131280bfe657fa68a0ef2121de75ee5ba388d46da9043d704ce7f74b39ba74b4e4df6c854e9486c3aaa03e2bf2d2d11a46a47ca9b3bb1d25a4818525363163ec5e36602f49ed4bc8524180a06417462ce90c8407f0fbf5ec2568750dd5fc2fec27160c28d1a82eaa0d43ce9180", - "0xf85180808080808080808080a054c782365886dd5f2712191e37bd03069d8c025b7f3d1acc58f76b9320d45194a044c7334cb85b15578f0c47fc57dfd4ecf7d72cb036de93fc0e320acbcce0d1798080808080", - "0xf85180808080808080a0c43c2c226b2cefa9ad6cbac2f914c073032f993d972061ef03a976c1cfa87fe9a094559a53ce7e36d9a26caa7a72d0f6e9f9554ac46179e4f1b99de0bc81dad18f8080808080808080", - "0xf851a0373fb608ed0f5df13386f02dd867f841be1fd9572b9fbb924cdc9b53da0457cb808080808080808080a09f21374c3afd6a568962757ac1b3e11256c27d858bc0e049f3e6e900304b065f808080808080", - "0xf8518080808080808080808080808080a03b7b9939ce0d773724162f91df4fc734e6d76f8fde3ad9e2ac345e1cb93d3299a017d3b9ff99c67bfd58fae896f90da846a4b445f5117020649bd117aef1a31bce80", - "0xf86f9c2081a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab850f84e808a1830e66656d6c3870771a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 5702743, - "address": "0x0000000000000000000000000000000000000002", - "storage_keys": [] - }, - { - "address": "0x0000000000000000000000000000000000000002", - "balance": "0x267779194846d3b", - "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "nonce": 0, - "storage_hash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a04633a1b99f3f55529bd5604cba0792025b9972a56b1a98339e06fe337a2ee7eba0e3d895c010636d95a11e925af09f671dbc492b0021c992826d5aac6bf31b7ccfa0130e5f685a7c1891cdcddabfcb012566f0101f14bdfe65ee9da89823cf400b5fa0e9138905ed9bec0df60ad97511e07e368ea3fb5a19ba67f34fa5c25e1c579f86a0b7ea6653412ef4d073385b76b49257333995c3df421da5861f3332183d060332a0b19bb9be3114f0fc028f50bab0afaec78b26630a681de0bd7a3d538938fa063ea01c202faa8128f4e10b944bcd1616c1ba0811047439d93a6bc4be50a7a003cad3a09ba9241fe33f777a21c80758f13f59d044c06e8831e939891e449f6998a33146a05d1913703c7dc2064d6f1cc358e27fb0dd52f104c5e5c4500ea08e0e28e92d15a0aa4e60c891ec72cd46d8c6ca11e445b86d635dda608165a0a16333c6a4793322a023e2b1c5eefffd213c81b96a1d7069a8bc53b138f96dd349fe45fba66a5976b4a0c2b7452f095d0162f3115fe9c0c7a3ef28f0471fa3a0caff6cfbce07c983a7c8a0e2cda5b262724b9f51f546f9b9e6e00c03b175ad5a3054d4d17c46cef4317024a044d87334706ee72397d0a9fddd2bcf5e71ecf2912b602e0e87e8174be0b4bcc0a00f6da27c729f3473536784518b4f14fd03ba9a49da7be1e7af630c4e356c2308a0bf7bbd879ed847ac3c356bfe668cb4be2b8d372977875b531eb2d946fef22f5580", - "0xf90211a05cf3b0a7808fb6e45f2fc4c2c36653c4ebd24a9f1943ab075fd4c9d1b8e2b082a000c67b5bc3d00bf9713670eff10d1e4cc9dcb96299a76fd2a16ce9a775828d60a0c2dfa1092ebf3a16bde05915c7254bd08ef1b711c9d6354e02733dc4bd5c48aca071806560798095a199ad29fd339a2d8be22e557f7b219ff7c2936779e1698f13a00b8e1f9a9f7507452da871b9a5b1ecb4b15c12cd619bf4d4ae42505debb39943a081b73bda6d4a32b297e59b9b074952fbaf8231666898703c758386d32e4cdeafa0f184486f6616641f48bd0e38ed9d239e45b39dccef6ec5cf5dd4836c3e54437ea06baebe1b2122ecfd72efcd818337dfde6cab603d5bdf399d6b7f1c8e195a02f9a03550ef5a9ba80abada8590cb7661b916271cac4f6a33afa6dca80fa0e4473961a02ebf5091ab77774211e8edc066af6d56b3cf276a13cfd5f142fedfe00fffcd7aa0de244bc72c8798b04bb515962caab97233dc66f9a4c63d20cfb46b570bb12f74a0c626e6012727633ae7e26d9ad2627cab6656e03b1b93f9a9bbcb9e58a2cf54c7a09d72a2464c3277b9da318898bb60747ef6d66e17e556e02454ed96f82a67a2d5a00e3a74f6ba67841da342904a998b2143bebb29e659e14bbec3ebb04f9aaf79dfa0c418a189a43c93ab732ee8259355309589600cb474ca022b71fb6db0d14fd618a0a00405b957779183223142ab4d37168aa6d8f07d0e3a13e8b92fbe2943ca498c80", - "0xf90211a047367192df87a3793e3d9ecf2e41f5e986e29b0e7f354de7621f0cdff1b0c4f8a017ac7ff248ff4eac648fd9c682886e8e908c4527773714d8d65b7b4391a658e5a005e74ebc14abd78e0f17cdd86796a5fe37d06fde56fe4cbe0ba566b2749817fda0964ac949b96b3e33e170b750377a8a92b1d8f62629f87532b860467b501318b6a06930bd1359f4963aa20ad0b566f3299fa8c845499bc47bd397b7233c71d6be66a0c5226c4275ec79dac06c864fd708c59aa076b6ad48f7a58b4f3efa5888f7c43ba01e111b9d4763ff97029ae1d3f8f4b1d2ce6ac324fe94412ae0a0795a9a1eb006a034ae0ad19bf9c128e9b007e1d3c640a3c849f0865ec21f97d27cd3cc4dba6427a01e0b328c06f787c8809e4002e8f62ce410c5343388aa2b3ee782f06f1962c15fa009aeb8af841796730d5df6ca3ed9f10066fc73c126dbc5b606271d893b5c84e4a0c62a74c43f47f2c72e238556328ad87ae8e6ea103cfaecf5e4477dfd5c161473a0bbee5b9be8ddd74691788169b77adf73c678eeda347eca979a2a50032c1c2834a0d0f0c2de4b18d80258f1748e17a4dc798029c4d5058248e6ee6ce7255acaba9da0e8685d5f27619cfa0af496ee93b3e045829668caf9ea2e7967c9bd5c8f9e3affa0f9bbb56565bca4cd510dae16464d66c08ea8f6eda4e89710b74e0dbb9584b899a065e188194187131c7a5e8024b11246c0d0bfaeaebf883ad4f0fcb7a27224e89280", - "0xf90211a0e3368bf76066586662e5ed6aabc0058a2863803603dd322220c1639ca97b600ba0ddb70d7ffb972602723468fae744b08bae31757031a294045b8bd6a132b3ff3da00cbce7e5bb348c989ac68028b9df894ac1a85195966dff480603e3edb1193549a0ba351f29167aafeaa657bfea78204b92daaa62fa84964bf49493d0fa2b28e4eca0882fcc93f50cadca7abf525454275cdffe4862c69627d81afdc6062d7d0f24eba028d133a0735876fdec7dc5137c5b98c5adef997d5d32ab55c4fd129bed7814e6a0d7aa5a126e82a3e41df50a9fb299aa5dbbd5aa0d925afe8d18bb6f9e1179e592a0cb09557a3386bf6a5ccf572b51c065687ddfd79c90cd791c885be801f37438dfa092b452c43843eb1af6f01ed7fe30c996a31d1d35f2f331c1a13a62131257e771a062c4d724578d667bf5f0a9f05da21191252551e631d4250ae1634d956c6cd354a0eab0d60641379c4b599b51fd1bd3fcc03abda48baaf920b9ad9f6be5dde8f395a0aff59739a41477fa19a584b5869301dd6147a0a551c277b22047973570bdd2d7a04a44d2348110d1fb387785254a59476e90aa9f5746c6d2a6dc6bc63659a3ae31a08ade7f772625c7e3ee64c74bd688eb14db29fe0aca563b8945e79046dc115f9ca056f7b0fabebf110d2872dc398b6a0298a561ade95c0074d0b5ec17d7df531004a04e8140031dd309db0085ad772cd1c72caf5fd4d636e810e2d3b02691da48890d80", - "0xf901f1a0143dc1816306a91ce09746cfb82e413f62814fd5086705c623494cfc6a467aaaa09605645950c78b0ce167aa956aba691b8a6997e6f6df8d497dbecc94ac22ba6b80a0c0ab0952a90b07a986ef2fc546920d8ca203b5310ab690b0eff6935ad4db6336a0562196812131105a8769ab5140dc6fd96cd366a9d9bc30acbc487e1246ed724da057dff238a1d1c1cdfa089f1ec4676a2dbd8660caff1474c7e34f87261e2dd2cfa0310a6bbc1ffeec396df220c61ff5927af4bf48256084653bd8cfb3fae33944e5a017f658f875e8e0100578a56d34efc139dd8e06fc835e298a33b5becaab022c77a07583cf84776861d0a0ee737d66533fb5ca919e01e6890d9c9f325a66cdbb7683a039c46501b1599a33723d9fb931f4c0dd27b868e2fd642eea7632dd49dbc822afa0fb1c088d9379447121c95e1ea391a15af80517f0cc4c69757d75e23e04ff472ca06416ef2e0149aee5c1b4d5d3225390af82836ab9d84c9f449a7cf0f2648c7a09a099b2cdded1e876b4f3c53dd05cc1219ae9ae938bf467d77f27b1e6eae4b8e210a00c89adc73254270808b9f3ab283f95f451fd8793998c6ab0d78faf92d97a6cd1a0b6e8f85ca5a9fc670851adcebbb1caf2305c2ce0762195c19cba38206f650116a0cae5b5e0f86ee1b3b1442507955be21318eb67240328c49cba4c639e458547a180", - "0xf86f9e20a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62b84ef84c80880267779194846d3ba056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 5702743, - "address": "0x3c31cdb4d84ca36f17a4a3215b1a56d2569daed8", - "storage_keys": [] - }, - { - "address": "0x3c31cdb4d84ca36f17a4a3215b1a56d2569daed8", - "balance": "0x0", - "code_hash": "0xb32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114", - "nonce": 1, - "storage_hash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a0826cd2334d1b5982bb3db5128c7d7a2f3a9c72a007d3d730b9c5b235de45e3bda06ff728d9c6bc6ed19233baba82a385afe4b301557b79170f0afbe60ad7327854a04af2e2d23a59a7a98c46631e0f5bf395d505e521020c4481285a6e4cced510e4a0b586f1676383d62ec99886ea5f4fab14acc6b1c56c8c7d16c2530817039d1a6ca022284bfab7b5968e861418fa5783d58afe3cc3ca2bd2c1635b5eb8b2f00a78a6a0e2766f88fb084cfc410e0a8e95c4adf042903904b0a585bf2be03b0202bd1955a07ea5ca40594cc7899d4d8c98665fd98b7e74f814e199a339f848df0ef0bf2907a0d06744eb6b1648ad4276fc1f1534615ead34f044d5f197e0876e0b57d91bf454a0d83247b6c859de0e881c08bc9ecb182219ba90d16dfd8c2f731d35b44e08e8f0a0f5204869c0f85e2278c617657fb31a8e0683d8f3f402c4ed4f344edaf4e6ffa0a019788e655b0533fb22b7871d33985dd01fe27b117a18b6f79e09a29195657dd2a0f8c16586725526ab0416e49e050d513a66338660290b8dfe0bb9237c698a7851a0b50b7032c6619f1557c9646d431f65a2404a1d909910268b4efd5b30400997c8a0adab837a0d3984b0dcdfcbf31b856df1cc2ed978dd8717f007c8b1154287d916a048ac09d06852c82d52ed06124228782f0dc011cffef354a10f3ebfa6627f167aa0d6c6480def7b086a5a7e42f67cb033fd98ba59990a577581cdb1f27e23ff7d1e80", - "0xf90211a0f1eddfbdeef1da342527ebf4da7ba554fcfdae8a0b826d26680e668669a8ec41a0ead64be6e2b71bca90bebd778571942df0938422469770081e4c2e85066161eba037b639021fc36c151732bea033c9f9801a97b29909b6573d10a8f0207647a3dba01172039ff90360d7ab569801f0b10010ac76abb98c777953be56ce2811c70720a0fc63ccfc92cba9a9398fd85ae348ceba717a7f1739e6d2ee9ba1015895ff7c22a025a4de20eaf0908b9414b67a7c42400e60faf646fbaa8cade2784ec9be838771a0b2eb0b08a6278fad90121fb57c5751da71113d29dac3fbd7d3e6784a99e39875a0e0436a8f7116951e5a4a1045811068253eaba13e65ca3641179e99482f2a40e6a0388cbfe1228955a167b4941be572d6d12821d8a6b8c6c2720baf6b1a7a7b1320a06e3f532116d98ff839cef0810ecd88f0004c892748ab9b7e7624027d0afb594da0f3eefceb204e2e15a946ce4cdc00541e366428b0d694511c1cdbe89771d6267ca03ec4fefe3b148a57dd5c2d0e68442c7b3fe0a0f8f83a26a194696257669e40dda08788246d3ef472d0d842273d14382ad8dcfae060d22c7e9334e2b8236f4f0b2ba0932b61380bfdbf5a90be94109f3bb9af99b64d78bc6242cbd85dd614a5ec574fa00b8b1a77450140756b29aeca6c0f9235db36aea8dc8b9617f42f87a7f2a8fee2a0c9f5709ab7763b9c3c7e20ef1a572a6b6877d0a424ff09415d82a7907ea619f280", - "0xf90211a0d8ddd2cb56ed033c2e867390669c6649d50848019ab98303c3539287e5c31b94a0c56eb2e1df508ebb6004d7026650d37671461697a09683cca90adf00cd9ca205a0c114a0205230d2a82c7f0d2e1af42e3136cebd817c5b6cee9693e41d5b12fe29a07b1343deaa9f595944f9dc3e022f694ff84f0e9c5bbb500cdc7d6a20a38cd76da0067b54f214c0c5df9dbf4e5c007d214998fb3baaf115308672548ca780ae235ea0a48c193547e13f811600a3c6096a1b951f6e2cb8175604f99af63cb5d68ee492a0954adae79726cc62b3c665869f2a2f809a3068483e319af055674a37e90b6458a0a31dd834a7af1b04fcd209619cb2feb57ef9867945e54b3361a175cae9b96d56a05914cba5e3ee671bbdca7564d039b41ff38a30f562c9be7130203e4c713f0bf0a02a68f61e791d6a257447b87773c36a791997914ed20f4b44f21819650bed7aa6a0f9f6f06f1da28d00e700d853a0279a87a5f2f6cf43f3391e8019e2d69f059f07a005d217f101a0e69e6f311007da9783dfdbfc264e94b90ae03d9e3410246e7f66a06094094e49b61f5c359b7b352357838ed318e0e8d764ca1886039481cf6a3b17a0b3d001c1bc76736518ab2310d9e4adc59b159ea4f00ff0d84e48e4d81ff15379a03e11ad72ec30f1580ce93977068758580d08c13bf6d676d20e5c86132f215aaba02473ce049fe3b3a286f5744145f52201198f580def83eccc9608f4394388af6e80", - "0xf90211a01c1576de6ebcd5d7151eddbf66e6f6dd6c3ac90303ce4a02f5967ccfbb2efcd0a0d84c2de4838a104d2e166543c11abec1fcb72866b4612fe9fec684eaf042697ca0d1fc3863882fbd2b32f2375d119134a135bd22a4610f83bd491e64bf9ea399fca0c58982a980d61b217fce351e02c222dc593b6e147d32472acdef09986855ff47a0b291431d46cb5b26e868347cc28187448c01f1feef9f4aea728b8be2cf59be72a0d0f6ae861a9fd4ddd5a4a66ea91222f05b5f34e198910cf25bebfb2877c49cc8a02e6e96175dfc8b464f43649c5a55c09f638ba4265f13a59ca5f5b260c6fc6268a06ae5f2949b29354e2b2b947f7fb797d24c2006328a62711667e11d4ce1305c78a01fec5dc560730516d29c135901b8342e48502fb441f685356eb2154a900ff281a0ce10ec08cf97bdff17b70a08efa4d1485bca9fa3d6dc2e64b9e9343828fc2982a068a101661802edd84a1c302280a2d3459531f1b3959415104587678d1b7ba95fa0d698ba2e03b40bb3ddfeca7d9dfa9ae196c1d070fc17ddc6480ffdd2463119b7a03aa254ab6d68468655f3e9ff8ffafa443aba6163a12c8973d9893d616831d141a03adc54dcd8548b0b9759c840d821396388bc2bc92d6499c2718de91c42ccf645a0444e23ca295b7afd0bff7b17a802437c34c8d9f7e62f5eed05eeae5035edec81a00473430396105e4f827574494ae1a6831cd9189731c1c36a885131656e4e133580", - "0xf8b180808080a0c7e15bb54dc8d79da5c45580ad5469d37617560c2b6ef0995f75ea25a12c9f94a000b8315b08efadbe5d01ae4a14637ef68d12dceb1867fc6ca275dae5dd1ce4378080a07e2c2d1316ffc0209a74091cc0fb2114088914e9d93b7996479ec480661b45c4a0648b9df04897e0d64a0286c2c909b365063bf32c1baad916422ce6888f60398e80a0a8237feb589a81d8e51e50f8c4b60ef2d33140463e1e8b4d4ea47d3d98e3195b8080808080", - "0xf85180808080a0265f6712ccc5cd0170c3c67e92ec81b0d50cf946cedfad6cdb6f8779607198ea808080808080808080a00fd4e33ad43f0b3a069ec2f4c0b09909f4e44431bf2ef76f7e7c5e33c2a2f6c58080", - "0xf8669d3c2a625b5c585abda33b7d610535dac594d8cd3a381e688b430cd52547b846f8440180a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0b32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 5702743, - "address": "0x3c31cdb4d84ca36f17a4a3215b1a56d2569daed8", - "storage_keys": [ - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] - }, - { - "address": "0x3c31cdb4d84ca36f17a4a3215b1a56d2569daed8", - "balance": "0x0", - "code_hash": "0xb32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114", - "nonce": 1, - "storage_hash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a0826cd2334d1b5982bb3db5128c7d7a2f3a9c72a007d3d730b9c5b235de45e3bda06ff728d9c6bc6ed19233baba82a385afe4b301557b79170f0afbe60ad7327854a04af2e2d23a59a7a98c46631e0f5bf395d505e521020c4481285a6e4cced510e4a0b586f1676383d62ec99886ea5f4fab14acc6b1c56c8c7d16c2530817039d1a6ca022284bfab7b5968e861418fa5783d58afe3cc3ca2bd2c1635b5eb8b2f00a78a6a0e2766f88fb084cfc410e0a8e95c4adf042903904b0a585bf2be03b0202bd1955a07ea5ca40594cc7899d4d8c98665fd98b7e74f814e199a339f848df0ef0bf2907a0d06744eb6b1648ad4276fc1f1534615ead34f044d5f197e0876e0b57d91bf454a0d83247b6c859de0e881c08bc9ecb182219ba90d16dfd8c2f731d35b44e08e8f0a0f5204869c0f85e2278c617657fb31a8e0683d8f3f402c4ed4f344edaf4e6ffa0a019788e655b0533fb22b7871d33985dd01fe27b117a18b6f79e09a29195657dd2a0f8c16586725526ab0416e49e050d513a66338660290b8dfe0bb9237c698a7851a0b50b7032c6619f1557c9646d431f65a2404a1d909910268b4efd5b30400997c8a0adab837a0d3984b0dcdfcbf31b856df1cc2ed978dd8717f007c8b1154287d916a048ac09d06852c82d52ed06124228782f0dc011cffef354a10f3ebfa6627f167aa0d6c6480def7b086a5a7e42f67cb033fd98ba59990a577581cdb1f27e23ff7d1e80", - "0xf90211a0f1eddfbdeef1da342527ebf4da7ba554fcfdae8a0b826d26680e668669a8ec41a0ead64be6e2b71bca90bebd778571942df0938422469770081e4c2e85066161eba037b639021fc36c151732bea033c9f9801a97b29909b6573d10a8f0207647a3dba01172039ff90360d7ab569801f0b10010ac76abb98c777953be56ce2811c70720a0fc63ccfc92cba9a9398fd85ae348ceba717a7f1739e6d2ee9ba1015895ff7c22a025a4de20eaf0908b9414b67a7c42400e60faf646fbaa8cade2784ec9be838771a0b2eb0b08a6278fad90121fb57c5751da71113d29dac3fbd7d3e6784a99e39875a0e0436a8f7116951e5a4a1045811068253eaba13e65ca3641179e99482f2a40e6a0388cbfe1228955a167b4941be572d6d12821d8a6b8c6c2720baf6b1a7a7b1320a06e3f532116d98ff839cef0810ecd88f0004c892748ab9b7e7624027d0afb594da0f3eefceb204e2e15a946ce4cdc00541e366428b0d694511c1cdbe89771d6267ca03ec4fefe3b148a57dd5c2d0e68442c7b3fe0a0f8f83a26a194696257669e40dda08788246d3ef472d0d842273d14382ad8dcfae060d22c7e9334e2b8236f4f0b2ba0932b61380bfdbf5a90be94109f3bb9af99b64d78bc6242cbd85dd614a5ec574fa00b8b1a77450140756b29aeca6c0f9235db36aea8dc8b9617f42f87a7f2a8fee2a0c9f5709ab7763b9c3c7e20ef1a572a6b6877d0a424ff09415d82a7907ea619f280", - "0xf90211a0d8ddd2cb56ed033c2e867390669c6649d50848019ab98303c3539287e5c31b94a0c56eb2e1df508ebb6004d7026650d37671461697a09683cca90adf00cd9ca205a0c114a0205230d2a82c7f0d2e1af42e3136cebd817c5b6cee9693e41d5b12fe29a07b1343deaa9f595944f9dc3e022f694ff84f0e9c5bbb500cdc7d6a20a38cd76da0067b54f214c0c5df9dbf4e5c007d214998fb3baaf115308672548ca780ae235ea0a48c193547e13f811600a3c6096a1b951f6e2cb8175604f99af63cb5d68ee492a0954adae79726cc62b3c665869f2a2f809a3068483e319af055674a37e90b6458a0a31dd834a7af1b04fcd209619cb2feb57ef9867945e54b3361a175cae9b96d56a05914cba5e3ee671bbdca7564d039b41ff38a30f562c9be7130203e4c713f0bf0a02a68f61e791d6a257447b87773c36a791997914ed20f4b44f21819650bed7aa6a0f9f6f06f1da28d00e700d853a0279a87a5f2f6cf43f3391e8019e2d69f059f07a005d217f101a0e69e6f311007da9783dfdbfc264e94b90ae03d9e3410246e7f66a06094094e49b61f5c359b7b352357838ed318e0e8d764ca1886039481cf6a3b17a0b3d001c1bc76736518ab2310d9e4adc59b159ea4f00ff0d84e48e4d81ff15379a03e11ad72ec30f1580ce93977068758580d08c13bf6d676d20e5c86132f215aaba02473ce049fe3b3a286f5744145f52201198f580def83eccc9608f4394388af6e80", - "0xf90211a01c1576de6ebcd5d7151eddbf66e6f6dd6c3ac90303ce4a02f5967ccfbb2efcd0a0d84c2de4838a104d2e166543c11abec1fcb72866b4612fe9fec684eaf042697ca0d1fc3863882fbd2b32f2375d119134a135bd22a4610f83bd491e64bf9ea399fca0c58982a980d61b217fce351e02c222dc593b6e147d32472acdef09986855ff47a0b291431d46cb5b26e868347cc28187448c01f1feef9f4aea728b8be2cf59be72a0d0f6ae861a9fd4ddd5a4a66ea91222f05b5f34e198910cf25bebfb2877c49cc8a02e6e96175dfc8b464f43649c5a55c09f638ba4265f13a59ca5f5b260c6fc6268a06ae5f2949b29354e2b2b947f7fb797d24c2006328a62711667e11d4ce1305c78a01fec5dc560730516d29c135901b8342e48502fb441f685356eb2154a900ff281a0ce10ec08cf97bdff17b70a08efa4d1485bca9fa3d6dc2e64b9e9343828fc2982a068a101661802edd84a1c302280a2d3459531f1b3959415104587678d1b7ba95fa0d698ba2e03b40bb3ddfeca7d9dfa9ae196c1d070fc17ddc6480ffdd2463119b7a03aa254ab6d68468655f3e9ff8ffafa443aba6163a12c8973d9893d616831d141a03adc54dcd8548b0b9759c840d821396388bc2bc92d6499c2718de91c42ccf645a0444e23ca295b7afd0bff7b17a802437c34c8d9f7e62f5eed05eeae5035edec81a00473430396105e4f827574494ae1a6831cd9189731c1c36a885131656e4e133580", - "0xf8b180808080a0c7e15bb54dc8d79da5c45580ad5469d37617560c2b6ef0995f75ea25a12c9f94a000b8315b08efadbe5d01ae4a14637ef68d12dceb1867fc6ca275dae5dd1ce4378080a07e2c2d1316ffc0209a74091cc0fb2114088914e9d93b7996479ec480661b45c4a0648b9df04897e0d64a0286c2c909b365063bf32c1baad916422ce6888f60398e80a0a8237feb589a81d8e51e50f8c4b60ef2d33140463e1e8b4d4ea47d3d98e3195b8080808080", - "0xf85180808080a0265f6712ccc5cd0170c3c67e92ec81b0d50cf946cedfad6cdb6f8779607198ea808080808080808080a00fd4e33ad43f0b3a069ec2f4c0b09909f4e44431bf2ef76f7e7c5e33c2a2f6c58080", - "0xf8669d3c2a625b5c585abda33b7d610535dac594d8cd3a381e688b430cd52547b846f8440180a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0b32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114" - ], - "storage_proof": [ - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000000", - "proof": [], - "value": "0x0" - } - ] - } - ], - [ - { - "block_no": 5702743, - "address": "0x44b48fd72becefe030c1b62fadbfe6a7b3465d19", - "storage_keys": [] - }, - { - "address": "0x44b48fd72becefe030c1b62fadbfe6a7b3465d19", - "balance": "0x0", - "code_hash": "0xb32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114", - "nonce": 1, - "storage_hash": "0x81d1fa699f807735499cf6f7df860797cf66f6a66b565cfcda3fae3521eb6861", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a039740048839100d4d440da007471674d9fd46f70bda83e91da83415efc9dd90aa0f2505d5072f233af929333914009e5565824470eeef2f14193a21350584f4a10a0d33fea3834857725717d0e19b49a12b5c3bd44c0cfdd697015b29e2f94ff2b90a0011fc513b3023d8c6524d8f5dcbe7ea9406b1739e32a72bb439a71335bb755daa0fd1bac5352cb21097c821f8cfe112d6212d5af8da07c453cf876554b3f3617aba06d732a9df7b7102a1f4dd3f987bfee4cf28dfb78aa09ad7450e974b8d629f380a008d584181e0d83ec51c8bd5c3f84d62f6fcd83c0f48dcd7a9a4e380e58b1ea16a0f0be2b69330518de573afae147553b46fa2f0acb10b46f90bfdfcb8cacc15f3ba063eff91503ef0ad16e69649014532754182e7fd924707f40a4ce9ac821ff3c28a03e90f71b93bef56654d574ffe351dbbd0dfba43e981a02ed0cfe6190df052904a0c187faf09b00a978505693623061e8c36acd3cf87961aec47678852ea10159c9a08fd67a720d5e8633cad793e0c1bfee9641aaed6241823e78c217b37c3f54de76a002018dcbd1108665d440b3f08d54b35706a5da113cd7f693203be00c63a28adda0abc10275bff476741d1d87621144a45c250658a36aa8057cb3f7a46f7afb7f2da0a19c241d6fc742341c93dd54b599a713d601917734582669177c236d161c8e16a00c68b1cdecd939c10058de5aa6b503daaeeeed034f3e189da26da2c00dd21b3680", - "0xf90211a03fb3b639fbf73c4ece36cbfd467ea42cfa5602e29830ded4113e1ff35dba1659a0bf6bbc0ad72481ec3a64c93f8d14992ffb4e2cbdfa49502e8e4b238329674e27a01ea6ce0c84544cabdc41a8c3e455aca66af68c70311157d0fd473ae6a23755b6a09f82e4a118cfd32622f3c8324c447f80223bb55dcad4ba53d6af62d6a08941bda06bbebf272b653d24ffb5f02a0b19f3819da5c64d764c7306c4199dd1f0126a67a001f0877c07aef2328a47d6c710944bbd75b59fbc7b57ffacf40f905a7eca40aba0011caad00366cbff8f4301dd87c17002934862b4a181f03482a4fcc4c2640e0aa081c22ab7e4ef58f9e84acb90271b1cedf2caa08d5be783512419b43242f50c91a0f8307a47fc60c8d5b6f4cb842819b4792e765825fdfb8e08bc333af86b5f7e64a06b491535768cacf2ea4c55aab40be047d565ebd569cc64aaa9a93a849b781259a0f4ccee8331266b0cf5f63aaf2cca0d7f8fcacd6ece7e4fecd392adb4d8621984a0d7a3bf029e264fc02d4ba386eaf85a01302c11e123eb0b01d9bf74f40c6e43fda0848ba73399a340f012743cc759d9b8d9f888f2a66c5f1b35779025aa0d09358ca0a14329c75f3c69e3cc9cbcac9e14ff6e79cacfbdd0a357a3407f0cbfa1240d8fa060e8052de67f788fd223214148ecb7a7f15f2b6e5cb60d285385f249d6356c82a0dc7fe2ad5bc19576fe1d2d2d12057296ae25655227e545c569faa7db2146c17b80", - "0xf90211a0b300e10e737e580bd1caa45406a7af189c36201875345f5d0454fe32a59fd1aaa0c7d3a22317d4f51ecb714e34abaa2c1c2722a0c881e2cda22ede4a08919c4c40a06afb389b7b3e54c924f25a58368351f0d6db9cdaed27330eb9c2d18e90b07065a0836e9dd2ad2b0d3dbc7a4e763a9f2f1e0850025f4f291fa7614a69b4758721f9a06051e75a2037832004696e5eb511580639a1388af0874012f399217c26acb5b9a0ee73158e5e838a1a9cb14bb301be01e4f5046d3fe9153db92da83cef4b1131a4a0b468950056561a0c27a11e48d5d3563e67116267be990ebf203cb67561190ca4a0792216cfe37d5ffbc438497ed390e6e150ca1b025da18f623b6b2678bf09e7e6a08ffca5d6235a10f7e9b639b22b36ec54ffcf3fbc2d25e5bdb1256223c62d4eeba0340c361eece5ad8a8b92b5d99ada819357bd32d5c9b20be215ca11bea74afbbea094f3ca3faf007935373cf3ad0fc2ad0848ae005d47316294aab8dc2ae8378599a076c1743df06a339d763afbc68b0aecb3d1abb1344b2d514e963c4505eede5206a0da0659e69694986b29bb302c33a1e58dcc286f984dc86e12de7e68d1093a96d9a0927643778d8a9ca04a5086283267a858b1ff2a401c2d7d512d3b1afc2a9ded25a08cb2341ec74c6c1d09d6ee5307b823d0dfc59c0eb2857854307c56bc52dd997ea0ae70ee673533ba348796de558557288e1bdc80ab3b6329a271c92529f606ca7880", - "0xf90211a0ca323c9cee8eb8bcd06c373562ab51a4d48f6f26c8901a8d3fa6f25f382c06a7a03262f238c763f8a8c939c4b2ba55488e3dacf07895779f4037478757b7f1f1a5a0fb6e50c20f3bb3121bf9154219e9f1fe93065e561f7f984122f9e1108e66ca42a088c2cee21879cbac74cc1e9f13cc300e84bfb7c3291e14535ea590ab55c12255a07e5dbc5cc11d25054670f28041ac97e64606f66025939a1bfb932294f1709a52a0939820027bc55983b5c87d4bc2af39dbcfe0ac428da8a3464ea642dc71dc379da0251ee48096773a66e9842842a2ee500349405921ad3965b6db2294c46606b8cca0c02cadc45c2479628cbc3a4f00b675d62c67522f14b04e549ec7a78cc4e84faea0dc628970af73bad6852a36aa5a58bb21b8374cf4538ee86c0e835c5bb69bffeaa08efd1589dac1c6a96ec7c267e1ee95eb86623f218dafac7fb6f2537e6687dfe5a0d78289682da36bb0e8b5531498cd16f4c7dd5f5d6b3d4125f66cfae918bf47b7a09cfdc1cb07308a5be892e244306109d07391d0268c6ad63959c731d91bf70ce4a0897d820134c9889214845ea745aa7e52465052016f347e010cd2d95c2d3da2eaa0fc46ef809fcb53d2820a2a121baff2710919ef22fe74d9dd309c2431efc84e91a0edd8358e5a57baae17675c3b3bfec116a97504e40ea2aeb4b382a5ce4e62df82a09a58f1bd001a3c815caf2fa22800c99053a8d45256ef0fa14dc91b5f5ccc9f4c80", - "0xf901b1a0c488dc03189a0826de8490daf0d2294458f16b2f9f80ba88f5dc85dfdce1c4eda025bc15ae6897f32a4d6b73743666cf07bbbf29e517b899c42b6cb38272fc20eba07e4ee714c829a06fd2f4ef8fe567a709ac969fcdf60ce35bd559206cd030080ea0538b0f75b771c81a1995256a1bfb2657993f150971021e8ecf9d73a25c010452a09749cb52982acfcdad116f1c24db87e6b5ff125288febc138fd8f5c6ce61b62380a035125e8c896c929a9adfe633ea748ed35348bc186220fc35d1bb0ca0bd3bc8d8a00ad3976334c529b07964cab9d5e2956da0a01c4f4b5b212ce81983bedcf060b480a0962b77a50e074310d98d889ce9fd8c8b0674af72c11eba324d38d2cd85f84921a0c7afa2d7db163ca7f341b1518c1a8bd9365d41b80ddac9c705d1ea44e2accfa9a0ae634b218d7c10de2f9127bf7d9abab7027b51139be2364290035e824622ea31a0ff796d8ef0d7548e19c3e4e0a97ba0c857eae9b5f4c7f9af7c55193a6cedb8afa062e28cc9cd7153b0d3f3579f8639c3e1a032591d6dffc93074dd47b4d9001dd280a09bbe4afee1fdf74a9e5c713bb9e0e31947827a6a740b8672fe93f5458b6050c080", - "0xf891a0e9aced5ae73a685021630728353da5d7f25a76fcc8497349e2340c4154930e1980a0993c0a18076f4a0930476c999a76899f8f9a3a3464c0d6207d6884c6bef657d0808080a0dbe1d583d9d55c8cd00e429759c1f65d69f049db751d24c4e6ddd961d149c4b7808080808080a0fb5337a13b77a4e4b638594292a6cb7ff7e85450b7e8e188516b61906d66b6de808080", - "0xf8669d3d1dfdfed5b06709670fb81708a56c2561b313c73e4c9b08c78d8dbec4b846f8440180a081d1fa699f807735499cf6f7df860797cf66f6a66b565cfcda3fae3521eb6861a0b32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 5702743, - "address": "0x44b48fd72becefe030c1b62fadbfe6a7b3465d19", - "storage_keys": [ - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] - }, - { - "address": "0x44b48fd72becefe030c1b62fadbfe6a7b3465d19", - "balance": "0x0", - "code_hash": "0xb32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114", - "nonce": 1, - "storage_hash": "0x81d1fa699f807735499cf6f7df860797cf66f6a66b565cfcda3fae3521eb6861", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a039740048839100d4d440da007471674d9fd46f70bda83e91da83415efc9dd90aa0f2505d5072f233af929333914009e5565824470eeef2f14193a21350584f4a10a0d33fea3834857725717d0e19b49a12b5c3bd44c0cfdd697015b29e2f94ff2b90a0011fc513b3023d8c6524d8f5dcbe7ea9406b1739e32a72bb439a71335bb755daa0fd1bac5352cb21097c821f8cfe112d6212d5af8da07c453cf876554b3f3617aba06d732a9df7b7102a1f4dd3f987bfee4cf28dfb78aa09ad7450e974b8d629f380a008d584181e0d83ec51c8bd5c3f84d62f6fcd83c0f48dcd7a9a4e380e58b1ea16a0f0be2b69330518de573afae147553b46fa2f0acb10b46f90bfdfcb8cacc15f3ba063eff91503ef0ad16e69649014532754182e7fd924707f40a4ce9ac821ff3c28a03e90f71b93bef56654d574ffe351dbbd0dfba43e981a02ed0cfe6190df052904a0c187faf09b00a978505693623061e8c36acd3cf87961aec47678852ea10159c9a08fd67a720d5e8633cad793e0c1bfee9641aaed6241823e78c217b37c3f54de76a002018dcbd1108665d440b3f08d54b35706a5da113cd7f693203be00c63a28adda0abc10275bff476741d1d87621144a45c250658a36aa8057cb3f7a46f7afb7f2da0a19c241d6fc742341c93dd54b599a713d601917734582669177c236d161c8e16a00c68b1cdecd939c10058de5aa6b503daaeeeed034f3e189da26da2c00dd21b3680", - "0xf90211a03fb3b639fbf73c4ece36cbfd467ea42cfa5602e29830ded4113e1ff35dba1659a0bf6bbc0ad72481ec3a64c93f8d14992ffb4e2cbdfa49502e8e4b238329674e27a01ea6ce0c84544cabdc41a8c3e455aca66af68c70311157d0fd473ae6a23755b6a09f82e4a118cfd32622f3c8324c447f80223bb55dcad4ba53d6af62d6a08941bda06bbebf272b653d24ffb5f02a0b19f3819da5c64d764c7306c4199dd1f0126a67a001f0877c07aef2328a47d6c710944bbd75b59fbc7b57ffacf40f905a7eca40aba0011caad00366cbff8f4301dd87c17002934862b4a181f03482a4fcc4c2640e0aa081c22ab7e4ef58f9e84acb90271b1cedf2caa08d5be783512419b43242f50c91a0f8307a47fc60c8d5b6f4cb842819b4792e765825fdfb8e08bc333af86b5f7e64a06b491535768cacf2ea4c55aab40be047d565ebd569cc64aaa9a93a849b781259a0f4ccee8331266b0cf5f63aaf2cca0d7f8fcacd6ece7e4fecd392adb4d8621984a0d7a3bf029e264fc02d4ba386eaf85a01302c11e123eb0b01d9bf74f40c6e43fda0848ba73399a340f012743cc759d9b8d9f888f2a66c5f1b35779025aa0d09358ca0a14329c75f3c69e3cc9cbcac9e14ff6e79cacfbdd0a357a3407f0cbfa1240d8fa060e8052de67f788fd223214148ecb7a7f15f2b6e5cb60d285385f249d6356c82a0dc7fe2ad5bc19576fe1d2d2d12057296ae25655227e545c569faa7db2146c17b80", - "0xf90211a0b300e10e737e580bd1caa45406a7af189c36201875345f5d0454fe32a59fd1aaa0c7d3a22317d4f51ecb714e34abaa2c1c2722a0c881e2cda22ede4a08919c4c40a06afb389b7b3e54c924f25a58368351f0d6db9cdaed27330eb9c2d18e90b07065a0836e9dd2ad2b0d3dbc7a4e763a9f2f1e0850025f4f291fa7614a69b4758721f9a06051e75a2037832004696e5eb511580639a1388af0874012f399217c26acb5b9a0ee73158e5e838a1a9cb14bb301be01e4f5046d3fe9153db92da83cef4b1131a4a0b468950056561a0c27a11e48d5d3563e67116267be990ebf203cb67561190ca4a0792216cfe37d5ffbc438497ed390e6e150ca1b025da18f623b6b2678bf09e7e6a08ffca5d6235a10f7e9b639b22b36ec54ffcf3fbc2d25e5bdb1256223c62d4eeba0340c361eece5ad8a8b92b5d99ada819357bd32d5c9b20be215ca11bea74afbbea094f3ca3faf007935373cf3ad0fc2ad0848ae005d47316294aab8dc2ae8378599a076c1743df06a339d763afbc68b0aecb3d1abb1344b2d514e963c4505eede5206a0da0659e69694986b29bb302c33a1e58dcc286f984dc86e12de7e68d1093a96d9a0927643778d8a9ca04a5086283267a858b1ff2a401c2d7d512d3b1afc2a9ded25a08cb2341ec74c6c1d09d6ee5307b823d0dfc59c0eb2857854307c56bc52dd997ea0ae70ee673533ba348796de558557288e1bdc80ab3b6329a271c92529f606ca7880", - "0xf90211a0ca323c9cee8eb8bcd06c373562ab51a4d48f6f26c8901a8d3fa6f25f382c06a7a03262f238c763f8a8c939c4b2ba55488e3dacf07895779f4037478757b7f1f1a5a0fb6e50c20f3bb3121bf9154219e9f1fe93065e561f7f984122f9e1108e66ca42a088c2cee21879cbac74cc1e9f13cc300e84bfb7c3291e14535ea590ab55c12255a07e5dbc5cc11d25054670f28041ac97e64606f66025939a1bfb932294f1709a52a0939820027bc55983b5c87d4bc2af39dbcfe0ac428da8a3464ea642dc71dc379da0251ee48096773a66e9842842a2ee500349405921ad3965b6db2294c46606b8cca0c02cadc45c2479628cbc3a4f00b675d62c67522f14b04e549ec7a78cc4e84faea0dc628970af73bad6852a36aa5a58bb21b8374cf4538ee86c0e835c5bb69bffeaa08efd1589dac1c6a96ec7c267e1ee95eb86623f218dafac7fb6f2537e6687dfe5a0d78289682da36bb0e8b5531498cd16f4c7dd5f5d6b3d4125f66cfae918bf47b7a09cfdc1cb07308a5be892e244306109d07391d0268c6ad63959c731d91bf70ce4a0897d820134c9889214845ea745aa7e52465052016f347e010cd2d95c2d3da2eaa0fc46ef809fcb53d2820a2a121baff2710919ef22fe74d9dd309c2431efc84e91a0edd8358e5a57baae17675c3b3bfec116a97504e40ea2aeb4b382a5ce4e62df82a09a58f1bd001a3c815caf2fa22800c99053a8d45256ef0fa14dc91b5f5ccc9f4c80", - "0xf901b1a0c488dc03189a0826de8490daf0d2294458f16b2f9f80ba88f5dc85dfdce1c4eda025bc15ae6897f32a4d6b73743666cf07bbbf29e517b899c42b6cb38272fc20eba07e4ee714c829a06fd2f4ef8fe567a709ac969fcdf60ce35bd559206cd030080ea0538b0f75b771c81a1995256a1bfb2657993f150971021e8ecf9d73a25c010452a09749cb52982acfcdad116f1c24db87e6b5ff125288febc138fd8f5c6ce61b62380a035125e8c896c929a9adfe633ea748ed35348bc186220fc35d1bb0ca0bd3bc8d8a00ad3976334c529b07964cab9d5e2956da0a01c4f4b5b212ce81983bedcf060b480a0962b77a50e074310d98d889ce9fd8c8b0674af72c11eba324d38d2cd85f84921a0c7afa2d7db163ca7f341b1518c1a8bd9365d41b80ddac9c705d1ea44e2accfa9a0ae634b218d7c10de2f9127bf7d9abab7027b51139be2364290035e824622ea31a0ff796d8ef0d7548e19c3e4e0a97ba0c857eae9b5f4c7f9af7c55193a6cedb8afa062e28cc9cd7153b0d3f3579f8639c3e1a032591d6dffc93074dd47b4d9001dd280a09bbe4afee1fdf74a9e5c713bb9e0e31947827a6a740b8672fe93f5458b6050c080", - "0xf891a0e9aced5ae73a685021630728353da5d7f25a76fcc8497349e2340c4154930e1980a0993c0a18076f4a0930476c999a76899f8f9a3a3464c0d6207d6884c6bef657d0808080a0dbe1d583d9d55c8cd00e429759c1f65d69f049db751d24c4e6ddd961d149c4b7808080808080a0fb5337a13b77a4e4b638594292a6cb7ff7e85450b7e8e188516b61906d66b6de808080", - "0xf8669d3d1dfdfed5b06709670fb81708a56c2561b313c73e4c9b08c78d8dbec4b846f8440180a081d1fa699f807735499cf6f7df860797cf66f6a66b565cfcda3fae3521eb6861a0b32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114" - ], - "storage_proof": [ - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000000", - "proof": [ - "0xe3a120290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5632a" - ], - "value": "0x2a" - } - ] - } - ], - [ - { - "block_no": 5702743, - "address": "0x455e5aa18469bc6ccef49594645666c587a3a71b", - "storage_keys": [] - }, - { - "address": "0x455e5aa18469bc6ccef49594645666c587a3a71b", - "balance": "0x48e53aedcdc84cc3430", - "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "nonce": 1, - "storage_hash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a053beda8affacded9ca23af30227fdd3601229895721c0dd3db9b02fef7f92a9aa0c6b9c538f6311d7a80cc1ffca2d84252dd55ab013743180e0460795f3e28a2b1a0d71810a8778f4681a01733fa1bcd411894cac12c1e745f14de500d541b55cec9a082f1e835097d19379a357f25e6cbd86b2bc7d1bae7ac9cd174abea283ea9a9c6a00da2ec0cbb33f833754ff6e1fb71bc208b20bc258fcc819be988f8ab049e69c6a09cce8fcf0e034c2fb3f333ac591393af96cec5d48f801cd99d7069edb2916492a0d20991e6674208b45ee366d5b75bbab1d67096823d42a0d7f00e46fc5823f1b4a08ab34e18e11e67bd8009ae48e331a4b06c234416b146f92432cec83d46127c59a0f1b3a863e80bcc51dd9d1d423364f63881a78fc5ffee136777eabd7b06f98684a0f2f74137dcdf84f2562bddc7e6e83e5fdf3445a56eaf7bdd4b4ffcc37d96e75ea06be65da1105005069ba66b4c24f80d85bdab61d9916d81412f685d4b4d738c9ea06080ddfa803a01567e4acd340d1f44b022076ea99c30588c9c6844ab7bca360aa008ffea40a1a15f9987546559bf10412016036889d635e44cdd5fce15d02b2278a0711d38ebcc759ec658a4f4223abacdb860438c068b9e93db6bc1265a248bfca0a040cdab08c8df2a90f034512ad3f0c7add8b7ef72bb11f95a70b97a4c67c4a94ea067d17a85c3f40702f829b4641e5e611823afffa92d04282f568ee654f516767f80", - "0xf90211a0d24efedf8a454a0d3fac2cf0f1158782611cd15f3ad07d2cf6de7397756473aca0c51f750462426129cfe33a2fc0f2e12c3516a43a8cbda7b97c8c79dd5b972e8ea026b1ead6e26bd7bb433cc1d0466eed9d6ad6eb49ae9166b7be920570497dc4d0a02d4c95953ee925367fd9bc95ce0a511aa05c5c0f0c36b5ebd90e3a1001e36748a0612386b2675e7518879d6217794bbc078caf9ed4aad400f06458566e853f49d8a0cb18fa17194c71e2f3a5ed3e52924239159023d01f2aed4f76db7a4f6a1bc8aea08df4f398d50f17c57cf75204f74d9ffeb79c82f5accf043fb9849304d0c2b571a0a806e559f2ce8bc5315c369fefc332734c59e0e1952288e2a78d9b99a3cafedba0e332005b0f0909ee9f6e626710c31e81d8f075366bf68baed6b553305ed07d17a023b9863e2fca03b66d52510acd09cd8350895bc2ceff916d4c3c52c3383dcf0aa0f51cd763de829b5163fac34d8e9fdff35f67f60b6f5955a0b47c0c9c3a49f38ba00f1820f3f47377a63e931a98fdf51bb5c64b451da543a44bd79494c7db150093a038904b7c6dabb8d1819dce6d12d3d95da15757cecd0ca7c31db1a280a45dca6fa01c64cd40c98a8ea20eb48c32d3d426394ab7d916a06b91d10b785ec3b69aa9d0a0e673ff71706d13297b7412ef4d974c6bf9421c238312b56e062406d9e1fd9cbea060ebc1efd84ad72e9a6249c3f17d28bb09e8300df586f46e17c73f8335f994f180", - "0xf90211a0d7d2739ba9a19eb2a0ac4f12e8258a1450739e5d9954057fc59ea39f215274a6a011796c637bd2d1ad43d9bba09b0df67f39985cd3c7001323d5fc6d62f28d65e2a07fe6c9a60edc58dc24dd93c1e9373690a8a32eb03b07621963af5d2fd3d1ee8ba05d33d4027e3087c8e08cb0b0989489c17784a926ab05174c597e37cad3c94084a041103d8b6310599160fd0f0b645a0a3f703f7791e843b80a1835e79f36346783a0f0ef09c01c0ab3e198bed05a771773a280e409b06ffaebe4792ff853950f0217a0c9058428b0e54405a04f169db21f84f5ccdea54c1b74f8e478957f8760abb26ca06f7b3626cfeabb1be21c80345e7bef3c77eb48c72fe50fbc1b1b9f83c77852eba0838ddccfb9e147fc115324461127ae97aba36e3369c06a378050f04f1a0e8b1da0d7f4b2920baa057b0c8d5eabbd9060339aa3e1e84e031cbf471327d2ae5b895fa01705095607dab37f0760ac40b1f3d39bfb6d1d4dce4e13ca6348af43c462f48fa0b06bd86896f2e2c40045177539ef5fa20a92fbc0431177c746eadf79fa8fdcb3a0272ab367042e32170d294ded64103a6c66c001a177f6cb89f1e76119d717ac0ca0097fc6336f1d77cecbf3be0287740c342bc76d396b8db5439a72795a68f594ffa02d802e568e39d74ccd567fc07951d895db2c13b4cf4353b61476d3b32c7eae16a0dfe48f5e741fc2aac4f4898f93c5dc41fd2e3406aeedc12786b773421c7e6e5580", - "0xf90211a04281d2938cd2e59b9fab2c32b037843c69657b136ff2ac408bd2fcb84e9826f1a0f37c41c8829800b782a583580358b2f5fc23dcccaa556791112fd144c7355d0ba0942cb1d6aeb45afd5c0bb5959d7df5e0c57f90bc994d02555123ae95accd488ca0bcf83b92fa106e8467de32b836820ebe6cc99584a8e76d0ec8d7dd4b79401300a03ec2bb286ddc78962ba86d7e9483c0932449dfa13c9f5c0135bf75a2f1170057a046f469bc13c6770b105379962726b5aa8669852bc8f46a823cb8b14c05de2baea039fd5c8f6210fd48da67e4029486145ada0a431f509315d1a6d6948081a45b0aa08968c8da38e38dc1d19a8027cda5842aeae9351404a7f25aac86723a132ef936a04aeed5330bc3653aa4e7e951805445e504f5173af5fe2bee117ccb10569aabd2a0c407bce26d76d3101560d81b52bfe352b7e7d24f0465a944bd2de0a411acf695a07818ac1ab06981a2f527dbf322c8f183aa749fdb97b4d932b526e39de1072ae8a00696a3192002cc997c2082c54ef0f6b293ac3590dd887933b8324788f7a00cfca029b22e442b31f4ca837bbf3983fb9d8953af9b38a146d7633dca938ac395f7f5a0be2973e4a1431fe96eb45196e155737ffda94657d06f17a42f9cdae318c66de8a099e58ee404f70c07b81405eba9cdbeff06bad97311d85bb44a645f81d88cbf1da0ec0a3bde9d3a8af047279f151f61606d08593c1a734f0ee51bd82126904bfe7080", - "0xf90171a034a375c8525e20280ca1c784dfa471ee212a9888c1ed2007bc3bfff81093b4a180a0c03699d9c9c6a0085b3a02ed975b8f72bc940b42ff766028700770f63ed1821b80a0e708d06b7672a56bfbd42e4f9ce453428e05768afa8921a5f94461dbdda4616f80a0df26fd99ac5e117099d345cbe620d3c4eda328b128e67289807a553be68329d9a0087b160284f27067bb999e1acb20d914b60e8b58d18fdbe113a4aed133eb3ffda05f87e042afe87d1b69af356a79a7bb9b9b97c666e849e32cdd3a1d64a131e28180a0b9a42e7325890186dcf34fad17239d6dcc0afa8d1c1082921ad9c94bfa139f31a095b68a386ffae88fb123f2c7add0e0b4bd4d92eb0c84cb01f2c6f15f485802d0a0456947ad0d0afcc32fd3ec8388d93d184d55d5c0c153b72357aff8f9f259d525a074506cebf4b6fd75cba3beb3d02ea2848e7165f37906698f76d9115bd0aea892a0a695efc42926a5cec6423bacc133deae3e3df8fded19320f02756d5cbde6f31b8080", - "0xf871808080a0c2fb54e023252a452f5273e38dcb5b144735a96cf3da1dcd11b30131bc0d9f7c8080a0df51977052c3e1239f8e289c885aeb96ab982c0c33f818cafbbe4e39eec18fd680808080808080a0a9a25ffacaabfd5500f37c3204b061a8678ba8c0011b677ef16800ece181292b8080", - "0xf8709d35c76107574668884c86f0086dbc124f542dc52239a4734e692810bbd1b850f84e018a048e53aedcdc84cc3430a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 5702743, - "address": "0xc5096d96dbc7594b3d0ba50e708ba654a7ae1f3e", - "storage_keys": [] - }, - { - "address": "0xc5096d96dbc7594b3d0ba50e708ba654a7ae1f3e", - "balance": "0x0", - "code_hash": "0xd8d7a917195ee296ca29e5415a804908c33276159b0f9beae6838f8fc0d1e2a6", - "nonce": 4, - "storage_hash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a0466eff422c8f41a83ddd675a4a7d0fb869b177b305601dbdcbfce0765c9958d6a04ebae0c533a08cb9669a45ca73538e75ac0f0be34d38f775a372c3e628337898a0f5ff79d40d9d2a1c0902cb1eec72f7113aa20f29d58c0d647e2e1ded8d326228a07766d38693bd8d8eff43acde502affb2f19a9083812728b28e2b7cebffc01849a04474b13a599775529d20c31b3db6c9dc9c5786555f1feb81fe9556ccef22840aa021eb1f05d46590f13b5cfc813f349d1fe891396bcfca18ff2970e81ac64fce4aa0dcd28d3e8417c174ecaee0d6f61c5caa965e520369ea00a0118b320bd5fe8923a08c365b5cf0002c98b5c2f72d6fb6785cf369864aafba558b8cdab37b0f505c84a0384683edd69d60650b2aca64a0ce1d6682aa8e5ff6bf70f1dc3481bf9382a57ba069cce4184be361358bed9eca483afd1b735b6c63bff0cdcbd799e706adcce628a0df9f8feea8794bd0f591bfa23dfcda7b0b0abbcdac6ce1a1fe2dc9d1d09ce117a0b104398c834a00c9e36e7d9126b5454fda992f576b2de5a337c3efdcc1be04e6a07bb8947f066d375efbd251e32ea6fc0e45022e0e88e88b6e3b6aa54162c11398a01ccb572d0b54791c06a4e3d2a79a21b2f63e1060e718e70d7fc551f448bd2aefa012c2428088219f9e48c1d5bf8d26abbe06a9e1b25f4ea43e454410d1c06ba456a08e13f2a438f01e0fa6fb487b19fe276c28d9713023fc84367074ba5ca74be98880", - "0xf90211a0db112c6bb242657260fc1b6096a747a0753f4ec97b5384413330fb32e1d04387a0d4c35bc659394c097e4187df960075720e6155c91d5d3ea58c15825568653a1da08b7f29ec2d39406d1b7be7282dfa6f58efd2c7929870053661749b55e0ed17efa0881b9db6aa685b60c8147e41d26765c1afba7bc6378c2885402a1dd9cc7c5779a027e940e8639f34fa7841447b685ca1eace1532e5d8c4189d1bd4f05eb17762b4a0109ad9af7c562aee76e9ddd8ad6b4ca06e52238e0a3e3fe16910e70ba2124065a05a79efc79193d044bcb0e886cc0fdd44fa13b7e727b4ff0615188624e4ca0b76a0c4b4c74bc6f5bbf9328bd38b2ac1eb2bf26ace136a87daa189c514500a7c08ffa0a6c9acdbd25ef38967622b026f27f21fe606b1490859006d0511796aa2f2112fa06830c2ecbad1e0f0705de2bdf100eb383cca06f531c9ef6051e4a5dac2649a59a03a4cdbd9bb07a666fb045e1b6d6c680e8d20d7d9e9d67c5c76e8c61dc807ec3ba082999b9f2f066dfe12caafd581b4d9dac64177a8190a16b361cd38ae967af45ba0160d07136a66dd69c17dcca33195c9ff047d8a5e5793ff94818297d10bdbf88fa08889be38b11c1801311292eb06e4e0fa6728447e9e7f238237c51fe3e5557182a06b595992febc1a899761b8381b3fc49795727883fcfa44788f230e677b20cf9ea0b9efbdf0ca8f11366c0eac26776cf1f3b6dbd3ea7999a01b0a8bcb64918c4d2680", - "0xf90211a0cdfd11896d996c1eb2105839e33b15ac5b98b3584bec90837f682bae07030a50a026d2f488487cc9f0e5b55f0e3195dfd0e1b1c99556cb225e2ef1f6072dbfa689a0edbe0ffb8e83536392f6dd064baf80f60c1a01338a5b89b70cf6cdbbde30e060a048433fa7bbe66027f40bdfa9d7f7230ef1685eacd981dea2d0cccf39b21493a0a084c00d3b91e0b3a2b231289ec0564346b6079fced3b66a4da2f2b6c7958bde62a0cdc968d0af5a79a0e9efeb99456a7d94f871f4911bbb325449d4d708c42741d0a08493ea3066ba537e26c082dbc8a86995647db055b2f9c192ac6296a6215bd9b0a024bdfbcb5221c4f7e483c090e9a27392efd5c655d476c439d8aac05c31ad33fda0323c822154773ea8e3982d0e9dd0d00bd6b8f13f7069d088f732f4f008c52a6aa085526517268e4b9f2c361513b45b6810de5188eecb0f9c9be60c862a2de837bea072cdda0e4880f289754c121ed166dffce16dde47f54a790820615e2c8ab11d05a09947bfb1a53c2ef86cb42273469093fb47fd71a85aa42bc65ea844ef8f0df54fa0b954d13e929ae8bc1232cbda6af00e8331717cc2a1c55019864cf3788e94f832a0e7f04ee24663e69375b3e26ea61e8e181ebd1e60f39d74a980778a65a4ff1c6ea0e8f8fd34c9305f092984df894166bd7f3aecd9bbaf6d3b2472f9bc84ac8ba3ffa03a8f6f8574b208ba8cd27bcb38325e9457e977cf3c1d071e9f97e90765e59cab80", - "0xf90211a0745362c5edaaf8dedaad40058864d4839aa1af52a9370ad38e20dad9295bb771a08cc6daa0010350c6127e6e4a95aef5a5d657d35f7f2cd69c6e1a0ea016ade5c6a02459f589e97ddad768498128c9c0b37eba75d25f4d0fedaafe8cb932a4e0721ea0f6f4b6d3daab40a9435ef0654086a8cf929a34e408fc1e710bac7599416c4ef9a08e2df1c9cd20fcb305f89972cbabeb2cd09c561f263d52f6db29da437fe2732aa0a8ae50fb68fb7c986814cf46333d1cc19a77a1a85e169158ecf749877a22ea4aa09a5a1174f392d361cf28c94e2c2b72eeb36f115164d1bda1fbd8828ee4e43840a02cc20d65723b469f7b4a75f60e2100283eb1ee80856cad5c95a75a913c946e19a03ef3463fd2667c7f0ea1039a81444ace044a262cc2da6892da4956e2578e62eca0bedf263f10f2c0a03a2abfabdb8393eafa02509e8436197899390c1dd9b3c393a0fe7c10a0beec3c99ff51c279b587ff7c3672ffdb2b89301fc700c0f0eacec738a0024a4f09abdf8de4887035a31c7c93f68162db155a54ac64a57685dfc1199d09a085362a9772c1a1ff4b6570121291f4ed1a7a2a2a12e0c2c01b3ded8febf8b92ca0046f0b2aafb056030d0a1eee92136e19d0434134dfba1e278b414cb61ae84f9ca0101a2097b8cd907eafcb73e174fdf470ca4e8dede09d1ed85c29435e35b4128fa083c6bd61551cb0acf3d8b7a20169b399cf18572a7cd9ff009057eb3a66c64f4480", - "0xf90171a02e3a23858b548fd8cfce5205f5652dc9074fd1f41582cf233e296e6948bd9046a05d054fd759af1838b50bf8794ee5aaf7b7fcdde2b491960a8bd0a657b7e08f25a01564e428d1f40b8df79be75d04ebeab909dd6ccc53b26ba49dfdb655b36ef71fa00a7ae2a38b5d0dccb75c3ae0e11ce7d458980e4004d5c251e4818d9f22334c75a06201d24aa39c2a555efc454fa01ba010985a7f41c6f0ab271e8b410f3ccea56fa0002dc84d2b6c1ccf89f986fe04801591e19f9e0e06233d979fe48e2d3b2c2cae8080a0b9e1425c3c36f6e8da0834e2a510b48899d54e0308d5fb6a81d14bbed4b05c3280a0081e8591497d1c42180e3bcfea92596cf7d576e898dd5a829fe79d864b2a503880a04156a6a164026530821c164051e64a8aa674a07a59531a3c12ecbd41dc9077d1a08c118c5f73b974d74369331fcf552c1c1e5d08b8a83f020f7062a6cc65bfed85a0ed2d73d10a148e44c4e207558873b8a2b7655b27d98cdf63e89bfa649a1269318080", - "0xf8718080a0184795fa17ad2385b718a47f64eed9b377bced6e918abe029b04bcafdccaa5f7a0f3ad0289c08180d80e27fd10453cf81285fe016293d6709555dc30e862d9fc1a80808080a083daf2b5841c4ccdfe50110b8cb1bf0945457a8fd62741fcc861f7fd471c59018080808080808080", - "0xf8669d37220711f731cd1a5ba78b80c2582e89735bac156b0da3a8c94d618517b846f8440480a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0d8d7a917195ee296ca29e5415a804908c33276159b0f9beae6838f8fc0d1e2a6" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 5702743, - "address": "0xdb0214b86e9eeca256d0680ede6d995570998e36", - "storage_keys": [] - }, - { - "address": "0xdb0214b86e9eeca256d0680ede6d995570998e36", - "balance": "0x0", - "code_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": 0, - "storage_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a0a424bf2f00ea331d3c45c11b9e89e08a2590380bc91d8d185c0ab05cd7788b9aa0c896f85c27a11f5b657378220386d20afcd4bbf2776efb9dae4c67057c0aaa56a01e932e20b995b0495e17e017ce064d67a6cfb7bbb2c2bdd55f2fa37bfa204b1ea00c4979f831e1c0e9cbdbfa3ddfc1f15c3d4274e942fdd5d0cfdeb14ff33462a7a0f8f38e2484feecf970786462d5263ddcb4c4d97a1424f0c817e326fc1ee05c91a0eaec8fdd6bf756348ab68b8c8bc5d2fb7a363b9f150c7a894c7ed18fd17c7bbea03ae6854881c7937076081d0f2560da199dcfcd65bb13fb338ad496deb6043585a01393a2cba343a411ee3a4cd64cf61d09fa9a86739e70e0c4e01f14ae5ee8eac2a0be58da572c4d19ad44d72681fa056177dee89a47757e0d189c033c5d4882602ea06b175bd4634d430085bccf94375229863c352910021fad7ac3afb696776419b1a03eda8f03337ad23fdd98b760bfaad18ab919f9f2a0312aaab1f655bb1e7a671ca03d45e2cba87797c109b47eab387726bd23aba5bca983f454f613970742988e6ea01cf511bff9968de16c2a9143549369b374eafafd2b7200993f9d7d020cf744b3a0500ffcd0c91c9c5e60fd51ff51d8a53d8289f106b22c2649d9cbd1d104cc9c41a0bd8dfb60a48523fdc71c1abf502f4e60b78720153ad13a1080643185eb2ef8a8a012052de9ceb2bc8c40128bff18b0db1eb24cc085c4a73643655599e35a96b78580", - "0xf90211a0c384127b99b66a4403472f3335fe93626f6811b3f0f70bcc09277e6a6ddf6b43a044680b0a0e58432e0f81131fecb5ed190cf5844db677ab9038c4d23f9c9c4455a03c299d8dfedf7f0c6c8fc45568f6f3c972ffeffd8cc89d464fdf8611631c1741a0958ce6e7db2949f45e9ecbe8274db92cbc675c482ab77a10ecf40c7dac6210c4a006947d33b56a2235a7bdc14557542aa97cf234b0e2fd19c72a8dce1b25c1aed0a03a9f4c491ffcdeaf429bced926ad8e04e1f3bc560588993d8f5485efef5cdc53a0d79b6848cdeafd1be411446a902fe8b43b214eca2c5f81fef66ad522890db3cba094ce6d229d8e84a472138d1d79cec3977f96944a492364e165769e2f0a8c701ca03ec918eb104c1000531a8b156868ce79651bc789e2ceb4e72670c8c055118664a0dcc684853f8cf2e357049fde46999f8f8a59aa4772b8e12cde8ebd61abc402d6a04d62e6ac2122658dbf552d70d6474570c39793876ad5656c3e8f10c0662e05f7a00eeb0701f38fbd31f6022140671379891406563b009b73b8b7471c0e85a35825a0b5580c82a86e1b9b1c0abe1c660eccede2aa905ebd74bf6476fd1ae72e8fb1eca0af2531bd2e64cb01b2d373eab46f1f808f80d107d852154a7fbccaaee7f4d18ea07346598b6b0197c98106ae6995a7ad152a21ea3f26d914d92ac13e560dcdd41ba0575d0cf2c7b9c78810a4db1bbc20c042e7aa44456b3433b338e9138f82508d4e80", - "0xf90211a02d7a99a1a442621d67e4d0d93e7f53606628c163efa1459e6ad33e4150c0ce73a031c84a576f9130361959b3d2fa365adc1cff825930d3f5002d96273ebd9a1262a0836944c669808f05980b79ec71f7e59b110f9207f641a5a511496ff892bbf1aba0ec2b1254fdb9cb41391ee89bb494af294ae5e3847c751bfa6567d42e0f7342c1a0a12d3255e7d3ea8b694a1239f9028c1e0ba11cf737a4d4a35be53be947386cbba0ca51b7cbb8e36fdc17384406253b0ea4501fe66b3d423085507c925e86f16337a000ffc2ede8f641bda76913fa5ebec34183d6b40433c51fa45c2ebdc8f072fc3ba0a7b559a6e61713221a495d211dcceb168016cf0c1c806633646b8f1f8ad5888da0ed4c8750d1b0a1397bc0b6b666269f165b034cc96613a756853f8f7b402776faa0bf0f13c4c8b4e2ea594478e642cae48f7991a2075ed2d4e894d0688c3f73322ba0d31e234ce90365a786de81e2b10447b18d1ccc0020f0aeba23885f455cf0a1c8a073082f91d4854a916fca6f780f6626c3c4bec4b0c37288a0ab354fbcdf8a006ca053a05318b3d47c3a10bc3b65b01872611a18760b642b81f4a125131811677bbca0d9f0d1167f2dedff6a81aae645334bc7f0d48d7c79976470854a23742277e2bea0bbf892a3153345380e3c4f839a8e53a4b01680d17f53e291d0117c9c4c5b6ae8a03b4ed0c126bd651122084086931cbc5c7ed856f741b3fc84133c12af29bb140480", - "0xf90211a0c1d631dd211d1cff93265256a48ca7c07449157075ca7c8c7ed0f6452f3e862da09b578b616b2d727dc70d44fc4f954d35bb522ba34bf7a40cf3188be4b15fca03a0cb34d4f2fa1a5edace8cdec2d6f3733d8b862868d117b91c4f76fb21e6a59b3fa0b603d058a28bd1cff30db37da3ddd52ded7d04c614d75c11eb7508469dde0eaca0565327a17891af23f5facf0383604d9b2a75ef3729f9b488d6cae8e487bad2c3a04b1e593441e7283b4f9298f63f10d40efd87fef87d513ba04fdb3abd511ccf55a0a7e628147978a0fbf7ac623b6aa2b2ea45c54b60baa456e552e01fab332aef63a09c67637cb443edba35d2ebae2d296a6dcda0da838ad2fa5668c8b5bda44a1b89a0312d8dfd5f31fa1303c5189d167041faf415fa209dd560cdb3341a505c3e4a1ea0a7daa87149c1cd2fad66d3c524e619e90ef39321656d7f1e13a674726c3c6256a01bb25638a7e9e87af64a7224bca1c64dff70331af1c5284586a6b9628bc00b84a09df8c3e6307b2aae557665688bb41ee2f5c8b80707a202349676aff6599b21efa0bf5fd14d00fb120409b71f3b1873c8ec2a644e8c6098584cbb7b0ee0fd571347a0fd82682fbd836824ba0558f2a0c9a7f22bff92f5b539424aaf3097d73a968cd9a06a7a13f9fe09fb21c08c8e449179df41902f5cbd05e6ec07fbddd9221af4f8d1a04f9bd6aecfa685718a46c11d56dde341977e45d8f59512d35c23adcbb66dd16a80", - "0xf901f1a01adb2057f2e92eb1e12aa483aea576d277dde3e539e944a31d8f2592052ad33aa052e4d4c82f255e2a119fb657830b0acb0d2fff25b53bd065b1c66f62487ab522a0f284476b11bd8b0f6a83a3f8bc9593308cad66ea3b52c53cb89a369b9c75fe9fa0cfeaebe55702eba2e181ca22c5cdc742b6c32e715d2ab0fa2e10737fcd054627a0331142f9aeb58c992ba94110b86c59d306f6968b38a6303f3aaa09b8de79e4d7a03205c14d87bab4cb315f584451f5558b8eabbbafe981cdcfb3513c65138080ffa060223f98a90da542ecade0b3c44e49f100938630a4e45b4d741fcb1dd804a22aa05d6b043cd40298779c4759079f27c81945281b5a024a6683b38a6fb646c5250da04a06d20f84169226257418b0c28a54784ef257fbe3116c71c5c98f385a39f9c9a0470078b02d0b895184a19ac22f53234fb62d09f0869b54a36670bad36718bf17a0972ba4cca9e04c8f05a8f465bf18bb01d2785b9509e5a9b648eaa9d072edaa25a0bd7b02cfa3f1c37445fed38578e7078a1304ab369190bbbeea8bdf560afb45a3a01a879938fd2fabe5c695280687bac3cc3d2843159f0269be2ec9a61c434ae0aaa02c421a2fa51be2d40cc433e3605a5c391ef11933c23594dbdace1a7f9c1f955f80a0e87274852c5ca004d634d55ce0833c57d6293e944fb72a748dbc7ee3c5d4838580", - "0xf8679e20ef38090bd6611ca88b84ed3818a051dfcf1c5aef75a604dcd7310f9ce8b846f8440180a0374b893364427e3d960d8e8d2e9048e789f19657245d4003a6b84212b27cd5cea03e476dfb982329928677928dc0365bfd0771af7e5d53d3709169ae561f53833e" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 5702743, - "address": "0xf9617c4744c85c04f85d40e4eb119ac52740f9a5", - "storage_keys": [] - }, - { - "address": "0xf9617c4744c85c04f85d40e4eb119ac52740f9a5", - "balance": "0x0", - "code_hash": "0xb32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114", - "nonce": 1, - "storage_hash": "0x81d1fa699f807735499cf6f7df860797cf66f6a66b565cfcda3fae3521eb6861", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a0d1e5796b37e8994fa688809172fa9392e94f685709462f1e46ceb68a0405a69ca070852fb4357239cd97ae6f7535781656f651de607ba8cb05def014e91982f701a0a3f0511e467811ab7d8d643ae473772fcb976248e679dfb2fba5917a2e3df5ada005242866b01240c3098d39e5cac3e3e5fae0c834cdeffee283d1e0bae255685ba0f637fe7f2a0b341a630683611074830b9a0003282c28693175dc3eeb046a1ec9a0ab2974b0ab7e777b78c9c1ce1df2e20b4605e4743c1b08adec6823c83720fe36a0246654aa476b43cba227d4606a1d19f1fcbad2767ecabfa2dee4305726846ec0a0c3848c1f5e7a6f3f8e9ec6519dba2680f8c19e648d34134ce211c811b3f77389a0553e82503781242e823066ab9dd7ed662346a9b8dc83d77cf6ded5d534996f5aa0bf55de416bd5c1e0a548c46d10703ef284a230a1463d5b96a1e5a23f383497eea012ed7f60c6dc90a2afbb75ecbabf0938e3a02313045d4cc1c9ceeb1e492858d1a0a11dd2dd9375cc132cc8bdffb498f848cb80e842e3b2b6a2144e9498f5974ae7a0beb16735cca78f6165ad876e1f17a0d7042a982d331188d3bd0a0c3ed7d1e4dda0e4d04d1e01d8715ada417078ab6c5b90a04676e8896dcc05a0ea4f26a2a5c027a0d8f2800aa5ca81a42e49fae1da05f1ed678c8729c293461b65df836790e1a6c2a028838fc043c10adbdeb638a43c8270ee9c9b80c0b26f6e83d6f2f174977dfabf80", - "0xf90211a09353ebae476c5388aad75e50ddc0576a9e7cd0341f3cd2b49298c976eb0f75d2a05c4eb1ea2fcbd0df67add8337d52eef7ece775f3d28b0d70eea2a5a883b86188a0af182c7ef39a62498dcfe78fe169ebcd356e8658d139168d5ca3834b6460602ea03b17bd5cbfa064f8a01d58125b7851f7fce0f47e03183dfaf805846a96899d01a0b836ce21ff8931447f4df0b78d4198fa5e00a5bebeaf1427aae5b8b911f51f76a0ee7b69de33ea3868075bdd4212ab0bf17bc6b682f586396375c6eaa5983a9ff4a0897b1e01287b4cb5d946828edcd4cd58e6aa8ae35e362e9ee267c96ea4390b4ca0447d105147eb37e4fc0913a1ac644b0e09c9188e77caf88c447471df4f8799eea0e90bcf93290dad9f19b2d4ac8f91d4830afbc920d0461bfbf34a2e4d36437d05a04581c0ccf50bad9c27ebb90e3612e16af059e2a0d3baaae1e0ca64578294d2dba02937ba29c78c18f9ab562bda16c5eb84a1fc7a50bc1186f970310233d6cf00eaa004268181e5702d66647f1a56658a7822e8536762bc6ccb38fc4093ea7e19ac7fa0faeacb8d105d37bc973e5bda61b9bfd5c6a2288a5e13e5532593c9d672d6d7a6a0b225ae417e9eb28406719de84954c657fd74bb8dc787227233f7992f21675a0ea07b91edd5e623fc4269e47646ff189454c2000e252b2abed8a9bf0c813fee349ca0eea3efeb1c9d2238285865fb1ef9244e72863904aa9b0c8eb799ae3323f0ac2980", - "0xf90211a0a4869d9d0198389e731a2079f6bf70e74bb520739c4024e8c3faf2269f523de6a014b4929a4560df1d252657ccace73c4e824320afa89d9d3ae8d0ef955aa84349a085f16f203bcc37199664713df3ae1e09188ec628d770bb714377ffa48db0c1aea041f134fdf7d2c74ddc0dcaf8777fb476bcb251b4cb2ee8e93f53d7ca25e3518ca0aea97f47051c28539caca5f8c9857804277e16397839ecc371c7ebc7aa63f98aa00a5e9e6f88522e7961857c4ae6455b9405e7abc099f7d41e6307f6e7d084330da049a738e639cab43a3a4d952cb36bd0ff61850a5ea0e7bb56d982de99672c6ba7a02eedcb3efcbe47e33941fe2a19bba3c80edc354903b27da5508049d1dd51a323a00c0111b6904592085beb75390a00d9c5e58b5570b04e986e8b930bcbfeafd566a08b311eded392ffc4b25b5da12ee0af0c3ceac8a3db0aa68bf1b598fc75135d2ca0526a84650b85866d0cf4e56dcf7fa8cf1e5be4cf7bb43e0510a08cd522252a1ba09e4ce8a60c2657484c68ff6ee060063fbeb0488e2875ddbe01d205dfd9a9d56aa0703d16f1b23f7632313d4e511215ad0086bf367fbd36b4c59b6b92eee772146fa0729aedfe1504756207d4a9be22efcc8341756897fb08133b54fa5b5599282339a03cbe3b75a821c6a1d226907a6cb02867e7360233ce3aace89cbd4d6ff1ba649fa072a8bde1bc871e145e797cf512a85a3bb9a7df7e18ee0edd7ac2efe15a69dcd380", - "0xf90211a0491339d3022d4c62cd679baf1c259a5ce10bd4cad416edbbb634f2199acebbf3a014ae743679dce467fedf4d3d2ba8d6e30e2ba7e529d5127f85c819f27383f700a086c17141c9ddb179dc1f35d596867936c9e69decd0df0daf5ad37b9d9b110befa0b1b00a059ed4cdb5e8c0d11ef148742f221bdd6ae93012d15d8c4c38f8c448eaa0ad59fe739df494142642cb20d940007c12c7f62c5df443d23da7024f27bd39e7a0a7f4f95877ab1593966a4ffe2a4126f992f40b23ce388096e09c46f6fefd95efa0a375e73837329fce26254bf5806fc2040c938d98c5e744372cd1d2a94e402c4ba077ce50e68f895dbf51658ce6fbbe7d2c1e8378d2bbd18189ead83ce2f020acd9a0e676dd966feab89a4133aa58f0713736798a44b93aab63b81db5570b7632de9da0b7f33be7d37e5d2b49b13945a25a4053f552ffa1437ef9856b7baebf304b10b6a0466d64ba7c5b962c5b7d7aea41efb168c5f9fdc7aae92d320cd33e296df3bcfca03c26140ba0f6ff8f78dd9e9a64986a2bcb8620c7c07252360a6d067cf4139fc7a09a789eb49bb71fb2a094b1b0a6049a8f3772446284d58a2b0efb9261c0d3dea9a09662ba0431ba8e02a81d383cdc54e56ec06a371a4002c1112ed51f39ad43e96aa05f11a71f79c75d5c9b9e5f512a3a3ddb6ae97ca08fd4dbd4b8319e6f107afe08a0b50f58b31428534cc355acfe6510a971ea3b1572cda61971ca6afa08308ccb2f80", - "0xf901f1a009789bdb0c6b27a35220a8455b48d13e184cbe7ff38107f61bb29d891d36c37fa08fc3f7520f54fdfe65a6282f7db285afdeb892f4116707bc0cf3ce04bc132a22a0f383703902b88c91ae9078337feffcb1ca338f57f5836ac7768baabbccd91556a09d29d88de1af443727c234ee0e3462874ea1e04a6ac137e9b45001f72aecd626a02b87420a91a13ca2e21f1bfe1b406db376255d3c5f00fe5ac8bbef4ad1bb9870a05c585fd8ca9be81cbe6ee073f468fec9e0f542fb5cfef0a8027547b8836ec229a0c6d07b99bf9094bab342f7f78e7ca525c442e7f07bcb8acd9407991600c519baa04f288f8aa1cbdea4a08729ffbe6fd2ed84bf127da1a1bfcedec8a86bfa44e78da02cf35642ada8d014a7d35d12d34ae814d79a6ac65ba54abd5ad91b97b27d9400a0804c411f4a6f3194c491a240123e86a8eb2fdf6ee988e45301ac14b3ae64d42da099623bd6b1c1977d9a6bb3b0edfa21046bccc24a4803970062e43cdc3f31fd6c80a0d5899676c344a911cb4b4e43ba602215061d7c0ed35f1cd6be368e2d305214dfa03002db8a43d0157c7809ac884becc5c137d6ce2271a611160edb8b4adedb3864a0cdc9eaa2d32b2eccb4d93584cc2480dd0c5b684d1f676d60ede32e21265971c7a0c5e630e35e5a8a3ea0506e8b740454e9f0345aa112d382dfb162c3075a14c50980", - "0xf851808080808080808080a0f901ebcb25b544319ffb035f8e98380ddc0aaeb643ad6b038ed812ad8ede35368080808080a062be5a2ec868b695885dd7dabb305ec589f40cdced8ebace6c5d817e5ae9af7880", - "0xf8669d33370847284588722e28abf112ac4df765cf886b5a082cc96b8cadbd8cb846f8440180a081d1fa699f807735499cf6f7df860797cf66f6a66b565cfcda3fae3521eb6861a0b32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 5702743, - "address": "0xf9617c4744c85c04f85d40e4eb119ac52740f9a5", - "storage_keys": [ - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] - }, - { - "address": "0xf9617c4744c85c04f85d40e4eb119ac52740f9a5", - "balance": "0x0", - "code_hash": "0xb32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114", - "nonce": 1, - "storage_hash": "0x81d1fa699f807735499cf6f7df860797cf66f6a66b565cfcda3fae3521eb6861", - "account_proof": [ - "0xf90211a0fbcf26780946bb7122c85d023e0ac19b2d1d20d4a28325dd301935f08f5c8c2aa0f0271f4f978f2498aa8a60494ec7ac46617d0bc60a4801b159df446dec5a8eb5a02594ecdc7fe00af62e7930926a1c18f7192e4147a41a1afe6e07ad0ae402e776a097f8d9b9a1dc35a0e1b7efc27a95baf6e85b7a670748b0d01332f7d1e38b709ea048baedd6fb793b5fff5ff9f1d9df161074abfada776f5fa25342a5dd3921b537a03e1514524e81e49ea4ab524a5de6fbb132ae5300cf7315f3b3c6313be064cfbca0c937c099734f45bc60315249c37c2017fb8dd4131c0d9157c607380fa7f151dca0c4f3b22ddbc0ed4d0124a4c7de177d40bbffc7a5230b02eea58132cafa7c564aa03208d1892af3d5be7f246ab2d8f8131efb56559dc20b380138f517532ee430a5a087af065200b06273ab630e4ae7f4313a434bebbb2ebb3f777bc0ed6038a9ea83a046682fa30a9f744d60be53e887af23695966be983962a8f5b0bbb4350344b528a02c49cef7526d643c4be4eaf2e809cc48a2461b398f7a1aa4bc85e98cd60e0c8ea0faae61a52434104dedb647a7f0457b121fb3101687a0f72d6991c7896e10a786a041abf1261106dc332e88d1c2fe868323f2451886549f6ebb99933c9939e4488ea07065a59ccef07f712950d8886a0a82697d90a86cb539d1c7a234dd5dd91621a8a0982796da99d67fd2dff86977d9099d444d04afaa1361fd707f42498ee696f26880", - "0xf90211a0d1e5796b37e8994fa688809172fa9392e94f685709462f1e46ceb68a0405a69ca070852fb4357239cd97ae6f7535781656f651de607ba8cb05def014e91982f701a0a3f0511e467811ab7d8d643ae473772fcb976248e679dfb2fba5917a2e3df5ada005242866b01240c3098d39e5cac3e3e5fae0c834cdeffee283d1e0bae255685ba0f637fe7f2a0b341a630683611074830b9a0003282c28693175dc3eeb046a1ec9a0ab2974b0ab7e777b78c9c1ce1df2e20b4605e4743c1b08adec6823c83720fe36a0246654aa476b43cba227d4606a1d19f1fcbad2767ecabfa2dee4305726846ec0a0c3848c1f5e7a6f3f8e9ec6519dba2680f8c19e648d34134ce211c811b3f77389a0553e82503781242e823066ab9dd7ed662346a9b8dc83d77cf6ded5d534996f5aa0bf55de416bd5c1e0a548c46d10703ef284a230a1463d5b96a1e5a23f383497eea012ed7f60c6dc90a2afbb75ecbabf0938e3a02313045d4cc1c9ceeb1e492858d1a0a11dd2dd9375cc132cc8bdffb498f848cb80e842e3b2b6a2144e9498f5974ae7a0beb16735cca78f6165ad876e1f17a0d7042a982d331188d3bd0a0c3ed7d1e4dda0e4d04d1e01d8715ada417078ab6c5b90a04676e8896dcc05a0ea4f26a2a5c027a0d8f2800aa5ca81a42e49fae1da05f1ed678c8729c293461b65df836790e1a6c2a028838fc043c10adbdeb638a43c8270ee9c9b80c0b26f6e83d6f2f174977dfabf80", - "0xf90211a09353ebae476c5388aad75e50ddc0576a9e7cd0341f3cd2b49298c976eb0f75d2a05c4eb1ea2fcbd0df67add8337d52eef7ece775f3d28b0d70eea2a5a883b86188a0af182c7ef39a62498dcfe78fe169ebcd356e8658d139168d5ca3834b6460602ea03b17bd5cbfa064f8a01d58125b7851f7fce0f47e03183dfaf805846a96899d01a0b836ce21ff8931447f4df0b78d4198fa5e00a5bebeaf1427aae5b8b911f51f76a0ee7b69de33ea3868075bdd4212ab0bf17bc6b682f586396375c6eaa5983a9ff4a0897b1e01287b4cb5d946828edcd4cd58e6aa8ae35e362e9ee267c96ea4390b4ca0447d105147eb37e4fc0913a1ac644b0e09c9188e77caf88c447471df4f8799eea0e90bcf93290dad9f19b2d4ac8f91d4830afbc920d0461bfbf34a2e4d36437d05a04581c0ccf50bad9c27ebb90e3612e16af059e2a0d3baaae1e0ca64578294d2dba02937ba29c78c18f9ab562bda16c5eb84a1fc7a50bc1186f970310233d6cf00eaa004268181e5702d66647f1a56658a7822e8536762bc6ccb38fc4093ea7e19ac7fa0faeacb8d105d37bc973e5bda61b9bfd5c6a2288a5e13e5532593c9d672d6d7a6a0b225ae417e9eb28406719de84954c657fd74bb8dc787227233f7992f21675a0ea07b91edd5e623fc4269e47646ff189454c2000e252b2abed8a9bf0c813fee349ca0eea3efeb1c9d2238285865fb1ef9244e72863904aa9b0c8eb799ae3323f0ac2980", - "0xf90211a0a4869d9d0198389e731a2079f6bf70e74bb520739c4024e8c3faf2269f523de6a014b4929a4560df1d252657ccace73c4e824320afa89d9d3ae8d0ef955aa84349a085f16f203bcc37199664713df3ae1e09188ec628d770bb714377ffa48db0c1aea041f134fdf7d2c74ddc0dcaf8777fb476bcb251b4cb2ee8e93f53d7ca25e3518ca0aea97f47051c28539caca5f8c9857804277e16397839ecc371c7ebc7aa63f98aa00a5e9e6f88522e7961857c4ae6455b9405e7abc099f7d41e6307f6e7d084330da049a738e639cab43a3a4d952cb36bd0ff61850a5ea0e7bb56d982de99672c6ba7a02eedcb3efcbe47e33941fe2a19bba3c80edc354903b27da5508049d1dd51a323a00c0111b6904592085beb75390a00d9c5e58b5570b04e986e8b930bcbfeafd566a08b311eded392ffc4b25b5da12ee0af0c3ceac8a3db0aa68bf1b598fc75135d2ca0526a84650b85866d0cf4e56dcf7fa8cf1e5be4cf7bb43e0510a08cd522252a1ba09e4ce8a60c2657484c68ff6ee060063fbeb0488e2875ddbe01d205dfd9a9d56aa0703d16f1b23f7632313d4e511215ad0086bf367fbd36b4c59b6b92eee772146fa0729aedfe1504756207d4a9be22efcc8341756897fb08133b54fa5b5599282339a03cbe3b75a821c6a1d226907a6cb02867e7360233ce3aace89cbd4d6ff1ba649fa072a8bde1bc871e145e797cf512a85a3bb9a7df7e18ee0edd7ac2efe15a69dcd380", - "0xf90211a0491339d3022d4c62cd679baf1c259a5ce10bd4cad416edbbb634f2199acebbf3a014ae743679dce467fedf4d3d2ba8d6e30e2ba7e529d5127f85c819f27383f700a086c17141c9ddb179dc1f35d596867936c9e69decd0df0daf5ad37b9d9b110befa0b1b00a059ed4cdb5e8c0d11ef148742f221bdd6ae93012d15d8c4c38f8c448eaa0ad59fe739df494142642cb20d940007c12c7f62c5df443d23da7024f27bd39e7a0a7f4f95877ab1593966a4ffe2a4126f992f40b23ce388096e09c46f6fefd95efa0a375e73837329fce26254bf5806fc2040c938d98c5e744372cd1d2a94e402c4ba077ce50e68f895dbf51658ce6fbbe7d2c1e8378d2bbd18189ead83ce2f020acd9a0e676dd966feab89a4133aa58f0713736798a44b93aab63b81db5570b7632de9da0b7f33be7d37e5d2b49b13945a25a4053f552ffa1437ef9856b7baebf304b10b6a0466d64ba7c5b962c5b7d7aea41efb168c5f9fdc7aae92d320cd33e296df3bcfca03c26140ba0f6ff8f78dd9e9a64986a2bcb8620c7c07252360a6d067cf4139fc7a09a789eb49bb71fb2a094b1b0a6049a8f3772446284d58a2b0efb9261c0d3dea9a09662ba0431ba8e02a81d383cdc54e56ec06a371a4002c1112ed51f39ad43e96aa05f11a71f79c75d5c9b9e5f512a3a3ddb6ae97ca08fd4dbd4b8319e6f107afe08a0b50f58b31428534cc355acfe6510a971ea3b1572cda61971ca6afa08308ccb2f80", - "0xf901f1a009789bdb0c6b27a35220a8455b48d13e184cbe7ff38107f61bb29d891d36c37fa08fc3f7520f54fdfe65a6282f7db285afdeb892f4116707bc0cf3ce04bc132a22a0f383703902b88c91ae9078337feffcb1ca338f57f5836ac7768baabbccd91556a09d29d88de1af443727c234ee0e3462874ea1e04a6ac137e9b45001f72aecd626a02b87420a91a13ca2e21f1bfe1b406db376255d3c5f00fe5ac8bbef4ad1bb9870a05c585fd8ca9be81cbe6ee073f468fec9e0f542fb5cfef0a8027547b8836ec229a0c6d07b99bf9094bab342f7f78e7ca525c442e7f07bcb8acd9407991600c519baa04f288f8aa1cbdea4a08729ffbe6fd2ed84bf127da1a1bfcedec8a86bfa44e78da02cf35642ada8d014a7d35d12d34ae814d79a6ac65ba54abd5ad91b97b27d9400a0804c411f4a6f3194c491a240123e86a8eb2fdf6ee988e45301ac14b3ae64d42da099623bd6b1c1977d9a6bb3b0edfa21046bccc24a4803970062e43cdc3f31fd6c80a0d5899676c344a911cb4b4e43ba602215061d7c0ed35f1cd6be368e2d305214dfa03002db8a43d0157c7809ac884becc5c137d6ce2271a611160edb8b4adedb3864a0cdc9eaa2d32b2eccb4d93584cc2480dd0c5b684d1f676d60ede32e21265971c7a0c5e630e35e5a8a3ea0506e8b740454e9f0345aa112d382dfb162c3075a14c50980", - "0xf851808080808080808080a0f901ebcb25b544319ffb035f8e98380ddc0aaeb643ad6b038ed812ad8ede35368080808080a062be5a2ec868b695885dd7dabb305ec589f40cdced8ebace6c5d817e5ae9af7880", - "0xf8669d33370847284588722e28abf112ac4df765cf886b5a082cc96b8cadbd8cb846f8440180a081d1fa699f807735499cf6f7df860797cf66f6a66b565cfcda3fae3521eb6861a0b32b7e95fe1702e6e82a78633931c4311f80588cf31e7cacc56d12d875839114" - ], - "storage_proof": [ - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000000", - "proof": [ - "0xe3a120290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5632a" - ], - "value": "0x2a" - } - ] - } - ], - [ - { - "block_no": 19493153, - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "storage_keys": [] - }, - { - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "balance": "0x0", - "code_hash": "0x54f2b4c90d2939269a9d3ea8a3081dce03328c947d54bf3d98b2820922840b35", - "nonce": 1, - "storage_hash": "0x5e57a60889ae6e791b78a66fe1906f9cf1ed01313a0a19faf7e234debdf4eff6", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a0ff92280515c1b2f2d6738d8665bd3e3395f88d50be2390e85297c3c25effc4b8a0e16965743d455c825267b39e41536ae0a8ddfbaeada35bc0fcd738619b180d0ca07b637f8aeb51ce49cdbd0c13f69a76aa441ff0ab56b4724176816d710e38d4bda0e2162d570329d26cd485f9c1c6d60330c40ef4048f353b4659a236f125f0d43ca0dab1f16482bcbe849f6c5bc3799d6431147718ed2bf8fbced1ebcaf9b7ee0eaca005ed4f40dfd73ccea25bb9f1506fe56c0d32960b2732d672b149e3513354c699a05cbbd810daf6adf4b64455f949bbd5f0ebdaea9453eb9fa2240c8539f0241cf0a0c8f460820eab4120d266372e935c750559440ffed29dd5e0dce62274c77df730a0c4cf1c56867e6a6f86a39920f1cd541132475c952473778db1fc1b40af0acfdaa0f536b3b135eea8bc6e82c492b067597d8bd0ed4070980c829c5eeddd48aa4a54a0dbec1df223ef521395a901852bf45cd595f028ecae72503157fe952910b57830a0decd508126776f56445a04890cfe0edc0022203b3a03fd42c3ee63ee5a7d1371a020b781eaf8390224622339435c3bfb8474e421b7cfb0ebd563ca24505df909e0a0138e7003bf401b0e58a2ebebd4f3af149b49898f26f115df58086501e09bc4d0a0e676ccbeef91b9953f1fe744f8d86a36aaa11b55e8c18142925e2f2c1db772b9a06495437fba3c66f86c8646bfeb06dceef5a08c58abbe9c646f6a5e56ec3f7d2380", - "0xf90211a0403b093e5740cf78f051efd3d96fd37a13aec680fdf38f27460c13d3369d0864a078bf4036baaf3a483f1bfc3e554b90e68bc3d0b45254ff14d732407995f6828da0c48d01c9a2281832f08f88fe8f4b2052d1d12f913b8fc70a959fc6acf1b8d0a6a03274ffd305e76eb60e13512e30a2333e3fbc7745dd82aec8e49baa73c8720fa9a009bb9a81543932d1b4f47371c0bc13b7a0af87f252eb22ea58cf0e033c0ba0e5a0bc9b0d3fa5669a80306486c045b5823530ce001e4cbcdaa98725f6d9aa802a40a038b5621c5d0b7a0160a9a8ddeeda4a4d9ea13c11c60e37241bcdef767f08c27ca058220e4992773a47dc834c82cfa4fc5ff66b0459ea4ccb1faebcd12598d6e001a08107e1dbc4544ef63c6418bab44d9188d3ee82a00bcb3f4ade5e052ef0589ddba0a809df04f6bd0265584e9cfcf77a7c9954deafb90797fca19183b8a9071a5b84a0e5826019d615e08fa7f3751cc8f16b26d5a4a2e6c02d748dcadcd05bbc9d07e5a0ffcf8b7399e8bfb7c133e5dfc4e1b048000910335f9d5a5e9bf1ef4c07ee8c3ba0da89e971f89db64d154df33036910997d1a491aa12e14d39017e9121a3fbaa11a04f2a28f5b737da5d55ae878f4323ff4ef3a9867819874e30389e2252c87b632ea0fc11b53269ed575292d688fb45c31bdfc71b3540dd1490a6b02624646578a0aaa06c9446c472be9b3bfce48c968269fff0ae2f8bdbfa2b513e3a38433bf5ad363180", - "0xf90211a0db7bf23ef980103c5ddee3660304030b6c62cd9b5ee863251aa71d518d5827a5a09329a03ffa9e0c0ab2d4a5bd121bc97fa8ce71b740571e1f69fd61fa4d43ce4fa0ae98bf8f3ec7a1f33211637123cdae14094f81cee2271a1bb8f9e787d64558e1a09736d564f483aa79c795bbd4702c98cb8470de794d07ae44496be8f37d3a730ba06eade8418284283fec5b3c6857c5f2e0c05ef7ed6fffac19532a9dfd335ae128a02652531621873643690b0e37c1f48635312d4575bd6993dfbad2e4ffef9bf504a0a19ae20e648bc651e4934800ce45a77af9bee8e59fb007ab5cc6c096d968a747a0f00af3eede9d9923143d7fbaee6f004518b346aed8f46d7d65bcd96f2796c9afa02d103be3dac80926afbcc055801b93c0391cacacc6f168ef270cc200c95c4a2da0a96e140ac21a8a32d38ce6a5dfcee96ade6c805334102259839c7b4b6acea7e5a03d57d94b9a47ffb196092421c21d8226e637c5e3662c24cd66fde33418abbb47a047d9025925a2ec4f908a946ca9d90c779e1d117c91f3c13ae00e7d257c9deea4a025e8a657a943d81b2d2ee03d58d0c69fe1f9323bbb0e15c2faa61204921dc2ada09481ed7c412529536fa4cd3d45ce8950d3be99c68a0ceb1edfa4dbc5b2bdaeeca0bae2b669a8e5a62cc1a2b6fc0655c86e1578fcd51c7b9950be63b5b7f7cc9631a007e5d190393358c90f0db5c1bf02f7fcb8be6a8703275bdcf93de8344b240ecc80", - "0xf90211a0ed3cd4ad082dbe5e03df86af5913ec72ba98b4a68b7c723d3725d36abe147c35a0181a5239bd86faacaf11fb7964007b6fdf7414a2716cc269f54f4cd1c16fc81fa0e7d60ea293bf97258e8f6877691475ea391f1dc6d2d2fa1c9ef7367b8494f6bba036278743ad1481779f14fc62e5fa7552d34386a441210b5d2d164cf46ca98e76a032b20bcf4acc1cbec679ae20b3f6cc21b3083cf693d6d2715e11df1d8b0f9de8a015308ce592b4344997b8bf0ca0bbdf91066fe3f2a0b765795dba9ff0c2181b68a03406b61338441657dd26d5ce335e003474915e0ef7592a8c099e90a421cbcc6ea050c688b2841c7c0e2ce558b68d5c8d46cec325d8f50e47d859be2ef946e9db0ba00e25d25a62600ef259bd4047fc019a2883220f68c75ec8b5706b45c3669f91afa0515d254a83fd6608523919877b5225de5ac68ef6e245247c333617fda7f4d95ba08c185017ceb61352c016b57d032030b04eb4463263a43cf21b4cef2f646c8292a0f36fe618dfb271791b41eeaadbcc2cc0a0fc5bc48d0d129a2db9d8f9e509e9dfa06c8c4cfa620154725fe2eae526e357e315fb184fde5da601a59a9409bbea3107a05d6a30117ed4bf79cd2011e4bb77261ac9afb7bfc8ad73f359b1cb0a3708e9bba0da1094c4c10a058804879c5d1a42c4f6e5c9554848303176dc96e7bec88d1bcca026333c6d0c821b42f22402e6959a3bb4d335ead3c65ac217ba610494e1f343b480", - "0xf90211a09376caa6667827047065418939ec9484729f239b2d075dc006454d714bc09d91a02fd1b4572ac1b538b2655f3d4c35908c84401fb59077eaadcb0b55ac4be4b560a07b3754af4b06a151a0ec4805323a948dd3ee5b420a0bed2c1d68589ac86cf606a0553c97cec8884599497822f3f52903714358da0a8d93cbcce355ce44db6604faa0e99617880cb766df68ac0756a6104bb508169e008cf04d5245973b42ac5a3af5a0d72306e8fad5757a25aeea1f960998354f6432ff425332d6b291d832d183d0eba07222c2c15cfd4c61d75581958ffbd415293384b57f8ea69a0e086e810d6ee0a4a0c8d187dd379235aa9f9f5a994ab68773b955635338e009736558a9622f148673a0363dcc96326165f937d44bbf74bdc6e505f9acb6a2444867f0cb2b00a1196058a038299e1372463bf338bb83de536e9b6cee8dc66de77f4ddb2688922b5a54614fa02886498375d11531a65c3880a3fd6c21d5648a46c11d197406f777b72d8ae3f5a02e94fb53e6831d9f913dd4c76f6e1fb13ad2b7771419f3fbed42d4373a22106ea03c0de4be7c83682af48da2c7192e63f6139ed200873c3c09d8e99ca0b2988ac5a079c38c7986828bf6fb30f3a02bb46a825bffb09455ca8c3e2b4ff33881b65934a065460f91fff3a3339a1a5786b5e5affc0d758b905349f0992421fd0608979ce2a010c1df619ab05b46643f73a2b9064d9c4804d3941e35bdc05b8df933f6a46b4480", - "0xf90171a032f57f97366f79faa218554d5dded9eede7b0e3a407c5022833087fe8975cc1ea0110bf4c97d41c1a5545ecde8945c2b4921c4a2852ef0dbfafc36ff7e6d5ec20aa0f1c62607b2cf1689b133785bed86d2f67ba9d30b9327789014d83d8e61294364a04aeaaa8c0f3cb370f47f7768af15b7c4fc2beed80b6bd9e99e833ed785639e00a0986b2a3445e71fdfaf20af08b15c26889af1829d10b3224f35230cd86452e193a0f7d33c4fa6746dbd83a6e7707498df28dae14a4be17da8b1dc7c7d087789dff0a08d989b502684afda0933878067069d98a4510baf2fbb4824a2e43a0897a310daa01319280f21d2a93c08c37fff958ad9356514a03cf252fa56466e30aa700378bb80a0b266cc9cd37a20de7bada6a344da96f57e1fde80cd08bf53d06100876ea49f6da021d406491e68030472f01778e14e1e12b15d2442724e3aea61fb1a538160ea5f8080a0d822b8c064a38cc20d681450aa72d3c9ac4332afcb4f18e482a33dad89d8247d808080", - "0xf851a00ffd601d1ab8d623cd968b5e534e225fdb9715339fbb138e245d2a70d39e2233808080a066eac627c3149fc65571ef287abc52768479c3bb42a84b59455115611a31a174808080808080808080808080", - "0xf8669d20b033f84c1a5ab5dcb2e3dc353b0af69edec575bcd8edfede887abc55b846f8440180a05e57a60889ae6e791b78a66fe1906f9cf1ed01313a0a19faf7e234debdf4eff6a054f2b4c90d2939269a9d3ea8a3081dce03328c947d54bf3d98b2820922840b35" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 19493153, - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "storage_keys": [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x00000000000000000000000000000000000000000000000000000000000000d2", - "0x51e86470d074b2eb973e9c895b2858f9860cc48a7abc1578969424279e898438" - ] - }, - { - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "balance": "0x0", - "code_hash": "0x54f2b4c90d2939269a9d3ea8a3081dce03328c947d54bf3d98b2820922840b35", - "nonce": 1, - "storage_hash": "0x5e57a60889ae6e791b78a66fe1906f9cf1ed01313a0a19faf7e234debdf4eff6", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a0ff92280515c1b2f2d6738d8665bd3e3395f88d50be2390e85297c3c25effc4b8a0e16965743d455c825267b39e41536ae0a8ddfbaeada35bc0fcd738619b180d0ca07b637f8aeb51ce49cdbd0c13f69a76aa441ff0ab56b4724176816d710e38d4bda0e2162d570329d26cd485f9c1c6d60330c40ef4048f353b4659a236f125f0d43ca0dab1f16482bcbe849f6c5bc3799d6431147718ed2bf8fbced1ebcaf9b7ee0eaca005ed4f40dfd73ccea25bb9f1506fe56c0d32960b2732d672b149e3513354c699a05cbbd810daf6adf4b64455f949bbd5f0ebdaea9453eb9fa2240c8539f0241cf0a0c8f460820eab4120d266372e935c750559440ffed29dd5e0dce62274c77df730a0c4cf1c56867e6a6f86a39920f1cd541132475c952473778db1fc1b40af0acfdaa0f536b3b135eea8bc6e82c492b067597d8bd0ed4070980c829c5eeddd48aa4a54a0dbec1df223ef521395a901852bf45cd595f028ecae72503157fe952910b57830a0decd508126776f56445a04890cfe0edc0022203b3a03fd42c3ee63ee5a7d1371a020b781eaf8390224622339435c3bfb8474e421b7cfb0ebd563ca24505df909e0a0138e7003bf401b0e58a2ebebd4f3af149b49898f26f115df58086501e09bc4d0a0e676ccbeef91b9953f1fe744f8d86a36aaa11b55e8c18142925e2f2c1db772b9a06495437fba3c66f86c8646bfeb06dceef5a08c58abbe9c646f6a5e56ec3f7d2380", - "0xf90211a0403b093e5740cf78f051efd3d96fd37a13aec680fdf38f27460c13d3369d0864a078bf4036baaf3a483f1bfc3e554b90e68bc3d0b45254ff14d732407995f6828da0c48d01c9a2281832f08f88fe8f4b2052d1d12f913b8fc70a959fc6acf1b8d0a6a03274ffd305e76eb60e13512e30a2333e3fbc7745dd82aec8e49baa73c8720fa9a009bb9a81543932d1b4f47371c0bc13b7a0af87f252eb22ea58cf0e033c0ba0e5a0bc9b0d3fa5669a80306486c045b5823530ce001e4cbcdaa98725f6d9aa802a40a038b5621c5d0b7a0160a9a8ddeeda4a4d9ea13c11c60e37241bcdef767f08c27ca058220e4992773a47dc834c82cfa4fc5ff66b0459ea4ccb1faebcd12598d6e001a08107e1dbc4544ef63c6418bab44d9188d3ee82a00bcb3f4ade5e052ef0589ddba0a809df04f6bd0265584e9cfcf77a7c9954deafb90797fca19183b8a9071a5b84a0e5826019d615e08fa7f3751cc8f16b26d5a4a2e6c02d748dcadcd05bbc9d07e5a0ffcf8b7399e8bfb7c133e5dfc4e1b048000910335f9d5a5e9bf1ef4c07ee8c3ba0da89e971f89db64d154df33036910997d1a491aa12e14d39017e9121a3fbaa11a04f2a28f5b737da5d55ae878f4323ff4ef3a9867819874e30389e2252c87b632ea0fc11b53269ed575292d688fb45c31bdfc71b3540dd1490a6b02624646578a0aaa06c9446c472be9b3bfce48c968269fff0ae2f8bdbfa2b513e3a38433bf5ad363180", - "0xf90211a0db7bf23ef980103c5ddee3660304030b6c62cd9b5ee863251aa71d518d5827a5a09329a03ffa9e0c0ab2d4a5bd121bc97fa8ce71b740571e1f69fd61fa4d43ce4fa0ae98bf8f3ec7a1f33211637123cdae14094f81cee2271a1bb8f9e787d64558e1a09736d564f483aa79c795bbd4702c98cb8470de794d07ae44496be8f37d3a730ba06eade8418284283fec5b3c6857c5f2e0c05ef7ed6fffac19532a9dfd335ae128a02652531621873643690b0e37c1f48635312d4575bd6993dfbad2e4ffef9bf504a0a19ae20e648bc651e4934800ce45a77af9bee8e59fb007ab5cc6c096d968a747a0f00af3eede9d9923143d7fbaee6f004518b346aed8f46d7d65bcd96f2796c9afa02d103be3dac80926afbcc055801b93c0391cacacc6f168ef270cc200c95c4a2da0a96e140ac21a8a32d38ce6a5dfcee96ade6c805334102259839c7b4b6acea7e5a03d57d94b9a47ffb196092421c21d8226e637c5e3662c24cd66fde33418abbb47a047d9025925a2ec4f908a946ca9d90c779e1d117c91f3c13ae00e7d257c9deea4a025e8a657a943d81b2d2ee03d58d0c69fe1f9323bbb0e15c2faa61204921dc2ada09481ed7c412529536fa4cd3d45ce8950d3be99c68a0ceb1edfa4dbc5b2bdaeeca0bae2b669a8e5a62cc1a2b6fc0655c86e1578fcd51c7b9950be63b5b7f7cc9631a007e5d190393358c90f0db5c1bf02f7fcb8be6a8703275bdcf93de8344b240ecc80", - "0xf90211a0ed3cd4ad082dbe5e03df86af5913ec72ba98b4a68b7c723d3725d36abe147c35a0181a5239bd86faacaf11fb7964007b6fdf7414a2716cc269f54f4cd1c16fc81fa0e7d60ea293bf97258e8f6877691475ea391f1dc6d2d2fa1c9ef7367b8494f6bba036278743ad1481779f14fc62e5fa7552d34386a441210b5d2d164cf46ca98e76a032b20bcf4acc1cbec679ae20b3f6cc21b3083cf693d6d2715e11df1d8b0f9de8a015308ce592b4344997b8bf0ca0bbdf91066fe3f2a0b765795dba9ff0c2181b68a03406b61338441657dd26d5ce335e003474915e0ef7592a8c099e90a421cbcc6ea050c688b2841c7c0e2ce558b68d5c8d46cec325d8f50e47d859be2ef946e9db0ba00e25d25a62600ef259bd4047fc019a2883220f68c75ec8b5706b45c3669f91afa0515d254a83fd6608523919877b5225de5ac68ef6e245247c333617fda7f4d95ba08c185017ceb61352c016b57d032030b04eb4463263a43cf21b4cef2f646c8292a0f36fe618dfb271791b41eeaadbcc2cc0a0fc5bc48d0d129a2db9d8f9e509e9dfa06c8c4cfa620154725fe2eae526e357e315fb184fde5da601a59a9409bbea3107a05d6a30117ed4bf79cd2011e4bb77261ac9afb7bfc8ad73f359b1cb0a3708e9bba0da1094c4c10a058804879c5d1a42c4f6e5c9554848303176dc96e7bec88d1bcca026333c6d0c821b42f22402e6959a3bb4d335ead3c65ac217ba610494e1f343b480", - "0xf90211a09376caa6667827047065418939ec9484729f239b2d075dc006454d714bc09d91a02fd1b4572ac1b538b2655f3d4c35908c84401fb59077eaadcb0b55ac4be4b560a07b3754af4b06a151a0ec4805323a948dd3ee5b420a0bed2c1d68589ac86cf606a0553c97cec8884599497822f3f52903714358da0a8d93cbcce355ce44db6604faa0e99617880cb766df68ac0756a6104bb508169e008cf04d5245973b42ac5a3af5a0d72306e8fad5757a25aeea1f960998354f6432ff425332d6b291d832d183d0eba07222c2c15cfd4c61d75581958ffbd415293384b57f8ea69a0e086e810d6ee0a4a0c8d187dd379235aa9f9f5a994ab68773b955635338e009736558a9622f148673a0363dcc96326165f937d44bbf74bdc6e505f9acb6a2444867f0cb2b00a1196058a038299e1372463bf338bb83de536e9b6cee8dc66de77f4ddb2688922b5a54614fa02886498375d11531a65c3880a3fd6c21d5648a46c11d197406f777b72d8ae3f5a02e94fb53e6831d9f913dd4c76f6e1fb13ad2b7771419f3fbed42d4373a22106ea03c0de4be7c83682af48da2c7192e63f6139ed200873c3c09d8e99ca0b2988ac5a079c38c7986828bf6fb30f3a02bb46a825bffb09455ca8c3e2b4ff33881b65934a065460f91fff3a3339a1a5786b5e5affc0d758b905349f0992421fd0608979ce2a010c1df619ab05b46643f73a2b9064d9c4804d3941e35bdc05b8df933f6a46b4480", - "0xf90171a032f57f97366f79faa218554d5dded9eede7b0e3a407c5022833087fe8975cc1ea0110bf4c97d41c1a5545ecde8945c2b4921c4a2852ef0dbfafc36ff7e6d5ec20aa0f1c62607b2cf1689b133785bed86d2f67ba9d30b9327789014d83d8e61294364a04aeaaa8c0f3cb370f47f7768af15b7c4fc2beed80b6bd9e99e833ed785639e00a0986b2a3445e71fdfaf20af08b15c26889af1829d10b3224f35230cd86452e193a0f7d33c4fa6746dbd83a6e7707498df28dae14a4be17da8b1dc7c7d087789dff0a08d989b502684afda0933878067069d98a4510baf2fbb4824a2e43a0897a310daa01319280f21d2a93c08c37fff958ad9356514a03cf252fa56466e30aa700378bb80a0b266cc9cd37a20de7bada6a344da96f57e1fde80cd08bf53d06100876ea49f6da021d406491e68030472f01778e14e1e12b15d2442724e3aea61fb1a538160ea5f8080a0d822b8c064a38cc20d681450aa72d3c9ac4332afcb4f18e482a33dad89d8247d808080", - "0xf851a00ffd601d1ab8d623cd968b5e534e225fdb9715339fbb138e245d2a70d39e2233808080a066eac627c3149fc65571ef287abc52768479c3bb42a84b59455115611a31a174808080808080808080808080", - "0xf8669d20b033f84c1a5ab5dcb2e3dc353b0af69edec575bcd8edfede887abc55b846f8440180a05e57a60889ae6e791b78a66fe1906f9cf1ed01313a0a19faf7e234debdf4eff6a054f2b4c90d2939269a9d3ea8a3081dce03328c947d54bf3d98b2820922840b35" - ], - "storage_proof": [ - { - "key": "0x51e86470d074b2eb973e9c895b2858f9860cc48a7abc1578969424279e898438", - "proof": [ - "0xf90211a026e88a3f0c11a86241bdce66c7fe8848547ea3c82c89872542b8851fe5ac9921a040b83948267d6bbd8fe77bb6d89cb99c056d9958e33ccbda036f0de91cd8c826a0476cd1f7a137da62f0b1363902ec749bec6c3d6fdc334c41772eea90c4e7544da0332cdfdcc5a766306aec0abfc7b1fd0f51dcfb6ac0c7e61c6679b687d66a7f47a07cb35a55cf65b510b857f9e85b19a7e92445733b1b0c42aaf52be6a77532dc6fa022f8370cbe2cd08ce501ae025d9d02da9b09bfafaa5a337493cb14d55fe51fb1a08e173efc635da95251c25412f520000434cde4ee4996d61d7ff7b73b8867ca84a0a49f89f63717024e16a62278ba030917ef8523e6532d5059530f56602512bb1ca074bfe9bede6bd6bc0b6d25691721dac3c7cdec005649f09f5a777ad06253c3a4a027012e87636d262f7deb97e1e96f029589bec201160306e7922aabaff1f06e80a0dcaa8237a3623aa6b90d5ef01222dd118aaa93fbcc65ae2fd1658d9bbab8fe16a04d0307917e7f4fcc7aad4f3b3c33ed43df1efc1e5ae5a1317d0c1f09f9b75835a0aa40cb7d98b00efb7e2de4567a386be26a60a09dde53faf0f8c8e0d3a8bd682aa0d0417dfe67acefca9e8c27db714cc194bbb1a3e20fe270d4ac0917640f62cbafa0f814d798e541e6c32eccd9203baff419ada315d408bb1f7558db3dc9120d4be1a0c9e98d0d915d9b9e6aef53094ba689961679a085e9c2070cc268dfae013ebb3980", - "0xf90211a06be8c04c93f49aba7cc17ef465a0b935c451dc8445a680beed624b80bb9b690ca0210e837f5f3dde358d6bfae6a6f68f079ba0a1e798e1fd46f43acb8baeb72db7a02181f7c71b1c31b7361eb07e246779d2f5f28bccb6575844716a435f78e81ae0a07f7d00f6642aac7a5b78e8dc72e31138b0c5127f978b0a562ef61907b1406b39a0b5416eccd7088195eb13320d9b2832c525603f0b51972689995f2934dfcd536fa0612b1de49e86bf385902d6240a4f2623b42f2e38d5f06d08a549351c9bedc7d2a0c9e2f8320a839a6255d5043229e84e6dbdf99b1f6e3d3d35985f53c619b9584ca089b9525e05302cee1bb824820fed469ed2ea012ac628a6691088509f5a3cfc32a0030d4d3499fe2582bcc705986c6f1db2de325b97ff0d898749fc506d9a35be32a075f2f6716f0f8bb1cfaaa44ecb81670370aa6d10d00a7224da754fe53f29c30fa03d00355276cf983aeeea4c7bf9b1157f532fbd3226562008a92d2df30b9d8933a02f821e6fe17dc1fd31446eba6230479915b4379f0bee793df654f7ca833324f7a074885bbd89a7098a32d2b148ce25d99ab3fdb5b91ff95e57cc3bff9f8a46e360a0d5194208f335ecf625a2cef5679aba99b3879660cc69b8329c325d8d9aaa8012a0aa4a8e4c2de8770ad699e24f332e5ba8ff7b67404a8b9adf7d0d7dd5a84c3921a0e2d94d76c41c18987855a4f858ef035afc90d785d8cc7ea431227941f9051f5f80", - "0xf90211a007859f94d052ab6e3375460e69314f0acab5ba85e233351e3926c61fc66f119fa0a88ce91ec3f3ee6cc1468adde3cde4e603d2fe3c8252ffbae750a128cdcdca30a05599640a0ee5950b72306ad4785cb3c37333e311f34322e81b6cce6d478cdfdda0ee0ab054eac6d70234757b97de62b7637b11c2997960bec13ffdf745015ef2f0a0d69fc8001b44f8f48f8a511f8685a768720251a8df3b904d78148ceb0b427627a0e153db87399bcd7f5f178b0473053e2dd2be23c0bc1eb6e0f179e1a118791ea5a07c326f1106c321e3d0b0713a665aa44f0c7232c56222c2c9f241747fc2f63478a0a375b1ce6b5be56883cc0847d48ef1d85c856eb49118f3a1b08561ba7675eab8a01fe2de929f1ed25cc9e2b3d1b6b0a9c5dd4934b70c0f1020f849ff63222875fea0f119ffb6f69c3ce6edd4204adb8d0ee1efcaf9b7e7f7003bf071a011bb3e371da00909d4061a362eb6523dea3444819df73baf7fe31c52e700033bb62028b307a5a09b299e4a187dad7e6d1248339528ee5e3128efd84467194ccdd8104f0825d942a0dee067b8836ae849e5dbd31432431775ebbe7aaccdd088cb3d992c96d73e3459a0dae2a6f6352754aaa7e941d9b09408a73a51d2d8d97b1154de7b8df7644f604da0f91a84fcea27fdc48eb3e3f84ed448d8a333b169598e00037ac34893244f6cfba01e281821ca9cf7616e6fa8261a36ec42dbd9fb983ec21d7bdde3af6e48ce329280", - "0xe217a03b0334fede0830676879d33238e049f8f941a78fe292284634d02f5ef709bb2a", - "0xf85180808080808080a083024acdc35d4102268c166094ec74854e1658102a83fdf3526e9e623516e1ff8080808080a03fc7f1328d76346cec56120707420b3d799f25b76b91fd73d51fb4d0c6208ee8808080", - "0xf8419e307563e959c00b8758b1ab987167234c254a32ed5aa3b8354c644a7b5ba7a1a0fdefffffffdf9d31da40414bc4805ed142011d80124080c0c04007001e9a0001" - ], - "value": "0xfdefffffffdf9d31da40414bc4805ed142011d80124080c0c04007001e9a0001" - }, - { - "key": "0x00000000000000000000000000000000000000000000000000000000000000d2", - "proof": [ - "0xf90211a026e88a3f0c11a86241bdce66c7fe8848547ea3c82c89872542b8851fe5ac9921a040b83948267d6bbd8fe77bb6d89cb99c056d9958e33ccbda036f0de91cd8c826a0476cd1f7a137da62f0b1363902ec749bec6c3d6fdc334c41772eea90c4e7544da0332cdfdcc5a766306aec0abfc7b1fd0f51dcfb6ac0c7e61c6679b687d66a7f47a07cb35a55cf65b510b857f9e85b19a7e92445733b1b0c42aaf52be6a77532dc6fa022f8370cbe2cd08ce501ae025d9d02da9b09bfafaa5a337493cb14d55fe51fb1a08e173efc635da95251c25412f520000434cde4ee4996d61d7ff7b73b8867ca84a0a49f89f63717024e16a62278ba030917ef8523e6532d5059530f56602512bb1ca074bfe9bede6bd6bc0b6d25691721dac3c7cdec005649f09f5a777ad06253c3a4a027012e87636d262f7deb97e1e96f029589bec201160306e7922aabaff1f06e80a0dcaa8237a3623aa6b90d5ef01222dd118aaa93fbcc65ae2fd1658d9bbab8fe16a04d0307917e7f4fcc7aad4f3b3c33ed43df1efc1e5ae5a1317d0c1f09f9b75835a0aa40cb7d98b00efb7e2de4567a386be26a60a09dde53faf0f8c8e0d3a8bd682aa0d0417dfe67acefca9e8c27db714cc194bbb1a3e20fe270d4ac0917640f62cbafa0f814d798e541e6c32eccd9203baff419ada315d408bb1f7558db3dc9120d4be1a0c9e98d0d915d9b9e6aef53094ba689961679a085e9c2070cc268dfae013ebb3980", - "0xf90211a0ebc55ea93f35388a6e2e9503b8dc19f40c22d2f78aa11c1b60fbed4169f2456aa0cd7d301f6df17adfeff4e8438ebae15c0fd74715bcf7e571100a5f9e9f423b87a0693a6f1b9bd6a1f0b47cd6dbd0f97d7851eca9493fd72d90d34cb839c989dc08a07f095168cc0c067854f97e0509e199af5a0cdd42e5396e4a22335d9e9322fc97a0432461f5002a634490613741a05d61a2d59b11f12c0ba46ff0ac90333a1a8aaba03e7c76631e453c5ea9d1161b9e4b754f76fda37d610d38818b4b8b17a52581e9a01b7e3de4a147505f758dd1c062e6d7a6e6ea43ad6a9af57e2af75e64519b82dca00878373a2995d918d325abc4ae9ff3174f663da8c2a19e307a69c37caf9a041da08adfd3fe8a8341d1708034a178e8eb2df1596e4a10288544836e1f03dc630b60a024cfaa7c32bd9ebd293d35361fc166a70626f1eb0f69eed56730156655207826a04cf3fb1e0cebd2f4a0246fc3237f630643064a2d0cf0707cb9febc3b013954a4a03dd90a708e88da5011390b57d42d7c2d1dd6b48079fc92254ca0c3b145340413a075c860421c5a3e3c3a396cc965e95ed68159b501e897d2ab8d64deab7f4978dea0712cf82ed2930326d838a290300d2a45d2934ec5044b5b61b1e0ad2ec5d36cfea0f6b9e60aa024182cbed40708c7aace661821146a4a0d7ca316cf45b4f663c616a02d8e852b0c5fc91472d27b68ae9096b44353e4282d9b9f44332a6474f2286caf80", - "0xf90211a0f1498582e878cd4da670de776effe7b27415ed4c113605448162e6e081845886a048048b536202b54289e7c7bb2c9147adea617094448f234c837d610ad36c6d14a0dca3ddb6154741913f1a94097db8f9c7132dc3d8f3243dd8c8170be6ff292d6ca03ba95422f84a62aea6e24ec1ad8257d52a54b6fcd67310ba8a7d81fa32f73136a0c5ea3f36d9ccff927fe369b50c9acb9d9165b839bc4b3a86625e597120ff24eea04d3fa0a6c562eed981fbc73690ac4f5b14c775c6e0d1cb66dcac2a4c20e9d678a023eaf203d5b9b4f90a34a163559a2d8a731a7d10a15e57a8bdaaefff25453e94a06aae6b89d11833826eab655ad07d3df690521b2a64ddb9c77a141338c36c726ba044b11eca327f9b7f8fa0fc62d57b21ce8cae961b6f62ab120e8652904b541ba2a00208543c4b83a217442b13ba73536ef74a84d878d7f7195d581faedda9a0ae5ea0bdd32a850e86dedc800ba8b884210e687c0280a6b49b194ba25cc8e13a1280c8a08c7be96f651042b16829b35fdaa6324b6f34d1338990c4eab5375bf8d95b34cba0f3046d5d72e55155f38e35de5522b8f55993994670ea973b96341c5ea39e7371a0d59f6ac705a576fb8a91b4ca82f180707fa19a2d0dda1839e66969c353e365cca06c8b7b2234872ba5d9eea920262a26a9485f1f5e4e5131b4b383888f15033e41a0ffe3e9fb3052d8f2db22f07cb0d91e020b8985a30e3928c606deee59b44df4ee80", - "0xf8d1a0f019fe0dce27468e16ef61a931dd6f67b5ba77c81bd7460c8c0bb2405cd0f6a88080a0fcdc19d5018cc254b52b33ec2b99048e2b7c6000fe3d500b65177db3b766ae81a0b22fd6eb6bbe6eb9e8ef0b7ae62ba7d0ca8b746131d041715024c05ae925170380a05fce712412d22ae61fb89871a42ce4c33817cf2d3652e5c41bbef651efea9dd88080a0ad2d08631caf5b56646b6f1d27cbf3acdd95e444e0d28db4b5b18736f32be7e78080a014ffd38b7b22bdacc2f1ba3fca369445aa722381864b0629a9d6d35169be3fcf80808080", - "0xf8429f202e1030363415d7b4fb0406540a0060e8e2fc8982f3f32289379e11fa6546a1a0010000000000000009af681fbae06a6a026262ff31ffef7e4911b30165fe06df" - ], - "value": "0x10000000000000009af681fbae06a6a026262ff31ffef7e4911b30165fe06df" - }, - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000004", - "proof": [ - "0xf90211a026e88a3f0c11a86241bdce66c7fe8848547ea3c82c89872542b8851fe5ac9921a040b83948267d6bbd8fe77bb6d89cb99c056d9958e33ccbda036f0de91cd8c826a0476cd1f7a137da62f0b1363902ec749bec6c3d6fdc334c41772eea90c4e7544da0332cdfdcc5a766306aec0abfc7b1fd0f51dcfb6ac0c7e61c6679b687d66a7f47a07cb35a55cf65b510b857f9e85b19a7e92445733b1b0c42aaf52be6a77532dc6fa022f8370cbe2cd08ce501ae025d9d02da9b09bfafaa5a337493cb14d55fe51fb1a08e173efc635da95251c25412f520000434cde4ee4996d61d7ff7b73b8867ca84a0a49f89f63717024e16a62278ba030917ef8523e6532d5059530f56602512bb1ca074bfe9bede6bd6bc0b6d25691721dac3c7cdec005649f09f5a777ad06253c3a4a027012e87636d262f7deb97e1e96f029589bec201160306e7922aabaff1f06e80a0dcaa8237a3623aa6b90d5ef01222dd118aaa93fbcc65ae2fd1658d9bbab8fe16a04d0307917e7f4fcc7aad4f3b3c33ed43df1efc1e5ae5a1317d0c1f09f9b75835a0aa40cb7d98b00efb7e2de4567a386be26a60a09dde53faf0f8c8e0d3a8bd682aa0d0417dfe67acefca9e8c27db714cc194bbb1a3e20fe270d4ac0917640f62cbafa0f814d798e541e6c32eccd9203baff419ada315d408bb1f7558db3dc9120d4be1a0c9e98d0d915d9b9e6aef53094ba689961679a085e9c2070cc268dfae013ebb3980", - "0xf90211a0e2ddbf226dad91ab12af8b0685017c93bd8bedcb8a887049720cd22174c70959a061140bd930296bde8440a9b40ce03da70a49641a98dbf9ffe937ccabe89ae9a5a09c7bd68276cfe70356f85a0e1ba4f506a2ae7cf4cec3e6f21426f160de540946a0b4268e81ef18256a8a41de412e50f183a3913518ed624a7b01899feda7bfa244a02c581899a571b62685819376c2173460ebfe76730130383526bc991151430bc7a09e8cc92b48dcbbbfb42d68dc27772143c45e4f2fd936fc71b017142b4453b022a05ec5eac385180a7aade77ad5a53a9b8f823fa0a90d0f2b37a2480bf4c34bb3eda0023b7e54af349747838a7dc6aa5f2e46f26354eaa5cc1c49e6277c2032609290a08b490ca329df00f65bdf37a5eb6692d6e94fb147431ae573f80d748327eb1be1a0e04f8e712ec2bc20960269a64e75d1585dc1fdb2f9c3e6fd2cdce521ff1caa04a02f7b2381d99d6eb65b61edcf472209206297cbc58d2776e80535dd3e330df7f4a0dd1e4081f2e40faa4f8992de9650fee41bfe2d41c9b4bf8ea856f0204b1d23c7a081149d4e55e9e29e6c946632707213485bb71e5717d644095a7f8e34c109cfb0a056456639a4c3a3b8ccc58c9676823f65c988b98abb31661e03e4c1fdca598097a0782031afbd6bc9a4614c7b23c71f6a373996cd6b004f478802171b4e09422eaca090045f62e07fd5afddae14e59dee4fc72369331f18aa00ad01cb85d26f85a78a80", - "0xf901f1a0ada3d58d81661d453874170a45476adcb3a2bad760ca2a5787858e5cb6e36f7ca03cd066f4060a6079a8e0924c27f45d762d21a537dc9f8d80bf945edb65f7041c80a00baf3a179bef15506a5f50ec9a8d8dbe792bc98118e8c636579ad34c70d0bf79a092cf37d4209a347a142b6e811ec19ce1b8f869f37d200b2e92c4c386a2bc4469a0bbdd195ca35593ff1df03235a700b494841b808bf1e7eea8e96054bcf07eee55a08c207b0e426e12f516224acd3a7252893abd59910921820b55a9e48dad6d4437a0fc5e67a9e2e90da2b47db9f2f1f5681628a02232b519a667d471f0e554e56a16a09cb9edb30ae60caebe1f87521d2c29c71d725f567d0a92a70de909734b950f42a088345ccc10681cdac11d947911a637036c9e980747fb15ec8e01342974b962d8a0b645dbd0ff4cfc5209c6bded668b05b75fcc3182d355dddfa861495285c83f9fa09e4aeccda5d64de47b46addd2c4249c5ea8f1f3f716f46d342cac0e4fff369c4a01d258acf43d6e8457ffb925b99e16021876e67da158e9e1456ebe82b88e96353a0b139a4854f72086b7590d28e048ea2a26fee134abe3242319a45c80888a07dc3a00dd5d9815b9a3134a23b4bc613d3f2cea231adcbbee4357a0dec08f3ec76152fa0158108846a6e7a132171886c405c7c0e88912a5a43915b3aebe60cd4b5b0f93b80", - "0xf8b1a098d64b2dfdc9a2c3a6783659276fd6e0a68936970dd18d634249d7ecb6a9cf3b80a077116ea72c55e28dec5f5492dcda5cd66ccba94d2d5c86273db774b313aa5b2aa090827563694b7f21b8bdd173a938296be1feaa23023fb5e2ffb76761c3d6da2180a09f1f9d9ff9541ad6237fca9f2570cf742162e8164cf2c86a904a27a091f437eb80808080808080a0dabf21b521aa91486dbc67c8cd2638b2a36334eb12ee1e7e5024da428625fbc6808080", - "0xea9f20acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b898860e805d8f13ebdca" - ], - "value": "0x60e805d8f13ebdca" - }, - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000002", - "proof": [ - "0xf90211a026e88a3f0c11a86241bdce66c7fe8848547ea3c82c89872542b8851fe5ac9921a040b83948267d6bbd8fe77bb6d89cb99c056d9958e33ccbda036f0de91cd8c826a0476cd1f7a137da62f0b1363902ec749bec6c3d6fdc334c41772eea90c4e7544da0332cdfdcc5a766306aec0abfc7b1fd0f51dcfb6ac0c7e61c6679b687d66a7f47a07cb35a55cf65b510b857f9e85b19a7e92445733b1b0c42aaf52be6a77532dc6fa022f8370cbe2cd08ce501ae025d9d02da9b09bfafaa5a337493cb14d55fe51fb1a08e173efc635da95251c25412f520000434cde4ee4996d61d7ff7b73b8867ca84a0a49f89f63717024e16a62278ba030917ef8523e6532d5059530f56602512bb1ca074bfe9bede6bd6bc0b6d25691721dac3c7cdec005649f09f5a777ad06253c3a4a027012e87636d262f7deb97e1e96f029589bec201160306e7922aabaff1f06e80a0dcaa8237a3623aa6b90d5ef01222dd118aaa93fbcc65ae2fd1658d9bbab8fe16a04d0307917e7f4fcc7aad4f3b3c33ed43df1efc1e5ae5a1317d0c1f09f9b75835a0aa40cb7d98b00efb7e2de4567a386be26a60a09dde53faf0f8c8e0d3a8bd682aa0d0417dfe67acefca9e8c27db714cc194bbb1a3e20fe270d4ac0917640f62cbafa0f814d798e541e6c32eccd9203baff419ada315d408bb1f7558db3dc9120d4be1a0c9e98d0d915d9b9e6aef53094ba689961679a085e9c2070cc268dfae013ebb3980", - "0xf90211a06be8c04c93f49aba7cc17ef465a0b935c451dc8445a680beed624b80bb9b690ca0210e837f5f3dde358d6bfae6a6f68f079ba0a1e798e1fd46f43acb8baeb72db7a02181f7c71b1c31b7361eb07e246779d2f5f28bccb6575844716a435f78e81ae0a07f7d00f6642aac7a5b78e8dc72e31138b0c5127f978b0a562ef61907b1406b39a0b5416eccd7088195eb13320d9b2832c525603f0b51972689995f2934dfcd536fa0612b1de49e86bf385902d6240a4f2623b42f2e38d5f06d08a549351c9bedc7d2a0c9e2f8320a839a6255d5043229e84e6dbdf99b1f6e3d3d35985f53c619b9584ca089b9525e05302cee1bb824820fed469ed2ea012ac628a6691088509f5a3cfc32a0030d4d3499fe2582bcc705986c6f1db2de325b97ff0d898749fc506d9a35be32a075f2f6716f0f8bb1cfaaa44ecb81670370aa6d10d00a7224da754fe53f29c30fa03d00355276cf983aeeea4c7bf9b1157f532fbd3226562008a92d2df30b9d8933a02f821e6fe17dc1fd31446eba6230479915b4379f0bee793df654f7ca833324f7a074885bbd89a7098a32d2b148ce25d99ab3fdb5b91ff95e57cc3bff9f8a46e360a0d5194208f335ecf625a2cef5679aba99b3879660cc69b8329c325d8d9aaa8012a0aa4a8e4c2de8770ad699e24f332e5ba8ff7b67404a8b9adf7d0d7dd5a84c3921a0e2d94d76c41c18987855a4f858ef035afc90d785d8cc7ea431227941f9051f5f80", - "0xf90211a0fbc5f5b6fc0e13db1ce036f3a0dbe8029e505599876789e850be83fef22aa7e7a0fbc044d688b981952941aad48c1c2d6e188d85bfbb881c20d3f534ac04ee3563a0d3e2ea696e6d2d60a2cbea0a78795d5f77376f91cfa92c79ce1d5abe72a7c88ba063dd437de601eed5db5b08455786a5f75d1c74c2166e97c656e157cf9534e97ba029de3982426fa2c308abed401b6174c3bbe0564d21c7227cccd68f3664073611a0c4a3af9bfe1258a95ac6b0b52e7d8d163e4847837d38f2327e410bd777191811a0926491be62bd3771da03fe69cbfa127162c5ce76e1c29fad5956d342af36da89a0e989ee7a53db9ea5abc89730d9dc6f2c22b973bb70afcc5fd5a787b823b570eba07e54b8d63769bc4be1d8b34e56397f901844618e8e58ed0cd68454f0cbdc26a4a078146b30e2ed11f10311cdf38f18f5ab076f91f442b5ce1a0e9b2d37ef542325a070f2837657c9a4c91db955fca61c24c6b79620c769ad1e20256c08b996832052a077c459e85a38a7d23d6c57d40472ada439003a4de0f2ef3da5c865d12384b0faa0362bfeb0055fd6259c540ee7101409d8597b0f2a6d52a6763aadb05355860beea0fd3e3e9c931a78b1ac895685ac3b0e61b3994fd6f07cfb511f7fdf2d5f1ed942a04b232544cbd597dff3a80a99d5d46810d979f1a3047077439799908708113193a0531fce08b0c003a55beaa924387d8a5412144adc5c5a7fb7cb73e629ca0e5c1a80", - "0xf9011180a0f96bfc51ac5626479f025eea2176393a8736bed0de2a3c4a05e57ef71fb3886ba0671b5955d41d3c4cdc08d2a9b4ab5dd19da145246f1673d629a631a2b1e02b608080a02e7f8e095592135a73d265d22e9787898b2bc48c68bc5f762516beb07a2f0489a0dd8c7d9d3d9778517347ac187a69c64ed8289abe2437b8aba6921695a0c511d9a041901263cc608d5fedf32bf8f2f0b94541028f0e682cccc01aa10ac5b208b40180a0b74562729ae9df77186edc9ba115967700645502ec56eb41f338353901df3aa880a0d8087b01f979961f04528cb807ba48f11d82fa7cf24660647b510f516dbd1f3e8080a017b7c2af09187c8fed387e41d1752677701daf3fe0ed7954513ec8a6da90d1248080", - "0xf87180a0cfeca03708911cf8fa4fe420015b4d466f2a6054a03e83633fcd96bf893ea3908080a0c7182757f2148e01333ed2c5b6878368a828cb77d016762e57c1777ae102aee5808080a02dd72dca72ecc7f7dfe3bf66e2445922c71fb1a70d12b6d0f7856405a2d9f3958080808080808080", - "0xef9e37fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace8f8ea64880bf553c2f0ca89ecae66704" - ], - "value": "0xa64880bf553c2f0ca89ecae66704" - }, - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000000", - "proof": [ - "0xf90211a026e88a3f0c11a86241bdce66c7fe8848547ea3c82c89872542b8851fe5ac9921a040b83948267d6bbd8fe77bb6d89cb99c056d9958e33ccbda036f0de91cd8c826a0476cd1f7a137da62f0b1363902ec749bec6c3d6fdc334c41772eea90c4e7544da0332cdfdcc5a766306aec0abfc7b1fd0f51dcfb6ac0c7e61c6679b687d66a7f47a07cb35a55cf65b510b857f9e85b19a7e92445733b1b0c42aaf52be6a77532dc6fa022f8370cbe2cd08ce501ae025d9d02da9b09bfafaa5a337493cb14d55fe51fb1a08e173efc635da95251c25412f520000434cde4ee4996d61d7ff7b73b8867ca84a0a49f89f63717024e16a62278ba030917ef8523e6532d5059530f56602512bb1ca074bfe9bede6bd6bc0b6d25691721dac3c7cdec005649f09f5a777ad06253c3a4a027012e87636d262f7deb97e1e96f029589bec201160306e7922aabaff1f06e80a0dcaa8237a3623aa6b90d5ef01222dd118aaa93fbcc65ae2fd1658d9bbab8fe16a04d0307917e7f4fcc7aad4f3b3c33ed43df1efc1e5ae5a1317d0c1f09f9b75835a0aa40cb7d98b00efb7e2de4567a386be26a60a09dde53faf0f8c8e0d3a8bd682aa0d0417dfe67acefca9e8c27db714cc194bbb1a3e20fe270d4ac0917640f62cbafa0f814d798e541e6c32eccd9203baff419ada315d408bb1f7558db3dc9120d4be1a0c9e98d0d915d9b9e6aef53094ba689961679a085e9c2070cc268dfae013ebb3980", - "0xf90211a0721a58ed2dcc097ed9e7d563e82c3e910a1d439774ae35fc2de446d820bd4ec7a042c1e4146523a5ca92ff149103fa1c3c0cfb65de38e4935a1493f6768ac13a4fa0b330377cf9f0ea895acab861a7a66886236b3dcb0a311a6b3bc8ba0b839f7deea02125bb579b7b14924ccfb83b943004de6a809e2ff41dbe6a0bb6f8c667017de3a08324b6f5f9b5cd5d0cd0586fadb914ea43eb83de8297eeda3ece3ad67aee6b92a0cd1e6dd038fa2e789eb08bae537095e6f17a1aa39537d38436c8af04e9f9b899a0eaf0aa9304bb37b5e9ee811ac588eba87712d041f97bf295db04462ec55dc093a08e8c98dab17e752d11ab63d2fc1d59696058bee61de9e82df4b101a2a941cbc7a0b6df16c8cfc3e816d5a928ec26d324231b26a1f513861089af369cc80d84f5c5a0dc896544edc74483bc53b5307d2cac28bd0f51acf11a03b72a1c83d9144926a5a0b91ca0c101c12d8c0e5bda152430e5e111a86c7fddb29bb7fa0fe5ff01984027a053c417c3dfa978463c2e2f153c776cea04b34bfe477b78138ed623ae32b62f8aa052b4319859bc395953c9ec4bb58e011cab9c80b7347fd9e4323977d517f6c3a3a0c680df77f322f619e1276f5c30168c9522c48a8c10c672ab60114b72a7f0d21aa06e2bfde468ab27b8158791ba49e1f08c59d6f454f3d3d5c0753fb6c8874fe960a03eaf35a00afe3060dfe10ca977e8eb9498d06153514c367e4f66e33429e2721e80", - "0xf90211a0f3ed83db40eb0daf05244e278d761f9b510973d1a3d2f4a5ac5a6ca9c5328eeea03e807c005e170304e51f1e1da1f24a0ab209cc761b13375ad5ab24b82b7bf76ba0200ab23042e1d5b28d7640b6a0734bb4f3340de76d3a3f4c3159398c9afd7fc2a0293d2d379c9ca235039384de3650b5686a5d6a8e765e55a090061e805b01847fa07fbddf434de5a62ed45b1f245cdc874b0cae8c02191864f0c3ffc541eb2a1a92a0a3cd2ae4b8ae6bceea64f97fe6d8ccbd0f32b709fc839ae254f67afbfc75295fa038a1835ccadc6e72a800df061643c4aa57c1aae5f52990d69ae5ac1d907ff418a00ad6d90748def67a6fcdda87186d416942529c01e35d1e64c77c315029b7cd7ca080397f3de32fd14c54142f26eeb9a4f0eeeff6d5f13645c04bcfe49142db4fe2a0e818e26e2eebc1fc9867192c5ca517d7d3b9ea6071acb4ead4f9c73347c36f6aa0e60ba8b4b161010cbf424555a55ca32e66488c999488a7f2154aecdada14ba12a063f127decc469f798ff79a33577c9e862262d91d68e2911fd7ec387d7fbf48f9a0126acc63e805f4701c34b529075491cd120a7f5c7ec46ba3abfb2f115eba0c33a0f67449e2afd22bf9d5134b367ec8c0a2b708aeaceb1ba578cdea2dafc15af9a8a0d9563bcd127caa45552f6297275988774bad9c0ea9d806eb772c9c66afd01da4a0b1bdf15b3ed87b11a1075b473d0c5c376b544be2165cdcb30a8a47c536c32e0d80", - "0xf8918080a0dfd6c397a1ce5eab0c8739e358c5116ea56b51583dce5de5952285c212e6ae4b80808080a0eb4e53ad2972e0f6c3ddd01405a66870797e2338df043c62274eb483cd8bd154808080a025d9b8c3414a9b05d12ae794d32d5bd136dc1b2904f7b3e92cf774441aeaa08a80a0b7450f6248c305cbcce269fa81a1f5854726a306fc3866c8f549b81809179781808080", - "0xf8419f20ecd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563a09f01000190019000cafd04f500000000000000000003c2101678675ef61742ad" - ], - "value": "0x1000190019000cafd04f500000000000000000003c2101678675ef61742ad" - } - ] - } - ], - [ - { - "block_no": 19493153, - "address": "0x388c818ca8b9251b393131c08a736a67ccb19297", - "storage_keys": [] - }, - { - "address": "0x388c818ca8b9251b393131c08a736a67ccb19297", - "balance": "0x7d2ab7f6f354d82b1", - "code_hash": "0x72542a8b00fec0860870905d6c4654c36c1031a3b1df5be337d18677a2792417", - "nonce": 1, - "storage_hash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a003e59aa2fdc2ac499f63996ea6fe129a498ccad6a3de9388c5c03538af69ae86a04ee5e47bea91562df21fda81d5b8fcc765bfedb45abe3c2b3ee9f1c8a516c385a070452694492ed0a110b7f79f62dfd6ba58adb1d138db988c60bc2d9b9ad6fbf0a01bb508ab5aa4896621a175b33c7749471a32902cc5a715cedb18b81ad457df88a076fdc0612e2814cb6c0197c683288d8b4fbf487201eceade4df07abd696aa77ba0f3cd452191e25cf6378cc5d6d043a5ca820c46328cdf4f8cf5925ac0d14f579fa0ea3b56e52c22240d7ee3d93d8db1c4495ceedc6744b0de7ba5d643a2ec357695a01e8694c5e743112609710361f01cf036d807d314beaff8393ff3dbb02981ceaca0688a3ca2aff1cc8f5c81a257862f791ad6156bd92ba8a6dc963eda4075c0f2e6a0c394b07d9568cf64dd6877c8a0d3b5b9cd66de7334cb36d21588ee5f33639c50a0d1641bb7d5ce8be51c6a0c2bc054ba713170f2d0fc3a022d58574c3fe95d4ac5a0dc5549949f6405c6a1c815842372ec5d5ce6b8e87cdc2f6c9ea0ea962bfc3eeaa06247a8a6ae0b94ae0450b261b031d3a8eee7e25c9ba45e01581cd7195b76094ba0a5e89d859297b9d68f2044f915f3f9417470a9bf934ee70969c90d5f089d9206a051c2826a25fc5dadb9208133dd2bb06b6e7a7d76c906b606e39e0258306d0dd7a022d9c016b63b568f8f212b4212c6ba69b09bf87199b10770c159c08031b1f6ec80", - "0xf90211a0de1ad87f6c4d5b13ce1c01a89497a88f3932abf5dbbfce092d959de2e897196ca0a26b3e2c1cfc5ffdb936b3ffe32f2f5ad312ca8380bbaa86c812c3d716510ccaa017dc27a9a2bdcda8f2e4094b4839baa486c9b09836d3fe544d83fcb62bcf13b5a08af4af43866c8facbbf64ee2e54b233fa4c09055231c2eadf3c64f8ee5e509e8a06b71fed091fb6241750e1844e90ac7a01276072e2b4b72d7f2dea406a59230c3a0c13d03282fb928f466d8d448670921924183bfe7686aee7b591978f6cb83722aa0a3fb8d6c432e201131929eaab737907635e0b4c59b4e1522771a67e6e7efb8d6a0016acc832cb9e0d071e81f4904ea77af4ae892295ffaef151a6eb970e32ab76fa0cd92aa9cb8b5731278c96fa82c579b2a9ccbb5f0c2605507a54159c62649cc4ea0d3315ce4d9ad1882d02b96820b80eb9272c07cb30c5f9a0e2447856bb6c4536fa0aed9ffcde8b066e3b164327949788dd259cd5d8a8505c091b88587d471cefef1a0f7869ee2560ea5cc6b53c314f91d6fed4ea76e6ad87c744714ebae68a98537f0a0b3590ecbc3504ffaf779947a479314559d0c7cd67e2f466b77d67330d3e470dca0aa271e233a28d93e58e14306765194ca8ebebd888b5b00ab3b9780305505bed9a005848e2663fd1ed56934ffcc496e1aa4d43880d62f9bd42507985ee8112a6da3a0fce334b755ceacaaa556f53159153203b5e6213cb5a355953d2a3a91f081f0f880", - "0xf90211a06bdbe9061f5a322ee032ee0cf4515cc63f6cca00f023f5083f06da407a4f0e0ca04e5c680dd07a10af0d14d23776fcf821da48c947d360962df041679ac696c076a03d947d9247b360d6cfc16c4da316885e9c040dd4b8da0fde6321a31b19db12d9a02b49bf0e6e544347f9e9c03e55f46e58ccba6ad4b8cbba8140ceb0d52f952046a085833a578dedd9fe27204a2ad09ff02ab51382d65e6e8b9f7a339e5581459788a0d6cec2767d78d1f3a10c0d5109c198af07a9dbb4728dcebbf5482c6b0f133e72a01cb0dc0d2e02fb7fc161542c7dc700557f61e7a584226ba5e9f31e9691fd8505a0b51d24d506f7d5b02e03e4e94284ef0b3e7f3dca0c3110cae263bcd701f831e0a08c9625b7afec75e208bf915814a6eca915296340878882967617839e0b536205a058cff6d0ecf7115d0ea3463b4d5dbc94e2865173cc1352795e72b8a93bc861b8a03a808476f9aebedd94b527360904babf76bb3de7623923854906cf67afeb67baa0d32356f8c064825e56d651242e653e08776dd8f3ad30b30ce4baf37cb9fd3e30a025a6235df538610f3180301d36d858df6c1ccdcbd3f7d1eed3b4edcd48cb0461a019ed583dfcad903c33f471d8fd66efff6b226109130d564f070044ee8c2a4a44a04d55f8427b4e840133a0c5f5d5a18c5277118e9f81b49144ddfffd8dbb032ebaa02e7e0be0114d06fab61f5f060853874199d0a46e5b37f4269c11ea20cadd74de80", - "0xf90211a03f81416c1b8eec1a1354ad51d9b0cfa0819cbaaff3d05f3fc552a5eb6fb5105da088ff28728c8925ba903493ca7f415d3ee5706e6081d06437172ee7dab7faa124a0aa038e907226af90d4f24319b1c8ba2e9b6474ba909b95cea7518f6486d6266ea03029c4bdebdbdb4d0145706c2685f9f9bad210167372d6694fb3760b239ef2dda04ec80794eb54e821078066561ba8714b2522b9e36fb4d54833dd936de5fc6273a0970856666d160cca695b466b4b08ba3f2b2c277c035484b72d31e2bcceb56964a0f7ead60ae9db86f1a5590b97e7847e9fa4e7de7e21d6f677a9d2fbd9694ff5bea08a08a3030e1ab6876fc690998812682821458fac146e251974728487e697e623a0ebe5800ad6a14458aabb7c539833812e55ee55298bb3ae2a8b74692d3c2a12aaa08dcaaa405e99e7043ef1aa062d170ed30d5812db77b46578798e0a748ae47e57a0d11dad935ae6c8eb9d284d6f29210770a5e65c6eb261e02704e83cfc32252780a011f556b034c40c2233db0b43e773037c36f15861516ae31979405bc40317b7b1a06430911dc5099cd55c4aa726599a0be11cbe41f976919459c01b065b7f12e620a075355071b58b163b4640f2cf4a80013434051d22c4e59d93a73f73960a32db2ba0ae6b9adc2a5c1754e169803d2bd94e33aa72cdf238dc7ec230192d074093181fa0d1745f11cb4398a9ceeae465ba436671904cc060fe7376c9db275e521ee78a5380", - "0xf90211a09d00482e682f6db2d2c75cea2a0e2d35689a3e9716f6f340c9d3a90b561ff570a0fcee0d7fb28990c42415d2e48377b085e52c3861ea31e8df80652d4b29e200dda01a77e41193bf09a391bd01eed34f770fe0f76d5634764ef93cbd9fc813e6a253a0cef3209780f552afb516612e895e2419f59d8fa6515107bec793adcdd98c3bdea0bfe8df54e02c585970669aadb0f397eb6e3f89d7a0d7c598436d64b50cc5105ca0e33f6c3e066e2fa8b687714f20d0d590d167d60a3db0079b43f2ee2256e7b030a0510b4d064e532babcda40a07302dc705987de66b4dca4df4bade4b9560c03427a01bf4ddee2e405c78fa0fc788570537995e1e5fb10fa6a79859957a43fce498e6a0977f31f57aea2c42aea2329e3bcca79eac2256e44724b636710107a3208c6076a0c987485426768c9105ccd26b9b0300730ea6828ad82b928290f648fe8872a5a3a03e1d049a9e19490554c237bfa61ef9b1bbafeaddccffc13405a7959a01fafde7a0ef4af586457a540c3e7675765421dfe770e14d6919e6cb02f24359ade70c5824a01cb7cf7624ba9c6e56d1b0e1b5bd06c8563d6abb1f75fabe6ad073bd5b334f42a081d54bf6c3319c1db5abb3453f92c7d85508875b52f5f16206bb24bed3824b4aa061b80bc3a4fedb86054cff910cb8f2b9979add7745bb76ece5cb298a1ee985c0a0d47fc7863471e5b2434e5a3ca9c66f6ec3f6dc891b0f5fdaff7eb931b3f630f180", - "0xf9013180a055438cd5f843d5e2304c3e7602ceead5aea96eae825ac8874df56c79a195ca3d808080a070ffe1ccab72b6c08633a23cb4fe88e4746f0414c6fa2387d24428fad55e66dda0accc1f07e5f6b0fb22fefe5fda75ed3f219cb9f375b2d30bd4eea265f9d1de17a0e42ccfef450b2550bb1de41f7becb61d2b97c7172fe83568b389a66de8f1f4b9a033d7f74c28b538a072eba1c53a34d6dfd8301484809b2ceaf32eb7caac0e76fc80a04fb17b8a48f44a2938e636abeb36cd89379f22f50f3e473697c7b39f9f073dd1a08aadfa9877512e99834274eb4bb203c8df43bd113596e86a044f8440a035832f80a0a0a1fa25004b4121a70d7d84694689a0769b571b36cea854fd3a33525a33e6efa078da3c24d82a6f339f7dc9acd5a07b01f680924ebde119098fcd3c3f5e86b1958080", - "0xf86f9d3e22175ba7c6be65526aeabe99d643a0f587031a741aef9e9d645e73afb84ff84d018907d2ab7f6f354d82b1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a072542a8b00fec0860870905d6c4654c36c1031a3b1df5be337d18677a2792417" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 19493153, - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "storage_keys": [] - }, - { - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "balance": "0x276505ab1fb37833287b0", - "code_hash": "0xd0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23", - "nonce": 1, - "storage_hash": "0xf71e47f1c3a32f09f968c64d41495d55e8c1866f22cf79ea6452f7c67f9eed8b", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a084a6df8a60e9f9e6c23cdcac12bedc626dd6936b0c4bb94d6eada2cbf655d558a075b1dc9f04119a7cfb33683a4cb0f816d4bb434eac4db8f1951ea6886c1a0811a0323cda734e99dfbfa93edbf76183846bc7c3d52da0971ef637d4a1497bae0210a0b2f0e87da6afcdee1c868c86c9cec713c689cd740b55045b5f3933d1eb9e42fda098ced1ca77f42a52a00c659835bcf632fff9d143202abee9f3c60209051caa1fa054bb4ae44bbfdc5b59d0c4dae52c9dc588183381dc754f53885ab3539959dc87a0e6cc346ca9f68734c01bbcd0c7d683efde7e22f0a662e61372bb36ee810032fda064c7ae341d641d6ad7f3349201b613548ab5af1968bcb4dcee33c1f6bc83cc28a0d4c2e648ffc7b4ffefb7055ee1a3057d83aa98a5ebe01248dffeca8182c6be4da0e55cc35ed1d794f2d0144d2b779c8f426d4c062f10c91f93e5a03a6de1f153a9a05ab7b3f9e75c1c06ff8f1f58bfd51313dde782f92886b22b9ae55c05cef8dcf2a07e3f7ccfefb8530d4648a9bde251947e4f110d5156487d2879fa556a0889e664a0b7afbd434e3300eb9068ea193395d0b587378583a6d5de432b4e06863d1e00a5a02b4fe03e6dd849069dd1dbc26699df1f9217b3c65b3dcf8cead863f8de24a415a0f5e86ec2ed40d5e3593c72e188659441764f9ea0ff05dd129403093cec8bddb3a063014473c20a0aa044ccf43aff9c7ba449e045067a520017bdf1fcf21f9c37e580", - "0xf90211a0a9e8f0755aabfef746a578e6b4ef8f326ee85214da5fba603a066684cdaed705a0460c20be22da9d3c92e63e85fa771f5a5cc1202f4df0653c30e8ea7de2b0a658a0f28bc10b89da7de7848fe7a7289cd59f4ffff5d4cc62f1b938b99b1cc7f7a7c3a0488188c36c04f0f467a18740c24d78ddefc7a25bcd30f8717ae642622545dae5a051d82d4590229e56a508c06d0c17d93d70431aec85cfc1129e6362289dd6fbaaa0bd5e2a883a395a3bd7430f7272966f2ea06e37089f7d1c2fbc0dc04442220ffca08843b2074a92a5f4a26ef974ad0c4812bc2fab2cc219d3bc1eb1cd19ed402271a0fd0c99adcda87adb31f0e999850fd68bad524f62eb969ac8a3f51010bc49795fa02aa22348a6017501aba01f3133c195ef9208daddf2a4babafd7465690c4324aca074a68be43fa48a1dc2311ebc13662d3c2322db8b29309659debacd91d4536f07a083f338c60d625a32cba1f1b633d4e4b25da978b559eb46de7335efe457b29247a0f892daf56d041fd983ecb7d15b7db55a32728413f12ed795fe27495cd8026136a05e49a4fdb1fc80c3e751e6857e6d9e0a6cf198e240d6037702f201291611267da0a48c4104bd8c66ffec9cecf2efc7274e3877231cab274b16aa057c27f248d97da0825cc09e86a3e24213abe65dd47913ee99c8814f81e645315c50b7bd27ca7a0ba06772f8bed963e61594689e600b55cb6ab8b8593d5520a9ed400b8dc0e738976680", - "0xf90211a0cdaf2b2bda12ebc2b59b01a49a3559ba63165c24a91bc4b2f027db84ebe5ac4ba091f3a5e775d56c79b8237649e486b5bbfc8fda25dae6bfc14a394c2c35c36102a0a0290956cc140bcf2212ac4de04cc41da5e3caa55afbf04b4df44af0f84e52dea079a44a071aba7ef032e2756b06c40ece107dc865eddf9e7a24c9cc4a4ff3528fa0c3db5654d44486e73873c9d522c7c5c8d4be509036426ae687efdd76f77c472fa00da59086ec0951a7fe7d9891b7b0f68ba4ce7e9ecc9ae1be8de4b6fc130c013fa00bcec8a188144d9ed5295e1582a1eb26ebf5f5e2fa87d0718ac2039af3adac9fa0ded4c5ea62bb8a081003dd4bd8a9af266a75d5dad80fe196673fb432feb83ed2a030bf7049d6d3041ee88947b586fd46fb8db89cc737de1d06d7dfaa67dd064c6fa0c6f7bc68177ffb46d15def4999189fa0906826621ca4cb59367a4b528911e892a032d49ea9f6351e9bafef067150f665760a873a5eadbe19842e94be57d55cdb4ba00e86de560c97e218cf7bad28edabb28fbf20bea173c1c27c24fb3f8e1b0adecba00a80e6ccaf2419c821a481b029cfaa13ae4e8fae435547de4097d81f43ca9e63a0bc8f3a5cc6c843a9aff9975effd40ae1145fb06d0423576be4bfe38ab03b5c23a0ac7537a7b3a65866eb4f63fb7a7988d02a97e1f552bb34e0c355763c439d85f4a0eed6ed6dc91a73201c0226ab0f0bcf29ba868b021319eebf3349c30420e6ab9f80", - "0xf90211a0e047ea9f3fbabdc8689f19b366f1fd65e2d8ad837d1374567ab7e637e9fc48a8a0c64a518928fbf82de8ea7d911b15ffa37a2b45e5903b47f607123d7de7e0c88ba0e1d12e3187d71f5d7a02c86cd42d89652906187883007093574690deb5777996a0b2f8e0eaddacbddc2570fb2f8995b6f29ed5fd2d2556c4060d5312b2a9def93ba00cf7265d957f5709bd49ec0dc9b353e0475d8698fd0da4620356018c4aad097fa038f53288379986c6b4a91ac399c83ef3fb41482c0830b55e212664d3f0b23084a0795b923ed6bc103731d5087c042bc7ef477e69c7cdd62aed1e125708292a4527a0b59f4b7925029459d5ca84f638fe8b514e0b606886f4c9f00f4015a92070f34ea0c0a466c74c60d3b9b6771293c34514e1ef654c4c5a9bb22aef40c2d1a3014b83a05d2c4df362c33e22e0534c52296d6f6800289981e1eb0ab8c41237e332740581a08191891d8c85005a92948a97f29f0d4eb5dbb69b7c2a46cb2397dd397e8cebaaa02de79420688c7f59d1ca43707f26d690f8115359a5789926dc94bdf3a35ee966a0e2135957777db7d329d2e21743388d6589bccc907776b2182b6babe7a9187834a00585e9e551c81253c0ff7c09624f23d0bc71bcaef6e12cd6c393df086e63768ea0247f7a60aef3ff0365a002a4a17a484dfe764a301c523333dd8c249a6c99ade0a0f96791e072366e32b3c2a4b99df6401c6971f4a3b2a297cd853a36049227e43580", - "0xf90211a09be6773d76d3ee2d2fc885bf7c893ed0155f5c6f55cd1d7763fa0ff4bdfe7ca3a03661a6bd0c24511a05b40f8ae74c737f47d0df70bbf3c7a0816810ed90a84426a01a724a756ab16c2542b21bbf5882c8c6f3f779af5ebaed2a014c7b50e8555685a0c3c0fcbe978a40fd7d8fe5236abf13ddad4950e1bad5608079cd866abae018b8a01d942c5f793bd295e61894015b65c2a0b772da5420e868784603db7d45fc38aba04c380650e9c5610bc9c2778e69ccd067781d25ef6b650173d64c74f8f12338e1a0e3981f17dbc1a00258432c0e34232f267d05e271590ee7a9783a51870f9873c8a03a7c4e1b76aa60dc9d631272c2ce6a72e82914e0cd8ffc759889d5f24cdedeeba0eb5f21bf15d971d64c82b79c5e96603d5249a06ca7bfa439e4d479ced8401e7fa051b7adf8443398d7a4c79f7dfa09e9aef92f9cdbb4dc628133d6422f3493cb74a0012fab999f402d6b302a07d3f7973ee8c357d5db8c7991903bd54d54d507cc23a0dff9c03e7b746d93ddfda2ca54bc89a1be5ecfb1c4eca3d860b1769f8418f38da0c55b2981a6fe08260cb6a076c76858d56aafdf255d0a12a2c50abe35d468c7e7a0a172e8a15f7f898f525d2e7593533df968989eff48f9ee23cc34f14762d45e7ba03909e6c87be78bf54588e521ebdded1d467e8104d18958f7dd079010ee221557a0e7aef0d8c9d7ac18853b8799630d1f904cbd62db280abf5396a568b84bf92b4680", - "0xf8f1a0ca06c2b4c97d9941e56c3c752abe4c2b0b2cd162e22a5d25f61774dc453deedfa0344f34e01710ba897da06172844f373b281598b859086cf00c546594b955b87080a09bc4a42b6376f15f2639c98ad195b6fb948459cca93c568eacb33574b826a7af80a0525e7dd1bf391cf7df9ffaaa07093363a2c7a1c7d467d01403e368bd8c1f4e56808080808080a0758bf45f49922e3f1273d3e589753038a18ce3bbd961e3493f276eb7c5d04a3fa0235db60b9fecfc721d53cb6624da22433e765569a8312e86a6f0b47faf4a2a23a048a6e62e559cc8601adbd8569eed533b3ac8df2cda487353e8acaa53ca9ce2528080", - "0xf85180a07f152c1e0fbe4b406b9a774b132347f174f02f3c2d6d1d4ad005c979996754b28080808080808080808080a0bef014b961a929e8082fe587ee8774238730e584d7e990b08e1d5dd08e14d928808080", - "0xf8719d20a65bd257638cf8cf09b8238888947cc3c0bea2aa2cc3f1c4ac7a3002b851f84f018b0276505ab1fb37833287b0a0f71e47f1c3a32f09f968c64d41495d55e8c1866f22cf79ea6452f7c67f9eed8ba0d0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 19493153, - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "storage_keys": [ - "0x0cb865ff1951c90111975d77bc75fa8312f25b08bb19b908f6b9c43691ac0caf", - "0x98be5cb53bc8c144acf7451f10098b397ac1c9626286fa6ac9782d3ae4d7a49b" - ] - }, - { - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "balance": "0x276505ab1fb37833287b0", - "code_hash": "0xd0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23", - "nonce": 1, - "storage_hash": "0xf71e47f1c3a32f09f968c64d41495d55e8c1866f22cf79ea6452f7c67f9eed8b", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a084a6df8a60e9f9e6c23cdcac12bedc626dd6936b0c4bb94d6eada2cbf655d558a075b1dc9f04119a7cfb33683a4cb0f816d4bb434eac4db8f1951ea6886c1a0811a0323cda734e99dfbfa93edbf76183846bc7c3d52da0971ef637d4a1497bae0210a0b2f0e87da6afcdee1c868c86c9cec713c689cd740b55045b5f3933d1eb9e42fda098ced1ca77f42a52a00c659835bcf632fff9d143202abee9f3c60209051caa1fa054bb4ae44bbfdc5b59d0c4dae52c9dc588183381dc754f53885ab3539959dc87a0e6cc346ca9f68734c01bbcd0c7d683efde7e22f0a662e61372bb36ee810032fda064c7ae341d641d6ad7f3349201b613548ab5af1968bcb4dcee33c1f6bc83cc28a0d4c2e648ffc7b4ffefb7055ee1a3057d83aa98a5ebe01248dffeca8182c6be4da0e55cc35ed1d794f2d0144d2b779c8f426d4c062f10c91f93e5a03a6de1f153a9a05ab7b3f9e75c1c06ff8f1f58bfd51313dde782f92886b22b9ae55c05cef8dcf2a07e3f7ccfefb8530d4648a9bde251947e4f110d5156487d2879fa556a0889e664a0b7afbd434e3300eb9068ea193395d0b587378583a6d5de432b4e06863d1e00a5a02b4fe03e6dd849069dd1dbc26699df1f9217b3c65b3dcf8cead863f8de24a415a0f5e86ec2ed40d5e3593c72e188659441764f9ea0ff05dd129403093cec8bddb3a063014473c20a0aa044ccf43aff9c7ba449e045067a520017bdf1fcf21f9c37e580", - "0xf90211a0a9e8f0755aabfef746a578e6b4ef8f326ee85214da5fba603a066684cdaed705a0460c20be22da9d3c92e63e85fa771f5a5cc1202f4df0653c30e8ea7de2b0a658a0f28bc10b89da7de7848fe7a7289cd59f4ffff5d4cc62f1b938b99b1cc7f7a7c3a0488188c36c04f0f467a18740c24d78ddefc7a25bcd30f8717ae642622545dae5a051d82d4590229e56a508c06d0c17d93d70431aec85cfc1129e6362289dd6fbaaa0bd5e2a883a395a3bd7430f7272966f2ea06e37089f7d1c2fbc0dc04442220ffca08843b2074a92a5f4a26ef974ad0c4812bc2fab2cc219d3bc1eb1cd19ed402271a0fd0c99adcda87adb31f0e999850fd68bad524f62eb969ac8a3f51010bc49795fa02aa22348a6017501aba01f3133c195ef9208daddf2a4babafd7465690c4324aca074a68be43fa48a1dc2311ebc13662d3c2322db8b29309659debacd91d4536f07a083f338c60d625a32cba1f1b633d4e4b25da978b559eb46de7335efe457b29247a0f892daf56d041fd983ecb7d15b7db55a32728413f12ed795fe27495cd8026136a05e49a4fdb1fc80c3e751e6857e6d9e0a6cf198e240d6037702f201291611267da0a48c4104bd8c66ffec9cecf2efc7274e3877231cab274b16aa057c27f248d97da0825cc09e86a3e24213abe65dd47913ee99c8814f81e645315c50b7bd27ca7a0ba06772f8bed963e61594689e600b55cb6ab8b8593d5520a9ed400b8dc0e738976680", - "0xf90211a0cdaf2b2bda12ebc2b59b01a49a3559ba63165c24a91bc4b2f027db84ebe5ac4ba091f3a5e775d56c79b8237649e486b5bbfc8fda25dae6bfc14a394c2c35c36102a0a0290956cc140bcf2212ac4de04cc41da5e3caa55afbf04b4df44af0f84e52dea079a44a071aba7ef032e2756b06c40ece107dc865eddf9e7a24c9cc4a4ff3528fa0c3db5654d44486e73873c9d522c7c5c8d4be509036426ae687efdd76f77c472fa00da59086ec0951a7fe7d9891b7b0f68ba4ce7e9ecc9ae1be8de4b6fc130c013fa00bcec8a188144d9ed5295e1582a1eb26ebf5f5e2fa87d0718ac2039af3adac9fa0ded4c5ea62bb8a081003dd4bd8a9af266a75d5dad80fe196673fb432feb83ed2a030bf7049d6d3041ee88947b586fd46fb8db89cc737de1d06d7dfaa67dd064c6fa0c6f7bc68177ffb46d15def4999189fa0906826621ca4cb59367a4b528911e892a032d49ea9f6351e9bafef067150f665760a873a5eadbe19842e94be57d55cdb4ba00e86de560c97e218cf7bad28edabb28fbf20bea173c1c27c24fb3f8e1b0adecba00a80e6ccaf2419c821a481b029cfaa13ae4e8fae435547de4097d81f43ca9e63a0bc8f3a5cc6c843a9aff9975effd40ae1145fb06d0423576be4bfe38ab03b5c23a0ac7537a7b3a65866eb4f63fb7a7988d02a97e1f552bb34e0c355763c439d85f4a0eed6ed6dc91a73201c0226ab0f0bcf29ba868b021319eebf3349c30420e6ab9f80", - "0xf90211a0e047ea9f3fbabdc8689f19b366f1fd65e2d8ad837d1374567ab7e637e9fc48a8a0c64a518928fbf82de8ea7d911b15ffa37a2b45e5903b47f607123d7de7e0c88ba0e1d12e3187d71f5d7a02c86cd42d89652906187883007093574690deb5777996a0b2f8e0eaddacbddc2570fb2f8995b6f29ed5fd2d2556c4060d5312b2a9def93ba00cf7265d957f5709bd49ec0dc9b353e0475d8698fd0da4620356018c4aad097fa038f53288379986c6b4a91ac399c83ef3fb41482c0830b55e212664d3f0b23084a0795b923ed6bc103731d5087c042bc7ef477e69c7cdd62aed1e125708292a4527a0b59f4b7925029459d5ca84f638fe8b514e0b606886f4c9f00f4015a92070f34ea0c0a466c74c60d3b9b6771293c34514e1ef654c4c5a9bb22aef40c2d1a3014b83a05d2c4df362c33e22e0534c52296d6f6800289981e1eb0ab8c41237e332740581a08191891d8c85005a92948a97f29f0d4eb5dbb69b7c2a46cb2397dd397e8cebaaa02de79420688c7f59d1ca43707f26d690f8115359a5789926dc94bdf3a35ee966a0e2135957777db7d329d2e21743388d6589bccc907776b2182b6babe7a9187834a00585e9e551c81253c0ff7c09624f23d0bc71bcaef6e12cd6c393df086e63768ea0247f7a60aef3ff0365a002a4a17a484dfe764a301c523333dd8c249a6c99ade0a0f96791e072366e32b3c2a4b99df6401c6971f4a3b2a297cd853a36049227e43580", - "0xf90211a09be6773d76d3ee2d2fc885bf7c893ed0155f5c6f55cd1d7763fa0ff4bdfe7ca3a03661a6bd0c24511a05b40f8ae74c737f47d0df70bbf3c7a0816810ed90a84426a01a724a756ab16c2542b21bbf5882c8c6f3f779af5ebaed2a014c7b50e8555685a0c3c0fcbe978a40fd7d8fe5236abf13ddad4950e1bad5608079cd866abae018b8a01d942c5f793bd295e61894015b65c2a0b772da5420e868784603db7d45fc38aba04c380650e9c5610bc9c2778e69ccd067781d25ef6b650173d64c74f8f12338e1a0e3981f17dbc1a00258432c0e34232f267d05e271590ee7a9783a51870f9873c8a03a7c4e1b76aa60dc9d631272c2ce6a72e82914e0cd8ffc759889d5f24cdedeeba0eb5f21bf15d971d64c82b79c5e96603d5249a06ca7bfa439e4d479ced8401e7fa051b7adf8443398d7a4c79f7dfa09e9aef92f9cdbb4dc628133d6422f3493cb74a0012fab999f402d6b302a07d3f7973ee8c357d5db8c7991903bd54d54d507cc23a0dff9c03e7b746d93ddfda2ca54bc89a1be5ecfb1c4eca3d860b1769f8418f38da0c55b2981a6fe08260cb6a076c76858d56aafdf255d0a12a2c50abe35d468c7e7a0a172e8a15f7f898f525d2e7593533df968989eff48f9ee23cc34f14762d45e7ba03909e6c87be78bf54588e521ebdded1d467e8104d18958f7dd079010ee221557a0e7aef0d8c9d7ac18853b8799630d1f904cbd62db280abf5396a568b84bf92b4680", - "0xf8f1a0ca06c2b4c97d9941e56c3c752abe4c2b0b2cd162e22a5d25f61774dc453deedfa0344f34e01710ba897da06172844f373b281598b859086cf00c546594b955b87080a09bc4a42b6376f15f2639c98ad195b6fb948459cca93c568eacb33574b826a7af80a0525e7dd1bf391cf7df9ffaaa07093363a2c7a1c7d467d01403e368bd8c1f4e56808080808080a0758bf45f49922e3f1273d3e589753038a18ce3bbd961e3493f276eb7c5d04a3fa0235db60b9fecfc721d53cb6624da22433e765569a8312e86a6f0b47faf4a2a23a048a6e62e559cc8601adbd8569eed533b3ac8df2cda487353e8acaa53ca9ce2528080", - "0xf85180a07f152c1e0fbe4b406b9a774b132347f174f02f3c2d6d1d4ad005c979996754b28080808080808080808080a0bef014b961a929e8082fe587ee8774238730e584d7e990b08e1d5dd08e14d928808080", - "0xf8719d20a65bd257638cf8cf09b8238888947cc3c0bea2aa2cc3f1c4ac7a3002b851f84f018b0276505ab1fb37833287b0a0f71e47f1c3a32f09f968c64d41495d55e8c1866f22cf79ea6452f7c67f9eed8ba0d0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23" - ], - "storage_proof": [ - { - "key": "0x0cb865ff1951c90111975d77bc75fa8312f25b08bb19b908f6b9c43691ac0caf", - "proof": [ - "0xf90211a066e4f0cbd350925961d891ca97a5baf428a761669a8a4337b954797e5d419f50a0a4b675b289491426cf7b2e62036086490974c4bbb0a43a36f8f521d6e57f2c4da02611c8bffeda98f7d05631872527195d73d4e44c3f081c6fbcb5295ec31ac76ca083c7617223c56d3e16f62dbcec97040b7bdde94053aaf50c28bc757f75232660a03875a33ec2ef9ea01f63589614a2adad7bdcfb53b688e0f575becc0e31a7ba70a0b46a06560de8c53735a88d438d24cd56d4cf0c2765062858314041bbd0969315a030fdf12f1274026693433477a6aeb108daa3c03f9f30b45a151b825f0553521ba09bdca3a71c57d30e92f8ac73f65d73cfa903d8c67888c9c59152acd52f22d5dda0c1afe1c3d27888e23755f7fdd144a9f27b006c2a46383ab5421a442369c6f3e5a045f7dc067f4a4eef2f14d038b868144e3db6f4723c50dd4e142248fe6c5f7618a08a5d43aa6ffbf5536d12a82438fffa4c3a818c882cf3565d09366c502de82ba6a0d4daba59f04e7e37b7547b262f2db0813e4d706df9c9ef72635f54c258e46dcfa0d39fd22b32b6750c5df41a94514c47c2ec3b55c1aa74fe4e49ae9f9aab9897bea08b9441ab1b60fac3704db85958cc037d495735eda9a072fdf2dfc9639b3d2c39a01ab348b83857205c77b61dbc64e542dc6150512d9be7fc3cf46f95d7d81ce895a0d7aae5cde515d6b1f228c5a6321b35904fe5ef66d1591c996d302d83300df0f580", - "0xf90211a0d058bf03d65dc11204a09adda70db2b36a18376cf80c10b29cb647d33e5b6e59a0ca14febe3c83aefbd1e3e2db9f2b31046d063ecd66a0b316a73e5ca9c7f4773ea08a976d0b3733dcfb5822b839c1696fd18404f4b6395b53adad5463311559230aa0f7614c3ba73bf821f9e2309e35659bbd3c66fbb36dd92b5d7a18c83676291444a07034b27d39bf8f611ef3f02e40b823e448fe06c9505fbb2f60718bda8f99da32a087547e12d5c5c1781430b900cb485601f6177c4338268e6624fa5d6c72c63e04a0871b626eaab589e3ab27b06fd69f842a92edd1593f56cd7e955dd5ecf7417251a0281b8c20ec3e6c75849b65c80994a3bb9bfd32d28cd8c8f84396fa4b747c310fa056e5e9570b96936f0b274312ea5976e068a04426e3856b74731cb61f32f072caa0505e8e9637317b7bfc3208ce62257b8b2ff89974d64ee37bf858ce6689a50868a051122d5faf1fe5998bcbc5c888b2660787587d486b9e654e47b6a0200206df17a06ae332d4dc5d7e5064350821c8ee4ad7a97172476a8a7bf3d0ad551f0525042fa0160d64e481f2eac3ccea18687f4938c20c6265106fd0f63c6bc2932424323c8da039969c51777fd5ddc6c917401be72e3012af5f8e5d069073a1ce307ecca224e1a0513c3338bf07947dd017118b1ee3fdcf81afe5e2f5cd7d57f5d400e9b445f58ea0f4a63e43c9aa7dd3dc18ba3a70b5e986258278e78e95284ffe2d93d8242aaa5d80", - "0xf90211a0f9f04fbeb1173cd7d9dbe3c59f030c987d82fa9f1863642a9182c1d84829b22aa096e6c6d7f5943a3a841f1f156caee1f3aced2ed8510fbc64996dd4fd0d8df601a008c99646f82aa35ce0c1caa6619b096caaa3a3c286ca2bbd0b1d2debccccf6d3a0bd915d0d51cc6c43c8228dcf7850751eb857cf612e4c934603b9519b063239fda0cffd6c140d8484b8559acbc8d2b181c724b10995414d234010e88ec94000e976a0449ae81c055284668ebbb90e6ebcfba7b841a505890ee8ac63aedbc2a7b3af7da0d2db09193e04fbb17b4c7bf86293a6b837392c976d42a59a91e0e0949939a387a0896ab187eb6f4cd4d051fce0590eb3c830ffa3414f55913f6797dfc8c1003e4da01e54285c7f67118e9f60f587c3e359ae679ada2d47d029999335ca0dbd76645ba07d2d763dcf7398e1905070bd7d17f26cdb11648c283784aa05964dc02219cf6fa07adb17d8dca4145f708a51d1de2df154b72eed36e60be040e1cf9746e5989335a076d779c4272dbdeff6d71283b5d2422e779e36e77f70b386c8b7b056693b4c4fa0f720da537525b82cf6923bea55e54bc460ac0ed85571e83bccdffa051652cfc3a0aa4e76dedebd90c3724224caf35312962747d05ed2be8f03961831eed9fdc97ba0f7a9e0b153c65b4427c11fcfa0fed4396a2c5aaa439cb5bf57405943db7402e3a0dcdb5b3a4323712ba65fbd5923471dba6204fc34e75b422533dd8222c72d26c280", - "0xf90211a0d890cad0aff909aa56d48afead3044ba90d8b5fe41378f400419d1b21810d481a0b6166dbadcf49aa4fa84987e345f238d821c368a5990bd32d7d4f8fcb49b87d5a0a3c9a4186707ea1572d6243c74f0f20e769045a0d60c138a0ad51afe326f0452a0c8634de049757216f0895c5b4c532cec66412ce1fa3763f47a4400e5949ecec0a036e670a55433490540da03b0bcd131fe8d659733ddec9b4da339baae00b01419a0ce840460511e29758db156fe79d064ce2072a65829cdfec84881ae4b83b60119a0f5d039c1fbdb91110ad6744e7e70d5268f6b7c55b613522ee092e6c5e34f2b77a093cf2edda959ed3c592070d4651213d17cb19a385057171e599baa7bc96081e4a0a723156ded24151831fea98ca2640a256c2d7ace47d5e245e661d8a295278a39a0b6c1e7272808abd2d830b84f656b6b084b24094877d96b2520cf044ab584181aa0af999c02876700934c4fd98d06424468fdde76fff5640fe3ace5a16ab12508c8a0c7400a3a445104c7507b2ee4cf2e094da945a0075b90e971666c3ba145831f95a0867fcc97c77faec5220aab4bc6cca37daf4852e4db4c88a3e77d360727d7fcc0a072a74fe2aae6f8edcbf69a78ac39725964bfff7cc2e90ce8cdc8d21fd1687ff5a073a65d78096bec3e84289c46d9dc585e081facf3d59be34292097a30245bd845a0f23dc003ae49de3162e109fd4a64901e5c7ae593651c08f526717d82f806589e80", - "0xf90211a04fdc7daa64e812f7a6085c59621bc3a57c142ac7af4cead5568f2ed1d8313c6ba0cc74c9310ff462be9d08436dfd14a69cb0c6a48e5c4cbf2dc006a22445d4aef0a06057bffd29ac2948b80a1bb11f848278a1f8b5503097393d390ae14f22a61285a05ae220339c7cde572ef813218149efc257069347707a235428e5dec5dc36dd07a06452db1b298a5632e9cd187826bcfc4efaabd2a50ce2ae417fdc469239c41c2aa01fe523c8e55cea4eb25621bf6a02b81f05a6e281605d8dc5d919b9cc0000e366a0f8bf5770f552818f6ab99e4be53c88adb21a3b35c13b29d25a489c854c252373a0fe3122bbda4ae610ef76ccbcdc12fc3dfcf238abc39dd99528170b6fca75b9faa0008f47d63452c4c7efb39246bcc0155334f574e09c1df08ea7096f12e2240ea0a02fd14f097824d7e40c487f181e71d25d6613ecc0b32aae31979334ebff508c6ba04a09985aeba24bfab309a2d82ea1ac9bd04b0ecde55aad1b451b2bcb8b6c91dca052c46dc74dc1f910e14b61262ccc76f994ed0f1fc94ad6c1d148be432757b954a0f548358c7322ea16478e4a0164c58fa87166121af2d430b1a1b29d8524285afea0b83d146cfce28f5532ebf493b2a2498e797cd8e5389cb36449d9f3b3cdff3993a01ed63e6c4b7f684a7ea3d8ffdb2531f29c95685d60bcfe3565a8148df14f5498a0f942a35b87a970d7ef825e30128c81223eaa97aee3a0df4c4064479e163b592c80", - "0xf8b18080808080a02f87bbd1ebe9c3b891012b0af8a5658081c475395df67b0b155a30e2368f038380a0cc3fb401e1de77964c72b49807814abfba7348920752b38308e7bb9652370857a0223eae795375f7471426f5249ffab792ba5cc2cd203d16fc00bbf7f44918a73ca03d9d7699d3593ef3871c049b37cc96191b4642b2fe4e950078740c6db15b094b80808080a0d705681da8ba858c19e8e104f8cfff2370281a8fdc342d4c2b8133b59d1752988080", - "0xeb9e200bf4e0310ff39ba41d6b3cc45f49a50f3a2e7e4e46742cf882b58353848b8a01969a8ffaf84aaeb3aa" - ], - "value": "0x1969a8ffaf84aaeb3aa" - }, - { - "key": "0x98be5cb53bc8c144acf7451f10098b397ac1c9626286fa6ac9782d3ae4d7a49b", - "proof": [ - "0xf90211a066e4f0cbd350925961d891ca97a5baf428a761669a8a4337b954797e5d419f50a0a4b675b289491426cf7b2e62036086490974c4bbb0a43a36f8f521d6e57f2c4da02611c8bffeda98f7d05631872527195d73d4e44c3f081c6fbcb5295ec31ac76ca083c7617223c56d3e16f62dbcec97040b7bdde94053aaf50c28bc757f75232660a03875a33ec2ef9ea01f63589614a2adad7bdcfb53b688e0f575becc0e31a7ba70a0b46a06560de8c53735a88d438d24cd56d4cf0c2765062858314041bbd0969315a030fdf12f1274026693433477a6aeb108daa3c03f9f30b45a151b825f0553521ba09bdca3a71c57d30e92f8ac73f65d73cfa903d8c67888c9c59152acd52f22d5dda0c1afe1c3d27888e23755f7fdd144a9f27b006c2a46383ab5421a442369c6f3e5a045f7dc067f4a4eef2f14d038b868144e3db6f4723c50dd4e142248fe6c5f7618a08a5d43aa6ffbf5536d12a82438fffa4c3a818c882cf3565d09366c502de82ba6a0d4daba59f04e7e37b7547b262f2db0813e4d706df9c9ef72635f54c258e46dcfa0d39fd22b32b6750c5df41a94514c47c2ec3b55c1aa74fe4e49ae9f9aab9897bea08b9441ab1b60fac3704db85958cc037d495735eda9a072fdf2dfc9639b3d2c39a01ab348b83857205c77b61dbc64e542dc6150512d9be7fc3cf46f95d7d81ce895a0d7aae5cde515d6b1f228c5a6321b35904fe5ef66d1591c996d302d83300df0f580", - "0xf90211a033117d4a1862b9bb8f45276c1a475172ea886832c92cfcd9f73313b93b5b4960a0543cd9e79a4e03183002275203120cafc31ed8d82134f06a55d06656f4ff08dda05aba4f2d74a92a3ca537bc22cd6ca546a580eebd39abb0e08103954b697a40f2a0670102b9b32a6952bafe25e9a8ecca563fdbeadb9544b21e15694a2b7174c3e7a071aeb0f0dc86be11df464be888ec8db24f98dedf6ccaeb873b2d64cb483d74c5a08cb47ddea61c239ab269d39982dff5f71833c7192d3664c6b2f7a6531d0f2a97a0e201ca8b4f90e8b52a48a8a0894ce1e094dfa110d9700bf7830b1be6be7f4f67a0d83e94140deb0afb5229fb599deb02ae3a78591c2ea88ebe3b516f665546924ca0870206fb77c2f07c5f12c5c187b2581818546d58fac97be6ace4b5482631213aa0009d62eb407624baf7fab1078e6d25d1435ad306ed0c936497e97d809e867123a00efa1a39e45a7d1c3e2bcba073063f684c16d56196f96cdd48223f39b35ddd9fa05fe09c349b6e045685ad0c474993623fbb8e6ddcc204a78ab1ce2c67863151d4a0fe60b26818776d87d72046ceccf2017cc1d955de1f4517e046f055df23c8f3fea021add17ed5d0c2ea9d0a18e5ada535bdaa03d679ba3d0782a1091feec81a9fa2a065d95d51a1c097ef941909aa798ed7223117d0e67cc4ec5a4104ba9b83a855f4a00110dfd5621b96d0c1485d6130c668d84976905c27c2b5f8f38703d3e24c779f80", - "0xf90211a0cba1792bfda8948f118114740a81481cdbe9d39188974676c742402b71f9d8a4a08cc950abf11a907df498e7f3ccc8aa2f3d38550cb0d276114d9967a726c31858a0f0436dcd19c8bd975cbf984e5448e5c63232f5f317b6552c2d7f4aa787fdebb3a0acc7193872f7d60c2a627b1bf9d8c9a22ef2719dc1ab139b7ae1c7ab2d53fb38a0905e9ea6f01a04e90c090836953d7d711ae589d881260eefb9369ed9741bdfeda0b2925971074da66c3784b2149c8d9f99225df0c3ce500a86ee17bb3ebd497974a082f8565d35e645c22b8976b8bab4ac2d41659f819e6087f97d3df41df51b9684a0c6d0ed8755f83dc915430c2e5fb2c3e4894ecd7ab9950237710f23526f3016daa02a2c3326890abee4c0584728f44daf1c699325a5b25dfc000d45da19c9d8b1e8a05d7cca2ba151c0b09ffd0abaf3d45c81d88e57d99efcbe3d66cc86a60e717eaca09734a6cff7263aef1dd376863eec6fa3f81b372c5fbe82dae03bcd6d8892c4d0a0a0a5dc737f5ca6915b06a9b2ed8fd5a4da0f428d271e391e13de6f2f12f6858fa02a697db8f26f6c6beea88d6aba1ebe6d8fab9f19c669ac816e62c0e0d74967d7a0bc0b8e181b1bbf60f9b496ac9cf60650a401b04648f326dbfabc02e380414b2fa0ebb295a90c8e2ccf6a97852179659c70d02faa3b52277d2e192cb0efad5122cea03be3a7b04a35266618d337c11a44baf4cd3311cd6a0dd1c2da5ea49fc2051ddb80", - "0xf90211a04006780dbde927dd8583548d8d9caee65738e2797c8fa2ac78bf8a7d7e9339eda0a0f8716a376ae814141e7f0fd529be4f4ec50e821dc043473fb5c662ea7135d9a022661b0cdbeeac31f93391e880e1a6749acf0daa93af0aa23f29aa75a054c36ea0f06782be8684a10f2784ddeadf3464e145398f0b1972cc08f45401b5ea1905f8a0c92fd81edfec710942145fc84b3ec0856532196b2da16093a45a1d30e10fc01ba0345a8e7e1006da4ee1328fad2eb3d6dc49cf5980a70913aa96502b9a9343c74ca0aabec4f150a213de7fc87f4196faf9dfdade337325e029d5a45d8939ab996588a00ce4f2c04f48136083c36e2620b57a2d4523773c46d8d7beb836b34cac6b83bfa0b8c69927a854ee0d73e6f54b81f3db8bf42d301a2df62fa99a304a695aead1c8a0a4f82facfe48e54162b92606a618a1664cc6badac608a984c932406dd8ea288ca01aa8ca56c85ec2b694ee07ab4377550f2d6ee5fd82c89b93caf34f5179a936c9a0a98c2a84677b8a0a31fc9786f8e226c8bda5cefb2724e16f91be950d8c8d092ca0f64798b65d795662d12f2d375cba3df65bf1f3a4582292ba1506fdc733107271a0ba387ed6e6ef8832336a027f183848dab7cd334a9be8880d207d2865b419e99da0a5360d1d0b8c23f69827400ca02c677b61f829180a57b3455e3f05c3cd6ae948a0b9a8c1a24240e3182f89d5a2a0f702decd0d9b6d34e3b0ff71dd5b9125c710c280", - "0xf901f1a077de2cba41f5357655f278635e14b206265555647bfb379713e35a1c6347b733a091946546369c7b05dd7c71ef247fb91ed28f938a872985c324434611aa0bb6d180a06b057a90a8fd4261d8216cc8045013fce93ea8e03be56ae1d60eca5504da25a8a0d95855e885797015b9f00ca0da601d1ad746e2ebb1e3b0b9b79563f368a86767a0e96cef740314d41238a4d23fc72dae0a9ecc478a95334161e23a8acf961a9241a001000631648a376d7d688bb65e67d9aa5b018cbdd5977148ac68506ce9c17daca09658c8abde1ce4a040c9ef6494773f7bab03aa71a981a9e66f8445cff3a8dc97a0cb254c1261a20b880df0bb96876106e839da1aa5bc2df2292de11535c06cc135a00071e3aad481311f5cfbf3d93da2b1d28d519f2ea60198393c9d6b4d1dea7942a054602acc251ab5731c590f7c65c61ca219e7c187b50cb4c398810e40ae26419fa06fad66d46263ea487a2244fb85fa03ddd85392b0a3c82019ff637b9fb1f1bcd3a0c3a9c2163878ed252819966093f927c973ad311859587ba13983c9ba0d39f751a02dae078755ac08701e31b511bf910964ba27b49ae1a9d2871ab4b20a814db492a0011585d53fd453d42ad3a7c6fd592ac21a36ac4c5baad1337a23ce9dcea2740aa01072f0f4a0f17d5b4091cba9c87cac78cc2e62d9847386d9e1b7306f76c5308680", - "0xf851a05ef48a2056e23f89a400cb1f4b77f387ea4d8c6d6aff24555dcaeb0e395bf8158080808080a026565667cbbba97707fb6099d9e54ec2a46b8fdfc15e4060ec699baef2d7f61080808080808080808080", - "0xea9e2003c43b5c0368a194661574b53a69c3d362098c7c2aa1553dba21ddd3438a891055d788f1f035bd1e" - ], - "value": "0x1055d788f1f035bd1e" - } - ] - } - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "storage_keys": [] - }, - { - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "balance": "0x1", - "code_hash": "0xb44fb4e949d0f78f87f79ee46428f23a2a5713ce6fc6e0beb3dda78c2ac1ea55", - "nonce": 1, - "storage_hash": "0xebe4613708ed2470e93df2288bb3fe45a5eb682b66a3b87dc06d4a1feece4b06", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a08c2cd51832b2e9d20457d4edaa2c6afe1371e79029715ace81f945f1ae66d495a0d9e2f1eea40221dad472f220f151d028fbb5058c575b150ec0527e19293ef506a03e5d90f78575a83b35f3911cc2dfd4daaa00f7ad01653b24ef84b7afdef906d4a04765e14ebad8f792e965c4cfd41e562189c995b3956c715c716ad301eb481855a05605376913ac2e29b26fe6c8a2156f583e9f11d7b99a83ca8b6a65ee2d7090d9a05ff0a75948c9b2b2e8d2a574f30c48193d06a1cb05db7fa7b3aa7178ed0382d6a0c262472241b1714b6dc754db85acac9baaf1c0f10c90aa68e18b4c7697a55e8ca0605c3d3bf5dc157daac4113213b255b021b2f1ebbf6e47173b7c0050c6c84fd0a07465c169006c4bd52af11975ff2117edb7621f088803237fd09b3cef446d7901a0d551428fa5c903ce518cbe78aa01476e68846c4507e88adbefc94d8ef9ef9966a0f4bb397c558fc522decb5fc5459310dfa92df3302e20f4775ec14a50aa0d4eaea0d8f10c4d16056c21f67188c6417f2b2d05e8fb22e519a13a97dd0683ba6a7de2a0aa054e44e49ba3c562117bb890b51b2be370f45979be1b5ace2f9b8ab3ea83a2a09131bc9c247f4327d138dcbe095c11e0b298c154f79938262e1198de06649df9a06797e447e810baa3673cd4894c04fdcf9bf925a09c5e1b0524d06cf912664598a0a21ef4110f094136b70de5003ea1afcf53484e6508f2fd90ba3161b2e67d229d80", - "0xf90211a0cc6be5aa022d0b3a80084940374eceeedad213c43cee81ef96491ea7152776d4a05f56c72f9b64362b4e9afbd6384c48380ab03e4bdf36d04c42a65308e249e613a0741f2a866c5083ffaaeba848183ce3a61ad86b2d269de734ae63c3b421432d61a0f06ee45a0f0be845c2ff2f278f961ddbc6155a58b29eded19d838aa70fa6abdda0daa76a6b44346487ef258200733c29ced9799b2b6a8ee47ba24825d4b6d79933a06e88ed05cb277304474e1bfba719f54403693cd04765f26a85ea254ec37adfe7a0d17e4e83932facbcd3bb2795d7c449c16ce61811369428223cf40ed059e9f6c0a024415606d36276da89833a1261760258e2df74660f2e431e355a79f3d9a26b6ea0bf4301031cca5bba39ae341b8721f200d39c6189dca22d664d32433dee69c79da0e4158de5943e4172083bfbc1ae7c0beed3c701db4ea21d906f11d6f30d041e55a09517ffeb0f416408e944b42cc00a7ad4bad2c8b79ea6efb8cf9b8bba3481f66da031a23470f63b79693a4199d432a6b649f7529943cfe0c4a04e50d4c225fd595ca0c4ce4ba5cc7205e919a1631b04727c5eddec768dcc455ff22f87d927609671d9a0461ede2aa4a4d087e13ffebeac33198a0ecb248e457b90039aafb22e38382485a0b3aa56319e23a1b36efd54a97c9879c7ebd092220d5c577a380ececc8ab550e2a01a5f120c09f9421578a00211a883caf03663ac3cfef429bd3301c851cabc84e480", - "0xf90211a0650c02d5e96a5be5bb4ca707d1a66f38654b6e727b3bf01aa4c68dc625414810a0d6e59e966f041f598dc7c4caaefbae828832577745676bd77c422d9cb230461ea0967cdc5781ff8355b63c84023eedc8264ea4796226f4b082a57a6db0b4ef824aa06f82e77302d8c66de396363bb3232ca655c5d71218ee22846f534eab28cc0a6ba07895700533d8a6a2c4136571fbed3233a8c9cd879e2c1df5f629e82c2c7e677da0cd4c2fcbd169da57273caf7be36b4ceebd14d19b7689531c57432a120631198fa0d9dc41447130535abc51cbcfac1b404e23507031ab37815c1334e8d30a69a0c6a0f932cc3471a46ff013088d1c5d5bc2294abe5be2c4ebe33a0794b294d1bf0b97a06807b893d0248793beced597cbac62a45a23bda69486879ed7831c42a7832716a0002dc6c71a918b7769482862a1b8dbbc9c2a3282db4de6c5defbb773360f8ee6a0b87311001a672884da42b8376d1af9f5a37c68a26c042f61d5949aa5f37a9a0fa02f9cc977f4dbda5da169bc9e027ea204f879dfe67b2bd10f293fe56516d47ec3a0fc7d232434031d1175819747b1bfd2b3ef5d908e09acda2c96f56dc950ba2f89a00bc66c05d2a19b22a74fb5a6c9fc3f31dff0158494da662f2d37632e3538ca7aa0abe343ae434790ddcf74e7ef3162a45d6858e491534fc7a76642ffe1d94c1790a0d589e7cd5def99817537f762c62f403f10a806a1102b93badf21a63cf164836f80", - "0xf90211a0a619077206004fc7de385b8172d96d7b3e27be8b1cac21942e46a4b41b0caa7ea0065d6b31e3e625ce3a383d77cf1a850e3fcb968bf60d876730bf837bb295c13ea0c06cb528cf500c6cfe405dc66b8b1553a43bd134de724e4c5e63b298610eabb0a0b31071e69e1d0e730170fac1c398e1c62234d8017c561a885ee102eeba7f674da0ea3f4b9480e2fa2bf8055b65a7ca36ba9113127312a6416bc1f188fec3405c56a035d56a7452951cbe0ceea12456421e3881b60a19101f8da6d08d38b944b3302da0e2120d6ee061bb1a5771c4b29809d8655e58020315793d2d334b5770e2cde9faa03a2f10f147a93395653e3f85530bdef2fbd50c0c8efb519a58c3f181e6f0b8cda00f2913560ce87703e4c48e999c8e76cadf0d1a375bee0189997643aa3b220ccaa0efc2b97d37a2c0cf6bff3e54ba88689fece309550d51f4d3625958bfd4ba428ba0f445a2356cec59e3aec5e15ebbe81b9acfaf2ebae5b8d62b07adee2ff49da0c8a0ddcc906df986f1a6f90aa3ad90fe4118ec0de92a2eda6e77abce280001ca3121a07e4b900e4cad7df4bdacebd67dd6b69b682d756f4f1291f47ded26b4ed5fd558a059e5bc2a3cd3df37a620261d4b95168f06cfeba06dc76437f7f04fcb30b48d94a085be2db4127fe3c8b5b1bfc9d1a24cbfa827b97afd702133debf0e6458baae52a07f4dd5b8ca6c5066bf7d51f78d59b5faf05382a0f45df983469995ecd28d3a8080", - "0xf90211a0e31b4c19fcc4fcb854b8e624b318ad21b022c57c58e30f80f27bcd9fe4e61649a0950522557eb40bafbd082f0f5cc4be3bcdcb7f80c14eee43afd2bcd01f8d5137a006344fc5ae8c6063578d0b997b0caebc50abb303fc195a9875c55a5d3e7566b4a0b685573fdad10d19fe4144655b27c065930447e0f573c7729f1f9f8a2b5516b7a0db22dc742b84718315cf3623f575787ce354a3b536f2916445b8c98841d28799a00975b2742460058745a4ee9f17d4c2cd50047b9831702204293a4648ea4e21d3a0bd1993cfbea039adca3be57058070fc3db8ecd77eeff5591466fcd17eb023ebba060b8953f8ef7514acd9d70452830ef4c54261369b411285f372f1aed66126adaa0a7bbe5c7d23562fa1577db79cf77c262d65862d50241de2b147a9b5b318aacb4a07bff4eedea913e11c281bf9631984344780fcc3dbcda40cab7c25dadbf13c2aba00b3757b624f3e65e3cadbd9b61e092af2f6086fe846ac6ed51a2f0261d21b475a0b7d528fc41c8fdc8ea18c6e7d0099270c777ec1403cf879d1f5134bdc12a6c6ca00ef9fc129b0c672d92ffe23f9ccd800f73526a6131906377f258c54b1a705117a0251c695862941c0ccb2313831b0f637e2b60301268ebbfb483afc5c821221e62a00935150c3df87a08dd451d2d98c8741416a09ecbf3a76c4baa9b8101edd150baa08bd2b242e992653fa60521d04209d0f948548de03ed9d063f6c847212da606f480", - "0xf90191a00a7a0118e00981ab321049c9d340cd52c3a4781037540f7c48d0fdc27e899b3280a08537f2e248702a6ae2a57e9110a5740f5772c876389739ac90debd6a0692713ea00b3a26a05b5494fb3ff6f0b3897688a5581066b20b07ebab9252d169d928717fa0a9a54d84976d134d6dba06a65064c7f3a964a75947d452db6f6bb4b6c47b43aaa01e2a1ed3d1572b872bbf09ee44d2ed737da31f01de3c0f4b4e1f046740066461a064231d115790a3129ba68c7e94cb10bfb2b1fc3872f7738439b92510b06551bea07da2bce701255847cf5169ba5a7578a9700133f7ce13fa26a1d4097c20d1e0fda0a5aa8d46ddda1c7764406a3a78efd76f028e4e3d855406aa4c512af7becb97d5a0c8d71dd13d2806e2865a5c2cfa447f626471bf0b66182a8fd07230434e1cad2680a0e9864fdfaf3693b2602f56cd938ccd494b8634b1f91800ef02203a3609ca4c21a0c69d174ad6b6e58b0bd05914352839ec60915cd066dd2bee2a48016139687f21a0513dd5514fd6bad56871711441d38de2821cc6913cb192416b0385f025650731808080", - "0xf8669d3802a763f7db875346d03fbf86f137de55814b191c069e721f47474733b846f8440101a0ebe4613708ed2470e93df2288bb3fe45a5eb682b66a3b87dc06d4a1feece4b06a0b44fb4e949d0f78f87f79ee46428f23a2a5713ce6fc6e0beb3dda78c2ac1ea55" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "storage_keys": [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x169228ca33ea854d54aa1e506e59ec687f618a41074f5f5de937a0e9c6343e5a", - "0x6f9cb8e37a2476be4d2303222000061c25157672c2487eaae4d8e4399bbc15b8", - "0x798780bf00cc81b39c0aae120a71d0848e69206d511bb237a63bfc8243990d32", - "0x9da0b11d802ea7d5f343d316fe8b1f884d871565b3589b4b5d6f6f07d1419c9d" - ] - }, - { - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "balance": "0x1", - "code_hash": "0xb44fb4e949d0f78f87f79ee46428f23a2a5713ce6fc6e0beb3dda78c2ac1ea55", - "nonce": 1, - "storage_hash": "0xebe4613708ed2470e93df2288bb3fe45a5eb682b66a3b87dc06d4a1feece4b06", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a08c2cd51832b2e9d20457d4edaa2c6afe1371e79029715ace81f945f1ae66d495a0d9e2f1eea40221dad472f220f151d028fbb5058c575b150ec0527e19293ef506a03e5d90f78575a83b35f3911cc2dfd4daaa00f7ad01653b24ef84b7afdef906d4a04765e14ebad8f792e965c4cfd41e562189c995b3956c715c716ad301eb481855a05605376913ac2e29b26fe6c8a2156f583e9f11d7b99a83ca8b6a65ee2d7090d9a05ff0a75948c9b2b2e8d2a574f30c48193d06a1cb05db7fa7b3aa7178ed0382d6a0c262472241b1714b6dc754db85acac9baaf1c0f10c90aa68e18b4c7697a55e8ca0605c3d3bf5dc157daac4113213b255b021b2f1ebbf6e47173b7c0050c6c84fd0a07465c169006c4bd52af11975ff2117edb7621f088803237fd09b3cef446d7901a0d551428fa5c903ce518cbe78aa01476e68846c4507e88adbefc94d8ef9ef9966a0f4bb397c558fc522decb5fc5459310dfa92df3302e20f4775ec14a50aa0d4eaea0d8f10c4d16056c21f67188c6417f2b2d05e8fb22e519a13a97dd0683ba6a7de2a0aa054e44e49ba3c562117bb890b51b2be370f45979be1b5ace2f9b8ab3ea83a2a09131bc9c247f4327d138dcbe095c11e0b298c154f79938262e1198de06649df9a06797e447e810baa3673cd4894c04fdcf9bf925a09c5e1b0524d06cf912664598a0a21ef4110f094136b70de5003ea1afcf53484e6508f2fd90ba3161b2e67d229d80", - "0xf90211a0cc6be5aa022d0b3a80084940374eceeedad213c43cee81ef96491ea7152776d4a05f56c72f9b64362b4e9afbd6384c48380ab03e4bdf36d04c42a65308e249e613a0741f2a866c5083ffaaeba848183ce3a61ad86b2d269de734ae63c3b421432d61a0f06ee45a0f0be845c2ff2f278f961ddbc6155a58b29eded19d838aa70fa6abdda0daa76a6b44346487ef258200733c29ced9799b2b6a8ee47ba24825d4b6d79933a06e88ed05cb277304474e1bfba719f54403693cd04765f26a85ea254ec37adfe7a0d17e4e83932facbcd3bb2795d7c449c16ce61811369428223cf40ed059e9f6c0a024415606d36276da89833a1261760258e2df74660f2e431e355a79f3d9a26b6ea0bf4301031cca5bba39ae341b8721f200d39c6189dca22d664d32433dee69c79da0e4158de5943e4172083bfbc1ae7c0beed3c701db4ea21d906f11d6f30d041e55a09517ffeb0f416408e944b42cc00a7ad4bad2c8b79ea6efb8cf9b8bba3481f66da031a23470f63b79693a4199d432a6b649f7529943cfe0c4a04e50d4c225fd595ca0c4ce4ba5cc7205e919a1631b04727c5eddec768dcc455ff22f87d927609671d9a0461ede2aa4a4d087e13ffebeac33198a0ecb248e457b90039aafb22e38382485a0b3aa56319e23a1b36efd54a97c9879c7ebd092220d5c577a380ececc8ab550e2a01a5f120c09f9421578a00211a883caf03663ac3cfef429bd3301c851cabc84e480", - "0xf90211a0650c02d5e96a5be5bb4ca707d1a66f38654b6e727b3bf01aa4c68dc625414810a0d6e59e966f041f598dc7c4caaefbae828832577745676bd77c422d9cb230461ea0967cdc5781ff8355b63c84023eedc8264ea4796226f4b082a57a6db0b4ef824aa06f82e77302d8c66de396363bb3232ca655c5d71218ee22846f534eab28cc0a6ba07895700533d8a6a2c4136571fbed3233a8c9cd879e2c1df5f629e82c2c7e677da0cd4c2fcbd169da57273caf7be36b4ceebd14d19b7689531c57432a120631198fa0d9dc41447130535abc51cbcfac1b404e23507031ab37815c1334e8d30a69a0c6a0f932cc3471a46ff013088d1c5d5bc2294abe5be2c4ebe33a0794b294d1bf0b97a06807b893d0248793beced597cbac62a45a23bda69486879ed7831c42a7832716a0002dc6c71a918b7769482862a1b8dbbc9c2a3282db4de6c5defbb773360f8ee6a0b87311001a672884da42b8376d1af9f5a37c68a26c042f61d5949aa5f37a9a0fa02f9cc977f4dbda5da169bc9e027ea204f879dfe67b2bd10f293fe56516d47ec3a0fc7d232434031d1175819747b1bfd2b3ef5d908e09acda2c96f56dc950ba2f89a00bc66c05d2a19b22a74fb5a6c9fc3f31dff0158494da662f2d37632e3538ca7aa0abe343ae434790ddcf74e7ef3162a45d6858e491534fc7a76642ffe1d94c1790a0d589e7cd5def99817537f762c62f403f10a806a1102b93badf21a63cf164836f80", - "0xf90211a0a619077206004fc7de385b8172d96d7b3e27be8b1cac21942e46a4b41b0caa7ea0065d6b31e3e625ce3a383d77cf1a850e3fcb968bf60d876730bf837bb295c13ea0c06cb528cf500c6cfe405dc66b8b1553a43bd134de724e4c5e63b298610eabb0a0b31071e69e1d0e730170fac1c398e1c62234d8017c561a885ee102eeba7f674da0ea3f4b9480e2fa2bf8055b65a7ca36ba9113127312a6416bc1f188fec3405c56a035d56a7452951cbe0ceea12456421e3881b60a19101f8da6d08d38b944b3302da0e2120d6ee061bb1a5771c4b29809d8655e58020315793d2d334b5770e2cde9faa03a2f10f147a93395653e3f85530bdef2fbd50c0c8efb519a58c3f181e6f0b8cda00f2913560ce87703e4c48e999c8e76cadf0d1a375bee0189997643aa3b220ccaa0efc2b97d37a2c0cf6bff3e54ba88689fece309550d51f4d3625958bfd4ba428ba0f445a2356cec59e3aec5e15ebbe81b9acfaf2ebae5b8d62b07adee2ff49da0c8a0ddcc906df986f1a6f90aa3ad90fe4118ec0de92a2eda6e77abce280001ca3121a07e4b900e4cad7df4bdacebd67dd6b69b682d756f4f1291f47ded26b4ed5fd558a059e5bc2a3cd3df37a620261d4b95168f06cfeba06dc76437f7f04fcb30b48d94a085be2db4127fe3c8b5b1bfc9d1a24cbfa827b97afd702133debf0e6458baae52a07f4dd5b8ca6c5066bf7d51f78d59b5faf05382a0f45df983469995ecd28d3a8080", - "0xf90211a0e31b4c19fcc4fcb854b8e624b318ad21b022c57c58e30f80f27bcd9fe4e61649a0950522557eb40bafbd082f0f5cc4be3bcdcb7f80c14eee43afd2bcd01f8d5137a006344fc5ae8c6063578d0b997b0caebc50abb303fc195a9875c55a5d3e7566b4a0b685573fdad10d19fe4144655b27c065930447e0f573c7729f1f9f8a2b5516b7a0db22dc742b84718315cf3623f575787ce354a3b536f2916445b8c98841d28799a00975b2742460058745a4ee9f17d4c2cd50047b9831702204293a4648ea4e21d3a0bd1993cfbea039adca3be57058070fc3db8ecd77eeff5591466fcd17eb023ebba060b8953f8ef7514acd9d70452830ef4c54261369b411285f372f1aed66126adaa0a7bbe5c7d23562fa1577db79cf77c262d65862d50241de2b147a9b5b318aacb4a07bff4eedea913e11c281bf9631984344780fcc3dbcda40cab7c25dadbf13c2aba00b3757b624f3e65e3cadbd9b61e092af2f6086fe846ac6ed51a2f0261d21b475a0b7d528fc41c8fdc8ea18c6e7d0099270c777ec1403cf879d1f5134bdc12a6c6ca00ef9fc129b0c672d92ffe23f9ccd800f73526a6131906377f258c54b1a705117a0251c695862941c0ccb2313831b0f637e2b60301268ebbfb483afc5c821221e62a00935150c3df87a08dd451d2d98c8741416a09ecbf3a76c4baa9b8101edd150baa08bd2b242e992653fa60521d04209d0f948548de03ed9d063f6c847212da606f480", - "0xf90191a00a7a0118e00981ab321049c9d340cd52c3a4781037540f7c48d0fdc27e899b3280a08537f2e248702a6ae2a57e9110a5740f5772c876389739ac90debd6a0692713ea00b3a26a05b5494fb3ff6f0b3897688a5581066b20b07ebab9252d169d928717fa0a9a54d84976d134d6dba06a65064c7f3a964a75947d452db6f6bb4b6c47b43aaa01e2a1ed3d1572b872bbf09ee44d2ed737da31f01de3c0f4b4e1f046740066461a064231d115790a3129ba68c7e94cb10bfb2b1fc3872f7738439b92510b06551bea07da2bce701255847cf5169ba5a7578a9700133f7ce13fa26a1d4097c20d1e0fda0a5aa8d46ddda1c7764406a3a78efd76f028e4e3d855406aa4c512af7becb97d5a0c8d71dd13d2806e2865a5c2cfa447f626471bf0b66182a8fd07230434e1cad2680a0e9864fdfaf3693b2602f56cd938ccd494b8634b1f91800ef02203a3609ca4c21a0c69d174ad6b6e58b0bd05914352839ec60915cd066dd2bee2a48016139687f21a0513dd5514fd6bad56871711441d38de2821cc6913cb192416b0385f025650731808080", - "0xf8669d3802a763f7db875346d03fbf86f137de55814b191c069e721f47474733b846f8440101a0ebe4613708ed2470e93df2288bb3fe45a5eb682b66a3b87dc06d4a1feece4b06a0b44fb4e949d0f78f87f79ee46428f23a2a5713ce6fc6e0beb3dda78c2ac1ea55" - ], - "storage_proof": [ - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000003", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a04f165e587aa9b54cd696111a4786bee0dde82431160e1bb738ebdd74397c8e71a026e5eb419cea15bfb33263d96706f5e9f26ef053f9253d59544d47e542f551f3a089f5c1d2c387598c1cc89a7c3caae3a192c710f25fa842a6bce36f72bd1ef7c5a081fb3e2d75b48bd15bfab48044b98e1e6841654432e0302ea9e6b091687ab57fa02fd1be21653f8626f8bee49e92ab9fd32453647b5b5aabcdbd1b73ea223fc646a0d9ad6ab709325ea8c3099d2d9521c3ca6e01252f21d1e88c49c37532cf16bb5da01cfd545cc8e52761d4687a140e6ba9e19ee6e71109f2ad95d7b7de8553eae135a043e0c8f71756fb0a13ae5d9d8e3a85f9ff16f991c9d765203dee8256818883eca0373ffb5c34af25ccdd6d83006741c370fca58e147ef914ef622a5181528d50a9a0dc0a89b9c12a6b0ab64ddb74395f0c522f9e509d1dc8f3954a3aaff6fcce0c03a021e277e6395b4eda2fc2d1f37e2ac87e2b580f41c8a57f25af390e5e63f4a51fa07cc010d648c2c8ca9f830002a7f6df80197bea95c74313b70f2e87447869e4efa084cb7748d18cf2f2a93e2af64f239052110c61b8c45d0911af1f119c0f811412a0248652c70c8a5ba11570818174f626a5cab9c229f073a03f4f1bcd9621ff5e7da0289a8b352cb2661624456552741f3a210489fb9ba67bcecae7188a878d199b20a0b95c0062cd74663c88ce1ddb4d27c0785afed0012bfc2fd206cb9961dce7a93f80", - "0xf90211a0541a0cc8cdda3d7d2e39269d830aa56c3535b67d6354bb3ea9661a906de55804a0cb3e6a68d63a839a30d22c370c357799d1e6a6fe6b36ec176ad7c3d74a96c6c6a0bb3d5d0731fc34e6087b1380373a8f079b62a0614625b7a2d24fd2730e36f7d1a0b708b666aae69ea3ccc06c05d7fbb7b62835cce852b57bba480ec2a8689eb87da03811b56cf34db8b1beb2521d66e6a04f67654647050175ffbcccdca430784dd3a08a669f990a349c9b004a381cbf6480064d24cf1dbca5923063aed628df88e053a084ab88347eca36616901aec5137080c586eb7500939ad4a1b96c54487ef240a2a082a6db4094b01a27744a3a31a83794ed20276b3d1c6c7124005a8e1c841ef41ca0338f12ddaa20c8b53209b08441d7285f8afcef49d2dc6a55bd16f1b90fbd303ba0c4dc7a846a839aaf9ec556cad158e31d405634aa3bbed5688c16388f4b3e62b1a0fc532c823eab217e219868ac94255f9b6a601a622abda14c9421c454c64d3195a030e95f38ff2467b8fd7cc250956f9188e857261833cf49e964b36c4e9f44b094a023ea1d6473bbb9ccd989610a8dcaf3295d7b1918896369291648a6374fc96a9fa03369ae7908d19ad6f777eb34cc72fcd42379916f136b303a7645ceb4af941ad8a03abaca37da15d922e997dfb5827a76facb99e141e57ed903d9e7d26a2f29f37ca0c763e2c52ea90823b9cd0b0517a16fb2552732fbebf46f7e8ed165f66bf587e780", - "0xf90211a0c3864daa99976787d6cd8d379bcaa7e833662177426fc070d59a06f6477002a2a00ca2d685cf0015215edbd951fdc1f4da289cee350c6940a9e05aa5fc88995e6da0f0ffdf35b44371c52f464ee615a68e4951a0dcea1c46de267a2991acbdc4e24ba09d09b350ff9420552e8f4b2fa9a22fb935222d55bd62bfc2fe1b5e74db1e0c9fa0783cf4ab617a17705dad68160902681fb2744087fab50e6577e20ce62e4eb207a01af54adbbe18849d17f56378f0252825fd6f204b63eb6498d1288167e060cd84a095ec60c07947c4bf844226308d4128f665c41f54cbdf76125ed25220754ca2a1a07c621202102ec3aa010c20c57853e5866955964a9a414e6ec64eb3c3eb2a350da0153cd04906652685d3729049c6d460ed94f4f033e1d5e635eafbf752bc6d73e7a05c62fd03b9a4a51d3dd89c824f0fabd66e06241375e1015330f67b8eaa1334c0a0efca5ead721ab465a7bf8608eff81adc33e902472a5d90e469bcd06a0088258ea017e18ec29d17377a5ebf75b82d94ae2cfbb6670a030f20ec6d2398690c4e45aca06b8e9f2705b7e51eb1373391eb8c0182fa81607901b7ffe69a553dc61846a82aa032a6027adb676a5eba262c71b10a38e9268ad50f8e21766a2175f34728cdef67a0a031429a02af1a53a47c89b63c44ad1bd57bbf9793c77a4dce873975dac56726a098dc6aef4bf0524a79289cfa60eabefb5ad0ef0be6aacb7822ce1e58ccb842a780", - "0xf90211a0083d1ee19617ff03aacdbe0986ab8d3092b7ca95e39e6fdbc19b8d5c18bca32aa01c0bb8ff4cc6c41db8148e2e6196b93992e4cc70e02605b407e5a1ebb6bf4827a01647a452a530eb13186e87d9db7b5d66ce97754887459c3231159b16a758b33ea07fdafe5b70d91149f9e6ab6be7036b9ab93611d721bddf8701378481bf5178cca0037c30a0e1bd67ce22e309e44862b573195d7b9e2296c830674a1e5e65bcb79ba00b2cc11b1df87608b528447a9a67f1b1f9229faecc2d0c9fe53f4932909c9f9ba05078850bf27c76dd988d6599b97178fb2c4c6863b859acd4cc176a19a39ab79ba00cb63fcf533299f6d883b851f7e5146395337b8da3d651ae21b41151a0f1615ea058adaf6670d26399638ca46ac5fd671b81915d2d578db745525a52e99b5b9b28a016e3d85ac70a1aff5ac2126a9301eabe848d880697afeb3bf967c97a53156075a0c28cdf228d0b90037d2f2fda3e45f9180bb4e7706192ba92915fca4d55d37865a010a7983a4b9b34faf4ce6b0e1306dd8249e8ea3ac9e9b3468cce1bbd87787222a0c038c6f13d9b4254875531ff6602ee908a9e798759e06e1c852bcd2fb9e0991ca011390c3bca0904dc739babc331a24b22fcc451c585e005351effedafcd2b33dea00017fef73517bc564555de983c6e8f7a8ec1cc4a8a108d0c529ef5c8f4e94dd0a09e73a29ce206abd33300f86f7fcc7610a717706705786e119c44e931bb0849d180", - "0xf8d1808080808080808080a08cee89a828d80f5f6e44f2e95d0f9ad9c532f60f36f0ca47feb5f0581054169aa045a821d6057cb90e9e8ccee4495189556ea9c87fedf03a217fa4a70fe00a5909a0ddc4fb70fa853bc1ea60eea92cce6a9154110ac6827fa48095b3098a43bafe9fa00a6f203d6d738440c6e363aceeb30f5e4b8ba2df4e38712a3117253d602d781aa060f729bfe5134efc193176a01583ff73e9a452498460ad434d144ac7c8e1f25180a09b6eadc044ebe802f52a104423bd34e055744a98cf4b8167bdba905074ab2db280", - "0xe59e2051acb55355675577d22118be87a8f921610866e11e3004c5d0375183678584073712fd" - ], - "value": "0x0" - }, - { - "key": "0x169228ca33ea854d54aa1e506e59ec687f618a41074f5f5de937a0e9c6343e5a", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a03575950bb07226eca4737bbf4f85964307bfa3bb821b78f269b2f32566ed121ba0971c81d098c64d0c203469d74ec11848c6b4a5820f9f7fe960baa8310965e37ba002d7ce2a82de8265b7f215c6da842e6e6b185b969014cb44e5307f1fccfd91f4a0940970c6cd799f6bb9de0785f9f92443e6a009b60f7ed821e0e9b67e69dc49aca08aaade375a3e315f151b4acf4e0be908bc375a563c568185e1ed7e1f8e0f601aa05880b616976f68407d15870fe76490573462f8bd7fd771ecd53130fd4bf37cc3a0d0734f559eb1d5100eb33ff6bcd3e222df79a9c41b371042265997636422c7c8a0284345a0752dc7d82b7d50ce49350a012cfc4dbf3a41cef5261e20afa960150ba0436bb4fc3de2365cc3a2c7756f0bc9cd7346d582c3bc7638bc89346194e37cf9a008e61d9e0434d51e77bac473b09cd1a98c6d86212af9d8cfa0bf1a4e3c2de9cea0b07540f6ea2d1862fc65246b34d7d36d4f33bf32b2d6b1b13070d4c9116aaa6fa06ba860c44e5103f054d4ddf8dab56a5981d82dff2b50f7b541ed2067aa57e5baa0c8ddddaa6b1d40dafd1ad0a6cd7f054df0e5945cc3302e19a645b169794783cea0f441b8c9b5179156d9409527109ed5dd9246f63970ef681c2c5b38a8db24f25ea0af6b579cb1c5906dae2f1c5d49dc2a6470edd435cc041cf6f5ba9cf9c2abba28a07e8fac417b80b5e1f971d3e95e7ede37b75aa0467376b6f4a712527bab68695b80", - "0xf90211a085bc02f9a6eeb01434527f3fdbe67d6c2737614daf36ce9aba66dba6fda724f7a0eeb66652cf41a3f3f38e52923ca688d79cfce164d561d04db8bf81af2dc7f9f3a08a7c744f795bd1a73e2f3c988b60b34a3fbf504c3cc81a8049c17f29ab03b2fca05f0583a66022666be2a368c2ebae33f6e4138b4f93e204929e8faea2d5ff3268a0b9356bae52eb847949ab50ba30d95444678225064f07063a40f84e26d3f6c270a08b91631dcf5bef76de3578474aa62cc7b3f1fe07c5dc25ef3516fb3e5783d49da0bfac9a8875830f7db2868060f92ee229abbd9586770262009a3033337fb1dcf5a03015abcea1bc6c659d7859f9c9bb0ce01dd4ca3ad6d9399ffc1aa396653e92a4a0de2c539a223ce502b33a2479103b3ff0312435ba38b73b380becf26aa78fb559a02c703cd982994fa40f16071fecc43d7d2736d04e31c5ec17f9fdcb6afa680f97a012733d901b3e6936cef8b9b48aa91ce13458940044a1156539fde67687822e92a0453ad4aef42bfc296f2da533139eb8ad247525a8d68dfd7794c5e5093ded6f70a036d40373e9a3b29071d453f2e9e6e96484007124551d21e804515c92366e92c2a0c3d33e7a2ea7333f5ab39dcd0a3075be44ada041fd6e173117b82cd1c19646b8a099b8e2b9fc65dfb66243305b536e96622d004e190916439cb07dc11b27e83af8a0dd2ace57f2ce0844b433c38a21c4297e84ce200f47de6f369db42b96543debaa80", - "0xf90211a0a7ea298c7ebbbd7ef2ca8a619e1e5633322dc7f3769e232f75dabb5a83cbfedfa0e5df075662e7d27b35fd040f34917ac3db56050379f51b8d0b6ff704e076f76ba0e3d5a63401fabda22dd502be6640bcff57a79d313cd3b6ede32d026b91c6b8c4a04fdb231c280d737ee6b351b3f7a48808aa41632d16c321509af64904e7ce6d04a027b6fd972eed1f5ac309b44e908cd12f15d80380523a653fc716835fb578d584a07a98b8397b69ac6b43ef29c93a26062c1a8111416b51f67489c90ea1af30be23a0e21a43ea919bcb5bbfd173c70568b46031982a06bf1f37d251172bc435c2a907a0d19ec08fe7accac737dc1eca42ce5841144327b973cf111ee92c9288c681a43da0e4bffd7294b680f1906775b39ea7ffb55eac22a8193c76cdf26809c69717099fa0acda2acdd349c1aaf8da7b1e3181affc70955d0877848367a5efc2954138d489a0dab08d49359179a4e82852872654ae5d036068a134be255ba0a72e3d19a036f0a0e15b5f52a322ef4de054f60db8b5ec4052323eee5fede5fa94cd6ace45af1549a08fd2dd88d114b81dc3fd4f2f3307f5725ac986448b7838a1b285b1afab3f36c0a0c10a04bee62c3dd7f0863644231705860d5f1fa4410b434c788ccbadad2818b1a0f73112e14b543498e7f509c8702ba970db83be58c4e5e2ef227e16d15c9c6ca5a05c6741b4ba28c9c35af1c928cc88c4f482f069534aee97bc261828d6e40f2e2680", - "0xf90211a04bce21d5d78914d20ba6f8bf933be1c31fee8a81191da49d88cbb755da4bde01a07d0087ff72781b8f12e4541bf6977d167cb850d3f3e1829884ecc0933dd277a1a01e0eec03216b16f604829fe2e98eaa08cc878c1590c5b1dfb9d8e0afa8f5ee1fa0d3662ef55e778d9f7dc46b45fc3f7c04e827e4631cf81e3b45ec8a123ad9bf2ca0677780ff2febdd248a6d5be5cb279bde4a1f2c4a9ae5f2cb926f67adb29af8ffa07b390439121c862085cf9d24cf175b64c8935c0de5ea5ea112b448dfc82f11bea0f13d2e972199d0cae57249f5cfdcf50cec76afa8f36770f57c62066d9dd04a8fa07aa12ab191022639c1f6aef2c895d46335988049b67c87a214589ce89afdf03fa07c1c4b7d56726e9fb05586e02c17b08d9de3cde6d14aada8232b5888ba913389a027c4f125478c5f1844ccb8898def3e5f595c678c6df8fef953e10e0b51f3c87ea0d93b086dff331bec9a2c3978918414c0887420d21c9d70673de729da740f2f13a04812364ac33ca192eefe5db6c21868bc8d1bdd6e88128dd8e40912354b8b6f73a0c11d06625792bdebaba279ab3d58235c67cd6d686b7fabef0f159493c5ad075aa0f5acbdfc1c920a3a9bb1e6b8d2ad84ae71c9a20c88bca56c771682590886ef87a0da05cb7c194aa4afa65ffa4ced070824963e0eecf677c86de5218cd40b8945b9a071ffb310b2bcfe23881d5a7a811a85d85b231507417a1f0aa01ca92ddc80211880", - "0xf8d180a0fcfd0569996d7e0ab6b8ca52a96a17068b441d047ac5c0883dad64f993b9ee2d808080a00e2df09def0f4b18a6079b1ab829cd31820ea70eb57147c025919c5f8c8d69ba8080a0865384d3a05376737a18b060698923a6b49bd0b48115bb1faf9924739154ad48a0eef644abafeefdeb06db0cbeb0ecc0210009e4e0d0aa5df30e4c4a213fd69bb4a097a5ab7b0e9cefc2ce783d906f16104223882e36c3c11c962601f8629b61f1e78080a0b6253cdc0717785505ff2f8c8d5a50da4665f4910c8e5f1349a0eb03d4190011808080", - "0xf85180808080a0fd2bc13819a05708ed91470c0eeb9874c9ee37cb1fe679e111821196eefe251580808080808080a0d476665a513260363ec9673c30fa9c6794fe977917c62c8c24e5acde93b20b8180808080", - "0xe69d3f3f58da6d9729f3f10bed5a63f8a5ae24bf7de61bdf99251b52d87591878610bce9b5d9c2" - ], - "value": "0x10bce9b5d9c2" - }, - { - "key": "0x000000000000000000000000000000000000000000000000000000000000000a", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a04f165e587aa9b54cd696111a4786bee0dde82431160e1bb738ebdd74397c8e71a026e5eb419cea15bfb33263d96706f5e9f26ef053f9253d59544d47e542f551f3a089f5c1d2c387598c1cc89a7c3caae3a192c710f25fa842a6bce36f72bd1ef7c5a081fb3e2d75b48bd15bfab48044b98e1e6841654432e0302ea9e6b091687ab57fa02fd1be21653f8626f8bee49e92ab9fd32453647b5b5aabcdbd1b73ea223fc646a0d9ad6ab709325ea8c3099d2d9521c3ca6e01252f21d1e88c49c37532cf16bb5da01cfd545cc8e52761d4687a140e6ba9e19ee6e71109f2ad95d7b7de8553eae135a043e0c8f71756fb0a13ae5d9d8e3a85f9ff16f991c9d765203dee8256818883eca0373ffb5c34af25ccdd6d83006741c370fca58e147ef914ef622a5181528d50a9a0dc0a89b9c12a6b0ab64ddb74395f0c522f9e509d1dc8f3954a3aaff6fcce0c03a021e277e6395b4eda2fc2d1f37e2ac87e2b580f41c8a57f25af390e5e63f4a51fa07cc010d648c2c8ca9f830002a7f6df80197bea95c74313b70f2e87447869e4efa084cb7748d18cf2f2a93e2af64f239052110c61b8c45d0911af1f119c0f811412a0248652c70c8a5ba11570818174f626a5cab9c229f073a03f4f1bcd9621ff5e7da0289a8b352cb2661624456552741f3a210489fb9ba67bcecae7188a878d199b20a0b95c0062cd74663c88ce1ddb4d27c0785afed0012bfc2fd206cb9961dce7a93f80", - "0xf90211a04e076e80867c88da12f85f4eb0ab7a374f3392ef4e9f5ef23c097ae8d268124ea0f7be93a47c6f77e141c3e023fd3b82d164bbf396e51df871cfb77a475584f0b3a0d81d379f5935447118ca78ff438b63c085756d68d3aff8f000e07a7cef63c20da06469591cf1e0908963a6b3041c788fe931398c6a1f04847ac96feb244027d7b1a0a2c2c8afa75776d4a79abaa58f87d389999454c46b61094d727608c931ab105da0ce5b8d049294659ddda01a4b32c4c6b681ea9c3dbf02775de68c1c32e136f39ca07161f3e40c6e0b9c3f92b0f38e94c8daaa67dbd0e5ab4a83014c1868564bcc37a0a7835a4831591e5687927d0ef47896144758fb7520cf8a1aca8e44715cba110ba020e376ca7031b2eb2ffdf02dc368dd9a1717e4226afeedda11f44a31ec927e08a0c1d166998591c65083bfd07a0710c4306dabb98dcbbba4a6079e39b7dc8cefb9a03196dfc9116d8fa52c2f7f9ce8189b9bbffb54a384d90537861add83a7aeef22a09c95f040cde30c079b28b14bb38e1bc67e6fabfb3edcefc542a12238f1223de4a0ee7916526f2e827d0c75c7be56424d8a7b0ad1bcc8cf3b93ed4caf190acabfd6a047000a4e021318ce18a634e8081036035bc2fd80f36a132806f6f3a99dd14054a0f5caaa4db700f53b8c14d7066fe091f1caa95ea72b6ef01a2e5f2cf2681314c1a0f3e8a296fa024d50988ee0882ee2f613731ac270108e3bf41ea1849129d6dda180", - "0xf90211a06c45dff71eee987dd843e9d120d73e12b9490e95f30ae032b9b5a4adf6378550a09619518f261a1e59bdd5a98bc10080cef12cb71829f1ea080f71698db46c0c52a01ee6da182dfa921922dd239fc6c8bb68a87382c955c45beb97315b540518fd35a010b41eede6114c15656c12651f7cc04558bf8b6115c9760dc581475ecbb239b4a06126ca3fa4b0e19ade26ace0a40733ddb2c7d9ee9114e819ebcee59e2bcf5401a0214b6597b53f9b868047eb7de637a6028c134668ad1ff0920a57c17f0c1efb3fa02b44c07256fefd7d951066b07910c887555f9b73717b268b931b0301d834219ea0c09e4d0a8762eca3fbc5f2ae32e66ca8be13673f96ba9dfdc8b904a806b667a7a0359b3b770f9538bc6d5070e57f7725475f714fbcc32c410b87a3888a9e73ee32a0728daee3ecbcd487bff6d4536a429dc2fa77463c81083d8ec5ed75816916b7eea071fb6dc83cc666bb7515d2ff26aa40a4073959b639d1f996fe6971bfae8e732da0f636a821ebc82b9d9486b637712330dcb56427d6113bbd1af650dc65d92ba62ea0f0ea41e687238b1cc11ae7ad5caf5deda7c5e72c9e909488db3c433a1c8c1a5da06a8436c6af74c53c68a36fc5fb426439d883bf993bdc445c59970ab56aefbad3a05027c6cb83af3bbbec853a856532ec10de049cc862b519fbaae52bc3bd001456a02084af6309d498a95779d9814e5a7a97bc5e2c14a339434690601d67bf7f00d480", - "0xf90211a09b6f413723da36aeb58a3adebcdab36239722eb05dd95b53635428b3525db581a04810c4775f6084b51ba4bafae6536acf7bb5ad52d897ec32c445b2943123175ea08499f591ea9512e2c3ee46459737519112931aa5cc33b5f7b827193ab0dbaba1a05906804f1174a550fdf96ddec62da0425175330b7ccb71796fb8e7d5b1b97f2aa0e7fa6d7a789a52df0d5f26e44cc25da0cb9db088e3e4ec3d3715edf46e0bded5a060f21e6ee5b20b8294b6b7ddf0acbd81d941496fbd434cfb638db305d7c1676aa0d05f9c974dd539c415049faf0522c6d65a3d165027adca211ddfef7187465cfba0fc11d7dc266be65e000c958a23a984a996e67cbbf1fce1f236eff001864f265fa082c9315abf475f80313319402a3eeffbe9e09d70a7847a4e9aa99b3f45a41ffea0c41907dcb78db53f2e9f7d8a77447922273a55586c4620717004e8fbb6334bf6a0b805fdf7a64e54babd019ddab4311e4ceaf97866657ab1cad28916f5f7957407a0b044a81a494abdf6839b9b62725742541667b0b29d36a32d34b9f465578dee54a0d4572dbddc2e7b057c6ddd311a35153815cd9dccd5137f97eb577c20a773c414a0972a85f080061831f3c5d1672c3262b26a84c2ca9c28c6104a7c2073ce055f05a05050a6b126d677215b719eb5576bb0f372a07138b03a30c96eaa5835cf4dc3a9a010b2f3bd30fb2ff3f5a937fbffa474bcbaf73bf1e91b12bb3d44cda3c1a459d480", - "0xf90151a03283e59372cf8ba97d07e74694ca34792553fbe66edb2977b0178f82eed5d08fa031d5c4844fba2038746021c42a037fdc66aaca5127ae5b751176c2e0ab6e4774a02f6255430890d5c26b7fae36e97d5604ca4275f8286068f86dd36f73da8c2bb1a0d3d89073d0998707abe6a5fb9c588d2b5f2c7daf4e06f5c4035947dc948ab242808080a08d66e7ecb126f5a94a76224c8bf8c95e923b9b04447ea6bac6231eaaf016247780a08a1be972896cd2069bccdd7c43e8beeb4e53bf0d46a4f5e9570188237f34b7f7a01dc8b12dca2bf5991fb5c32228944884d05898d46fc1a8bca4afda2da07a31eba0040bfcfb1efca195677f9c895ebc128c7fc2da9dc9d7ba0f39910766fe08a730a08eba7db6df439f693d48604c1e4e9e8dffceb2d3f9fb9b024d64ed16d4c856a8a0cc8af5746c0a29c3209229ea8946d2005b64b9bf0c5f44e3675c0c475a0f16a6808080", - "0xe49e2063df22a0e142a321099692a25f57671635492324bb2fdb852cbb7224528483559704" - ], - "value": "0x0" - }, - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000000", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a0310e1b1583619869ff83c1a48b48be4550b55bf29abfa3f1aec93e11771bbcc6a0cd9d16489c2b52c0a61f169fad7e3aeffb30f41405dfe82782c4ca8e4d6f736ba092ccd9a48f6a3323503a8b4a1d1b552750d6dedb950b6fa6787d197506f9cab3a0afe755ec780c317e3737a0c0a5f7d169b6d87baf4cb0e8ae3385efed5fa6d9a3a065c60da6614dbcaa503459ab9f79fdf52a6cfa6d36bee996bee3b7d184014e7ca0cc624970c154af39ded5d3de5c816558517a02d596cbe6a4307752bd88d308c2a02fe66e51bf2b3c9deed4b6b1cb56a9b3e3c5be9eee967802073e18fbc59cc6bfa0bf3e33fd03d5b6df0683b58444e6d9148143a579f82e343f0e1d15d18cdc0702a0af0a02156f86180e689e9798596b90caba023a68c8c14c22c77126b8989aacd8a04a534a3e040f37629210c3c4c0328f3f0136eccfd0652ca37fc559faacf68e95a0fd836ff9b7581c44f4c31197f04024f9dce0ad33d6ac0aa0ab3fb45e4126d846a066079379ebdfcaf414b4931969ab4151fee61f37ce06b13c09a90744fcd1b294a04f84340c81c2d01d00c37fb9eb02a1777c5ac38c7eb4f172cfa1fdf204880fd6a0a0fd2cea43f89c2cc7a714e033bef3760ee9759fa22d668e4ff62be408df8347a0fc4ede02a21d0084bab0ca826ecb64bcf295b9968ce875011679da87180a2e1ba0d57445170f5a2dcff602b62d6438362c5d26072c64008d09a08acbc5e3f064b680", - "0xf90211a028f91a696afe311f0316a4753e715016ce183c5f63effa95001f6d6341e149d3a042784a3aa21f2549de3819358c49553e0743472d18369d9aad180f50696b5878a0c59a25c5849add231b0b19d85bbcbbcd6097070e19891340061e1c9de4dba75aa05df58102245af71ef8ac5e47ff824a6c3df819c079a3e0d99bded5e24f1be6eaa06f20b2c7ff93e8e7acb4db0c6be0cb437377a9f71095a0585cfec88f71a4e769a03036fb95861076e07511a3f33173cb2cd2454baef999bcb388fae2e7155a50aea0d9a92ac925dc160ef0a62383046607b9eccd5a705bfbbee3bd7376a68b5b6ce1a05cebfd6af9e8a5cde3eaf60f3c3efaefb902545bdb3dc5ae5a159eb8f937a6f8a05597d5c61310120196909af778f63ca1da7a2dc37294f3048ade3f20328a2541a00422b6a089e53fe172f9b6392f1b1d4cea07813bd9a6e69a6d5e24728d67a6b8a013132a9d7e53b0fbaab20991dd4381f6cfef2bc145a2a5cf18a12921b36985c6a05ade0bfa491f749a541dbc8fd9f574b6366e4cce8354c41c0457093a1e9eb7eca09ef2bb3ba49b4e622552241713c2e3af1538e22f0114b40ce0b631bc4f21299aa033aec112d752745ea38b2caa3b90f0c2e6f993d5d676316bb632b6a73e1e79f5a0043981873554f6d0bde8090733a202f81d8052025a0af426530f2f8785e88362a07e7a973874ae3264be7c8033088a172e8c26493a9f5fa068d1a273e2a076473780", - "0xf90211a00e5a63ce3268845d9b2c08d609dba1dd769f1a5f36f2ce7f5e0152b01fddcbf2a053880caa533539dea062e2adca6cd3f8cec5495a2a9b6a16e45daf6409cf4d23a05e1eecf465d7103720bb4034cbdd6a4427512edf19325229872f3f2adc08cee4a042123762aee69f56997e70668440abb3b6a4002116478c91e0435a8f3100bc7ca043922f163d319564b2c17c9bdcff71c39d7786791e290e0e7b7b60f530497263a071ee06388e174db88f36d75e35e2628c69aee61f0c0926ae3230cd3d4d79e673a004e250f33155559c29e2b77bb3a123649b49012582a822c524a328fc708fc8d7a0743646785656cb69aa2afdd71a845f2371c1c0ec472cd05d0052fb043b5837cba05a0373d2697a554bcbd344bfc712b4c07a60e8fa63ce6b6e33e535561b3005d5a0053ed994af313288cc7764845425ce62c365b6361eb2863a0b1feff0ba21c04fa09a964ffddbe9d8271345b540299cdd2b6c7a3f3eb9f4063363d52704a099339fa06ad06a598bb74377c63fe3485a0888e28c05b09a0bc1eb8030edc9393747a266a000968aac8b84c80596c717ba399f40049b56e89a1916523bfab4b5c3edb883e0a0d0c59c61fd2f8d6c85aaa07d0048cb186100e62c1dc5e209ab7b1bafdc21820ea053df006537d257cd99e8a1db9f885e18734b6228f429b9ad765c35482f196b94a0bf4bd512faf5d8f2d7b7128e7490b8705477a9701a4ba5de3687cec7d48ad66e80", - "0xf90211a0d03c05d72a1c3d5433636f13233f3b224d45ea81d45d42a44ead1a6c4a8239b2a0b1c1b304838d9d643f2c415e10d8da7cb63b03d5d9560fc55a895d212ca40b6da0a3312ae24368ad32ba0fd0d0b914ac629249a550c49a139155b0f088dd4f2e8ea0984b146abcf5a51354940f293e4f4bbd80bb92c5bec5def402a29a61f3aab64ca08bd15b433970a82c8eb0187cc823f954f7bbbe7b2dc0ebb449326fc0de1a330aa0f95b3dd51d3aa68760ef9d6633380deec058c5b0c2c2792528bf73fa165b2d78a0cb764458d937662dd6f069e5b4fcf108e7a6ba97f4ae71e632a1eca69846aa06a08b1c20a1d78357d6ea01a961e4bb50f20c2fda4d6ff6a0986dec42b425240e2aa00e288a99692ed418776f98672783f8f3d7de0c54a8767cdeb51d432dede5c65ba0cd15dfc4cfdc3ba07065266ede5054fa4882daa87ef17efc655dff2ffc32f6a5a052a88c40a5f016da16d0a0a270a94bf2972766a0751b996e64b895a0ea3d14f7a0a059bd971573515cda3990ceb521e19955f3c02e5d0e9379454f8bd483d0c99fa0b08c024a582f3a2ec5cb79ecdece83d2cd46f6fc66415bb394f47b4870dce0bca0869fdaa7de613efa9d969488ce36fdfe6edfea8cc1f0b5ff1ab3cb0746c1d093a0f3b9df00a2a3b219f02a61ca57f34b6bc23df1219da8800d30d26a51b50170a4a03b87967e51dc7e5834d589ba305b67ef1d785997669163153c42dada4e5187aa80", - "0xf90111a022b9d68ec893e46a41c316bde1406b19b1b15e51f5c35f3dfbbaeff3e302661e80a00ad2d2e385dff997534ad374657268101fda36e31285552d4ac0f06209ff6df6808080a0723c2be5593e7d8f85c4aeab316dcfaee9254a66a1c6c25d9ffc61e454f6906da0294bde53062110328103e301062faad0e1175bc1e3649eadc5b281a298f4df1680a06634703c405b8015855bb7bea0084457878c1b806f1db3997ed8889a82f85c948080a032f769f61f78abf648e9985feb6e0712a65ed03fdd534069a16594c895712f11a0de64a3a75f4323d8f7c9db0c643ef1c2bf521e28ad8540271be9d4e7b9da198a80a06f23ca1f167b52e366a7cb9628d5d7d5ca2af5377e951e6907721d6a2227210380", - "0xf8718080a03269a56e4a8c5a0db5480a777c04f55435708b2aa668221eca0a51597f917eed8080808080808080a0188adbc95db819328813c282bfe9d78819dff2c5c83041ba936431635424da8a80a0f4873cb7178849abe99b3515f3195aebc99d9534da6ec2e0810451fa4b9991d8808080", - "0xf49d39548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5639594c6cde7c39eb2f0f0095f41570af89efc2c1ea828" - ], - "value": "0xc6cde7c39eb2f0f0095f41570af89efc2c1ea828" - }, - { - "key": "0x798780bf00cc81b39c0aae120a71d0848e69206d511bb237a63bfc8243990d32", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a0e75dc11fbb3b37eb9727aca766818f797c67c2166c0cac233551464079fbbb39a027eedc5bfcdac9537898e5de4ebf940365145ab18a885b2c4054111aadae13a2a0446b0fa75ded7c699cba6860f2f691ddd6d382d6d8b9c6b20c5806651a977892a0199a5a2fd7c384934b9d720a7d5c87962369c8fdbeb60c30567b47a4bbfa0545a00957ef7a48c2d4d807ae6f1d5770be48c30d927511a7b58436762906df36884fa0a642558faa851498850a5047c4be7a0ba9b937621ffa9d7241889bc2de152837a0d7723cbdac288728c459702f559fd2ad23f30734f7ca76c951ff4ba0d9f279b4a0a123881762c604e4162d0bc6ed3a7880aaff18c0a7f0a780e1ff93e645a04a6da0d54743e83fb41ef60adeb49c85e7157a0e2bddaaed3cfe0c139f57f0022794f1a0cec781914b72cd9ad15664a7e297e5f8dd5c752065eb1b6a30a388618ee1df56a0e107e8db1b304cdadecdc6e83b551309a42a180cb9d8057769d450031246188da095e350d294e70afad50a19acfa051bc320fb51a1ae72694152a144016abef4a5a058e48813e545afc1c91f65e0112cca561515dc16927232c8f19d73f1b4420d1aa04e3c0e0c36c32194fbad61941c89213bc9653040ad73f4a94947e39deca03dc1a04e03bf045f85a0af21918291c3749047a63b039f4ea63202674122535f3960a7a0096df2b2dc9ac0405949f2c2fe9d6e7709dc82b5d95bc778afb808bec9f0dbf880", - "0xf90211a0a9ef60588aaee31162f3801ce8065fa85fc62ed28cbd3d695997006404519694a0b73faa83d34b09a5a67a85a6e1eb7ae0e4fd26eb9b0dab7cd606fc22bc2612d1a01ae2e4800bd6897f1f074b8a8a1d225a21b2f844ee1e2852bcdf62fa3df952eaa04f1cfcd99e115cff13b4f504e1b9726e1c11956a67400eab18a598250ae6221ba0795f1c759719f84bb606f21ed1ca9bfcafd3ed2a5a7c6c41b0aee0f632ca6fb2a0de87ba46a3114f70ea7fd97947aeee9da991f6559fcefa4228ae813ba52f6f98a0b5fe74ea62b3e051a56e12ca88213e71e726a201c314ccce1ada4f646187bce5a00eec90ae50ed07ca187b11bd552308052c91292dceafc2cd788e8cccb027efe8a0622df5dfe08ff27bf3653d6e34d0fa3841c31a5479d5d8542e44d82203c78c3ba047bf9d5f656780c716e4ffec7f156fca2d55dfb947d586d652de08bc7953b3b1a0d9df0d59227bdafd5f517f1ea97e2146d99e7b9e3a7aea4d786e44cefd15797da0f506d5394e08932796332513555169699853c9099f3ebac0aa0c6e4d716c88bfa0b0d176549ec8ef8e83b4d158a2d7c6a4dc55a8809871baa08cb13a6f142daf13a093078a6e4cb967fe8d026cba7c9fbeeca67b155bc5498d4eb6b9a4dafce57909a080ede9308716d9e1e512c93c8c532306bc4f699c4da0ae25bfba16788587ec54a007f6f049f7fb1a0623082f840eeaa3164b8d6cdf63b34deacdb909d210157b3680", - "0xf90211a06596ee45cc85a60a7a53473559375be95e3b9f1a16d83a8fa059bebfbe2d1bd1a0f682a9299cbc40ea4d20e366a5312bbe6dc79adb2cd34e2621a46386cf2141fca03d3f3a28cfc22c3328ba5c67120b3c33e917825b48b1baa8d14e6f05a25a4118a0bb47d511a816b3c09d5113b7bb8b73eb923e99860d790451f729f052b6b39b62a0cf7d40ede7d3105080ce5afc411ade13d326d0592b85a7f71a78463c424f6686a01ba27f8fb5502e122a377ea924bcd048b7323d01056b9d306f85a48de89e4519a089d897bef61e60a4c5c6fc0afaa59200b1ec6723bcfc2ccb8e1ce65849d2a01ba006487dbd05acc2956278ec2fdfb35ad8dfd2bf0c8b213172cbb6fc7801746195a0bf71fc2d79cd5d04b663a9ac843537e2e14310ae0e5f6e42a50dc6606b0c1db0a0e8f6ca2855f4818a85544ad950b84390bf6ae5500fbedf560ad0cad18cb87fc2a03f6207cd96def8f7ca7e6b2616b7e5c957f6799dacbcee5d2a588f4227afc800a05c86e481298045b05338811145ee7c61bc06bc3242b9dca30cb513bce2b1d1e6a021ecfed6a8d4018ba47dcdc46d6faed65f6022783c4411b64c3d8e3a34baf08aa06f8b620b7f76702c2289de9c67dd9c4e7b59c302d444eff1b02f5d9cab8e181fa05f52817c3f3d25f095451363256ba7ec54dabdf5ab76f26744b2b8eb86cb6046a07da1a65ff97b02525bfd99091b9960273ad97a385f02e655680a0dae56e219f780", - "0xf90211a0eb8ba08d67691356296aa335a90d54e9c9e217a24fd8714ad8eaccef2bb6e37ba0130d4db1b58d8d4c0203a63d06415d80f26ef137b2f710fe3ff9c983f49f75b7a0840cffe52f7ab11a6c390f72c8f10f59c3a632ec4ab710d30b4e90448ac4e119a03aac48ed84077740d30e475998039f524abe65fcbf436fd33b5d4f91008244b1a0a1e3b68c0a6fc8ba8055d0808fb4e7e45971ffb3bf1faab1539b0e333028c3caa040f85525c7370f4b7b956d5386b51d39e6a873631f4db267b4783fff45869bc3a013acf1cf0cf9faa2e206c1e6226974c9ca66b021d8249d868ea03535b979a903a0d8ff696d167e30b11d8de1863b930aece845b8c0099c7700e4e022048003d6a7a0be19debc0f2f62326723a0c7216880ba561a44898df9af71ea2f6e9688246387a0dc52f74cf65b286c5b050f0f745ad295fd1da755042fbcccc701c218b5f35bdba0e920f060e1cf02dcccf541b7be4172f41bde5ce87410faa6075928786b18174da030b02af4d1d96b286a47752fde0c8e85bffe41b06058d783df1b5c209cf533c9a00002859dd28525a23b10127819f16c36e5eb6d6f9dc25da49b1314423c1167e7a02cbcc20e7676ba34e34fa83e657c866fbe1b3ac2420935d588713d5f0f41cb97a0d73e59f7eb50dce09b49cb33ca8c000ebf088eaffedc397c34726a9b2fe938e8a02a0c0006d013f5753c896c58e9562495a0ce0f0b14c2939bce41500adc59e2d480", - "0xf8d18080a07308fe08e524d045d04d714c38ee9db68fa63370b227df62118e94bb2df0ffb880a0b172c5cb04e01df7016161a2e0800a8fd274e281db4a6735ea763cf1b67a6fa9a03b89f463dc5d1a4628ed04c73b571d2a5f6cfb20b071ee897efdf83cb50c38c28080808080a0d954c3101eb7f6d6ec22d578b6f51da6ac317d096f1c3ca76179805576bb6b35a0856ba870a54547a1f933199022bbc5ee3ffdaf0daa7107af74f91e450a0ec82680a0cd026f908fe838bb4c5d474fa8d6ad42a37c16cc8796528e236fa5225e16e2688080" - ], - "value": "0x0" - }, - { - "key": "0x9da0b11d802ea7d5f343d316fe8b1f884d871565b3589b4b5d6f6f07d1419c9d", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a064490ab944b1690da71c52093a252bb342da829e63ea19051add19850f4d62b8a0381bd80d9cd404503460d0ab3e1e017fddc353c47caf0a6dbfbdc45c91a145efa014016f67c009c885650f4878942fee34f339128de77ace70820f9401097d428aa0a2f5018512433efcf8698dd20ed2e294803c653affc1c1bc7d5a59f09a5d115ca0c3db92f660784a8c1ad328a759180ea704c1563c37d26cdac606ce90b75d23faa0a5c32174eb3af60dbd019b6301520b279904aba7858ad0f9b27f27a1892f6273a07da2bdc668d0c46c79683baa3e09ebe4d3c97aa54a299f92281b873ab8b4d2cba0c343c11ce0d7354dcf234c6c62fdabec80c22da04d90d64b7b6b4f4fb5ec759da0a21ab9b49e98eef55a20b6969983761d7336301d4ba4b7f57dd49897501e2815a086a829b2c17692e4f03fade63c2f1c097526633235623a041f1600bc79dafdb5a01e3b7bf22ed96fa511eccfd24175831a1d66cdb7b8fb8ad288a32bbcdce15203a0b086da94c55e94de234eb204b388092c85ddd52bf36670cec71407c9a6ada77ea03ac3c357627a959de7ce718a7edbc353642d2686d15c7d65f1ef044a0478ee2fa0aadc724eec6fcdf34a5d79d48ea85336c4141b971e96b97867cd9de945dee42ba06694cd529f741d576c2cb194f1a6743d71e0d00c6d60b2f357a59f6bf411be65a032178dad8cf66075588484b8863d7ca73ca96c02d2763c1fd9d4a86a593b4cba80", - "0xf90211a07574dd78f05ea5122cede435ef289e41ac6d5ca17330d08bf7f5f1aecc3488dfa0f7e142c117f5c47fddefe9a332b5557a6de592fd6d5c5b02f05b6c5da53e456fa05597bac108e0262871ade9f34e076fbc0fc8be77b64782a62324dec50253dc0fa05d724c2d3e80bad656b2c38ffa9d9f3ea9793e5243be75f508531774560d6539a0112e8fb01e72989236908b0da946fee80aa3424ad15eceebd7e91adc877275fca0ce606fc0fa9b7e6c6f521b862200646706e1db89e2742747e4bd7fcdb48dacd1a0fcbd2713520d2f3ddbf6bdeac00f1ed3a9555c36b270dc55a91e594dc8493237a0ea53bc78b16e75da2c0c325e1d01679da7b1b813365bca1fad888000c7e5f349a06e96eaf55f2415df77cf20fbd69075000417011eab077d56caf8c70bdb0996a8a067f1107501e1a4391d52ea973375ec9968bcfcb7711a8d6371df8895255d8cd1a0624cda18fb94192df367405d94fd46d14fa673ed13b527b94683b883d8651f55a0bae4aab8a4d6476d1000ca21a595c3d03bc136d57998481c63f1c787081d62f2a08482e48273b6d942d5a03c73b6e213f3f514cc53e712dd8102940f90f2bea35fa03ace74e41d9ffecbb9e780e26fadd03f0b4d35a3fa1236308850c82d13832b09a040cb4fc00688095f4f901be53ae2261110c11cdbc417afa852e8e2dd55089ad1a0eddd7b487760d808a7a0e45ba3aa55ed426e4d222ed87addc0c9a03df566ab9880", - "0xf90211a09d07380d522c1625815936704dc2316b7d7d4692d0d7c8addaeae1a5e605a55da01848887c8d944b299336f38008fb204e2b9395aacb6684881ca5afccb49b2134a02d621120629c1c48e3e0ec7a7e641a18e479b70f4c76870f2e9fbd914fbbfdf3a026321e24ad44df0daf0c57d53d97dfc396a54ae1a0d1ef307adb0568f9faf729a06685468de63f2ff4048496318af40598922941ba496cd9d08c19a785fa885dfaa0259bd60c1268d1fbe5018c276b68335ae33b3a34685090c4d99bc3f57c7d58cba0b06180815e5240a0dad613c8617bc8874260e17f45512c4de403616e6cf04faca01028a81f6b9766ecd8cb27c3296bd5cb94f84910914530846d1c623660fea742a0a5c8715e75d0108c92bbb31a83ec3cfb4c96b2935fcbe1b8d4ddd66c49c14e14a006cc6a1a336f950a77696bf0d980e5618cb4232240602e3852880d5e2230eb38a04e0efedc181c6965ef486954053f02ee93ddcb95db74c291fbdf996bfcd9822aa081346f91598a1d030bb239d1c25e726f988fdc109f7565191f3e0d940a6f108fa05b0a1fb99c58962a97eb7060c20433069737420d080b4daccab80b1f5e7a2a63a095334eadbfbb00bb194dd64040ca16ba8668a1f20a4c1a879e55934931d48329a067568c7b4f0e684c7c55ee3348169a94bc5e5d754d4bac2e2392c30314a38b2ba0f443c9e5e77097e2278103b300e3497a3ca9e592aaeaa2194728f421e2c0c08a80", - "0xf90211a03959f43391365132bb7bc7d3c1232235f4d6106bb6982cb2f6c8c169a6bd33c6a0f3a0d5abba7bba8c42cf097ae7f0d389f05776536d80562383369f07a9696eaca02a2bb2e0e7ad119ea1ab1fed2a2f278c8b558fa2f4efa18524c72857ef7fa7f6a07224bd3230bc9b709bd437275ab2de24e91c5791f2b024287396dbcdd084325ca0ccfa3aede7e87755694628eb7e05d89385114bee43a6ed00ec99543bab2a8f4ba02774b3746d735cebdb42dad896f4dcdf1ec7a2902881a5d1378b62382da210a6a0600d48a70df616ae19b40b3e75b32d543c3c94d6769e55efc5f7050f32a4b3cfa09a8fd7ea6226cc98efe0cb292773913ce0b18240d8dc9e98a4b126f1e339bb8ca0f79c9502201b518f4813ffe857e83126853ed5a3ec3fe0a1922d824e9cfd6b38a09844d0b48eaf5d50293018f5b636b69998b1d4bd553ae09af79eca2232f7fe18a02d451c8feee0ab0e3c09531d7f66da5d519e81a99bb3206c1ec30c55f1e277c0a0c50ce15a442d4a11af7bef576e9db8f105b7faee0b6e28692193bdd11a8642e0a0dd59170a62673857b2a8af2465556aad8275c899e64c87bfdc64945398ae7fe0a073a7c9bfe65a430eca7f0085133d87465304aa2c8f00ae06d56a25f682a15e44a05261563c99b23a6d2fcd5659a301c9de3bbc77ae6ccef8fd88657c9cc7fe88e2a094bd4f5599d6cc5571de433a1024781788143db584bf810e8ea6efa9146a49d080", - "0xf901718080a0fafefb9080a4cfed00a600731c5b209b74c1a02952acedb277e85814992b0c3fa0195bd8dc642cbed50e86fb09160911c51a6da599376568a3cd6eec947518a048a0494677d031321824fa859156d35c5351eef991e1cb4d754a1c1027351a6a0883a0eb2a9ee1da914515ce461271a025e61334c5d429c01948f89c26e7145f3f58b5a00923f52553bf1eb96915e229f3e09ac27eecb99b901501fd0554910a8f0d5b06a011ca14966f555ec1df9bd1437f5ff404db1a5e4af789a668fd7b89bf2728012280a066e008a965ec6ca8d2e58d157a2bd4e82357df11ed57779db1112a17754afa19a015f41c727e28a5d34967d67d90ed5fef4421d056839ffd430601e3fefeabc97880a09aed077af3b68dfe5032c70028ef42069b4ee71d7e682d0903b78386257b7193a0d14433f3d0040e6a26a24ae9067ad8d854d33f251a1583892597c54c9ac31bb4a0ac6e73b878bfa798e00a393d9592b132932c65d21fbf41e35a9b41443a4f84218080", - "0xf851808080808080808080a02ef3212f2fbeabdb9bc4b61e860743687132cfbe449a57e30b9cee14beb38fdd8080808080a04e0096d37f18b5fa73f404154f969c2b28a6314d677c1aa4d0c2c5d92f02771b80", - "0xe99d3efff510d7a6be6305ed6db4f0aaff9abbd7e549efb87ede8442250e158a89056bc6b88d147733de" - ], - "value": "0x56bc6b88d147733de" - }, - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000004", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a0dea591b2ff8d6638c81d82819164dbe683c3de6287e2e58c683802544efde26ba0ce8ba63266cfad375bf63ed79352550752d8041f49ec7bed5996c378fa01302da09ec5f1431a6a29256097fb09d09ad61925e7031dec401ed94f241f69147611a0a0ef6429cbaf69d47d52043166cc8716c54d3f6e8eede54dfa3010eca04264cb74a0172ca12a89e04bf9180e5ccd1444eb132003ae3de20813fb965c8cb8b50c9e43a0494b81bfd0733555bcc748300b649324949ef5a98450eaa501e96d5818e16a06a038e8a9d7adccfc196ce61af40ec3a5ffbf6b61f7b581aa0ea35d9d1b0c6ddc6da04594b660fda7f9e4a7ab13cab436e160c3652ea63c045df6ea58a24341695b0ea0c8a5950856aed36626f0bd6c48cba67ac2fdf533d971db95be8045a1c780c5cfa0af65227ff80915bea9d709c4a37dc3766c88954e4b28447799157d98f4060976a055ec0994d25870be8a3a0beace6b480879e16487c54aceae1fdadd3398528a0ea05d34171cbbc3a995d65105647dd5174ed003edf1cf702e56f34722eed54117f8a0b70d0cfc082c782158f24fd1a9dbd6ea730553da3fb59de3f9bbf11a39614cf6a0f42275ebcaecea4e45fc57bc2b05e64d587afdc74f8c3d2e8d149cafe85cdcfaa0bf8bab34f60efb0f344cea4509a5a5b51627e11a10b3a8b413bf9aab94cba79aa063255f805a9c3dedc79b95e6ab9f6948b3c1776240ab06af711b582a9145741e80", - "0xf90211a059246777d01e175031f746f32a78baa54bff2b8f3861e475f036be8fd436dd4aa02f89ebdeffcd4ff84a021fcf6f23c88cb91e84a983a954c623947630e0debe7da0732c46d251f27174a2c61bc417a150b80514e354bf31f0f465a376102160c578a08aa25b04eb7524d03b37dff3ee548c842acd9ef3d9cb450b70925ac31e2b3565a070dde9218a6cbe8cef6f22e3bf696a2cac6964e801b8fcdf40749c45760391a2a0482f769d9a1f2c05494f7db28e1ba18b32daa2843f1c615ae2d5c4d62b011da0a07cc0edbef667d2e65c2a13e30ed131ce98e69e1a503d5554642cbcdf66e23ff3a034118e6e84cf53e3c7f7bf19513daea196224dfabc6e5ec3e183d4ff49e32b53a0e9fb3edd037e52db89a349b49d8b5dbfc8cd72792bb4028325272fcbe0ee87bba0ea9e54909cb008890665f2b7cf09fa941d870aa8499d2dcda809c0d31ceed1b7a03800e75e50b658f8da2f11e99372713c04681c2b62bdb816b6107eee07878092a09c06fd12167a05f1e11eeff8803e65261a737d6d020e0e541f0bb7e4192fead6a09d0bfd604dc57ba7a399beddb137003beb801011f9962042cff3d7296db48155a06b6981d1cd2fc36f384d9c431727c282f9257a3b44af3ce0ea80fe80d70b362ea0d5e851d592d0d61033d01df6fb94e21bf3e7f897c00f0f348a73d2e9ac1c5f07a0464a7c46b53ab1c84a7fc52ee0a8b89174499739073cb8a5ae953b10043356aa80", - "0xf90211a0f427c187187f97e46cb225bcdaaa4abd3c15491679c1d82d4f3e66ffefc63a16a0c825a693ef2424ac1d987ee5f5fc3aa5d03439e770fce8d9c01ef36c40becdeca036085d307d6523767a502171e917b6e144d4c98af95fce340c253139c0c72857a08a16a856734cecdc4b331730be8c613dd6ea3e00ced776cbac5f414da9a7a125a0b06f132dc6ba3aa3a61cee8d57969e26d9c49bbe9b7c342e1139d25e4a707f16a0b7d32f4f87988711c920b6363a42a7fdb09a35728f9c1c990e39ca2c3904eaa4a0c93ef71a8e54afc40b22401b00d9766f515cbaabaf8f3e3168d0afa9fdf5a543a041461c381330b0fd359b986015477dcffa7e2a085eca14399ef9846b702570bea09dc7744b9d691ed9395602a330f8b9f959de0b1f01e54bb13de998bd97d97069a0678dea4cfe0732a6362f9f12d0b3dc3a62dc15189d87f1160f7843cd1782102aa0b760de48afefde0c87ac515322d0c1e441a96c56605f55565be3130bb0e9560ba06d09110cf2b7e2c8e97f2b300ee34e836eade4a6e257dd00aa8bd73a70caf647a04e912b1e8a7c670a1b87a6fa4ca3562031ae77f14a04224abb4d242d5e0a82f3a04de168d0f46f928b789d65fe791c3e033f700264933d2a813400a4564f0eb2d8a05d05f80f4805de5e27fadd84babf2a85f7c164e5ffbbd4f553d0c9381ec3118fa08889fcf3ac394cec72f2ac7ba13c190d5ece49a799b9481208fae26d0032c01c80", - "0xf90211a05b632e3a566a6bb19d3dd4091b4763db5fc78682f29f2f11da889ee4ca1e9be6a03a708a602625a611589b1a936c4b801c099013b5d88ac06371ca16e8ce7f4588a0570243399cc607fb2784f45b94471809d002f27d6fa1d4638eb8ebb33db4a337a051ad5f06a756df5c13a369c1daaa785a54b4e7027361b1947187e7c4ff339cc0a0ecb9732e2ec86f643c110c8c40420495d5e61df5ebf7c8e552a5ae53916477a9a0bc59c56b7aef25d95441310f72d0661a418671d817527c0b66f5cc2bb7e9a564a0d938c757979a41e4c971fd7c021119fb51aac875a07ee809ad6f0c03e79666e1a0966ca97c7a052b5a7281448523d895bb66f94ed8791c7e159adfef510fe67723a0c38b142de1a60f3df26e0fdcccb4459962369e2366a312aa0168d523545a6125a075393a744477193e7be9d802ada0866010bc2ee3e593c311ba80badda757281fa05ef94bf41345ad2ee91aaafe0fe888ede969f5d73f927dcb5bc726ac78d4e395a0248cac967a837aade7280dfec989e91b8b4549068ed79587347c26736842245ba04d6935540c7e92fa3c389ef53b5b4cd0227d3016a2032673fe6f324deab32f9ca0c16ac2aa52b6ec9002907eb6abacd6044435be59d6ad1f09ecf17f1a7b40f15ca0b2778bf84d98a102753eee37a209b33e4adb2512f43413072df49ef7094d0af0a02078d91a0afb5418649cb9d16448a57f4d3dbbf1c25caa18760ff2721d82dffc80", - "0xf8f180a02659ad6b6d2c8a8d025a659aa3b444748f0ec8a7073da289bc604cfa71dd0e8f8080a01aa9a26489beb79da8d4acddb84d34c71a1ca0a97140a64102beb973506d1591a0fa60bc86d247f44a26985b46980ea63e5723d0b85a5401640ef668ae5090fff68080a0bbf4d56b7150983e40bf77ad6483d1747b64179bf48c9b88b477ee0d7bddfaed808080a01a6f152cb96304e04a80c228786fcb6306c133a5815af5593b47789e619dc705a024fece1b4d947a09849dde3afdda676ef54e3c6fdda21fa363678ab9c3ae019ca0db7faf143ed701aea3ef5839b1699df55ef6685fc01abdbe4815ea75624d3c798080", - "0xe49e208b53cf7a408a0451c5313a3b6e5bf6b2c65702e164f153275be5ec7ec58483061a80" - ], - "value": "0x0" - }, - { - "key": "0x6f9cb8e37a2476be4d2303222000061c25157672c2487eaae4d8e4399bbc15b8", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a0d6a01d1abdf22c9fd4add8ab5e758d5e19924ac90743611aafb28eaafb90a630a09953b4da80be049ba0af365bd31ebe58411c55d72a749bcd24e1987ac3647fdca092b0e7f059a4d68253a9d0f1faab525e855677a95f7c9d0ac0395831755af6f0a062e031af1e94e545c4f4c341039186244b40f2f89cdbb19518f57c93c29a2a8fa008c809083572f45e26d71b54e779bc7d4b4e9a1ad94786b33ff24a188232902ea0bedcd35db054adef1acf6c5bee00fd45d757c80ab3d4dc672aef14e1fa172eafa0f29248906b60af8f3b8c150ba6c6e381b3429fcb74ea7fb72b73b4d5bffdc837a064b35f3030d210f97983ff5d0c88d6f978db69ca42a2209e5467d45ad491223fa0f626d2dbc4b29aa3e9eb84a4fe7f6ade124689094494eecd867b027f7397fad1a0d2e90903af8bd80e98ad3e8bbaa693e0f1d8450205b33d53ddd80c321411c83da0d6a95bad7a2923cb0750e7dac12121e6ccba95347aff5c4f677544af0b19c1c5a008ccdc182085a911c13e4c6cef207b4aeb1a32bc840338e31b29ff3391d9a726a04918f1b073f6fa9913e79ce394c2966b5902dfee14df394e7a71d0eaafb72298a0458df12b431fec94a3c5c751597ac83723a9697c559e19d98e3782b8e16d8de1a023dea6a9ff1f7f209a67155ff8a1997b513eaa2154a0bc947f87e012544fc5e2a09e94adb26cd068823d8f20695cab6f42b4719ba5b855a198956a16916193fba480", - "0xf90211a0c73f60414c6eb6bda3b3cd200d38374de544560de1d108b1662e1a1051655879a084c1dead9f06687a0f794d1cabed598421f4685fae4748dde952ec8a48cf37fca0ba964cfa048c7adc8d0950ef1a8814673a715991754b0b5c749945535c6fce5da09f5a9c8151a2c8e4078795e7a753002fcc283a47f1a1863fa2670623511f0203a07586cc0fecf188842129ccd6a29e772398c60b19471c09be6ce6a4fa7569a5f4a0cbf97c777d1b67a16387a5bfd0c4c94a8101c38a82d72dd627536a74161c1c4ea0f83f6cfa57a2f63a0e5505110d3b39dd388b226c42a6370b6f755452be531d03a00b89ce8db489945e5c857cd85585af4fe4cb2dcbb2911b32648b1fecd63761eea0ea9bcd050c38f78b32969f48ca6c60e0f60f8a826e82f4d9fc631735894d94c6a0bd8a053f889c91218d9db341851dc83d89204b28801dc4dc8cfae2705163659aa0ba5e42ed804c284e960c3eaa35f0171b52e87fd3fc7d00791b15c0be1016e745a0e21a8aa99550acca9e4f52da833388159611cd0411c294f3fb362493e76a68baa0a5f252dbf6c94364b8d583a8fee2d937f2d8d95497c6b522df07fea169d440c9a03640a742e6ce3e47a16d280692d96c304a8873057cc05ca28e28b717d85e53d2a0efc62a478c8c230ab344240c87c2de780d0b592399f898d538751e21475a76afa04dac8b5ecec715e4e56181f344346940463094f8df5555d895a85ab23786c76680", - "0xf90211a002296a660ee110fade619525b32c556864854649cf92c7fc38e529cc82958034a02618509033f02497d2b616a44c9af54fbd0224f9355c71b78d84d878bb8f30efa059d5a5bf04e25b02b40576ea38f179edcb0351e2ce57c6a4c757961c67d8f987a014bd70cddf4606f90dbed2da458d9a6a6b4dd2a0fe8e683935f8c1c046ee4eb5a0b3fd9ac75b384664cdecc39b54e07bd8f1712df5c052d984ff44160fdfb90b27a0eea61c162c0e807db879d7dd138c3a38f7cb96cc83136e55b01e170f7ec528b5a053fc08caaa7adb596bba675523ec7a7f1b41941e3afa90c7b3983261c72427e4a066ff8cf0f911e4bdd27e10463cea71038f2f7e3b8bb2f4b7e4ff3321f42f6deda09bb398242060070fe876b3b5010886e7478cde74c06e069b2cad55d56028e9c8a0a93a9628eb7c28a632f003251ef4bdef6b968d30441dd8bc4e7f72878607fc33a0669d62e808fb3cee43b42414089b15c182c2fb2147313e76d6562cc4735017d8a0a95a1d59c0cada34b35ae28af7763a1cd7334637f47ab5b3c6a4ef92b8238524a09ffdf1b24166547dd7c2a3116137b1c58d52cae91648cf86ec36201053964b0fa002a21bd79ba79bba70e04c77ca2ece06f8338ac2f0a9dbce0381fc387b5c1ae7a0a6fcc7fd20efbb8ac8fe3f435c2eafd9519cd9463640d1aa86e370ba726b1613a06c8a837f0206f34636aebeac2562067f450eb508346a429a1d63d012550d2c1b80", - "0xf90211a00b510aeee08a336ac32be38758713a847f36497fc8e82ad649f54552f5d9f2b0a05dcffb364b4d73d32308e1667a4159d3d2f32e77544880d2ea94651b4ee96ac2a0255c0ab5cb033f5dfdeb7e47f55e6944ff221a964365d8fd3408c30705962c0aa06d6e77763c8aa853ed2c5a808763e8c8f28aa71ffc6f9d48c510584123ce58f9a0b84a46cf166c3cd98d4758f934a3efb312667abc17ab815b773933940dd2ca4da0b8b4f47d43bad9ca0f620b035cd08c2cca9be27ea3471657fcad58b10a43198ca0545418ec203c9b5db68948ba6bbe4e846efa1ff5938f114411f29d7662a488d4a035433137f441a58d9b3efb3111270e52fb1960898ad7f43d2f1e6f288206ea95a0e720032d240b0f5e862d639ace59191d1bb23a1cbe9879a54f52418aaf214fdca031153cc7d095cb9228c9ccd4c15f5dec00a1a3245df563a0c47009d365c888b6a0d3f0bb6b31d306f32bdb03cf228c376ef2694dfcb47255f0efdc6449d0b7f988a00aa1017065f92908b9dab2797a3b96d235c650ec33994fa9915bd945c8339a7da04ed3ea4a9155bd186d00f632e5e28254aa9c47031269e529125ee775e1fdef8ba0dc63f3071fd3d5f3d40804651492f788b873a9a721c2654c5956bd7e6023e806a095f6dd7d94f60b3174f56852408d715ef87a504025fe8ab8b41bd702b522acb3a00e40057b2a0427c49502669659bcd7cc9f33f0fa89a6963264f5d7551e55ab0a80", - "0xf90191a0410857ec96c8c1eb143bbcf0c45b83fe9ccc1ad9d01d010398facbb49a3e3ca0a01d904e6b0e2eac0de35ff48c6a52e9d254e5983a055035b8e4a889b82d79f091a0b39a2006e04c399aa186d8f27ff6e0b3e51bc70c55034128626a85c93e9565b3a0e2dead49c77d2eb84c367f8b9e6dee5433bb6ff474f3e7766698a9f47a3ccc5da09a5535ee92e62514335228bb4a90f69b8e882dd3c7ae677fa3ebdd7245c6b83ea04211006a01da43191c0f2c30d2820b66bd51bb8ec571763fe6c079d3e484d971a0dd358554b87a2c6afa9ad663957a199e21937b06aff53583fa92150f1c7ba96f80a0c2e84e09a0a054c878acc7ad92896110659ede9773f693fd020c76f6aab03a3d80a000b9c72bbdc056974f92977e3d703da72839f6fd81a8735eb1d0e7cd4dd9f519a00b97454e369e3052aae4393da1f904aa17cc09cc3bfb504bcf02ef9f006c6556a0735c87c254dfb5b987653a6105e40f97081f66cbb3ac4b8e3fe36a007fea36fc8080a09acb0566b0eccacab9c25f26f1086dd23af22080034c00fc7b3c1d78cd2cb9e280", - "0xf87180808080a06b2164b8f3f7731ecfd7525725c044ab23c78f809090fdc6b56fb79b9865e2c3808080a011b154c2f18b45e2fb87319949c8662ac54450b81a3be6a12757ede02a82dc52808080a070265d5d32f9ed75bd28df173c161d56a9ebc5a60e48d6b74dd09d7fd11bbb9680808080", - "0xe59d3162cb324e17e05d80ec3e10910f9e75aec2441fdc5cd4482d475a075a868580683379cb" - ], - "value": "0x80683379cb" - } - ] - } - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "storage_keys": [ - "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x0be16d71963429204d70543701f859c43526c316ac005c10114f4694ca405f36" - ] - }, - { - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "balance": "0x1", - "code_hash": "0xb44fb4e949d0f78f87f79ee46428f23a2a5713ce6fc6e0beb3dda78c2ac1ea55", - "nonce": 1, - "storage_hash": "0xebe4613708ed2470e93df2288bb3fe45a5eb682b66a3b87dc06d4a1feece4b06", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a08c2cd51832b2e9d20457d4edaa2c6afe1371e79029715ace81f945f1ae66d495a0d9e2f1eea40221dad472f220f151d028fbb5058c575b150ec0527e19293ef506a03e5d90f78575a83b35f3911cc2dfd4daaa00f7ad01653b24ef84b7afdef906d4a04765e14ebad8f792e965c4cfd41e562189c995b3956c715c716ad301eb481855a05605376913ac2e29b26fe6c8a2156f583e9f11d7b99a83ca8b6a65ee2d7090d9a05ff0a75948c9b2b2e8d2a574f30c48193d06a1cb05db7fa7b3aa7178ed0382d6a0c262472241b1714b6dc754db85acac9baaf1c0f10c90aa68e18b4c7697a55e8ca0605c3d3bf5dc157daac4113213b255b021b2f1ebbf6e47173b7c0050c6c84fd0a07465c169006c4bd52af11975ff2117edb7621f088803237fd09b3cef446d7901a0d551428fa5c903ce518cbe78aa01476e68846c4507e88adbefc94d8ef9ef9966a0f4bb397c558fc522decb5fc5459310dfa92df3302e20f4775ec14a50aa0d4eaea0d8f10c4d16056c21f67188c6417f2b2d05e8fb22e519a13a97dd0683ba6a7de2a0aa054e44e49ba3c562117bb890b51b2be370f45979be1b5ace2f9b8ab3ea83a2a09131bc9c247f4327d138dcbe095c11e0b298c154f79938262e1198de06649df9a06797e447e810baa3673cd4894c04fdcf9bf925a09c5e1b0524d06cf912664598a0a21ef4110f094136b70de5003ea1afcf53484e6508f2fd90ba3161b2e67d229d80", - "0xf90211a0cc6be5aa022d0b3a80084940374eceeedad213c43cee81ef96491ea7152776d4a05f56c72f9b64362b4e9afbd6384c48380ab03e4bdf36d04c42a65308e249e613a0741f2a866c5083ffaaeba848183ce3a61ad86b2d269de734ae63c3b421432d61a0f06ee45a0f0be845c2ff2f278f961ddbc6155a58b29eded19d838aa70fa6abdda0daa76a6b44346487ef258200733c29ced9799b2b6a8ee47ba24825d4b6d79933a06e88ed05cb277304474e1bfba719f54403693cd04765f26a85ea254ec37adfe7a0d17e4e83932facbcd3bb2795d7c449c16ce61811369428223cf40ed059e9f6c0a024415606d36276da89833a1261760258e2df74660f2e431e355a79f3d9a26b6ea0bf4301031cca5bba39ae341b8721f200d39c6189dca22d664d32433dee69c79da0e4158de5943e4172083bfbc1ae7c0beed3c701db4ea21d906f11d6f30d041e55a09517ffeb0f416408e944b42cc00a7ad4bad2c8b79ea6efb8cf9b8bba3481f66da031a23470f63b79693a4199d432a6b649f7529943cfe0c4a04e50d4c225fd595ca0c4ce4ba5cc7205e919a1631b04727c5eddec768dcc455ff22f87d927609671d9a0461ede2aa4a4d087e13ffebeac33198a0ecb248e457b90039aafb22e38382485a0b3aa56319e23a1b36efd54a97c9879c7ebd092220d5c577a380ececc8ab550e2a01a5f120c09f9421578a00211a883caf03663ac3cfef429bd3301c851cabc84e480", - "0xf90211a0650c02d5e96a5be5bb4ca707d1a66f38654b6e727b3bf01aa4c68dc625414810a0d6e59e966f041f598dc7c4caaefbae828832577745676bd77c422d9cb230461ea0967cdc5781ff8355b63c84023eedc8264ea4796226f4b082a57a6db0b4ef824aa06f82e77302d8c66de396363bb3232ca655c5d71218ee22846f534eab28cc0a6ba07895700533d8a6a2c4136571fbed3233a8c9cd879e2c1df5f629e82c2c7e677da0cd4c2fcbd169da57273caf7be36b4ceebd14d19b7689531c57432a120631198fa0d9dc41447130535abc51cbcfac1b404e23507031ab37815c1334e8d30a69a0c6a0f932cc3471a46ff013088d1c5d5bc2294abe5be2c4ebe33a0794b294d1bf0b97a06807b893d0248793beced597cbac62a45a23bda69486879ed7831c42a7832716a0002dc6c71a918b7769482862a1b8dbbc9c2a3282db4de6c5defbb773360f8ee6a0b87311001a672884da42b8376d1af9f5a37c68a26c042f61d5949aa5f37a9a0fa02f9cc977f4dbda5da169bc9e027ea204f879dfe67b2bd10f293fe56516d47ec3a0fc7d232434031d1175819747b1bfd2b3ef5d908e09acda2c96f56dc950ba2f89a00bc66c05d2a19b22a74fb5a6c9fc3f31dff0158494da662f2d37632e3538ca7aa0abe343ae434790ddcf74e7ef3162a45d6858e491534fc7a76642ffe1d94c1790a0d589e7cd5def99817537f762c62f403f10a806a1102b93badf21a63cf164836f80", - "0xf90211a0a619077206004fc7de385b8172d96d7b3e27be8b1cac21942e46a4b41b0caa7ea0065d6b31e3e625ce3a383d77cf1a850e3fcb968bf60d876730bf837bb295c13ea0c06cb528cf500c6cfe405dc66b8b1553a43bd134de724e4c5e63b298610eabb0a0b31071e69e1d0e730170fac1c398e1c62234d8017c561a885ee102eeba7f674da0ea3f4b9480e2fa2bf8055b65a7ca36ba9113127312a6416bc1f188fec3405c56a035d56a7452951cbe0ceea12456421e3881b60a19101f8da6d08d38b944b3302da0e2120d6ee061bb1a5771c4b29809d8655e58020315793d2d334b5770e2cde9faa03a2f10f147a93395653e3f85530bdef2fbd50c0c8efb519a58c3f181e6f0b8cda00f2913560ce87703e4c48e999c8e76cadf0d1a375bee0189997643aa3b220ccaa0efc2b97d37a2c0cf6bff3e54ba88689fece309550d51f4d3625958bfd4ba428ba0f445a2356cec59e3aec5e15ebbe81b9acfaf2ebae5b8d62b07adee2ff49da0c8a0ddcc906df986f1a6f90aa3ad90fe4118ec0de92a2eda6e77abce280001ca3121a07e4b900e4cad7df4bdacebd67dd6b69b682d756f4f1291f47ded26b4ed5fd558a059e5bc2a3cd3df37a620261d4b95168f06cfeba06dc76437f7f04fcb30b48d94a085be2db4127fe3c8b5b1bfc9d1a24cbfa827b97afd702133debf0e6458baae52a07f4dd5b8ca6c5066bf7d51f78d59b5faf05382a0f45df983469995ecd28d3a8080", - "0xf90211a0e31b4c19fcc4fcb854b8e624b318ad21b022c57c58e30f80f27bcd9fe4e61649a0950522557eb40bafbd082f0f5cc4be3bcdcb7f80c14eee43afd2bcd01f8d5137a006344fc5ae8c6063578d0b997b0caebc50abb303fc195a9875c55a5d3e7566b4a0b685573fdad10d19fe4144655b27c065930447e0f573c7729f1f9f8a2b5516b7a0db22dc742b84718315cf3623f575787ce354a3b536f2916445b8c98841d28799a00975b2742460058745a4ee9f17d4c2cd50047b9831702204293a4648ea4e21d3a0bd1993cfbea039adca3be57058070fc3db8ecd77eeff5591466fcd17eb023ebba060b8953f8ef7514acd9d70452830ef4c54261369b411285f372f1aed66126adaa0a7bbe5c7d23562fa1577db79cf77c262d65862d50241de2b147a9b5b318aacb4a07bff4eedea913e11c281bf9631984344780fcc3dbcda40cab7c25dadbf13c2aba00b3757b624f3e65e3cadbd9b61e092af2f6086fe846ac6ed51a2f0261d21b475a0b7d528fc41c8fdc8ea18c6e7d0099270c777ec1403cf879d1f5134bdc12a6c6ca00ef9fc129b0c672d92ffe23f9ccd800f73526a6131906377f258c54b1a705117a0251c695862941c0ccb2313831b0f637e2b60301268ebbfb483afc5c821221e62a00935150c3df87a08dd451d2d98c8741416a09ecbf3a76c4baa9b8101edd150baa08bd2b242e992653fa60521d04209d0f948548de03ed9d063f6c847212da606f480", - "0xf90191a00a7a0118e00981ab321049c9d340cd52c3a4781037540f7c48d0fdc27e899b3280a08537f2e248702a6ae2a57e9110a5740f5772c876389739ac90debd6a0692713ea00b3a26a05b5494fb3ff6f0b3897688a5581066b20b07ebab9252d169d928717fa0a9a54d84976d134d6dba06a65064c7f3a964a75947d452db6f6bb4b6c47b43aaa01e2a1ed3d1572b872bbf09ee44d2ed737da31f01de3c0f4b4e1f046740066461a064231d115790a3129ba68c7e94cb10bfb2b1fc3872f7738439b92510b06551bea07da2bce701255847cf5169ba5a7578a9700133f7ce13fa26a1d4097c20d1e0fda0a5aa8d46ddda1c7764406a3a78efd76f028e4e3d855406aa4c512af7becb97d5a0c8d71dd13d2806e2865a5c2cfa447f626471bf0b66182a8fd07230434e1cad2680a0e9864fdfaf3693b2602f56cd938ccd494b8634b1f91800ef02203a3609ca4c21a0c69d174ad6b6e58b0bd05914352839ec60915cd066dd2bee2a48016139687f21a0513dd5514fd6bad56871711441d38de2821cc6913cb192416b0385f025650731808080", - "0xf8669d3802a763f7db875346d03fbf86f137de55814b191c069e721f47474733b846f8440101a0ebe4613708ed2470e93df2288bb3fe45a5eb682b66a3b87dc06d4a1feece4b06a0b44fb4e949d0f78f87f79ee46428f23a2a5713ce6fc6e0beb3dda78c2ac1ea55" - ], - "storage_proof": [ - { - "key": "0x000000000000000000000000000000000000000000000000000000000000000a", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a04f165e587aa9b54cd696111a4786bee0dde82431160e1bb738ebdd74397c8e71a026e5eb419cea15bfb33263d96706f5e9f26ef053f9253d59544d47e542f551f3a089f5c1d2c387598c1cc89a7c3caae3a192c710f25fa842a6bce36f72bd1ef7c5a081fb3e2d75b48bd15bfab48044b98e1e6841654432e0302ea9e6b091687ab57fa02fd1be21653f8626f8bee49e92ab9fd32453647b5b5aabcdbd1b73ea223fc646a0d9ad6ab709325ea8c3099d2d9521c3ca6e01252f21d1e88c49c37532cf16bb5da01cfd545cc8e52761d4687a140e6ba9e19ee6e71109f2ad95d7b7de8553eae135a043e0c8f71756fb0a13ae5d9d8e3a85f9ff16f991c9d765203dee8256818883eca0373ffb5c34af25ccdd6d83006741c370fca58e147ef914ef622a5181528d50a9a0dc0a89b9c12a6b0ab64ddb74395f0c522f9e509d1dc8f3954a3aaff6fcce0c03a021e277e6395b4eda2fc2d1f37e2ac87e2b580f41c8a57f25af390e5e63f4a51fa07cc010d648c2c8ca9f830002a7f6df80197bea95c74313b70f2e87447869e4efa084cb7748d18cf2f2a93e2af64f239052110c61b8c45d0911af1f119c0f811412a0248652c70c8a5ba11570818174f626a5cab9c229f073a03f4f1bcd9621ff5e7da0289a8b352cb2661624456552741f3a210489fb9ba67bcecae7188a878d199b20a0b95c0062cd74663c88ce1ddb4d27c0785afed0012bfc2fd206cb9961dce7a93f80", - "0xf90211a04e076e80867c88da12f85f4eb0ab7a374f3392ef4e9f5ef23c097ae8d268124ea0f7be93a47c6f77e141c3e023fd3b82d164bbf396e51df871cfb77a475584f0b3a0d81d379f5935447118ca78ff438b63c085756d68d3aff8f000e07a7cef63c20da06469591cf1e0908963a6b3041c788fe931398c6a1f04847ac96feb244027d7b1a0a2c2c8afa75776d4a79abaa58f87d389999454c46b61094d727608c931ab105da0ce5b8d049294659ddda01a4b32c4c6b681ea9c3dbf02775de68c1c32e136f39ca07161f3e40c6e0b9c3f92b0f38e94c8daaa67dbd0e5ab4a83014c1868564bcc37a0a7835a4831591e5687927d0ef47896144758fb7520cf8a1aca8e44715cba110ba020e376ca7031b2eb2ffdf02dc368dd9a1717e4226afeedda11f44a31ec927e08a0c1d166998591c65083bfd07a0710c4306dabb98dcbbba4a6079e39b7dc8cefb9a03196dfc9116d8fa52c2f7f9ce8189b9bbffb54a384d90537861add83a7aeef22a09c95f040cde30c079b28b14bb38e1bc67e6fabfb3edcefc542a12238f1223de4a0ee7916526f2e827d0c75c7be56424d8a7b0ad1bcc8cf3b93ed4caf190acabfd6a047000a4e021318ce18a634e8081036035bc2fd80f36a132806f6f3a99dd14054a0f5caaa4db700f53b8c14d7066fe091f1caa95ea72b6ef01a2e5f2cf2681314c1a0f3e8a296fa024d50988ee0882ee2f613731ac270108e3bf41ea1849129d6dda180", - "0xf90211a06c45dff71eee987dd843e9d120d73e12b9490e95f30ae032b9b5a4adf6378550a09619518f261a1e59bdd5a98bc10080cef12cb71829f1ea080f71698db46c0c52a01ee6da182dfa921922dd239fc6c8bb68a87382c955c45beb97315b540518fd35a010b41eede6114c15656c12651f7cc04558bf8b6115c9760dc581475ecbb239b4a06126ca3fa4b0e19ade26ace0a40733ddb2c7d9ee9114e819ebcee59e2bcf5401a0214b6597b53f9b868047eb7de637a6028c134668ad1ff0920a57c17f0c1efb3fa02b44c07256fefd7d951066b07910c887555f9b73717b268b931b0301d834219ea0c09e4d0a8762eca3fbc5f2ae32e66ca8be13673f96ba9dfdc8b904a806b667a7a0359b3b770f9538bc6d5070e57f7725475f714fbcc32c410b87a3888a9e73ee32a0728daee3ecbcd487bff6d4536a429dc2fa77463c81083d8ec5ed75816916b7eea071fb6dc83cc666bb7515d2ff26aa40a4073959b639d1f996fe6971bfae8e732da0f636a821ebc82b9d9486b637712330dcb56427d6113bbd1af650dc65d92ba62ea0f0ea41e687238b1cc11ae7ad5caf5deda7c5e72c9e909488db3c433a1c8c1a5da06a8436c6af74c53c68a36fc5fb426439d883bf993bdc445c59970ab56aefbad3a05027c6cb83af3bbbec853a856532ec10de049cc862b519fbaae52bc3bd001456a02084af6309d498a95779d9814e5a7a97bc5e2c14a339434690601d67bf7f00d480", - "0xf90211a09b6f413723da36aeb58a3adebcdab36239722eb05dd95b53635428b3525db581a04810c4775f6084b51ba4bafae6536acf7bb5ad52d897ec32c445b2943123175ea08499f591ea9512e2c3ee46459737519112931aa5cc33b5f7b827193ab0dbaba1a05906804f1174a550fdf96ddec62da0425175330b7ccb71796fb8e7d5b1b97f2aa0e7fa6d7a789a52df0d5f26e44cc25da0cb9db088e3e4ec3d3715edf46e0bded5a060f21e6ee5b20b8294b6b7ddf0acbd81d941496fbd434cfb638db305d7c1676aa0d05f9c974dd539c415049faf0522c6d65a3d165027adca211ddfef7187465cfba0fc11d7dc266be65e000c958a23a984a996e67cbbf1fce1f236eff001864f265fa082c9315abf475f80313319402a3eeffbe9e09d70a7847a4e9aa99b3f45a41ffea0c41907dcb78db53f2e9f7d8a77447922273a55586c4620717004e8fbb6334bf6a0b805fdf7a64e54babd019ddab4311e4ceaf97866657ab1cad28916f5f7957407a0b044a81a494abdf6839b9b62725742541667b0b29d36a32d34b9f465578dee54a0d4572dbddc2e7b057c6ddd311a35153815cd9dccd5137f97eb577c20a773c414a0972a85f080061831f3c5d1672c3262b26a84c2ca9c28c6104a7c2073ce055f05a05050a6b126d677215b719eb5576bb0f372a07138b03a30c96eaa5835cf4dc3a9a010b2f3bd30fb2ff3f5a937fbffa474bcbaf73bf1e91b12bb3d44cda3c1a459d480", - "0xf90151a03283e59372cf8ba97d07e74694ca34792553fbe66edb2977b0178f82eed5d08fa031d5c4844fba2038746021c42a037fdc66aaca5127ae5b751176c2e0ab6e4774a02f6255430890d5c26b7fae36e97d5604ca4275f8286068f86dd36f73da8c2bb1a0d3d89073d0998707abe6a5fb9c588d2b5f2c7daf4e06f5c4035947dc948ab242808080a08d66e7ecb126f5a94a76224c8bf8c95e923b9b04447ea6bac6231eaaf016247780a08a1be972896cd2069bccdd7c43e8beeb4e53bf0d46a4f5e9570188237f34b7f7a01dc8b12dca2bf5991fb5c32228944884d05898d46fc1a8bca4afda2da07a31eba0040bfcfb1efca195677f9c895ebc128c7fc2da9dc9d7ba0f39910766fe08a730a08eba7db6df439f693d48604c1e4e9e8dffceb2d3f9fb9b024d64ed16d4c856a8a0cc8af5746c0a29c3209229ea8946d2005b64b9bf0c5f44e3675c0c475a0f16a6808080", - "0xe49e2063df22a0e142a321099692a25f57671635492324bb2fdb852cbb7224528483559704" - ], - "value": "0x0" - }, - { - "key": "0x0be16d71963429204d70543701f859c43526c316ac005c10114f4694ca405f36", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a064490ab944b1690da71c52093a252bb342da829e63ea19051add19850f4d62b8a0381bd80d9cd404503460d0ab3e1e017fddc353c47caf0a6dbfbdc45c91a145efa014016f67c009c885650f4878942fee34f339128de77ace70820f9401097d428aa0a2f5018512433efcf8698dd20ed2e294803c653affc1c1bc7d5a59f09a5d115ca0c3db92f660784a8c1ad328a759180ea704c1563c37d26cdac606ce90b75d23faa0a5c32174eb3af60dbd019b6301520b279904aba7858ad0f9b27f27a1892f6273a07da2bdc668d0c46c79683baa3e09ebe4d3c97aa54a299f92281b873ab8b4d2cba0c343c11ce0d7354dcf234c6c62fdabec80c22da04d90d64b7b6b4f4fb5ec759da0a21ab9b49e98eef55a20b6969983761d7336301d4ba4b7f57dd49897501e2815a086a829b2c17692e4f03fade63c2f1c097526633235623a041f1600bc79dafdb5a01e3b7bf22ed96fa511eccfd24175831a1d66cdb7b8fb8ad288a32bbcdce15203a0b086da94c55e94de234eb204b388092c85ddd52bf36670cec71407c9a6ada77ea03ac3c357627a959de7ce718a7edbc353642d2686d15c7d65f1ef044a0478ee2fa0aadc724eec6fcdf34a5d79d48ea85336c4141b971e96b97867cd9de945dee42ba06694cd529f741d576c2cb194f1a6743d71e0d00c6d60b2f357a59f6bf411be65a032178dad8cf66075588484b8863d7ca73ca96c02d2763c1fd9d4a86a593b4cba80", - "0xf90211a0e734bae6abf4a37cfc5c02e2c03adbc7063f4b64901546d711291c08486067a6a06705281594290ec7f4afb77d66c848c03247cce8df292c2b77a3c0382bdf9d93a03d18b7eed254f30493645e49523f27ff67e02a4d0cdb5c313d1130e4e2695262a0e73534db1fa707517040d730875e8f99a706f2fd08f754d3a31ba45bd48beb3da0dc55552ec2c8dbb787090b40144d4518f943a3dba7f68b071af0360053830da8a0d36eb3e6aa2e4496127f5da996548b84c521cb700d550bcce40d0eab61e96860a03f6d1d1e090888cc0e06c314d062d3d596f6e16f6945e38b73f550d2e5908b82a0dc4882c6e32047838ba6ed38f7b67ed4d72bd3225a0cbba6da6db27b2cc8cd43a0f392f9cbdf95be55906fe2a8fc972a9c0c330e42c2cc2a27986a25077f9a0e4ea038609469e26ada966b1ec4cd4ef5f61547cf49923ea41f82f3935cfa21146fd2a086afc861c09a76960b7dc06b5c032f443ffde13b955248e9008d65bcdc08a880a0339205e21bf0e52102081bd565edd658fc41e2f0c7cae282309354a198c0762fa087dde466098dcb599b9e5d3ca023ca8bf1390ce3a787580f8e034f0803f61de2a0c705ae835337b82a7aebf90152629538cef7eb31d40be2b4650b31d7d34a89efa0c8a3ce54021c8dace0f7b19914b96d2711e75d810c249e1a050326a7b6e88b3ba0969b136554ad451da47ad4e40845fe4ee5f9e8879a81f88c1e81993c865ff4ef80", - "0xf90211a0f3a9ac3149f12572678adfdeef138dd1805be5d3257f62909209072fa6c42abea0d8533785fcfe46e91a1d587a53d8e198b5fd2c977c89f484f317247966728713a0825e958bd436ef06385cf097dda31a3ba87d2de9628c195135b2b06bf8caed96a09e073e1cfeaae376ed41e86b7d54646ddeb84c6b6d54273b88edd6d69075a99ca0923b6cb77e1cc51f3ebce9787dfd9819e3d10f1e8327f4d5b4483264a20b4292a051a6639a40cde9e681fb4a0513ec325911b477aaa2d9207581aed1caaf3f7452a0c45ad3c3e00c06b52feeaa8d8d3e8779d399b8ad9be029e808fb8f49ece46bd1a0560cb020aba467d0da4b70fdf5429c9eedef214f92173f716b7c7f587ed40017a0e97e9a0160e7d68110dc294e289813a7ab9c84c2ac430cecd1a85017403a18e4a0c040d43b3c1db8dc87a61aadff4b2af6bcc769af69a68de249068dbac125d20ba0840f6be7cb9a1bd81fd1c0a54ceda89a1b2aa28d22ee33b7a395530e861662dda024e6b1b63fbb89883f4b33606eace065bac7b5fccf5cc00e2e86e441d58e6889a0894f06a178c8df971f4bd258c503623e64dcc1ecc1041f6ec0a790b9e2f44b6fa0a21a0b1ce15911ebad53aafe985b97eaabb4302ca4b7fc24475729672c8bd39ba0d4293c0807cced83f3f6c24177192c933b539c296e5a6fdb744467423a1c262aa07d98522ccb950688dfc5c05920c10b6f64c0ccd412c762b09640f05c5cf3383e80", - "0xf90211a0cb7b2f99709c331a9836cf0ed7a489ff4cac3364f6bc1333fd93dcc4c882c427a0e79c4c93ae69692662f14883889c6e396a0df26fb33225b0507526393ff51d5ea0e607472605789ceb55f67a57a8ae3cc4507cded5f22359e93f7f34e70f3d84eca03f4b13d049fe272072a08a73409b7dcea8bb14a3f8d9da068ef20438bef29e58a08251cc96c8cff32f8dc4de17d2219bff1481cc4ea114f2f5b5534dc7d4aa6761a03d1783e93cb51562e096dac7c3c0ad1b2d5af8b8de99fe0d5066fea24e9d77d0a0f9f6f7306771823cc0668a90be4b4f9c58731b23f66250c1163095c3dac2048ea0ebcdfaefbe22cfdca6b12258d0f316b638aab358690b46c3b57ab55a4b08fe98a07cd1a6123e613b0ed42ec9d8e24f3f12fc4eba0207bcc670f80706958a0c94dba0a80c49fbaac93a046ffce4b6d85dcd798202f4b446bed9c31b3bf2f59750766da082ff26ac0c13ee58ba9a04840a73d32580f81a15e32aff1f3b85f61622798271a0261c81ab6def7ecb1f2f470f89ea57b5c2ac5637b2f4df0ff5574faf36aeac93a0ab4fe449fc537f77fa8da5d1c1128203a3fd49affb2346f8550fd885abd12adca0de06ad085538d2004912faf268eb05fbac9abb150ed8544864e7b70aab2fa81da02f8e67dc2ab33e86cb2a5a1b3dee16296f06294d3e060d0bbed467feac22d045a0df0c6c454f6098b5bd691a7d967bd1b0e53bae7963fee2a68583cf01d2e11b0880", - "0xf90131a01d4a8ee3af146a91366409c1e2c59b4569ac872f76ad4677c8337a1f3e12201180a065f2bab38d4a0e3118597b6b0067191de9afaa4d2935ec7c1cfcd81db4cc5dc5a09b7d0b7c923dbc4bad13443d3c1c1374b7646c5e9a004a419bc373b8c7c9ad60a019df7efb0770b0b07403c6a0b64364a6bd164c0dea5a12547754589fb764b7e280a0d624be59151c7fec940628a0a819ec7055c4894ea6af0e0b8a0302bfe50a02cca0f4e2577d9f1df04697fee1442b264c26dcd9b9b51f607cce167b0266187b15f38080a0a40c701e3a3c2d88f6c26a39e058e0a37ba67cb6db22f078b1b9abecf0b795e4a08259e9dab6f6b0c72cfb9153e9aed7ecca1e26afc519de71877d7e14aadee7f2808080a0512206a36824e4c0cef92e11a6071846ad68e8b12f042c23f16243e56bf0df9a80", - "0xf851808080808080808080a0315e225878d124ad74a228bdc9f82e0e8b0963a0b8d391eb54b484baad536acf808080a07771ba1e5b4b9fd6a525c493fb96e6fb5894ad847cf39eb60c3b24df5025eefa808080", - "0xe79d362366783a4fc90e52c8cc595ba9fd2b278bc52248117c14c07e5394d888870aa87bee538000" - ], - "value": "0xaa87bee538000" - } - ] - } - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "storage_keys": [ - "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x0be16d71963429204d70543701f859c43526c316ac005c10114f4694ca405f36", - "0x7ea29a65f431835045c27ccf1699b8986f6310efc5565f53bae18a1b1075bb1b" - ] - }, - { - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "balance": "0x1", - "code_hash": "0xb44fb4e949d0f78f87f79ee46428f23a2a5713ce6fc6e0beb3dda78c2ac1ea55", - "nonce": 1, - "storage_hash": "0xebe4613708ed2470e93df2288bb3fe45a5eb682b66a3b87dc06d4a1feece4b06", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a08c2cd51832b2e9d20457d4edaa2c6afe1371e79029715ace81f945f1ae66d495a0d9e2f1eea40221dad472f220f151d028fbb5058c575b150ec0527e19293ef506a03e5d90f78575a83b35f3911cc2dfd4daaa00f7ad01653b24ef84b7afdef906d4a04765e14ebad8f792e965c4cfd41e562189c995b3956c715c716ad301eb481855a05605376913ac2e29b26fe6c8a2156f583e9f11d7b99a83ca8b6a65ee2d7090d9a05ff0a75948c9b2b2e8d2a574f30c48193d06a1cb05db7fa7b3aa7178ed0382d6a0c262472241b1714b6dc754db85acac9baaf1c0f10c90aa68e18b4c7697a55e8ca0605c3d3bf5dc157daac4113213b255b021b2f1ebbf6e47173b7c0050c6c84fd0a07465c169006c4bd52af11975ff2117edb7621f088803237fd09b3cef446d7901a0d551428fa5c903ce518cbe78aa01476e68846c4507e88adbefc94d8ef9ef9966a0f4bb397c558fc522decb5fc5459310dfa92df3302e20f4775ec14a50aa0d4eaea0d8f10c4d16056c21f67188c6417f2b2d05e8fb22e519a13a97dd0683ba6a7de2a0aa054e44e49ba3c562117bb890b51b2be370f45979be1b5ace2f9b8ab3ea83a2a09131bc9c247f4327d138dcbe095c11e0b298c154f79938262e1198de06649df9a06797e447e810baa3673cd4894c04fdcf9bf925a09c5e1b0524d06cf912664598a0a21ef4110f094136b70de5003ea1afcf53484e6508f2fd90ba3161b2e67d229d80", - "0xf90211a0cc6be5aa022d0b3a80084940374eceeedad213c43cee81ef96491ea7152776d4a05f56c72f9b64362b4e9afbd6384c48380ab03e4bdf36d04c42a65308e249e613a0741f2a866c5083ffaaeba848183ce3a61ad86b2d269de734ae63c3b421432d61a0f06ee45a0f0be845c2ff2f278f961ddbc6155a58b29eded19d838aa70fa6abdda0daa76a6b44346487ef258200733c29ced9799b2b6a8ee47ba24825d4b6d79933a06e88ed05cb277304474e1bfba719f54403693cd04765f26a85ea254ec37adfe7a0d17e4e83932facbcd3bb2795d7c449c16ce61811369428223cf40ed059e9f6c0a024415606d36276da89833a1261760258e2df74660f2e431e355a79f3d9a26b6ea0bf4301031cca5bba39ae341b8721f200d39c6189dca22d664d32433dee69c79da0e4158de5943e4172083bfbc1ae7c0beed3c701db4ea21d906f11d6f30d041e55a09517ffeb0f416408e944b42cc00a7ad4bad2c8b79ea6efb8cf9b8bba3481f66da031a23470f63b79693a4199d432a6b649f7529943cfe0c4a04e50d4c225fd595ca0c4ce4ba5cc7205e919a1631b04727c5eddec768dcc455ff22f87d927609671d9a0461ede2aa4a4d087e13ffebeac33198a0ecb248e457b90039aafb22e38382485a0b3aa56319e23a1b36efd54a97c9879c7ebd092220d5c577a380ececc8ab550e2a01a5f120c09f9421578a00211a883caf03663ac3cfef429bd3301c851cabc84e480", - "0xf90211a0650c02d5e96a5be5bb4ca707d1a66f38654b6e727b3bf01aa4c68dc625414810a0d6e59e966f041f598dc7c4caaefbae828832577745676bd77c422d9cb230461ea0967cdc5781ff8355b63c84023eedc8264ea4796226f4b082a57a6db0b4ef824aa06f82e77302d8c66de396363bb3232ca655c5d71218ee22846f534eab28cc0a6ba07895700533d8a6a2c4136571fbed3233a8c9cd879e2c1df5f629e82c2c7e677da0cd4c2fcbd169da57273caf7be36b4ceebd14d19b7689531c57432a120631198fa0d9dc41447130535abc51cbcfac1b404e23507031ab37815c1334e8d30a69a0c6a0f932cc3471a46ff013088d1c5d5bc2294abe5be2c4ebe33a0794b294d1bf0b97a06807b893d0248793beced597cbac62a45a23bda69486879ed7831c42a7832716a0002dc6c71a918b7769482862a1b8dbbc9c2a3282db4de6c5defbb773360f8ee6a0b87311001a672884da42b8376d1af9f5a37c68a26c042f61d5949aa5f37a9a0fa02f9cc977f4dbda5da169bc9e027ea204f879dfe67b2bd10f293fe56516d47ec3a0fc7d232434031d1175819747b1bfd2b3ef5d908e09acda2c96f56dc950ba2f89a00bc66c05d2a19b22a74fb5a6c9fc3f31dff0158494da662f2d37632e3538ca7aa0abe343ae434790ddcf74e7ef3162a45d6858e491534fc7a76642ffe1d94c1790a0d589e7cd5def99817537f762c62f403f10a806a1102b93badf21a63cf164836f80", - "0xf90211a0a619077206004fc7de385b8172d96d7b3e27be8b1cac21942e46a4b41b0caa7ea0065d6b31e3e625ce3a383d77cf1a850e3fcb968bf60d876730bf837bb295c13ea0c06cb528cf500c6cfe405dc66b8b1553a43bd134de724e4c5e63b298610eabb0a0b31071e69e1d0e730170fac1c398e1c62234d8017c561a885ee102eeba7f674da0ea3f4b9480e2fa2bf8055b65a7ca36ba9113127312a6416bc1f188fec3405c56a035d56a7452951cbe0ceea12456421e3881b60a19101f8da6d08d38b944b3302da0e2120d6ee061bb1a5771c4b29809d8655e58020315793d2d334b5770e2cde9faa03a2f10f147a93395653e3f85530bdef2fbd50c0c8efb519a58c3f181e6f0b8cda00f2913560ce87703e4c48e999c8e76cadf0d1a375bee0189997643aa3b220ccaa0efc2b97d37a2c0cf6bff3e54ba88689fece309550d51f4d3625958bfd4ba428ba0f445a2356cec59e3aec5e15ebbe81b9acfaf2ebae5b8d62b07adee2ff49da0c8a0ddcc906df986f1a6f90aa3ad90fe4118ec0de92a2eda6e77abce280001ca3121a07e4b900e4cad7df4bdacebd67dd6b69b682d756f4f1291f47ded26b4ed5fd558a059e5bc2a3cd3df37a620261d4b95168f06cfeba06dc76437f7f04fcb30b48d94a085be2db4127fe3c8b5b1bfc9d1a24cbfa827b97afd702133debf0e6458baae52a07f4dd5b8ca6c5066bf7d51f78d59b5faf05382a0f45df983469995ecd28d3a8080", - "0xf90211a0e31b4c19fcc4fcb854b8e624b318ad21b022c57c58e30f80f27bcd9fe4e61649a0950522557eb40bafbd082f0f5cc4be3bcdcb7f80c14eee43afd2bcd01f8d5137a006344fc5ae8c6063578d0b997b0caebc50abb303fc195a9875c55a5d3e7566b4a0b685573fdad10d19fe4144655b27c065930447e0f573c7729f1f9f8a2b5516b7a0db22dc742b84718315cf3623f575787ce354a3b536f2916445b8c98841d28799a00975b2742460058745a4ee9f17d4c2cd50047b9831702204293a4648ea4e21d3a0bd1993cfbea039adca3be57058070fc3db8ecd77eeff5591466fcd17eb023ebba060b8953f8ef7514acd9d70452830ef4c54261369b411285f372f1aed66126adaa0a7bbe5c7d23562fa1577db79cf77c262d65862d50241de2b147a9b5b318aacb4a07bff4eedea913e11c281bf9631984344780fcc3dbcda40cab7c25dadbf13c2aba00b3757b624f3e65e3cadbd9b61e092af2f6086fe846ac6ed51a2f0261d21b475a0b7d528fc41c8fdc8ea18c6e7d0099270c777ec1403cf879d1f5134bdc12a6c6ca00ef9fc129b0c672d92ffe23f9ccd800f73526a6131906377f258c54b1a705117a0251c695862941c0ccb2313831b0f637e2b60301268ebbfb483afc5c821221e62a00935150c3df87a08dd451d2d98c8741416a09ecbf3a76c4baa9b8101edd150baa08bd2b242e992653fa60521d04209d0f948548de03ed9d063f6c847212da606f480", - "0xf90191a00a7a0118e00981ab321049c9d340cd52c3a4781037540f7c48d0fdc27e899b3280a08537f2e248702a6ae2a57e9110a5740f5772c876389739ac90debd6a0692713ea00b3a26a05b5494fb3ff6f0b3897688a5581066b20b07ebab9252d169d928717fa0a9a54d84976d134d6dba06a65064c7f3a964a75947d452db6f6bb4b6c47b43aaa01e2a1ed3d1572b872bbf09ee44d2ed737da31f01de3c0f4b4e1f046740066461a064231d115790a3129ba68c7e94cb10bfb2b1fc3872f7738439b92510b06551bea07da2bce701255847cf5169ba5a7578a9700133f7ce13fa26a1d4097c20d1e0fda0a5aa8d46ddda1c7764406a3a78efd76f028e4e3d855406aa4c512af7becb97d5a0c8d71dd13d2806e2865a5c2cfa447f626471bf0b66182a8fd07230434e1cad2680a0e9864fdfaf3693b2602f56cd938ccd494b8634b1f91800ef02203a3609ca4c21a0c69d174ad6b6e58b0bd05914352839ec60915cd066dd2bee2a48016139687f21a0513dd5514fd6bad56871711441d38de2821cc6913cb192416b0385f025650731808080", - "0xf8669d3802a763f7db875346d03fbf86f137de55814b191c069e721f47474733b846f8440101a0ebe4613708ed2470e93df2288bb3fe45a5eb682b66a3b87dc06d4a1feece4b06a0b44fb4e949d0f78f87f79ee46428f23a2a5713ce6fc6e0beb3dda78c2ac1ea55" - ], - "storage_proof": [ - { - "key": "0x000000000000000000000000000000000000000000000000000000000000000a", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a04f165e587aa9b54cd696111a4786bee0dde82431160e1bb738ebdd74397c8e71a026e5eb419cea15bfb33263d96706f5e9f26ef053f9253d59544d47e542f551f3a089f5c1d2c387598c1cc89a7c3caae3a192c710f25fa842a6bce36f72bd1ef7c5a081fb3e2d75b48bd15bfab48044b98e1e6841654432e0302ea9e6b091687ab57fa02fd1be21653f8626f8bee49e92ab9fd32453647b5b5aabcdbd1b73ea223fc646a0d9ad6ab709325ea8c3099d2d9521c3ca6e01252f21d1e88c49c37532cf16bb5da01cfd545cc8e52761d4687a140e6ba9e19ee6e71109f2ad95d7b7de8553eae135a043e0c8f71756fb0a13ae5d9d8e3a85f9ff16f991c9d765203dee8256818883eca0373ffb5c34af25ccdd6d83006741c370fca58e147ef914ef622a5181528d50a9a0dc0a89b9c12a6b0ab64ddb74395f0c522f9e509d1dc8f3954a3aaff6fcce0c03a021e277e6395b4eda2fc2d1f37e2ac87e2b580f41c8a57f25af390e5e63f4a51fa07cc010d648c2c8ca9f830002a7f6df80197bea95c74313b70f2e87447869e4efa084cb7748d18cf2f2a93e2af64f239052110c61b8c45d0911af1f119c0f811412a0248652c70c8a5ba11570818174f626a5cab9c229f073a03f4f1bcd9621ff5e7da0289a8b352cb2661624456552741f3a210489fb9ba67bcecae7188a878d199b20a0b95c0062cd74663c88ce1ddb4d27c0785afed0012bfc2fd206cb9961dce7a93f80", - "0xf90211a04e076e80867c88da12f85f4eb0ab7a374f3392ef4e9f5ef23c097ae8d268124ea0f7be93a47c6f77e141c3e023fd3b82d164bbf396e51df871cfb77a475584f0b3a0d81d379f5935447118ca78ff438b63c085756d68d3aff8f000e07a7cef63c20da06469591cf1e0908963a6b3041c788fe931398c6a1f04847ac96feb244027d7b1a0a2c2c8afa75776d4a79abaa58f87d389999454c46b61094d727608c931ab105da0ce5b8d049294659ddda01a4b32c4c6b681ea9c3dbf02775de68c1c32e136f39ca07161f3e40c6e0b9c3f92b0f38e94c8daaa67dbd0e5ab4a83014c1868564bcc37a0a7835a4831591e5687927d0ef47896144758fb7520cf8a1aca8e44715cba110ba020e376ca7031b2eb2ffdf02dc368dd9a1717e4226afeedda11f44a31ec927e08a0c1d166998591c65083bfd07a0710c4306dabb98dcbbba4a6079e39b7dc8cefb9a03196dfc9116d8fa52c2f7f9ce8189b9bbffb54a384d90537861add83a7aeef22a09c95f040cde30c079b28b14bb38e1bc67e6fabfb3edcefc542a12238f1223de4a0ee7916526f2e827d0c75c7be56424d8a7b0ad1bcc8cf3b93ed4caf190acabfd6a047000a4e021318ce18a634e8081036035bc2fd80f36a132806f6f3a99dd14054a0f5caaa4db700f53b8c14d7066fe091f1caa95ea72b6ef01a2e5f2cf2681314c1a0f3e8a296fa024d50988ee0882ee2f613731ac270108e3bf41ea1849129d6dda180", - "0xf90211a06c45dff71eee987dd843e9d120d73e12b9490e95f30ae032b9b5a4adf6378550a09619518f261a1e59bdd5a98bc10080cef12cb71829f1ea080f71698db46c0c52a01ee6da182dfa921922dd239fc6c8bb68a87382c955c45beb97315b540518fd35a010b41eede6114c15656c12651f7cc04558bf8b6115c9760dc581475ecbb239b4a06126ca3fa4b0e19ade26ace0a40733ddb2c7d9ee9114e819ebcee59e2bcf5401a0214b6597b53f9b868047eb7de637a6028c134668ad1ff0920a57c17f0c1efb3fa02b44c07256fefd7d951066b07910c887555f9b73717b268b931b0301d834219ea0c09e4d0a8762eca3fbc5f2ae32e66ca8be13673f96ba9dfdc8b904a806b667a7a0359b3b770f9538bc6d5070e57f7725475f714fbcc32c410b87a3888a9e73ee32a0728daee3ecbcd487bff6d4536a429dc2fa77463c81083d8ec5ed75816916b7eea071fb6dc83cc666bb7515d2ff26aa40a4073959b639d1f996fe6971bfae8e732da0f636a821ebc82b9d9486b637712330dcb56427d6113bbd1af650dc65d92ba62ea0f0ea41e687238b1cc11ae7ad5caf5deda7c5e72c9e909488db3c433a1c8c1a5da06a8436c6af74c53c68a36fc5fb426439d883bf993bdc445c59970ab56aefbad3a05027c6cb83af3bbbec853a856532ec10de049cc862b519fbaae52bc3bd001456a02084af6309d498a95779d9814e5a7a97bc5e2c14a339434690601d67bf7f00d480", - "0xf90211a09b6f413723da36aeb58a3adebcdab36239722eb05dd95b53635428b3525db581a04810c4775f6084b51ba4bafae6536acf7bb5ad52d897ec32c445b2943123175ea08499f591ea9512e2c3ee46459737519112931aa5cc33b5f7b827193ab0dbaba1a05906804f1174a550fdf96ddec62da0425175330b7ccb71796fb8e7d5b1b97f2aa0e7fa6d7a789a52df0d5f26e44cc25da0cb9db088e3e4ec3d3715edf46e0bded5a060f21e6ee5b20b8294b6b7ddf0acbd81d941496fbd434cfb638db305d7c1676aa0d05f9c974dd539c415049faf0522c6d65a3d165027adca211ddfef7187465cfba0fc11d7dc266be65e000c958a23a984a996e67cbbf1fce1f236eff001864f265fa082c9315abf475f80313319402a3eeffbe9e09d70a7847a4e9aa99b3f45a41ffea0c41907dcb78db53f2e9f7d8a77447922273a55586c4620717004e8fbb6334bf6a0b805fdf7a64e54babd019ddab4311e4ceaf97866657ab1cad28916f5f7957407a0b044a81a494abdf6839b9b62725742541667b0b29d36a32d34b9f465578dee54a0d4572dbddc2e7b057c6ddd311a35153815cd9dccd5137f97eb577c20a773c414a0972a85f080061831f3c5d1672c3262b26a84c2ca9c28c6104a7c2073ce055f05a05050a6b126d677215b719eb5576bb0f372a07138b03a30c96eaa5835cf4dc3a9a010b2f3bd30fb2ff3f5a937fbffa474bcbaf73bf1e91b12bb3d44cda3c1a459d480", - "0xf90151a03283e59372cf8ba97d07e74694ca34792553fbe66edb2977b0178f82eed5d08fa031d5c4844fba2038746021c42a037fdc66aaca5127ae5b751176c2e0ab6e4774a02f6255430890d5c26b7fae36e97d5604ca4275f8286068f86dd36f73da8c2bb1a0d3d89073d0998707abe6a5fb9c588d2b5f2c7daf4e06f5c4035947dc948ab242808080a08d66e7ecb126f5a94a76224c8bf8c95e923b9b04447ea6bac6231eaaf016247780a08a1be972896cd2069bccdd7c43e8beeb4e53bf0d46a4f5e9570188237f34b7f7a01dc8b12dca2bf5991fb5c32228944884d05898d46fc1a8bca4afda2da07a31eba0040bfcfb1efca195677f9c895ebc128c7fc2da9dc9d7ba0f39910766fe08a730a08eba7db6df439f693d48604c1e4e9e8dffceb2d3f9fb9b024d64ed16d4c856a8a0cc8af5746c0a29c3209229ea8946d2005b64b9bf0c5f44e3675c0c475a0f16a6808080", - "0xe49e2063df22a0e142a321099692a25f57671635492324bb2fdb852cbb7224528483559704" - ], - "value": "0x0" - }, - { - "key": "0x7ea29a65f431835045c27ccf1699b8986f6310efc5565f53bae18a1b1075bb1b", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a032c830556d693f46832432e449874b9184955d0474e4bb645e6197d53a458f55a0bb65f798004f5ec3017c0f05041d59c4842f2acf916dfb2c0c73f5c3a1ddebdda0bbf4906264c449881cd2606d0d249889e9d4122157b6467730c2792680c46665a05be813280538eec6c84a26b3778c48e39a5262fe20b564b53729db0462657982a097b02496b76981ea1fa3c02c29664a44b49b48e52ceec339bd7dde3e871c3aaaa0fb242d7dc8fced4f1bd8794ac2c5215cd636562eb7177fb81b84b975378a5607a049aaab5219eb3144fbda39efa187c0b6d54e3b87bfdef10f5104ec015e80860ea0d8302ffa257b30d8262ebb4df55f01c5afadfeecddf3345bf42be02861952ccba05b69ae5ccd3c9c5b80b6e373be9af65883b69f53b6a0f3d3c96402f964e9c8e7a00d99c70ea207a74d80b2dcb0c584c75d39670e904c02346ce5d18dbcf1e5d754a0083be534fe5b586c2e32babcb9497fccb36cc40f87b6248db9d7786981c383cfa08ad3540fb4adb6b732caae4033613b546f3cc842a9ea6a8a6dee1ff836253f4ca063b6f497c22a2ef8a1a682215b4ff1dfd685d82723f3ff55a7ab9ad05dfbab9ea0cbd6607b1cc989c2831cd6d0358421159ee394c920a1852d3e79492911e05a30a0962e973244cdb3a2e4d33c25ffb0295a3cd1c73ce2b574e2d7fea530e762b88aa01a54df2ff6762fa879a69686072cac766817c827d39fbe89df0cef1e77ae2f7d80", - "0xf90211a0bc04f912973fdc180a32ff5dfbd7e330ef204bcd7cd716519f8a45d4ffe09c33a09d7d589c26ed58cc5127ef0d8a48b7607df4e58aee5256eb39dc4e0525294136a03ccc8964e3c68725830bc604d06b8383b6d7ac42336f43c1a2f6a04cfd9e1a1da03a13c39eca3dba60adbf0e49e7daf2afa64489f0796f8f5d970cf32f29b25ceda0457cc95afa9c18dfbaba1e2caaacc7900003e82491fa7ca4aa75550eec980291a07e5accec68453c065f97448ad6fa1b273e3cdeae0100882d41d212ad784ca698a06fd96dcdb74f54450d96f52c8f8ba1dd5f3081527318e29b1db8cde9d9b6b39ba046e15c11da5b6bd42b1bd54d84f1226f797399f23bdbf865d94c1080496b9cc8a04349ec5e72f3546f6c62400905a128ef4b94d1a38c602f70e217588d53734e27a0dbd9720c189a0fd2b6ce3df79780ef61b0e29727d0202ba8023a534a7863b679a0672914fbe6f6113b3988ab58b1d2435f2a4c41cbf4c289616e25d9236eb19dcca0a5ba1028eb661c2a65249b452f65a0f080af2f5b6b1a84f45121d7b20b425ad2a0eca8f8906174f40b78e7c7e1861109efe2fe084297de4d7ffda09a154a83aa7ca0006454aacb618ac73ade6ecde29e6cb3fdb56330a2f9757ebbcd6bb316c9c722a0f320e4b752e83cb86aad060b3723ebe7164ec49fea5b1d5ab7500468f13fa621a00168fa81a74a2a0f5bf9731c02ba5eb7668455afc04208f7e9661bbe37be586780", - "0xf90211a0278fbe60719be394cde85d0991759d44db453d053ce221e34045164bb95e143fa0f42c4ce0d9b99f9025818803a00a7f2a2e860c53cf10de4a4435d341f2ee31d4a0bbef51d6946d6e3b8bc7748375018cc7927007c4d4258aac3f274f5531ba135da09031267c1e6e8fe02342925021672a45f267aface2336a71580d8d50c383f141a04c4cd7ae5c5f3853084cc78cc81ab462b6d79b87e5fd1dcdbf1bec22ec2aec43a0a276837a3d392e60f54b3e529a8aba2d754e5d5008646b60c1ac8d7191e8b496a0ce2a52cd081a5d6054b4cd26058d3c8005c4fb6500548cfd0966f7d3176eddeba00ec2fca8338300b24668644f77acee16dfaad0ac567ba5d34f5a554649e47760a0a7a21ebe5a71a09190524dfc825ef1f79dd1c83e8ac1c868b3af1f1ab16e4ce9a00c099275ffd647d8b461121f6c10b6892e03b4d5396d381fb9bce68abb9bf479a0796635cf598e2ba9208f94d905249cc1fc8dbef0a4a59d0266c4d71774012068a023c9535b40c795592369a014d227eba027708f95547aa42709d0925ce5313258a0899558776b28a17b207f3edd0caf085c58f7cdb7b7f45fd59abfa475e9068afea0e6e8be5cce65f085157250c59eec9637b2942c09cdcf77e6725f73a558663f74a0ed0281ecb1840aae827c88e49561ce4c7d1089e246fa6bb0a52a22654404f6c7a0dd4dcd7404e12866f0041c35ccf4b825e315c65702250bfb435b43472a1ace9680", - "0xf90211a0596cc951d69cc12768fc74c5684311a9ad9273b5aa7858af958bb9fb2777b3eaa0a6e3773316ca6e805a938df2f7412cc76b69cbce83e1e88adbb2b42d3ff827e7a042618cbd76f168579ee42cdaa0c89433d99459be071e1031c408e38fd0fbfd2ca0931cfa8060236645cfb2d74ad2a7e384fe3e5c3aa047373d3817ea718cc0c44ea06e598febeeca2e9efd8e78d7f3dab366154fc2ec94d0288856e842692381fee5a0cda0d5b9054597c31bf92855ffe07e3ce390e70b0c55d7b05a004b2864acd21ca010efa6db623987db8127fb8c745c18f15a557385177836bcf637212e15267b2fa01ab65e8164d6620b13296a71e0f64b3d16536abed5d1ac32db7ebc453b7caafba085f708cb9e8dabf4ac2c936d926b9d663b8a596f145a3ba60daf8be42d1164b8a0e36fe5b6d0c003b557997277c06795aa0ade967741ee87803d4f9c3c779cf2a4a0763dc452ef208fd56b5b71b2a19ee1b7d68778daa515557ecbb4b748ded47881a0a02dfc97ad618f7d7a6dee597a38012ea4f90e2c14920da97e5f4b3522620348a0ce443cd210a19b9afb2a0438586a0050efd66ddce747de1733df3cbf9227ba9ba077be96ed019222e0f358f1d8b4d88d897c7a95291079ad5ce5d3f29350698734a051f0f9024ae4d61584eef6e60f49fcb71154f674c6aaad428af3f5e99f031e76a089b2987c661096f791468ac5996056c3cf239abf2ca34cd01453b1a2830a54de80", - "0xf9011180a0608b6e2d7edb5aa8f0dc4b40d0698553f2861cd3465d53f1a61938d69140277280a092fcb872901023cee33e68be0720d18e444ff9392a3ee2d9d918325b961c2a12a01d6c4132e489e40f13b852c03eaf5ab2cc60409421f12f53a0677097e419539ca00286f963e57783565382d39ada86b097c36ac6a8d7da06d4fb3236f873cd80a280a0cc2ea3340ad1653e151ff4ec5962f7b79ecb768af143a22f9379fff541f132fa80a0b26950b01abc1966cad1a8f462ecd271a949e1796a0667609080c7d3061ca63b8080a0c73c8b3e3120f3c2b578184770c83e504558213d84a96735fb6a9194cac6fa9a8080a0fcf5c3b53c30e8961b12f93e47ec24657da16e7443245f3ad2dca6324f14149780", - "0xe89e20abc0077a218615c4d64b2b3e5c5bba6dc680cf67e24748c75d823000db8887038d7ea4c68000" - ], - "value": "0x38d7ea4c68000" - }, - { - "key": "0x0be16d71963429204d70543701f859c43526c316ac005c10114f4694ca405f36", - "proof": [ - "0xf90211a09235188b22a50ce827e57fcfef947deb326fbf3e53bcf1474685480da3c2ffb5a0124fb25dc9082774374203142e5ff837fb44be60418986a732e5658eefd0ec89a0adcd3cff81b5693747d69aa39667502c03d9b5aee0ba855c097d12c1a8d8923aa0983047462e406f693e5264e62e26eac74effc79cc083932ca5203a50a16e1e62a0f7b249143623dc8871973992ad4b2dfe9cced61a8bd87d9a4608969c187bb67fa00b3c1fa487924d1b23867f5c0fbfd3e65358189179f81523038d5efaaecd8d24a001073d1ca8036fa1b48546fa7c754e4fa5557ec368c1486eb4ace03b73d3b7eea0788b9ce7088d7a318b5cabcccf6aa6cd8aecb5c7768b6f34c2289c035e3a8644a0601661ef25ef2349c519e2be7eb2f406b0f7feaca6c51e68927d8383e7e11246a003eb96526aac14d5852e167af569bd28a2b9418dc7800c97c036309e5064d830a0652be8bca8d1f41583acadceed5b9f88889cc7013f277fa4635bb61168431d22a053f92800c9c034e98d39883ffb259b28ce6f8b6be08c38d0b4e6f70e8e3b47b1a0fd95fe8383860c043ff2086ee13dacdcfffec7c6541f0f2685a3ca04d8442229a093cd739621c1dee11f02ec367be5bdcd45cc93b3fd922bf32be25c16c242aab5a01512f47aae14a95a2c51d419836f161928fe88b8ebb600a1f769fa6b6059fd7fa0ae910af04f2a1ff8ee77ec3ddc920ba51d82c72e9d5034a18ae8cbc335a17e7580", - "0xf90211a064490ab944b1690da71c52093a252bb342da829e63ea19051add19850f4d62b8a0381bd80d9cd404503460d0ab3e1e017fddc353c47caf0a6dbfbdc45c91a145efa014016f67c009c885650f4878942fee34f339128de77ace70820f9401097d428aa0a2f5018512433efcf8698dd20ed2e294803c653affc1c1bc7d5a59f09a5d115ca0c3db92f660784a8c1ad328a759180ea704c1563c37d26cdac606ce90b75d23faa0a5c32174eb3af60dbd019b6301520b279904aba7858ad0f9b27f27a1892f6273a07da2bdc668d0c46c79683baa3e09ebe4d3c97aa54a299f92281b873ab8b4d2cba0c343c11ce0d7354dcf234c6c62fdabec80c22da04d90d64b7b6b4f4fb5ec759da0a21ab9b49e98eef55a20b6969983761d7336301d4ba4b7f57dd49897501e2815a086a829b2c17692e4f03fade63c2f1c097526633235623a041f1600bc79dafdb5a01e3b7bf22ed96fa511eccfd24175831a1d66cdb7b8fb8ad288a32bbcdce15203a0b086da94c55e94de234eb204b388092c85ddd52bf36670cec71407c9a6ada77ea03ac3c357627a959de7ce718a7edbc353642d2686d15c7d65f1ef044a0478ee2fa0aadc724eec6fcdf34a5d79d48ea85336c4141b971e96b97867cd9de945dee42ba06694cd529f741d576c2cb194f1a6743d71e0d00c6d60b2f357a59f6bf411be65a032178dad8cf66075588484b8863d7ca73ca96c02d2763c1fd9d4a86a593b4cba80", - "0xf90211a0e734bae6abf4a37cfc5c02e2c03adbc7063f4b64901546d711291c08486067a6a06705281594290ec7f4afb77d66c848c03247cce8df292c2b77a3c0382bdf9d93a03d18b7eed254f30493645e49523f27ff67e02a4d0cdb5c313d1130e4e2695262a0e73534db1fa707517040d730875e8f99a706f2fd08f754d3a31ba45bd48beb3da0dc55552ec2c8dbb787090b40144d4518f943a3dba7f68b071af0360053830da8a0d36eb3e6aa2e4496127f5da996548b84c521cb700d550bcce40d0eab61e96860a03f6d1d1e090888cc0e06c314d062d3d596f6e16f6945e38b73f550d2e5908b82a0dc4882c6e32047838ba6ed38f7b67ed4d72bd3225a0cbba6da6db27b2cc8cd43a0f392f9cbdf95be55906fe2a8fc972a9c0c330e42c2cc2a27986a25077f9a0e4ea038609469e26ada966b1ec4cd4ef5f61547cf49923ea41f82f3935cfa21146fd2a086afc861c09a76960b7dc06b5c032f443ffde13b955248e9008d65bcdc08a880a0339205e21bf0e52102081bd565edd658fc41e2f0c7cae282309354a198c0762fa087dde466098dcb599b9e5d3ca023ca8bf1390ce3a787580f8e034f0803f61de2a0c705ae835337b82a7aebf90152629538cef7eb31d40be2b4650b31d7d34a89efa0c8a3ce54021c8dace0f7b19914b96d2711e75d810c249e1a050326a7b6e88b3ba0969b136554ad451da47ad4e40845fe4ee5f9e8879a81f88c1e81993c865ff4ef80", - "0xf90211a0f3a9ac3149f12572678adfdeef138dd1805be5d3257f62909209072fa6c42abea0d8533785fcfe46e91a1d587a53d8e198b5fd2c977c89f484f317247966728713a0825e958bd436ef06385cf097dda31a3ba87d2de9628c195135b2b06bf8caed96a09e073e1cfeaae376ed41e86b7d54646ddeb84c6b6d54273b88edd6d69075a99ca0923b6cb77e1cc51f3ebce9787dfd9819e3d10f1e8327f4d5b4483264a20b4292a051a6639a40cde9e681fb4a0513ec325911b477aaa2d9207581aed1caaf3f7452a0c45ad3c3e00c06b52feeaa8d8d3e8779d399b8ad9be029e808fb8f49ece46bd1a0560cb020aba467d0da4b70fdf5429c9eedef214f92173f716b7c7f587ed40017a0e97e9a0160e7d68110dc294e289813a7ab9c84c2ac430cecd1a85017403a18e4a0c040d43b3c1db8dc87a61aadff4b2af6bcc769af69a68de249068dbac125d20ba0840f6be7cb9a1bd81fd1c0a54ceda89a1b2aa28d22ee33b7a395530e861662dda024e6b1b63fbb89883f4b33606eace065bac7b5fccf5cc00e2e86e441d58e6889a0894f06a178c8df971f4bd258c503623e64dcc1ecc1041f6ec0a790b9e2f44b6fa0a21a0b1ce15911ebad53aafe985b97eaabb4302ca4b7fc24475729672c8bd39ba0d4293c0807cced83f3f6c24177192c933b539c296e5a6fdb744467423a1c262aa07d98522ccb950688dfc5c05920c10b6f64c0ccd412c762b09640f05c5cf3383e80", - "0xf90211a0cb7b2f99709c331a9836cf0ed7a489ff4cac3364f6bc1333fd93dcc4c882c427a0e79c4c93ae69692662f14883889c6e396a0df26fb33225b0507526393ff51d5ea0e607472605789ceb55f67a57a8ae3cc4507cded5f22359e93f7f34e70f3d84eca03f4b13d049fe272072a08a73409b7dcea8bb14a3f8d9da068ef20438bef29e58a08251cc96c8cff32f8dc4de17d2219bff1481cc4ea114f2f5b5534dc7d4aa6761a03d1783e93cb51562e096dac7c3c0ad1b2d5af8b8de99fe0d5066fea24e9d77d0a0f9f6f7306771823cc0668a90be4b4f9c58731b23f66250c1163095c3dac2048ea0ebcdfaefbe22cfdca6b12258d0f316b638aab358690b46c3b57ab55a4b08fe98a07cd1a6123e613b0ed42ec9d8e24f3f12fc4eba0207bcc670f80706958a0c94dba0a80c49fbaac93a046ffce4b6d85dcd798202f4b446bed9c31b3bf2f59750766da082ff26ac0c13ee58ba9a04840a73d32580f81a15e32aff1f3b85f61622798271a0261c81ab6def7ecb1f2f470f89ea57b5c2ac5637b2f4df0ff5574faf36aeac93a0ab4fe449fc537f77fa8da5d1c1128203a3fd49affb2346f8550fd885abd12adca0de06ad085538d2004912faf268eb05fbac9abb150ed8544864e7b70aab2fa81da02f8e67dc2ab33e86cb2a5a1b3dee16296f06294d3e060d0bbed467feac22d045a0df0c6c454f6098b5bd691a7d967bd1b0e53bae7963fee2a68583cf01d2e11b0880", - "0xf90131a01d4a8ee3af146a91366409c1e2c59b4569ac872f76ad4677c8337a1f3e12201180a065f2bab38d4a0e3118597b6b0067191de9afaa4d2935ec7c1cfcd81db4cc5dc5a09b7d0b7c923dbc4bad13443d3c1c1374b7646c5e9a004a419bc373b8c7c9ad60a019df7efb0770b0b07403c6a0b64364a6bd164c0dea5a12547754589fb764b7e280a0d624be59151c7fec940628a0a819ec7055c4894ea6af0e0b8a0302bfe50a02cca0f4e2577d9f1df04697fee1442b264c26dcd9b9b51f607cce167b0266187b15f38080a0a40c701e3a3c2d88f6c26a39e058e0a37ba67cb6db22f078b1b9abecf0b795e4a08259e9dab6f6b0c72cfb9153e9aed7ecca1e26afc519de71877d7e14aadee7f2808080a0512206a36824e4c0cef92e11a6071846ad68e8b12f042c23f16243e56bf0df9a80", - "0xf851808080808080808080a0315e225878d124ad74a228bdc9f82e0e8b0963a0b8d391eb54b484baad536acf808080a07771ba1e5b4b9fd6a525c493fb96e6fb5894ad847cf39eb60c3b24df5025eefa808080", - "0xe79d362366783a4fc90e52c8cc595ba9fd2b278bc52248117c14c07e5394d888870aa87bee538000" - ], - "value": "0xaa87bee538000" - } - ] - } - ], - [ - { - "block_no": 19493153, - "address": "0xe592427a0aece92de3edee1f18e0157c05861564", - "storage_keys": [] - }, - { - "address": "0xe592427a0aece92de3edee1f18e0157c05861564", - "balance": "0x0", - "code_hash": "0xbb90113d2f9a5e9b7feb15a1d1fff06c1ee1575b3f9b1181778ffd0cf633e7ea", - "nonce": 1, - "storage_hash": "0xca6f0fbdeda818216f399c395dc814121e66bca0139cef25a2b81223c438c1f6", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a084a6df8a60e9f9e6c23cdcac12bedc626dd6936b0c4bb94d6eada2cbf655d558a075b1dc9f04119a7cfb33683a4cb0f816d4bb434eac4db8f1951ea6886c1a0811a0323cda734e99dfbfa93edbf76183846bc7c3d52da0971ef637d4a1497bae0210a0b2f0e87da6afcdee1c868c86c9cec713c689cd740b55045b5f3933d1eb9e42fda098ced1ca77f42a52a00c659835bcf632fff9d143202abee9f3c60209051caa1fa054bb4ae44bbfdc5b59d0c4dae52c9dc588183381dc754f53885ab3539959dc87a0e6cc346ca9f68734c01bbcd0c7d683efde7e22f0a662e61372bb36ee810032fda064c7ae341d641d6ad7f3349201b613548ab5af1968bcb4dcee33c1f6bc83cc28a0d4c2e648ffc7b4ffefb7055ee1a3057d83aa98a5ebe01248dffeca8182c6be4da0e55cc35ed1d794f2d0144d2b779c8f426d4c062f10c91f93e5a03a6de1f153a9a05ab7b3f9e75c1c06ff8f1f58bfd51313dde782f92886b22b9ae55c05cef8dcf2a07e3f7ccfefb8530d4648a9bde251947e4f110d5156487d2879fa556a0889e664a0b7afbd434e3300eb9068ea193395d0b587378583a6d5de432b4e06863d1e00a5a02b4fe03e6dd849069dd1dbc26699df1f9217b3c65b3dcf8cead863f8de24a415a0f5e86ec2ed40d5e3593c72e188659441764f9ea0ff05dd129403093cec8bddb3a063014473c20a0aa044ccf43aff9c7ba449e045067a520017bdf1fcf21f9c37e580", - "0xf90211a06ec937061e1e78f61cf69bfa2afe65f73fbc1a2f6fd8ee801a4744c63b0c4daba0e5595a2318b7cbe8f273481db5cc9ce01634d86be2c6c3eb5c52bb081ad22baea0b6bc498a411a212f8e5f5dd4c236f4c85c03471b21b79c1f3b2e601f814cba7fa0337fb9ca45521c7532b08864c79b6ce1d41b41c3139f6a0df5ac47fc3e4d7409a0fd4e586c5d72cf0bb662601ec37f9a2af542de59c71b2c0bbb3620e39938330ea00707e640ca559d228ac439daa56ec647108ab3ea8d880e2a77429f97de7a224ea0c1bbdae3178256c4b3f0cb91ee4199f85fcc3c64692d3e98f3554319787faaeaa0d1257ca9e81e885ca80f132092919bf5f3bba67fbdfcd3c4527005d753c3a439a063ef396b9a2752f32a63dbd82821316625cbc66591f72fd7ed6034e92b57c92da0323742d95d396b7e03798b920565972ca79e0d7dd460fb3c348da7f68be57f92a0505287ff880f29acab4efb5709ac6e620eaa47e4229e95eab3da6b7ba298e101a0fcb616a46ecf1e0b3e2c28babbd0a588c75d201cf05981d54964ee545aac90c2a0db6bacd145ec6f4aebbd7e20033c68a7cfb44faf67328e464a9f70328791c4bba0a42b1e303f916acf3e3b9ce07abcd869bfcf35fb3541995439dfc04157154afaa081d45c4cdccb42bbdfd041a94734b8e99a28b56164de8cec605c50a103d0e16da00f4477a5e70c609f9db14d8efc64b0d37f1e42588afa4efed06ba96802e36b5b80", - "0xf90211a003777ac19e340205e318c6226ad6b55bfa2ce5dba179a042ce7831ef7758fc9fa01d503513f319760ba5e6678a03d336ca8f8c2e51f283ed57e019c2932f9cc4eea02447b2894cbe2531319f26c52cab3704874a08845cfb49ffe3bf570ea3a2702ea0ef182931124ef089aace8911928c61cfe69a4b9cd7cf4f992a7bf73a40f266aca02022d9daf0692841d2153c21f482996afc2858b6b22ca7d4d9fc16ac74aa1204a02677eb4d6106e1af102081453ea762b7e6c8ac03c183d504166c499d2d722f56a0674548b6a846d0c020d1ae032e893c27118faa52f9536a100c61bb1f2634b800a00febb010da79ad5d66a45d0e9f3c3aa3cac09acfa60ad31fc6665f7839289d4fa0ae9bf18f7726510deb64e5ba1a495912ae897a2e3cc702eaa29ce976c109835ea07e12da1eede8622a9470d5549bc2b2ee0f13cf835eedb658a97336f548a10335a090eb645ce3b75691fd8b579e33f5cc9a4be8c56df3c608babc187845f6f4a19ba0afb4f15d699cf28db4edf7cb1564adcb271109e6b7ad6c225b2dd59a767fc633a0cb868789cf99e7d0535e5c34b91360cc5e7bdb1440b5da345500011a2eb45096a0cf9d3f2afdd50a2dffedd48f73dab0104f6096594448d0a94da97c687c56542fa065578aee746d5a06764f53403515bc799eab65119d86594e20e76c7629b04c96a00bed62f795117b57961bf01fb63ec0a80176587875e0688215d1a37db0b9fe6180", - "0xf90211a07a50fe37486dec12adeb5821321873c936018ce5ea2d899fef9f37e57b1f53c5a09b404b0c12cce6325c98ed9872ff37bb10fa82b1bcc26f0d5260bda08aa227bfa089b668c33d365d8e61bb44a86e7f13cd014e77e1a32c2328a7f97bcc88760b0ba0326947c16aa2b28be124827051e9dbe909583a77e34acebaa866fb702f1515c6a0220086652caabad53b15526faeb7082306b695c9b1b12d8dfb549d7c234e6b74a0037fb4fd32f289235a3c519f4790140ee6eb3b9ffe00b4e93d4f7896215ac6dca02cddc312da0a0722db5c52abfd637ac5cc07e996146a809686a471e6d37bdf7aa0a0f16b515da15d540e3585f1525023a29fef722057e00395119ec72a951158e4a092f7d51d0cc654776cf4a6ad633d1f22445025f44c285c9dd238c03381704e06a08ca32f1bd7a9a63fe9ff8d886289c0a169ef7818823762850d815e349393f14ca074fad7f18a8acb64d592d24433ecb90dbe33058880fef1e1f71017dbacafe308a07dce5da07d7cafe086e8c8226aad5f3734550e7cb234468e028c1e1eb1c77beaa059ee0e8435841790c59f0d10289d2b365713b684e5f9529a29e411af1b0fe716a095aa4b6a2c80c2c5421429ac3021e31ed62f11954f0dd799b30721d4db8fcf01a0aa731331b7a5dd9c0e9b5924adb337935ff539a94e63c57d3ca2f922a723cba4a0b1119a49d1a7913f5c55d383e380017279e4630854e86fdf58b7a7ee7caa422280", - "0xf90211a08465e29360cb5013fac0febda0eed782a23a1ab9d69854d5bb85fed91d022359a0ffe37f48bca727e4516faa78ceb27fe45ac19cef5be53fc31b44479213d3366aa0ec254f560ce60dbceb952ce0c2c50175429f5398ab6dad41ab905776bcb4fb8ba07f96ff03a44f109bb78afac9e60157cfb800467aaaf0db428023adee3046bfeaa0c522f0487a5339d6b68f2895b15deeedbc3a6f2f7dac4f7bd7a3650eed9a5f74a0c3d9090592a0bce578e02d3a4ad6dbaa1bc793de6631ecbf24767b2b2f8eb6f3a0f480a3fe97f8440a6f1177463737537e718c6a046841afe097c7cb45153d58bca039f23ce75318e7c7c2326321c774050b452531559005b895b6a0fe8d9f5a588fa0ac01deef43ba5d63c05399b9637a44983abeaa912bb8badb178e2e4bece8f4aea001b6a1dc1302f68a54331a14b58c9e605587fb168ad4c338557f16a8ee6b9d7ba093fb72a87e7542016348b43be80a4f4a134e2228fde2059ffbcc5d78625ee1c3a04f63323287dd526f54128bf50b7fa383b7ffe95c4da4248aa712d993ecc7590fa05c196f82b6e8f9a5852d1dbb025271dbdd8081419b4c9f65c229674fc1afc89fa09074b1b4f7c60edb1ec640c655d15d5e8d2676a9ce43400834deae605c3a1ed2a01e9aa4db8b2729959782b2627db212baf3c83735a85e83ca9787458852de7ddfa02d46593d26db5545248d92f9d486528c84fd5bdbc2ed84dfae6b345a3a6108f980", - "0xf9015180a091d884567ae0e2c4d5e711cbd9eeefd724927b0240229a989e92157fa8f4e5a7a0f3414ebc85a5b49d3df836a633bbbc10418cf90d1154d20cb5ae6aff7221df4480a086bc548f9d6d895a120a933b7c55a8cf5a82a0496661dc902fd3e7c69d1f2bada0fe42500cdd99a46a709ed2f8b8ed09921ee4996c4638c0aa7948a10db562d47ea0ed1ec40f0c830a8eef0035d5642178a4833b0b95906b233b03e819fc78ce080f8080a0c5c6051942b8c49a5876622af3f304ef3ef5982d83c625522613238ffb97b2b480a061414046ff4e1489795e40a37881c3fba3f7c845b62bbdea8f4792ef5abd07f5a05102e5abb9ff5f4a9388c36fe9275c156a37dd9f021efbe0862cc76d95d9c93580a084f4f87a67fc6e7c575b5f6ac63605e59b6fcc7b339a0177ce37a1e25fc0bdafa084291fc72151750bb1327081ea45f38010266fe55d11e964821e897e491def3980", - "0xf8669d3d2b096184691ac1f4d2a3fa2fbeccc6ce1a97d0e02994ccbb80d0911cb846f8440180a0ca6f0fbdeda818216f399c395dc814121e66bca0139cef25a2b81223c438c1f6a0bb90113d2f9a5e9b7feb15a1d1fff06c1ee1575b3f9b1181778ffd0cf633e7ea" - ], - "storage_proof": [] - } - ], - [ - { - "block_no": 19493153, - "address": "0xe592427a0aece92de3edee1f18e0157c05861564", - "storage_keys": [ - "0x0000000000000000000000000000000000000000000000000000000000000000" - ] - }, - { - "address": "0xe592427a0aece92de3edee1f18e0157c05861564", - "balance": "0x0", - "code_hash": "0xbb90113d2f9a5e9b7feb15a1d1fff06c1ee1575b3f9b1181778ffd0cf633e7ea", - "nonce": 1, - "storage_hash": "0xca6f0fbdeda818216f399c395dc814121e66bca0139cef25a2b81223c438c1f6", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a084a6df8a60e9f9e6c23cdcac12bedc626dd6936b0c4bb94d6eada2cbf655d558a075b1dc9f04119a7cfb33683a4cb0f816d4bb434eac4db8f1951ea6886c1a0811a0323cda734e99dfbfa93edbf76183846bc7c3d52da0971ef637d4a1497bae0210a0b2f0e87da6afcdee1c868c86c9cec713c689cd740b55045b5f3933d1eb9e42fda098ced1ca77f42a52a00c659835bcf632fff9d143202abee9f3c60209051caa1fa054bb4ae44bbfdc5b59d0c4dae52c9dc588183381dc754f53885ab3539959dc87a0e6cc346ca9f68734c01bbcd0c7d683efde7e22f0a662e61372bb36ee810032fda064c7ae341d641d6ad7f3349201b613548ab5af1968bcb4dcee33c1f6bc83cc28a0d4c2e648ffc7b4ffefb7055ee1a3057d83aa98a5ebe01248dffeca8182c6be4da0e55cc35ed1d794f2d0144d2b779c8f426d4c062f10c91f93e5a03a6de1f153a9a05ab7b3f9e75c1c06ff8f1f58bfd51313dde782f92886b22b9ae55c05cef8dcf2a07e3f7ccfefb8530d4648a9bde251947e4f110d5156487d2879fa556a0889e664a0b7afbd434e3300eb9068ea193395d0b587378583a6d5de432b4e06863d1e00a5a02b4fe03e6dd849069dd1dbc26699df1f9217b3c65b3dcf8cead863f8de24a415a0f5e86ec2ed40d5e3593c72e188659441764f9ea0ff05dd129403093cec8bddb3a063014473c20a0aa044ccf43aff9c7ba449e045067a520017bdf1fcf21f9c37e580", - "0xf90211a06ec937061e1e78f61cf69bfa2afe65f73fbc1a2f6fd8ee801a4744c63b0c4daba0e5595a2318b7cbe8f273481db5cc9ce01634d86be2c6c3eb5c52bb081ad22baea0b6bc498a411a212f8e5f5dd4c236f4c85c03471b21b79c1f3b2e601f814cba7fa0337fb9ca45521c7532b08864c79b6ce1d41b41c3139f6a0df5ac47fc3e4d7409a0fd4e586c5d72cf0bb662601ec37f9a2af542de59c71b2c0bbb3620e39938330ea00707e640ca559d228ac439daa56ec647108ab3ea8d880e2a77429f97de7a224ea0c1bbdae3178256c4b3f0cb91ee4199f85fcc3c64692d3e98f3554319787faaeaa0d1257ca9e81e885ca80f132092919bf5f3bba67fbdfcd3c4527005d753c3a439a063ef396b9a2752f32a63dbd82821316625cbc66591f72fd7ed6034e92b57c92da0323742d95d396b7e03798b920565972ca79e0d7dd460fb3c348da7f68be57f92a0505287ff880f29acab4efb5709ac6e620eaa47e4229e95eab3da6b7ba298e101a0fcb616a46ecf1e0b3e2c28babbd0a588c75d201cf05981d54964ee545aac90c2a0db6bacd145ec6f4aebbd7e20033c68a7cfb44faf67328e464a9f70328791c4bba0a42b1e303f916acf3e3b9ce07abcd869bfcf35fb3541995439dfc04157154afaa081d45c4cdccb42bbdfd041a94734b8e99a28b56164de8cec605c50a103d0e16da00f4477a5e70c609f9db14d8efc64b0d37f1e42588afa4efed06ba96802e36b5b80", - "0xf90211a003777ac19e340205e318c6226ad6b55bfa2ce5dba179a042ce7831ef7758fc9fa01d503513f319760ba5e6678a03d336ca8f8c2e51f283ed57e019c2932f9cc4eea02447b2894cbe2531319f26c52cab3704874a08845cfb49ffe3bf570ea3a2702ea0ef182931124ef089aace8911928c61cfe69a4b9cd7cf4f992a7bf73a40f266aca02022d9daf0692841d2153c21f482996afc2858b6b22ca7d4d9fc16ac74aa1204a02677eb4d6106e1af102081453ea762b7e6c8ac03c183d504166c499d2d722f56a0674548b6a846d0c020d1ae032e893c27118faa52f9536a100c61bb1f2634b800a00febb010da79ad5d66a45d0e9f3c3aa3cac09acfa60ad31fc6665f7839289d4fa0ae9bf18f7726510deb64e5ba1a495912ae897a2e3cc702eaa29ce976c109835ea07e12da1eede8622a9470d5549bc2b2ee0f13cf835eedb658a97336f548a10335a090eb645ce3b75691fd8b579e33f5cc9a4be8c56df3c608babc187845f6f4a19ba0afb4f15d699cf28db4edf7cb1564adcb271109e6b7ad6c225b2dd59a767fc633a0cb868789cf99e7d0535e5c34b91360cc5e7bdb1440b5da345500011a2eb45096a0cf9d3f2afdd50a2dffedd48f73dab0104f6096594448d0a94da97c687c56542fa065578aee746d5a06764f53403515bc799eab65119d86594e20e76c7629b04c96a00bed62f795117b57961bf01fb63ec0a80176587875e0688215d1a37db0b9fe6180", - "0xf90211a07a50fe37486dec12adeb5821321873c936018ce5ea2d899fef9f37e57b1f53c5a09b404b0c12cce6325c98ed9872ff37bb10fa82b1bcc26f0d5260bda08aa227bfa089b668c33d365d8e61bb44a86e7f13cd014e77e1a32c2328a7f97bcc88760b0ba0326947c16aa2b28be124827051e9dbe909583a77e34acebaa866fb702f1515c6a0220086652caabad53b15526faeb7082306b695c9b1b12d8dfb549d7c234e6b74a0037fb4fd32f289235a3c519f4790140ee6eb3b9ffe00b4e93d4f7896215ac6dca02cddc312da0a0722db5c52abfd637ac5cc07e996146a809686a471e6d37bdf7aa0a0f16b515da15d540e3585f1525023a29fef722057e00395119ec72a951158e4a092f7d51d0cc654776cf4a6ad633d1f22445025f44c285c9dd238c03381704e06a08ca32f1bd7a9a63fe9ff8d886289c0a169ef7818823762850d815e349393f14ca074fad7f18a8acb64d592d24433ecb90dbe33058880fef1e1f71017dbacafe308a07dce5da07d7cafe086e8c8226aad5f3734550e7cb234468e028c1e1eb1c77beaa059ee0e8435841790c59f0d10289d2b365713b684e5f9529a29e411af1b0fe716a095aa4b6a2c80c2c5421429ac3021e31ed62f11954f0dd799b30721d4db8fcf01a0aa731331b7a5dd9c0e9b5924adb337935ff539a94e63c57d3ca2f922a723cba4a0b1119a49d1a7913f5c55d383e380017279e4630854e86fdf58b7a7ee7caa422280", - "0xf90211a08465e29360cb5013fac0febda0eed782a23a1ab9d69854d5bb85fed91d022359a0ffe37f48bca727e4516faa78ceb27fe45ac19cef5be53fc31b44479213d3366aa0ec254f560ce60dbceb952ce0c2c50175429f5398ab6dad41ab905776bcb4fb8ba07f96ff03a44f109bb78afac9e60157cfb800467aaaf0db428023adee3046bfeaa0c522f0487a5339d6b68f2895b15deeedbc3a6f2f7dac4f7bd7a3650eed9a5f74a0c3d9090592a0bce578e02d3a4ad6dbaa1bc793de6631ecbf24767b2b2f8eb6f3a0f480a3fe97f8440a6f1177463737537e718c6a046841afe097c7cb45153d58bca039f23ce75318e7c7c2326321c774050b452531559005b895b6a0fe8d9f5a588fa0ac01deef43ba5d63c05399b9637a44983abeaa912bb8badb178e2e4bece8f4aea001b6a1dc1302f68a54331a14b58c9e605587fb168ad4c338557f16a8ee6b9d7ba093fb72a87e7542016348b43be80a4f4a134e2228fde2059ffbcc5d78625ee1c3a04f63323287dd526f54128bf50b7fa383b7ffe95c4da4248aa712d993ecc7590fa05c196f82b6e8f9a5852d1dbb025271dbdd8081419b4c9f65c229674fc1afc89fa09074b1b4f7c60edb1ec640c655d15d5e8d2676a9ce43400834deae605c3a1ed2a01e9aa4db8b2729959782b2627db212baf3c83735a85e83ca9787458852de7ddfa02d46593d26db5545248d92f9d486528c84fd5bdbc2ed84dfae6b345a3a6108f980", - "0xf9015180a091d884567ae0e2c4d5e711cbd9eeefd724927b0240229a989e92157fa8f4e5a7a0f3414ebc85a5b49d3df836a633bbbc10418cf90d1154d20cb5ae6aff7221df4480a086bc548f9d6d895a120a933b7c55a8cf5a82a0496661dc902fd3e7c69d1f2bada0fe42500cdd99a46a709ed2f8b8ed09921ee4996c4638c0aa7948a10db562d47ea0ed1ec40f0c830a8eef0035d5642178a4833b0b95906b233b03e819fc78ce080f8080a0c5c6051942b8c49a5876622af3f304ef3ef5982d83c625522613238ffb97b2b480a061414046ff4e1489795e40a37881c3fba3f7c845b62bbdea8f4792ef5abd07f5a05102e5abb9ff5f4a9388c36fe9275c156a37dd9f021efbe0862cc76d95d9c93580a084f4f87a67fc6e7c575b5f6ac63605e59b6fcc7b339a0177ce37a1e25fc0bdafa084291fc72151750bb1327081ea45f38010266fe55d11e964821e897e491def3980", - "0xf8669d3d2b096184691ac1f4d2a3fa2fbeccc6ce1a97d0e02994ccbb80d0911cb846f8440180a0ca6f0fbdeda818216f399c395dc814121e66bca0139cef25a2b81223c438c1f6a0bb90113d2f9a5e9b7feb15a1d1fff06c1ee1575b3f9b1181778ffd0cf633e7ea" - ], - "storage_proof": [ - { - "key": "0x0000000000000000000000000000000000000000000000000000000000000000", - "proof": [ - "0xf844a120290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563a1a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ], - "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } - ] - } - ], - [ - { - "block_no": 19493153, - "address": "0xf5213a6a2f0890321712520b8048d9886c1a9900", - "storage_keys": [] - }, - { - "address": "0xf5213a6a2f0890321712520b8048d9886c1a9900", - "balance": "0x7eb6df9c77d2a97ac", - "code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "nonce": 51151, - "storage_hash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "account_proof": [ - "0xf90211a0fdfd62d3822d28ac969c4e4d8fde521af934da0883a985328dde97c0605cf6f7a0587af64a13c3da485cc8bd180aa2336f3ea8db1a67bd1734e798cc6f29f047dfa0f912cf8518419e9e616d9741a9f3f57632ecb78f9a7c57c7fa296df43fd8d96da068ac44764ceab12df95d7607e45dca0b026ec7f0d74a3a2fc36879846a2edc6ca0596f6123c7d10f601fd17eea97b979b5f81342d74307abc6cb87f5001ac8397ba0d2d08ff49377b169966ea3f7ea479723850794ea6172a848deba1de69e0010faa022997e01425371506be34478791c0b0120fcbb9298846360f5608c83a3d6abb6a0ae1343775a659d0ee6e7479a2d35733b243ef747eb6c4319dee9b1149e946f60a0db1b3610fbab40a1cb9d9f4e9a126bcb458f166d0c03509ca255d79670498866a04adb044dae9daa5fbeea8e24d3ec662267d0ac19b14857b18977895e9ef689daa0cfe5b287c85a94852c21efd3929bcd7ff7fc7c92b34706926ca88102e3bc6492a0e65cd9b3c7777f2c2ac7ad0a6720c7f9926f76fc8257e54067bc69d85aff3afba04a28cc739153d6d4a1513c7feb1978bdc9310d9c56da4e9145a35546915eb647a0d996dbc2dba1cc0b249e2d0dbe2e47731881b4540922b4fe0e6a68cdea8c77e9a08ed4d3dba9a867c5a6708132c8c1973e50780db26b8949b4bf665720191fcdc6a0ecb2e1438c1d6e3b16938a6b90aa2ec208e22dee8e385a5e144cfff02b3d809e80", - "0xf90211a03c6c6e1f1f3d2481061c7c01fbf067c2301bd2fd8c06d41bae8797298ec1c9b2a0be7b9460642bc9365fbebc76738661384cda26cf9158b98a41e7c79b0ccaf960a041dfe6219a35dd959327a618a7dc630e50c1ac2d9f75bb19972df79066bf6eafa09ad4a0a05d854defe6735c0b1d2d08b9402c1e792c872c6d97813c170ef8f2c3a0fcb7ce0b2c8c6810f3544e0e76200924865d93456d5c4224ea16927f84a55880a093f827e51e12d902f2bf442d065b51cb9e78081ae9fd47f55cb5ea8b3e37d22ea04b23afcd0351e5911cbae64e2932e9916cf3bce8ce5da7b0d555314662d4e31aa09164d21ba5ef02ee666e913f36818922d588c05cca0af66f8bff20e8b49b606aa0600a887d69173cf0baff93d87b543683012f31b91e9b99147e71403de8caad3ba096d15b1aebc2d2a82209e8d9a240d1e8951319a9a15f1ac77d557ddec28090eaa06129d2219082d983dd70bffebdf3e2db62689555b7dbf0002eef145403509d13a0ac7b1d7dce4db2e4263e1401894ffaa53114d002bff18f4b7306575cf714e964a0883c9dac7ccef21b4ce6889eb5903d730fbf552bdf84556239cbc621f3c4b051a0d099adab57383ac6a0057d481d3abd66eceacab3932f28aa0623f289cb95e4ada0c4ee8da268a5ad6c0afb97a57b4dae70ed3ab68f195a56343a633974b6295bd8a08c685f3294a544c52fa38a4e2c007edc3fa4352021082b15c01cbbd7183a8dff80", - "0xf90211a0df3e660e582b8ee2a521fad6f650d087865df55acc24f8060fef86497c284512a0620404dd0e82502bfc2158e912165a3fb08f6ecd61ebd8842765aadbcc20565fa0d1baab7a71da3aef8498073c098ab6f3fe013d48cae87b132fbce334420fd54ca040494bd5ac85f245036e06df3436d6787f06d69ea4ce9db6bbc314235cd1cdfea028acb886b362410e09680e071aace0e522bdd91e8a2c9de28c43a479a7bee50da0bf657d97910cbfdb15a5333b81c874ac0b7aab592c9dbde4bb48e42eeafe8696a01f351de147afc3a91ef9246aacd1cc37c49cc2d4ff1610324df674f7c2b62088a02460acf49ba826d7c6afd09953b03317223211cca045549ffa4a0bd274432b49a060a7259d83ef4da6e064179befce95a51299e1b0f2e0c437201ecefb7a8c1773a0c63920049aca79df06a39931cf5a9a44406e432ecc5640c726c1077ca4f352e9a01cc60b8277d24e2e6a5edc20a1a6fa1ed7606d7c3b4d3e5f699295361cd0cc53a0b642891bbec0d654b9605803ee95c615c5bfe38997476c4cfb46d02a8865d805a0e5cf4e7251f2a4424754ab954837e3039448eef72acc526a88296b8d9a569cc3a05a26090dc203ba9bb66df2bea00f792e4f2ef982dd2df6fab2018e39cdc44e8aa07f66c8b086aa4334411a1d99918780dd9863bbd47c614a592df8dff1445346bfa01d41f44f72f4a976fe40265a0316bc5d10cbf084f11ec474ab41134d5194b41980", - "0xf90211a07dc319fc42a22d3f62693ca180dca5cd91f5d57fce6bfeab5c4fa387dcfb5714a06611750d9da2f964ed3c17d4b9c63d9331f06863e521c556abb908932dbeb45aa0936f503581372541e560f8ea1c836d9f0eea7d292f1ef1529850be7e7e9d8bb7a01995652397fae7732edef7f7b9c5ab37872eb32205f2b826b95fa79324d7c4b0a09f37566a4826de6a515c7a60863e63be36a7681cc02201407f858e9d3ae9820da063d8fff947e64af3a4e940dd58000dc2506f52f39fc9f49a7d752c7d5bc03a6ca05198a4073b71e81b632f17abfd2d337df255dc49388b3161c38852a109e5fb0aa038adadd67fca5570dc3622272ea1a204e1eb4870192a450dcda6c73f2c2fecc9a0279798e70ab254fecfce16a8e73e8bfcc46b99e2762db614c1d395a216bb20fea03cef062303e7e2dadb91fb0ba76fd6e2425dc0be299cd7977c882d72a9796bd9a06e51b9a8cdd43c43ad38701610a77462e5346e00d44105109420b3eab033a466a07f4c02df084280cd9cabc8133fe6488e912eeaf75952492527554d8ffe45a8faa0bf581bfae9b343c0ca617e9224d12f3e0fc7d58cebf3362c6fa5a14f13823a9da04efaa58374602080d5fa21159babaf5304fec80ba399aff09b1082b7302bbd3aa0a475ab9a228e8f9a6d223fd4a8b402de1366f450b1e3f6b242ea00fd42bccdc6a0348a7a4b05c1c89b28a78b8769f27db7d533a688229f3ac37db045cd566cb29180", - "0xf90211a019a7677c148c823c61e76902707dd8e960fd2014d2d3b089f6f70707d3f0be87a026211c54580eb8bb582b6fa76926c0be001e776ec9d41e74b413c4ae98ce094aa0b0c0214024b3c4b2f7ef6e9f019c6e7123c70af50d6d30e19bd6e86274139dffa092acaca1feb153452034c8590f6bc1cf7fa9d8fdaa86adab9ab4408fcec0e986a0024ed108e28b8862efac3e3e0203dd093ce834b7543f7b88301be38bdc9753f6a02ddc285c04ab7ca67c0064d58bf61cc35c080f49b0a9ea5181beb690970cabf8a05dd74124bdcf1ce2eebbe2f7b6a4671f74591c0778d886ad0c484b63d364a872a056225a8b88ecbb0de748d18ee2471fbac3fd7d160f69898dae6a09eec7a7f4b4a08fad27b18dd24ee8aa0f09132a49ada1f79711a6aa47ef89976f89295901c3e7a08c36b0e270389274701eb72c14e6f133b5cb67da6fedea15de2b01f029317631a044a5289bb022d00322937eb08d807dda53af1556d726822812fe086034cb46caa0ca520bc929e951cd810688d0b158a7c68a59f03c6bb6be3c115318d5cf395048a0c12def2e1f4c7c18c8196bf3702551c4484e96c8b5d16ea2450814ff82a071d6a07e3ac0b2750caa49806732ef191f4da8984fff63b319661a227f9a3d70dfab0ea0babbdbb594787b8c2113aff111ce877c08d5f51d6e756011c6d1806443f4ad76a018df140a6a9b37d5ef8941d8c86d64dccf4b49e58dd3225e23609cbab08ab79380", - "0xf90211a086bf52710afcd2700a8ac004ad4e807ca19d121a7fdb176ef6e78e99883d8c98a02ee483c5b2247cb2efbd5707d6a07464a68001d504b2b5654a445fff797e3423a095eea97d3cda5e51a1ab7b893e4e6f7ccc04de42fed08abe77edcf03555398daa05749a38c2cf14a4cf9cbe871ff0811228b118f630accac9a3f604222aa7c0ef6a0d3bdf4bdb66089dc189b9bf82b776c2a3668d4384d06905c8bd791bf4c72af6ba0b8e9197e6f7af9a453becc14cc4560eb3303b2a7b37a891e17cf616c72375e1ea0ddd1978cd1d25b56b79d4b02b79a62213ba5543ce9c7e780413f6c3ddfa31d4ca0a7b0a5ddc2c1d9e11c1eea555e675ac9d0c20ec40bb0aec93135882bf62371dda0f650fd573502736794b0d89f439993d2dc2d89cceba63f340862f7161458196da08be8c24b784d4855ceda55a14cfe51051ed8d43189ffb3f269bb9a1198fc0569a02a391927d73573ece103b28acd362963c1104cd3b1b7b15c1a3a2b1ae23557dea099282a0d5e614995a69a2af9a2003ff1d8e2524aa5b50f5410472870bb58544ea062e61a8a36c91393105408e40d3f366ba6846bfe7909561e48e98bf2d32d72e7a0db10dd5708609524e2ccb0d71e8399104f38c241cf46ce1a1ae2f2f37b0b6c7fa00baf8bac1c11975ab89e41bb39d6b5c8d0fad8e0c0309c1772ba7be21233f7b7a0090c055ebe2c59fa8987e463dfa02b32fd23af5515b905d06bf6cf085017603780", - "0xf9013180a05f7038c3369fc31c1e766a5e05e0543bf703c98f1ddf291d4bf27be5e507ebe9a066dda60d688836440899c388b515292f7b2650ced947c81ae258204e85ec380ba02f6fccd0878d14a3ad6d44961bf231a7682a6a7ecc330bdaec614a2b4036bc8780808080a077cd1159e6b8f5b306aad4e1205c6c2fd54f4ee1ef5bf38da967b46eefdd300380a01e6260c6dd72b75f33da633db3d99f3f4819ac119fb70eb3f89f45c9fa961a1680a048d18abd89f2c72c8bca25eeede5e039445600f0b5b5150e3d38d49787be0016a0f5d4d3b98133bd8f6568cb10fb9d685af0d9ab99f8511deb050640b8ae0e70cda0da17c6a820b6820442677ff9c7cbd59b8c39b045503fbfa28a03da35607ea5b5a0daf8438f80c877c9e2eda2f5b04d0a1552c3d8f2712796818b4057e276236fd380", - "0xf85180a0bfc629e3a6ea15f467eed2d0c2ce291e31aa2b54ba42851cac12bbe2beb91fc0a00f2796f10e3760a8256210f099bcbc53b16aef1c9434e4770157a20693483b878080808080808080808080808080", - "0xf8719d20df2eb10d4a4b0204d872b17392b090703a348cc89fc4ffaddaa814d4b851f84f82c7cf8907eb6df9c77d2a97aca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" - ], - "storage_proof": [] - } - ] - ], - "transaction_count": [], - "balance": [], - "code": [ - [ - { - "block_no": 5702743, - "address": "0x3c31cdb4d84ca36f17a4a3215b1a56d2569daed8" - }, - "0x6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60306044565b604051603b9190605f565b60405180910390f35b5f5481565b5f819050919050565b6059816049565b82525050565b5f60208201905060705f8301846052565b9291505056fea2646970667358221220bc3172233e9f6e16a098b28fa0d2b1096f46372dd3707bb06f9280cc2169d54464736f6c63430008190033" - ], - [ - { - "block_no": 5702743, - "address": "0x44b48fd72becefe030c1b62fadbfe6a7b3465d19" - }, - "0x6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60306044565b604051603b9190605f565b60405180910390f35b5f5481565b5f819050919050565b6059816049565b82525050565b5f60208201905060705f8301846052565b9291505056fea2646970667358221220bc3172233e9f6e16a098b28fa0d2b1096f46372dd3707bb06f9280cc2169d54464736f6c63430008190033" - ], - [ - { - "block_no": 5702743, - "address": "0xc5096d96dbc7594b3d0ba50e708ba654a7ae1f3e" - }, - "0x608060405234801561000f575f80fd5b506004361061007b575f3560e01c8063445bda4311610059578063445bda43146100d95780637d732b5f146100f75780639f6f32aa14610115578063ab8fd80c146101335761007b565b80630692d13c1461007f57806330e496631461009d57806341317185146100bb575b5f80fd5b610087610151565b6040516100949190610400565b60405180910390f35b6100a5610159565b6040516100b29190610400565b60405180910390f35b6100c3610160565b6040516100d09190610400565b60405180910390f35b6100e161016d565b6040516100ee9190610400565b60405180910390f35b6100ff61032e565b60405161010c9190610400565b60405180910390f35b61011d610335565b60405161012a9190610431565b60405180910390f35b61013b6103c2565b6040516101489190610431565b60405180910390f35b5f803b905090565b5f3a905090565b5f80449050803b91505090565b5f7f000000000000000000000000f9617c4744c85c04f85d40e4eb119ac52740f9a573ffffffffffffffffffffffffffffffffffffffff16633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101fb9190610478565b7f00000000000000000000000044b48fd72becefe030c1b62fadbfe6a7b3465d1973ffffffffffffffffffffffffffffffffffffffff16633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610264573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102889190610478565b7f0000000000000000000000003c31cdb4d84ca36f17a4a3215b1a56d2569daed873ffffffffffffffffffffffffffffffffffffffff16633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102f1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103159190610478565b61031f91906104d0565b61032991906104d0565b905090565b5f46905090565b5f805f600273ffffffffffffffffffffffffffffffffffffffff1660405161035c90610530565b5f60405180830381855afa9150503d805f8114610394576040519150601f19603f3d011682016040523d82523d5f602084013e610399565b606091505b5091509150816103a7575f80fd5b808060200190518101906103bb919061056e565b9250505090565b5f60024310156103d5576103d4610599565b5b6002436103e291906105c6565b40905090565b5f819050919050565b6103fa816103e8565b82525050565b5f6020820190506104135f8301846103f1565b92915050565b5f819050919050565b61042b81610419565b82525050565b5f6020820190506104445f830184610422565b92915050565b5f80fd5b610457816103e8565b8114610461575f80fd5b50565b5f815190506104728161044e565b92915050565b5f6020828403121561048d5761048c61044a565b5b5f61049a84828501610464565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6104da826103e8565b91506104e5836103e8565b92508282019050808211156104fd576104fc6104a3565b5b92915050565b5f81905092915050565b50565b5f61051b5f83610503565b91506105268261050d565b5f82019050919050565b5f61053a82610510565b9150819050919050565b61054d81610419565b8114610557575f80fd5b50565b5f8151905061056881610544565b92915050565b5f602082840312156105835761058261044a565b5b5f6105908482850161055a565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b5f6105d0826103e8565b91506105db836103e8565b92508282039050818111156105f3576105f26104a3565b5b9291505056fea26469706673582212202195be41f1a71d266f38ec6f3b39402e1d470a67710c55a003b55562a9f9a56964736f6c63430008190033" - ], - [ - { - "block_no": 5702743, - "address": "0xf9617c4744c85c04f85d40e4eb119ac52740f9a5" - }, - "0x6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60306044565b604051603b9190605f565b60405180910390f35b5f5481565b5f819050919050565b6059816049565b82525050565b5f60208201905060705f8301846052565b9291505056fea2646970667358221220bc3172233e9f6e16a098b28fa0d2b1096f46372dd3707bb06f9280cc2169d54464736f6c63430008190033" - ], - [ - { - "block_no": 19493153, - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6" - }, - "0x608060405234801561001057600080fd5b50600436106101ae5760003560e01c806370cf754a116100ee578063c45a015511610097578063ddca3f4311610071578063ddca3f4314610800578063f305839914610820578063f30dba9314610828578063f637731d146108aa576101ae565b8063c45a0155146107d1578063d0c93a7c146107d9578063d21220a7146107f8576101ae565b8063883bdbfd116100c8578063883bdbfd14610633578063a34123a71461073c578063a38807f214610776576101ae565b806370cf754a146105c65780638206a4d1146105ce57806385b66729146105f6576101ae565b80633850c7bd1161015b578063490e6cbc11610135578063490e6cbc146104705780634f1eb3d8146104fc578063514ea4bf1461054d5780635339c296146105a6576101ae565b80633850c7bd1461035b5780633c8a7d8d146103b45780634614131914610456576101ae565b80631ad8b03b1161018c5780631ad8b03b146102aa578063252c09d7146102e157806332148f6714610338576101ae565b80630dfe1681146101b3578063128acb08146101d75780631a68650214610286575b600080fd5b6101bb6108d0565b604080516001600160a01b039092168252519081900360200190f35b61026d600480360360a08110156101ed57600080fd5b6001600160a01b0382358116926020810135151592604082013592606083013516919081019060a08101608082013564010000000081111561022e57600080fd5b82018360208201111561024057600080fd5b8035906020019184600183028401116401000000008311171561026257600080fd5b5090925090506108f4565b6040805192835260208301919091528051918290030190f35b61028e6114ad565b604080516001600160801b039092168252519081900360200190f35b6102b26114bc565b60405180836001600160801b03168152602001826001600160801b031681526020019250505060405180910390f35b6102fe600480360360208110156102f757600080fd5b50356114d6565b6040805163ffffffff909516855260069390930b60208501526001600160a01b039091168383015215156060830152519081900360800190f35b6103596004803603602081101561034e57600080fd5b503561ffff1661151c565b005b610363611616565b604080516001600160a01b03909816885260029690960b602088015261ffff9485168787015292841660608701529216608085015260ff90911660a0840152151560c0830152519081900360e00190f35b61026d600480360360a08110156103ca57600080fd5b6001600160a01b03823516916020810135600290810b92604083013590910b916001600160801b036060820135169181019060a08101608082013564010000000081111561041757600080fd5b82018360208201111561042957600080fd5b8035906020019184600183028401116401000000008311171561044b57600080fd5b509092509050611666565b61045e611922565b60408051918252519081900360200190f35b6103596004803603608081101561048657600080fd5b6001600160a01b0382351691602081013591604082013591908101906080810160608201356401000000008111156104bd57600080fd5b8201836020820111156104cf57600080fd5b803590602001918460018302840111640100000000831117156104f157600080fd5b509092509050611928565b6102b2600480360360a081101561051257600080fd5b506001600160a01b03813516906020810135600290810b91604081013590910b906001600160801b0360608201358116916080013516611d83565b61056a6004803603602081101561056357600080fd5b5035611f9d565b604080516001600160801b0396871681526020810195909552848101939093529084166060840152909216608082015290519081900360a00190f35b61045e600480360360208110156105bc57600080fd5b503560010b611fda565b61028e611fec565b610359600480360360408110156105e457600080fd5b5060ff81358116916020013516612010565b6102b26004803603606081101561060c57600080fd5b506001600160a01b03813516906001600160801b036020820135811691604001351661220f565b6106a36004803603602081101561064957600080fd5b81019060208101813564010000000081111561066457600080fd5b82018360208201111561067657600080fd5b8035906020019184602083028401116401000000008311171561069857600080fd5b5090925090506124dc565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156106e75781810151838201526020016106cf565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561072657818101518382015260200161070e565b5050505090500194505050505060405180910390f35b61026d6004803603606081101561075257600080fd5b508035600290810b91602081013590910b90604001356001600160801b0316612569565b6107a06004803603604081101561078c57600080fd5b508035600290810b9160200135900b6126e0565b6040805160069490940b84526001600160a01b03909216602084015263ffffffff1682820152519081900360600190f35b6101bb6128d7565b6107e16128fb565b6040805160029290920b8252519081900360200190f35b6101bb61291f565b610808612943565b6040805162ffffff9092168252519081900360200190f35b61045e612967565b6108486004803603602081101561083e57600080fd5b503560020b61296d565b604080516001600160801b039099168952600f9790970b602089015287870195909552606087019390935260069190910b60808601526001600160a01b031660a085015263ffffffff1660c0840152151560e083015251908190036101000190f35b610359600480360360208110156108c057600080fd5b50356001600160a01b03166129db565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6000806108ff612bf0565b85610936576040805162461bcd60e51b8152602060048201526002602482015261415360f01b604482015290519081900360640190fd5b6040805160e0810182526000546001600160a01b0381168252600160a01b8104600290810b810b900b602083015261ffff600160b81b8204811693830193909352600160c81b810483166060830152600160d81b8104909216608082015260ff600160e81b8304811660a0830152600160f01b909204909116151560c082018190526109ef576040805162461bcd60e51b81526020600482015260036024820152624c4f4b60e81b604482015290519081900360640190fd5b87610a3a5780600001516001600160a01b0316866001600160a01b0316118015610a35575073fffd8963efd1fc6a506488495d951d5263988d266001600160a01b038716105b610a6c565b80600001516001600160a01b0316866001600160a01b0316108015610a6c57506401000276a36001600160a01b038716115b610aa3576040805162461bcd60e51b815260206004820152600360248201526214d41360ea1b604482015290519081900360640190fd5b6000805460ff60f01b191681556040805160c08101909152808a610ad25760048460a0015160ff16901c610ae5565b60108460a0015160ff1681610ae357fe5b065b60ff1681526004546001600160801b03166020820152604001610b06612c27565b63ffffffff168152602001600060060b815260200160006001600160a01b031681526020016000151581525090506000808913905060006040518060e001604052808b81526020016000815260200185600001516001600160a01b03168152602001856020015160020b81526020018c610b8257600254610b86565b6001545b815260200160006001600160801b0316815260200184602001516001600160801b031681525090505b805115801590610bd55750886001600160a01b031681604001516001600160a01b031614155b15610f9f57610be261560e565b60408201516001600160a01b031681526060820151610c25906006907f000000000000000000000000000000000000000000000000000000000000000a8f612c2b565b15156040830152600290810b810b60208301819052620d89e719910b1215610c5657620d89e7196020820152610c75565b6020810151620d89e860029190910b1315610c7557620d89e860208201525b610c828160200151612d6d565b6001600160a01b031660608201526040820151610d13908d610cbc578b6001600160a01b031683606001516001600160a01b031611610cd6565b8b6001600160a01b031683606001516001600160a01b0316105b610ce4578260600151610ce6565b8b5b60c085015185517f00000000000000000000000000000000000000000000000000000000000001f461309f565b60c085015260a084015260808301526001600160a01b031660408301528215610d7557610d498160c00151826080015101613291565b825103825260a0810151610d6b90610d6090613291565b6020840151906132a7565b6020830152610db0565b610d828160a00151613291565b825101825260c08101516080820151610daa91610d9f9101613291565b6020840151906132c3565b60208301525b835160ff1615610df6576000846000015160ff168260c0015181610dd057fe5b60c0840180519290910491829003905260a0840180519091016001600160801b03169052505b60c08201516001600160801b031615610e3557610e298160c00151600160801b8460c001516001600160801b03166132d9565b60808301805190910190525b80606001516001600160a01b031682604001516001600160a01b03161415610f5e57806040015115610f35578360a00151610ebf57610e9d846040015160008760200151886040015188602001518a606001516008613389909695949392919063ffffffff16565b6001600160a01b03166080860152600690810b900b6060850152600160a08501525b6000610f0b82602001518e610ed657600154610edc565b84608001515b8f610eeb578560800151610eef565b6002545b608089015160608a015160408b0151600595949392919061351c565b90508c15610f17576000035b610f258360c00151826135ef565b6001600160801b031660c0840152505b8b610f44578060200151610f4d565b60018160200151035b600290810b900b6060830152610f99565b80600001516001600160a01b031682604001516001600160a01b031614610f9957610f8c82604001516136a5565b600290810b900b60608301525b50610baf565b836020015160020b816060015160020b1461107a57600080610fed86604001518660400151886020015188602001518a606001518b6080015160086139d1909695949392919063ffffffff16565b604085015160608601516000805461ffff60c81b1916600160c81b61ffff958616021761ffff60b81b1916600160b81b95909416949094029290921762ffffff60a01b1916600160a01b62ffffff60029490940b93909316929092029190911773ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116179055506110ac9050565b60408101516000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039092169190911790555b8060c001516001600160801b031683602001516001600160801b0316146110f25760c0810151600480546001600160801b0319166001600160801b039092169190911790555b8a1561114257608081015160015560a08101516001600160801b03161561113d5760a0810151600380546001600160801b031981166001600160801b03918216909301169190911790555b611188565b608081015160025560a08101516001600160801b0316156111885760a0810151600380546001600160801b03808216600160801b92839004821690940116029190911790555b8115158b1515146111a157602081015181518b036111ae565b80600001518a0381602001515b90965094508a156112e75760008512156111f0576111f07f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec78d87600003613b86565b60006111fa613cd4565b9050336001600160a01b031663fa461e3388888c8c6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561127e57600080fd5b505af1158015611292573d6000803e3d6000fd5b5050505061129e613cd4565b6112a88289613e0d565b11156112e1576040805162461bcd60e51b815260206004820152600360248201526249494160e81b604482015290519081900360640190fd5b50611411565b600086121561131e5761131e7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28d88600003613b86565b6000611328613e1d565b9050336001600160a01b031663fa461e3388888c8c6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156113ac57600080fd5b505af11580156113c0573d6000803e3d6000fd5b505050506113cc613e1d565b6113d68288613e0d565b111561140f576040805162461bcd60e51b815260206004820152600360248201526249494160e81b604482015290519081900360640190fd5b505b60408082015160c083015160608085015184518b8152602081018b90526001600160a01b03948516818701526001600160801b039093169183019190915260020b60808201529151908e169133917fc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca679181900360a00190a350506000805460ff60f01b1916600160f01b17905550919890975095505050505050565b6004546001600160801b031681565b6003546001600160801b0380821691600160801b90041682565b60088161ffff81106114e757600080fd5b015463ffffffff81169150640100000000810460060b90600160581b81046001600160a01b031690600160f81b900460ff1684565b600054600160f01b900460ff16611560576040805162461bcd60e51b81526020600482015260036024820152624c4f4b60e81b604482015290519081900360640190fd5b6000805460ff60f01b19169055611575612bf0565b60008054600160d81b900461ffff169061159160088385613eb5565b6000805461ffff808416600160d81b810261ffff60d81b19909316929092179092559192508316146115fe576040805161ffff80851682528316602082015281517fac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a929181900390910190a15b50506000805460ff60f01b1916600160f01b17905550565b6000546001600160a01b03811690600160a01b810460020b9061ffff600160b81b8204811691600160c81b8104821691600160d81b8204169060ff600160e81b8204811691600160f01b90041687565b600080548190600160f01b900460ff166116ad576040805162461bcd60e51b81526020600482015260036024820152624c4f4b60e81b604482015290519081900360640190fd5b6000805460ff60f01b191690556001600160801b0385166116cd57600080fd5b60008061171b60405180608001604052808c6001600160a01b031681526020018b60020b81526020018a60020b81526020016117118a6001600160801b0316613f58565b600f0b9052613f69565b9250925050819350809250600080600086111561173d5761173a613cd4565b91505b841561174e5761174b613e1d565b90505b336001600160a01b031663d348799787878b8b6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b1580156117d057600080fd5b505af11580156117e4573d6000803e3d6000fd5b50505050600086111561183b576117f9613cd4565b6118038388613e0d565b111561183b576040805162461bcd60e51b815260206004820152600260248201526104d360f41b604482015290519081900360640190fd5b841561188b57611849613e1d565b6118538287613e0d565b111561188b576040805162461bcd60e51b81526020600482015260026024820152614d3160f01b604482015290519081900360640190fd5b8960020b8b60020b8d6001600160a01b03167f7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde338d8b8b60405180856001600160a01b03168152602001846001600160801b0316815260200183815260200182815260200194505050505060405180910390a450506000805460ff60f01b1916600160f01b17905550919890975095505050505050565b60025481565b600054600160f01b900460ff1661196c576040805162461bcd60e51b81526020600482015260036024820152624c4f4b60e81b604482015290519081900360640190fd5b6000805460ff60f01b19169055611981612bf0565b6004546001600160801b0316806119c3576040805162461bcd60e51b81526020600482015260016024820152601360fa1b604482015290519081900360640190fd5b60006119f8867f00000000000000000000000000000000000000000000000000000000000001f462ffffff16620f42406141a9565b90506000611a2f867f00000000000000000000000000000000000000000000000000000000000001f462ffffff16620f42406141a9565b90506000611a3b613cd4565b90506000611a47613e1d565b90508815611a7a57611a7a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28b8b613b86565b8715611aab57611aab7f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec78b8a613b86565b336001600160a01b031663e9cbafb085858a8a6040518563ffffffff1660e01b815260040180858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b158015611b2d57600080fd5b505af1158015611b41573d6000803e3d6000fd5b505050506000611b4f613cd4565b90506000611b5b613e1d565b905081611b688588613e0d565b1115611ba0576040805162461bcd60e51b8152602060048201526002602482015261046360f41b604482015290519081900360640190fd5b80611bab8487613e0d565b1115611be3576040805162461bcd60e51b8152602060048201526002602482015261463160f01b604482015290519081900360640190fd5b8382038382038115611c725760008054600160e81b9004600f16908115611c16578160ff168481611c1057fe5b04611c19565b60005b90506001600160801b03811615611c4c57600380546001600160801b038082168401166001600160801b03199091161790555b611c66818503600160801b8d6001600160801b03166132d9565b60018054909101905550505b8015611cfd5760008054600160e81b900460041c600f16908115611ca2578160ff168381611c9c57fe5b04611ca5565b60005b90506001600160801b03811615611cd757600380546001600160801b03600160801b8083048216850182160291161790555b611cf1818403600160801b8d6001600160801b03166132d9565b60028054909101905550505b8d6001600160a01b0316336001600160a01b03167fbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca6338f8f86866040518085815260200184815260200183815260200182815260200194505050505060405180910390a350506000805460ff60f01b1916600160f01b179055505050505050505050505050565b600080548190600160f01b900460ff16611dca576040805162461bcd60e51b81526020600482015260036024820152624c4f4b60e81b604482015290519081900360640190fd5b6000805460ff60f01b19168155611de460073389896141e3565b60038101549091506001600160801b0390811690861611611e055784611e14565b60038101546001600160801b03165b60038201549093506001600160801b03600160801b909104811690851611611e3c5783611e52565b6003810154600160801b90046001600160801b03165b91506001600160801b03831615611eb7576003810180546001600160801b031981166001600160801b03918216869003821617909155611eb7907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2908a908616613b86565b6001600160801b03821615611f1d576003810180546001600160801b03600160801b808304821686900382160291811691909117909155611f1d907f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7908a908516613b86565b604080516001600160a01b038a1681526001600160801b0380861660208301528416818301529051600288810b92908a900b9133917f70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0919081900360600190a4506000805460ff60f01b1916600160f01b17905590969095509350505050565b60076020526000908152604090208054600182015460028301546003909301546001600160801b0392831693919281811691600160801b90041685565b60066020526000908152604090205481565b7f0000000000000000000000000000000000005e8b2285f864419ac400be90719681565b600054600160f01b900460ff16612054576040805162461bcd60e51b81526020600482015260036024820152624c4f4b60e81b604482015290519081900360640190fd5b6000805460ff60f01b1916905560408051638da5cb5b60e01b815290516001600160a01b037f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f9841691638da5cb5b916004808301926020929190829003018186803b1580156120c157600080fd5b505afa1580156120d5573d6000803e3d6000fd5b505050506040513d60208110156120eb57600080fd5b50516001600160a01b0316331461210157600080fd5b60ff82161580612124575060048260ff16101580156121245750600a8260ff1611155b801561214e575060ff8116158061214e575060048160ff161015801561214e5750600a8160ff1611155b61215757600080fd5b60008054610ff0600484901b16840160ff908116600160e81b9081027fffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841617909355919004167f973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b1336010826040805160ff9390920683168252600f600486901c16602083015286831682820152918516606082015290519081900360800190a150506000805460ff60f01b1916600160f01b17905550565b600080548190600160f01b900460ff16612256576040805162461bcd60e51b81526020600482015260036024820152624c4f4b60e81b604482015290519081900360640190fd5b6000805460ff60f01b1916905560408051638da5cb5b60e01b815290516001600160a01b037f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f9841691638da5cb5b916004808301926020929190829003018186803b1580156122c357600080fd5b505afa1580156122d7573d6000803e3d6000fd5b505050506040513d60208110156122ed57600080fd5b50516001600160a01b0316331461230357600080fd5b6003546001600160801b039081169085161161231f578361232c565b6003546001600160801b03165b6003549092506001600160801b03600160801b9091048116908416116123525782612366565b600354600160801b90046001600160801b03165b90506001600160801b038216156123e7576003546001600160801b038381169116141561239557600019909101905b600380546001600160801b031981166001600160801b039182168590038216179091556123e7907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc29087908516613b86565b6001600160801b0381161561246d576003546001600160801b03828116600160801b90920416141561241857600019015b600380546001600160801b03600160801b80830482168590038216029181169190911790915561246d907f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec79087908416613b86565b604080516001600160801b0380851682528316602082015281516001600160a01b0388169233927f596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151929081900390910190a36000805460ff60f01b1916600160f01b1790559094909350915050565b6060806124e7612bf0565b61255e6124f2612c27565b858580806020026020016040519081016040528093929190818152602001838360200280828437600092018290525054600454600896959450600160a01b820460020b935061ffff600160b81b8304811693506001600160801b0390911691600160c81b900416614247565b915091509250929050565b600080548190600160f01b900460ff166125b0576040805162461bcd60e51b81526020600482015260036024820152624c4f4b60e81b604482015290519081900360640190fd5b6000805460ff60f01b1916815560408051608081018252338152600288810b602083015287900b918101919091528190819061260990606081016125fc6001600160801b038a16613f58565b600003600f0b9052613f69565b925092509250816000039450806000039350600085118061262a5750600084115b15612669576003830180546001600160801b038082168089018216600160801b93849004831689019092169092029091176001600160801b0319161790555b604080516001600160801b0388168152602081018790528082018690529051600289810b92908b900b9133917f0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c919081900360600190a450506000805460ff60f01b1916600160f01b179055509094909350915050565b60008060006126ed612bf0565b6126f785856143a1565b600285810b810b60009081526005602052604080822087840b90930b825281206003830154600681900b9367010000000000000082046001600160a01b0316928492600160d81b810463ffffffff169284929091600160f81b900460ff168061275f57600080fd5b6003820154600681900b985067010000000000000081046001600160a01b03169650600160d81b810463ffffffff169450600160f81b900460ff16806127a457600080fd5b50506040805160e0810182526000546001600160a01b0381168252600160a01b8104600290810b810b810b6020840181905261ffff600160b81b8404811695850195909552600160c81b830485166060850152600160d81b8304909416608084015260ff600160e81b8304811660a0850152600160f01b909204909116151560c08301529093508e810b91900b1215905061284d575093909403965090039350900390506128d0565b8a60020b816020015160020b12156128c1576000612869612c27565b602083015160408401516004546060860151939450600093849361289f936008938893879392916001600160801b031690613389565b9a9003989098039b5050949096039290920396509091030392506128d0915050565b50949093039650039350900390505b9250925092565b7f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f98481565b7f000000000000000000000000000000000000000000000000000000000000000a81565b7f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec781565b7f00000000000000000000000000000000000000000000000000000000000001f481565b60015481565b60056020526000908152604090208054600182015460028301546003909301546001600160801b03831693600160801b909304600f0b9290600681900b9067010000000000000081046001600160a01b031690600160d81b810463ffffffff1690600160f81b900460ff1688565b6000546001600160a01b031615612a1e576040805162461bcd60e51b8152602060048201526002602482015261414960f01b604482015290519081900360640190fd5b6000612a29826136a5565b9050600080612a41612a39612c27565b60089061446a565b6040805160e0810182526001600160a01b038816808252600288810b6020808501829052600085870181905261ffff898116606088018190529089166080880181905260a08801839052600160c0909801979097528154600160f01b73ffffffffffffffffffffffffffffffffffffffff19909116871762ffffff60a01b1916600160a01b62ffffff9787900b9790971696909602959095177fffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffff16600160c81b9091021761ffff60d81b1916600160d81b909602959095177fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1692909217909355835191825281019190915281519395509193507f98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c9592918290030190a150505050565b60008082600281900b620d89e71981612b9957fe5b05029050600083600281900b620d89e881612bb057fe5b0502905060008460020b83830360020b81612bc757fe5b0560010190508062ffffff166001600160801b03801681612be457fe5b0493505050505b919050565b306001600160a01b037f00000000000000000000000011b815efb8f581194ae79006d24e0d814b7697f61614612c2557600080fd5b565b4290565b60008060008460020b8660020b81612c3f57fe5b05905060008660020b128015612c6657508460020b8660020b81612c5f57fe5b0760020b15155b15612c7057600019015b8315612ce557600080612c82836144b6565b600182810b810b600090815260208d9052604090205460ff83169190911b80016000190190811680151597509294509092509085612cc757888360ff16860302612cda565b88612cd1826144c8565b840360ff168603025b965050505050612d63565b600080612cf4836001016144b6565b91509150600060018260ff166001901b031990506000818b60008660010b60010b8152602001908152602001600020541690508060001415955085612d4657888360ff0360ff16866001010102612d5c565b8883612d5183614568565b0360ff168660010101025b9650505050505b5094509492505050565b60008060008360020b12612d84578260020b612d8c565b8260020b6000035b9050620d89e8811115612dca576040805162461bcd60e51b81526020600482015260016024820152601560fa1b604482015290519081900360640190fd5b600060018216612dde57600160801b612df0565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615612e24576ffff97272373d413259a46990580e213a0260801c5b6004821615612e43576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b6008821615612e62576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b6010821615612e81576fffcb9843d60f6159c9db58835c9266440260801c5b6020821615612ea0576fff973b41fa98c081472e6896dfb254c00260801c5b6040821615612ebf576fff2ea16466c96a3843ec78b326b528610260801c5b6080821615612ede576ffe5dee046a99a2a811c461f1969c30530260801c5b610100821615612efe576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610200821615612f1e576ff987a7253ac413176f2b074cf7815e540260801c5b610400821615612f3e576ff3392b0822b70005940c7a398e4b70f30260801c5b610800821615612f5e576fe7159475a2c29b7443b29c7fa6e889d90260801c5b611000821615612f7e576fd097f3bdfd2022b8845ad8f792aa58250260801c5b612000821615612f9e576fa9f746462d870fdf8a65dc1f90e061e50260801c5b614000821615612fbe576f70d869a156d2a1b890bb3df62baf32f70260801c5b618000821615612fde576f31be135f97d08fd981231505542fcfa60260801c5b62010000821615612fff576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b6202000082161561301f576e5d6af8dedb81196699c329225ee6040260801c5b6204000082161561303e576d2216e584f5fa1ea926041bedfe980260801c5b6208000082161561305b576b048a170391f7dc42444e8fa20260801c5b60008460020b131561307657806000198161307257fe5b0490505b64010000000081061561308a57600161308d565b60005b60ff16602082901c0192505050919050565b60008080806001600160a01b03808916908a1610158187128015906131245760006130d88989620f42400362ffffff16620f42406132d9565b9050826130f1576130ec8c8c8c6001614652565b6130fe565b6130fe8b8d8c60016146cd565b955085811061310f578a965061311e565b61311b8c8b838661478a565b96505b5061316e565b8161313b576131368b8b8b60006146cd565b613148565b6131488a8c8b6000614652565b935083886000031061315c5789955061316e565b61316b8b8a8a600003856147d6565b95505b6001600160a01b038a81169087161482156131d15780801561318d5750815b6131a35761319e878d8c60016146cd565b6131a5565b855b95508080156131b2575081155b6131c8576131c3878d8c6000614652565b6131ca565b845b945061321b565b8080156131db5750815b6131f1576131ec8c888c6001614652565b6131f3565b855b9550808015613200575081155b613216576132118c888c60006146cd565b613218565b845b94505b8115801561322b57508860000385115b15613237578860000394505b81801561325657508a6001600160a01b0316876001600160a01b031614155b15613265578589039350613282565b61327f868962ffffff168a620f42400362ffffff166141a9565b93505b50505095509550955095915050565b6000600160ff1b82106132a357600080fd5b5090565b808203828113156000831215146132bd57600080fd5b92915050565b818101828112156000831215146132bd57600080fd5b600080806000198587098686029250828110908390030390508061330f576000841161330457600080fd5b508290049050613382565b80841161331b57600080fd5b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150505b9392505050565b60008063ffffffff8716613430576000898661ffff1661ffff81106133aa57fe5b60408051608081018252919092015463ffffffff8082168084526401000000008304600690810b810b900b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff16151560608301529092508a161461341c57613419818a8988614822565b90505b806020015181604001519250925050613510565b8688036000806134458c8c858c8c8c8c6148d2565b91509150816000015163ffffffff168363ffffffff161415613477578160200151826040015194509450505050613510565b805163ffffffff8481169116141561349f578060200151816040015194509450505050613510565b8151815160208085015190840151918390039286039163ffffffff80841692908516910360060b816134cd57fe5b05028460200151018263ffffffff168263ffffffff1686604001518660400151036001600160a01b031602816134ff57fe5b048560400151019650965050505050505b97509795505050505050565b600295860b860b60009081526020979097526040909620600181018054909503909455938301805490920390915560038201805463ffffffff600160d81b6001600160a01b036701000000000000008085048216909603169094027fffffffffff0000000000000000000000000000000000000000ffffffffffffff90921691909117600681810b90960390950b66ffffffffffffff1666ffffffffffffff199095169490941782810485169095039093160263ffffffff60d81b1990931692909217905554600160801b9004600f0b90565b60008082600f0b121561365457826001600160801b03168260000384039150816001600160801b03161061364f576040805162461bcd60e51b81526020600482015260026024820152614c5360f01b604482015290519081900360640190fd5b6132bd565b826001600160801b03168284019150816001600160801b031610156132bd576040805162461bcd60e51b81526020600482015260026024820152614c4160f01b604482015290519081900360640190fd5b60006401000276a36001600160a01b038316108015906136e1575073fffd8963efd1fc6a506488495d951d5263988d266001600160a01b038316105b613716576040805162461bcd60e51b81526020600482015260016024820152602960f91b604482015290519081900360640190fd5b77ffffffffffffffffffffffffffffffffffffffff00000000602083901b166001600160801b03811160071b81811c67ffffffffffffffff811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211600190811b92831c979088119617909417909217179091171717608081106137b757607f810383901c91506137c1565b80607f0383901b91505b908002607f81811c60ff83811c9190911c800280831c81831c1c800280841c81841c1c800280851c81851c1c800280861c81861c1c800280871c81871c1c800280881c81881c1c800280891c81891c1c8002808a1c818a1c1c8002808b1c818b1c1c8002808c1c818c1c1c8002808d1c818d1c1c8002808e1c9c81901c9c909c1c80029c8d901c9e9d607f198f0160401b60c09190911c678000000000000000161760c19b909b1c674000000000000000169a909a1760c29990991c672000000000000000169890981760c39790971c671000000000000000169690961760c49590951c670800000000000000169490941760c59390931c670400000000000000169290921760c69190911c670200000000000000161760c79190911c670100000000000000161760c89190911c6680000000000000161760c99190911c6640000000000000161760ca9190911c6620000000000000161760cb9190911c6610000000000000161760cc9190911c6608000000000000161760cd9190911c66040000000000001617693627a301d71055774c8581026f028f6481ab7f045a5af012a19d003aa9198101608090811d906fdb2df09e81959a81455e260799a0632f8301901d600281810b9083900b146139c257886001600160a01b03166139a682612d6d565b6001600160a01b031611156139bb57816139bd565b805b6139c4565b815b9998505050505050505050565b6000806000898961ffff1661ffff81106139e757fe5b60408051608081018252919092015463ffffffff8082168084526401000000008304600690810b810b900b6020850152600160581b83046001600160a01b031694840194909452600160f81b90910460ff161515606083015290925089161415613a575788859250925050613510565b8461ffff168461ffff16118015613a7857506001850361ffff168961ffff16145b15613a8557839150613a89565b8491505b8161ffff168960010161ffff1681613a9d57fe5b069250613aac81898989614822565b8a8461ffff1661ffff8110613abd57fe5b825191018054602084015160408501516060909501511515600160f81b027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001600160a01b03909616600160581b027fff0000000000000000000000000000000000000000ffffffffffffffffffffff60069390930b66ffffffffffffff16640100000000026affffffffffffff000000001963ffffffff90971663ffffffff199095169490941795909516929092171692909217929092161790555097509795505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1781529251825160009485949389169392918291908083835b60208310613c025780518252601f199092019160209182019101613be3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613c64576040519150601f19603f3d011682016040523d82523d6000602084013e613c69565b606091505b5091509150818015613c97575080511580613c975750808060200190516020811015613c9457600080fd5b50515b613ccd576040805162461bcd60e51b81526020600482015260026024820152612a2360f11b604482015290519081900360640190fd5b5050505050565b604080513060248083019190915282518083039091018152604490910182526020810180516001600160e01b03166370a0823160e01b17815291518151600093849384936001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21693919290918291908083835b60208310613d6d5780518252601f199092019160209182019101613d4e565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114613dcd576040519150601f19603f3d011682016040523d82523d6000602084013e613dd2565b606091505b5091509150818015613de657506020815110155b613def57600080fd5b808060200190516020811015613e0457600080fd5b50519250505090565b808201828110156132bd57600080fd5b604080513060248083019190915282518083039091018152604490910182526020810180516001600160e01b03166370a0823160e01b17815291518151600093849384936001600160a01b037f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec716939192909182919080838360208310613d6d5780518252601f199092019160209182019101613d4e565b6000808361ffff1611613ef3576040805162461bcd60e51b81526020600482015260016024820152604960f81b604482015290519081900360640190fd5b8261ffff168261ffff1611613f09575081613382565b825b8261ffff168161ffff161015613f4f576001858261ffff1661ffff8110613f2e57fe5b01805463ffffffff191663ffffffff92909216919091179055600101613f0b565b50909392505050565b80600f81900b8114612beb57600080fd5b6000806000613f76612bf0565b613f88846020015185604001516143a1565b6040805160e0810182526000546001600160a01b0381168252600160a01b8104600290810b810b900b602080840182905261ffff600160b81b8404811685870152600160c81b84048116606080870191909152600160d81b8504909116608086015260ff600160e81b8504811660a0870152600160f01b909404909316151560c08501528851908901519489015192890151939461402c9491939092909190614acf565b93508460600151600f0b6000146141a157846020015160020b816020015160020b12156140815761407a6140638660200151612d6d565b6140708760400151612d6d565b8760600151614c84565b92506141a1565b846040015160020b816020015160020b12156141775760045460408201516001600160801b03909116906140d3906140b7612c27565b60208501516060860151608087015160089493929187916139d1565b6000805461ffff60c81b1916600160c81b61ffff938416021761ffff60b81b1916600160b81b939092169290920217905581516040870151614123919061411990612d6d565b8860600151614c84565b93506141416141358760200151612d6d565b83516060890151614cc8565b92506141518187606001516135ef565b600480546001600160801b0319166001600160801b0392909216919091179055506141a1565b61419e6141878660200151612d6d565b6141948760400151612d6d565b8760600151614cc8565b91505b509193909250565b60006141b68484846132d9565b9050600082806141c257fe5b84860911156133825760001981106141d957600080fd5b6001019392505050565b6040805160609490941b6bffffffffffffffffffffffff1916602080860191909152600293840b60e890811b60348701529290930b90911b60378401528051808403601a018152603a90930181528251928201929092206000908152929052902090565b60608060008361ffff1611614287576040805162461bcd60e51b81526020600482015260016024820152604960f81b604482015290519081900360640190fd5b865167ffffffffffffffff8111801561429f57600080fd5b506040519080825280602002602001820160405280156142c9578160200160208202803683370190505b509150865167ffffffffffffffff811180156142e457600080fd5b5060405190808252806020026020018201604052801561430e578160200160208202803683370190505b50905060005b87518110156143945761433f8a8a8a848151811061432e57fe5b60200260200101518a8a8a8a613389565b84838151811061434b57fe5b6020026020010184848151811061435e57fe5b60200260200101826001600160a01b03166001600160a01b03168152508260060b60060b81525050508080600101915050614314565b5097509795505050505050565b8060020b8260020b126143e1576040805162461bcd60e51b8152602060048201526003602482015262544c5560e81b604482015290519081900360640190fd5b620d89e719600283900b1215614424576040805162461bcd60e51b8152602060048201526003602482015262544c4d60e81b604482015290519081900360640190fd5b620d89e8600282900b1315614466576040805162461bcd60e51b815260206004820152600360248201526254554d60e81b604482015290519081900360640190fd5b5050565b6040805160808101825263ffffffff9283168082526000602083018190529282019290925260016060909101819052835463ffffffff1916909117909116600160f81b17909155908190565b60020b600881901d9161010090910790565b60008082116144d657600080fd5b600160801b82106144e957608091821c91015b68010000000000000000821061450157604091821c91015b640100000000821061451557602091821c91015b62010000821061452757601091821c91015b610100821061453857600891821c91015b6010821061454857600491821c91015b6004821061455857600291821c91015b60028210612beb57600101919050565b600080821161457657600080fd5b5060ff6001600160801b0382161561459157607f1901614599565b608082901c91505b67ffffffffffffffff8216156145b257603f19016145ba565b604082901c91505b63ffffffff8216156145cf57601f19016145d7565b602082901c91505b61ffff8216156145ea57600f19016145f2565b601082901c91505b60ff821615614604576007190161460c565b600882901c91505b600f82161561461e5760031901614626565b600482901c91505b60038216156146385760011901614640565b600282901c91505b6001821615612beb5760001901919050565b6000836001600160a01b0316856001600160a01b03161115614672579293925b8161469f5761469a836001600160801b03168686036001600160a01b0316600160601b6132d9565b6146c2565b6146c2836001600160801b03168686036001600160a01b0316600160601b6141a9565b90505b949350505050565b6000836001600160a01b0316856001600160a01b031611156146ed579293925b7bffffffffffffffffffffffffffffffff000000000000000000000000606084901b166001600160a01b03868603811690871661472957600080fd5b8361475957866001600160a01b031661474c8383896001600160a01b03166132d9565b8161475357fe5b0461477f565b61477f6147708383896001600160a01b03166141a9565b886001600160a01b0316614cf7565b979650505050505050565b600080856001600160a01b0316116147a157600080fd5b6000846001600160801b0316116147b757600080fd5b816147c95761469a8585856001614d02565b6146c28585856001614de3565b600080856001600160a01b0316116147ed57600080fd5b6000846001600160801b03161161480357600080fd5b816148155761469a8585856000614de3565b6146c28585856000614d02565b61482a61564a565b600085600001518503905060405180608001604052808663ffffffff1681526020018263ffffffff168660020b0288602001510160060b81526020016000856001600160801b03161161487e576001614880565b845b6001600160801b031673ffffffff00000000000000000000000000000000608085901b16816148ab57fe5b048860400151016001600160a01b0316815260200160011515815250915050949350505050565b6148da61564a565b6148e261564a565b888561ffff1661ffff81106148f357fe5b60408051608081018252919092015463ffffffff81168083526401000000008204600690810b810b900b6020840152600160581b82046001600160a01b031693830193909352600160f81b900460ff1615156060820152925061495890899089614ed8565b15614990578663ffffffff16826000015163ffffffff16141561497a57613510565b8161498783898988614822565b91509150613510565b888361ffff168660010161ffff16816149a557fe5b0661ffff1661ffff81106149b557fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b90910416151560608201819052909250614a6c57604080516080810182528a5463ffffffff811682526401000000008104600690810b810b900b6020830152600160581b81046001600160a01b031692820192909252600160f81b90910460ff161515606082015291505b614a7b88836000015189614ed8565b614ab2576040805162461bcd60e51b815260206004820152600360248201526213d31160ea1b604482015290519081900360640190fd5b614abf8989898887614f9b565b9150915097509795505050505050565b6000614ade60078787876141e3565b60015460025491925090600080600f87900b15614c24576000614aff612c27565b6000805460045492935090918291614b499160089186918591600160a01b810460020b9161ffff600160b81b83048116926001600160801b0390921691600160c81b900416613389565b9092509050614b8360058d8b8d8b8b87898b60007f0000000000000000000000000000000000005e8b2285f864419ac400be90719661513b565b9450614bba60058c8b8d8b8b87898b60017f0000000000000000000000000000000000005e8b2285f864419ac400be90719661513b565b93508415614bee57614bee60068d7f000000000000000000000000000000000000000000000000000000000000000a615325565b8315614c2057614c2060068c7f000000000000000000000000000000000000000000000000000000000000000a615325565b5050505b600080614c3660058c8c8b8a8a61538b565b9092509050614c47878a8484615437565b600089600f0b1215614c75578315614c6457614c6460058c6155cc565b8215614c7557614c7560058b6155cc565b50505050505095945050505050565b60008082600f0b12614caa57614ca5614ca085858560016146cd565b613291565b6146c5565b614cbd614ca085858560000360006146cd565b600003949350505050565b60008082600f0b12614ce457614ca5614ca08585856001614652565b614cbd614ca08585856000036000614652565b808204910615150190565b60008115614d755760006001600160a01b03841115614d3857614d3384600160601b876001600160801b03166132d9565b614d50565b6001600160801b038516606085901b81614d4e57fe5b045b9050614d6d614d686001600160a01b03881683613e0d565b6155f8565b9150506146c5565b60006001600160a01b03841115614da357614d9e84600160601b876001600160801b03166141a9565b614dba565b614dba606085901b6001600160801b038716614cf7565b905080866001600160a01b031611614dd157600080fd5b6001600160a01b0386160390506146c5565b600082614df15750836146c5565b7bffffffffffffffffffffffffffffffff000000000000000000000000606085901b168215614e91576001600160a01b03861684810290858281614e3157fe5b041415614e6257818101828110614e6057614e5683896001600160a01b0316836141a9565b93505050506146c5565b505b614e8882614e83878a6001600160a01b03168681614e7c57fe5b0490613e0d565b614cf7565b925050506146c5565b6001600160a01b03861684810290858281614ea857fe5b04148015614eb557508082115b614ebe57600080fd5b808203614e56614d68846001600160a01b038b16846141a9565b60008363ffffffff168363ffffffff1611158015614f0257508363ffffffff168263ffffffff1611155b15614f1e578163ffffffff168363ffffffff1611159050613382565b60008463ffffffff168463ffffffff1611614f46578363ffffffff1664010000000001614f4e565b8363ffffffff165b64ffffffffff16905060008563ffffffff168463ffffffff1611614f7f578363ffffffff1664010000000001614f87565b8363ffffffff165b64ffffffffff169091111595945050505050565b614fa361564a565b614fab61564a565b60008361ffff168560010161ffff1681614fc157fe5b0661ffff169050600060018561ffff16830103905060005b506002818301048961ffff87168281614fee57fe5b0661ffff8110614ffa57fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b9091041615156060820181905290955061506557806001019250614fd9565b898661ffff16826001018161507657fe5b0661ffff811061508257fe5b60408051608081018252929091015463ffffffff811683526401000000008104600690810b810b900b60208401526001600160a01b03600160581b8204169183019190915260ff600160f81b909104161515606082015285519094506000906150ed908b908b614ed8565b905080801561510657506151068a8a8760000151614ed8565b15615111575061512e565b8061512157600182039250615128565b8160010193505b50614fd9565b5050509550959350505050565b60028a810b900b600090815260208c90526040812080546001600160801b031682615166828d6135ef565b9050846001600160801b0316816001600160801b031611156151b4576040805162461bcd60e51b81526020600482015260026024820152614c4f60f01b604482015290519081900360640190fd5b6001600160801b03828116159082161581141594501561528a578c60020b8e60020b1361525a57600183018b9055600283018a90556003830180547fffffffffff0000000000000000000000000000000000000000ffffffffffffff166701000000000000006001600160a01b038c16021766ffffffffffffff191666ffffffffffffff60068b900b161763ffffffff60d81b1916600160d81b63ffffffff8a16021790555b6003830180547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f81b1790555b82546001600160801b0319166001600160801b038216178355856152d35782546152ce906152c990600160801b9004600f90810b810b908f900b6132c3565b613f58565b6152f4565b82546152f4906152c990600160801b9004600f90810b810b908f900b6132a7565b8354600f9190910b6001600160801b03908116600160801b0291161790925550909c9b505050505050505050505050565b8060020b8260020b8161533457fe5b0760020b1561534257600080fd5b60008061535d8360020b8560020b8161535757fe5b056144b6565b600191820b820b60009081526020979097526040909620805460ff9097169190911b90951890945550505050565b600285810b80820b60009081526020899052604080822088850b850b83529082209193849391929184918291908a900b126153d1575050600182015460028301546153e4565b8360010154880391508360020154870390505b6000808b60020b8b60020b121561540657505060018301546002840154615419565b84600101548a0391508460020154890390505b92909803979097039b96909503949094039850939650505050505050565b6040805160a08101825285546001600160801b0390811682526001870154602083015260028701549282019290925260038601548083166060830152600160801b900490911660808201526000600f85900b6154d65781516001600160801b03166154ce576040805162461bcd60e51b815260206004820152600260248201526104e560f41b604482015290519081900360640190fd5b5080516154e5565b81516154e290866135ef565b90505b60006155098360200151860384600001516001600160801b0316600160801b6132d9565b9050600061552f8460400151860385600001516001600160801b0316600160801b6132d9565b905086600f0b6000146155565787546001600160801b0319166001600160801b0384161788555b60018801869055600288018590556001600160801b03821615158061558457506000816001600160801b0316115b156155c2576003880180546001600160801b031981166001600160801b039182168501821617808216600160801b9182900483168501909216021790555b5050505050505050565b600290810b810b6000908152602092909252604082208281556001810183905590810182905560030155565b806001600160a01b0381168114612beb57600080fd5b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b6040805160808101825260008082526020820181905291810182905260608101919091529056fea164736f6c6343000706000a" - ], - [ - { - "block_no": 19493153, - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" - }, - "0x6060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7" - }, - "0x606060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461019b5780630753c30c14610229578063095ea7b3146102625780630e136b19146102a45780630ecb93c0146102d157806318160ddd1461030a57806323b872dd1461033357806326976e3f1461039457806327e235e3146103e9578063313ce56714610436578063353907141461045f5780633eaaf86b146104885780633f4ba83a146104b157806359bf1abe146104c65780635c658165146105175780635c975abb1461058357806370a08231146105b05780638456cb59146105fd578063893d20e8146106125780638da5cb5b1461066757806395d89b41146106bc578063a9059cbb1461074a578063c0324c771461078c578063cc872b66146107b8578063db006a75146107db578063dd62ed3e146107fe578063dd644f721461086a578063e47d606014610893578063e4997dc5146108e4578063e5b5019a1461091d578063f2fde38b14610946578063f3bdc2281461097f575b600080fd5b34156101a657600080fd5b6101ae6109b8565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101ee5780820151818401526020810190506101d3565b50505050905090810190601f16801561021b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561023457600080fd5b610260600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a56565b005b341561026d57600080fd5b6102a2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b73565b005b34156102af57600080fd5b6102b7610cc1565b604051808215151515815260200191505060405180910390f35b34156102dc57600080fd5b610308600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cd4565b005b341561031557600080fd5b61031d610ded565b6040518082815260200191505060405180910390f35b341561033e57600080fd5b610392600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610ebd565b005b341561039f57600080fd5b6103a761109d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f457600080fd5b610420600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506110c3565b6040518082815260200191505060405180910390f35b341561044157600080fd5b6104496110db565b6040518082815260200191505060405180910390f35b341561046a57600080fd5b6104726110e1565b6040518082815260200191505060405180910390f35b341561049357600080fd5b61049b6110e7565b6040518082815260200191505060405180910390f35b34156104bc57600080fd5b6104c46110ed565b005b34156104d157600080fd5b6104fd600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506111ab565b604051808215151515815260200191505060405180910390f35b341561052257600080fd5b61056d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611201565b6040518082815260200191505060405180910390f35b341561058e57600080fd5b610596611226565b604051808215151515815260200191505060405180910390f35b34156105bb57600080fd5b6105e7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611239565b6040518082815260200191505060405180910390f35b341561060857600080fd5b610610611348565b005b341561061d57600080fd5b610625611408565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561067257600080fd5b61067a611431565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156106c757600080fd5b6106cf611456565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561070f5780820151818401526020810190506106f4565b50505050905090810190601f16801561073c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561075557600080fd5b61078a600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506114f4565b005b341561079757600080fd5b6107b6600480803590602001909190803590602001909190505061169e565b005b34156107c357600080fd5b6107d96004808035906020019091905050611783565b005b34156107e657600080fd5b6107fc600480803590602001909190505061197a565b005b341561080957600080fd5b610854600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611b0d565b6040518082815260200191505060405180910390f35b341561087557600080fd5b61087d611c52565b6040518082815260200191505060405180910390f35b341561089e57600080fd5b6108ca600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611c58565b604051808215151515815260200191505060405180910390f35b34156108ef57600080fd5b61091b600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611c78565b005b341561092857600080fd5b610930611d91565b6040518082815260200191505060405180910390f35b341561095157600080fd5b61097d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611db5565b005b341561098a57600080fd5b6109b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611e8a565b005b60078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a4e5780601f10610a2357610100808354040283529160200191610a4e565b820191906000526020600020905b815481529060010190602001808311610a3157829003601f168201915b505050505081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ab157600080fd5b6001600a60146101000a81548160ff02191690831515021790555080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcc358699805e9a8b7f77b522628c7cb9abd07d9efb86b6fb616af1609036a99e81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b604060048101600036905010151515610b8b57600080fd5b600a60149054906101000a900460ff1615610cb157600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663aee92d333385856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1515610c9857600080fd5b6102c65a03f11515610ca957600080fd5b505050610cbc565b610cbb838361200e565b5b505050565b600a60149054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d2f57600080fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f42e160154868087d6bfdc0ca23d96a1c1cfa32f1b72ba9ba27b69b98a0d819dc81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b6000600a60149054906101000a900460ff1615610eb457600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610e9257600080fd5b6102c65a03f11515610ea357600080fd5b505050604051805190509050610eba565b60015490505b90565b600060149054906101000a900460ff16151515610ed957600080fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610f3257600080fd5b600a60149054906101000a900460ff161561108c57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638b477adb338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050600060405180830381600087803b151561107357600080fd5b6102c65a03f1151561108457600080fd5b505050611098565b6110978383836121ab565b5b505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60026020528060005260406000206000915090505481565b60095481565b60045481565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561114857600080fd5b600060149054906101000a900460ff16151561116357600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6005602052816000526040600020602052806000526040600020600091509150505481565b600060149054906101000a900460ff1681565b6000600a60149054906101000a900460ff161561133757600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561131557600080fd5b6102c65a03f1151561132657600080fd5b505050604051805190509050611343565b61134082612652565b90505b919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113a357600080fd5b600060149054906101000a900460ff161515156113bf57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60088054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114ec5780601f106114c1576101008083540402835291602001916114ec565b820191906000526020600020905b8154815290600101906020018083116114cf57829003601f168201915b505050505081565b600060149054906101000a900460ff1615151561151057600080fd5b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561156957600080fd5b600a60149054906101000a900460ff161561168f57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e18980a3384846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b151561167657600080fd5b6102c65a03f1151561168757600080fd5b50505061169a565b611699828261269b565b5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116f957600080fd5b60148210151561170857600080fd5b60328110151561171757600080fd5b81600381905550611736600954600a0a82612a0390919063ffffffff16565b6004819055507fb044a1e409eac5c48e5af22d4af52670dd1a99059537a78b31b48c6500a6354e600354600454604051808381526020018281526020019250505060405180910390a15050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156117de57600080fd5b60015481600154011115156117f257600080fd5b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011115156118c257600080fd5b80600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550806001600082825401925050819055507fcb8241adb0c3fdb35b70c24ce35c5eb0c17af7431c99f827d44a445ca624176a816040518082815260200191505060405180910390a150565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156119d557600080fd5b80600154101515156119e657600080fd5b80600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515611a5557600080fd5b8060016000828254039250508190555080600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507f702d5967f45f6513a38ffc42d6ba9bf230bd40e8f53b16363c7eb4fd2deb9a44816040518082815260200191505060405180910390a150565b6000600a60149054906101000a900460ff1615611c3f57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b1515611c1d57600080fd5b6102c65a03f11515611c2e57600080fd5b505050604051805190509050611c4c565b611c498383612a3e565b90505b92915050565b60035481565b60066020528060005260406000206000915054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611cd357600080fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fd7e9ec6e6ecd65492dce6bf513cd6867560d49544421d0783ddf06e76c24470c81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611e1057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515611e8757806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611ee757600080fd5b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611f3f57600080fd5b611f4882611239565b90506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550806001600082825403925050819055507f61e6e66b0d6339b2980aecc6ccc0039736791f0ccde9ed512e789a7fbdd698c68282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15050565b60406004810160003690501015151561202657600080fd5b600082141580156120b457506000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b1515156120c057600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a3505050565b60008060006060600481016000369050101515156121c857600080fd5b600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054935061227061271061226260035488612a0390919063ffffffff16565b612ac590919063ffffffff16565b92506004548311156122825760045492505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84101561233e576122bd8585612ae090919063ffffffff16565b600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6123518386612ae090919063ffffffff16565b91506123a585600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ae090919063ffffffff16565b600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061243a82600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008311156125e4576124f983600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000806040600481016000369050101515156126b657600080fd5b6126df6127106126d160035487612a0390919063ffffffff16565b612ac590919063ffffffff16565b92506004548311156126f15760045492505b6127048385612ae090919063ffffffff16565b915061275884600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ae090919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506127ed82600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000831115612997576128ac83600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a35050505050565b6000806000841415612a185760009150612a37565b8284029050828482811515612a2957fe5b04141515612a3357fe5b8091505b5092915050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000808284811515612ad357fe5b0490508091505092915050565b6000828211151515612aee57fe5b818303905092915050565b6000808284019050838110151515612b0d57fe5b80915050929150505600a165627a7a72305820645ee12d73db47fd78ba77fa1f824c3c8f9184061b3b10386beb4dc9236abb280029" - ], - [ - { - "block_no": 19493153, - "address": "0xe592427a0aece92de3edee1f18e0157c05861564" - }, - "0x6080604052600436106101125760003560e01c8063c04b8d59116100a5578063df2ab5bb11610074578063f28c049811610059578063f28c0498146102f5578063f3995c6714610308578063fa461e331461031b576101bd565b8063df2ab5bb146102cf578063e0e189a0146102e2576101bd565b8063c04b8d5914610281578063c2e3140a14610294578063c45a0155146102a7578063db3e2198146102bc576101bd565b80634aa4a4fc116100e15780634aa4a4fc146102195780639b2c0a371461023b578063a4a78f0c1461024e578063ac9650d814610261576101bd565b806312210e8a146101c2578063414bf389146101ca5780634659a494146101f357806349404b7c14610206576101bd565b366101bd573373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216146101bb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f4e6f742057455448390000000000000000000000000000000000000000000000604482015290519081900360640190fd5b005b600080fd5b6101bb61033b565b6101dd6101d83660046129f8565b61034d565b6040516101ea9190612df1565b60405180910390f35b6101bb610201366004612776565b6104bf565b6101bb610214366004612aff565b61057f565b34801561022557600080fd5b5061022e610745565b6040516101ea9190612c37565b6101bb610249366004612b2e565b610769565b6101bb61025c366004612776565b610981565b61027461026f3660046127d6565b610a56565b6040516101ea9190612caa565b6101dd61028f36600461294d565b610bb0565b6101bb6102a2366004612776565b610d0f565b3480156102b357600080fd5b5061022e610dc4565b6101dd6102ca3660046129f8565b610de8565b6101bb6102dd3660046126d7565b610f78565b6101bb6102f0366004612718565b611095565b6101dd610303366004612a14565b6111fb565b6101bb610316366004612776565b61132f565b34801561032757600080fd5b506101bb610336366004612868565b6113c7565b471561034b5761034b334761150e565b565b600081608001358061035d61165c565b11156103ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b61047060a08401356103e260808601606087016126b4565b6103f3610100870160e088016126b4565b604080518082019091528061040b60208a018a6126b4565b61041b60608b0160408c01612adc565b61042b60408c0160208d016126b4565b60405160200161043d93929190612bc1565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611660565b91508260c001358210156104b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b090612d72565b60405180910390fd5b50919050565b604080517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101879052606481018690526001608482015260ff851660a482015260c4810184905260e48101839052905173ffffffffffffffffffffffffffffffffffffffff881691638fcbaf0c9161010480830192600092919082900301818387803b15801561055f57600080fd5b505af1158015610573573d6000803e3d6000fd5b50505050505050505050565b60007f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561060857600080fd5b505afa15801561061c573d6000803e3d6000fd5b505050506040513d602081101561063257600080fd5b50519050828110156106a557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e742057455448390000000000000000000000000000604482015290519081900360640190fd5b8015610740577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561071e57600080fd5b505af1158015610732573d6000803e3d6000fd5b50505050610740828261150e565b505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b60008211801561077a575060648211155b61078357600080fd5b60007f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561080c57600080fd5b505afa158015610820573d6000803e3d6000fd5b505050506040513d602081101561083657600080fd5b50519050848110156108a957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e742057455448390000000000000000000000000000604482015290519081900360640190fd5b801561097a577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561092257600080fd5b505af1158015610936573d6000803e3d6000fd5b50505050600061271061095285846117e690919063ffffffff16565b8161095957fe5b049050801561096c5761096c838261150e565b6109788582840361150e565b505b5050505050565b604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015290517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b158015610a1657600080fd5b505afa158015610a2a573d6000803e3d6000fd5b505050506040513d6020811015610a4057600080fd5b50511015610978576109788686868686866104bf565b60608167ffffffffffffffff81118015610a6f57600080fd5b50604051908082528060200260200182016040528015610aa357816020015b6060815260200190600190039081610a8e5790505b50905060005b82811015610ba95760008030868685818110610ac157fe5b9050602002810190610ad39190612dfa565b604051610ae1929190612c27565b600060405180830381855af49150503d8060008114610b1c576040519150601f19603f3d011682016040523d82523d6000602084013e610b21565b606091505b509150915081610b8757604481511015610b3a57600080fd5b60048101905080806020019051810190610b5491906128e3565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b09190612d28565b80848481518110610b9457fe5b60209081029190910101525050600101610aa9565b5092915050565b6000816040015180610bc061165c565b1115610c2d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b335b6000610c3e8560000151611810565b9050610c97856060015182610c57578660200151610c59565b305b60006040518060400160405280610c738b6000015161181c565b81526020018773ffffffffffffffffffffffffffffffffffffffff16815250611660565b60608601528015610cb7578451309250610cb09061182b565b8552610cc4565b8460600151935050610cca565b50610c2f565b8360800151831015610d08576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b090612d72565b5050919050565b604080517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201529051869173ffffffffffffffffffffffffffffffffffffffff89169163dd62ed3e91604480820192602092909190829003018186803b158015610d8457600080fd5b505afa158015610d98573d6000803e3d6000fd5b505050506040513d6020811015610dae57600080fd5b505110156109785761097886868686868661132f565b7f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f98481565b6000816080013580610df861165c565b1115610e6557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b610f0e60a0840135610e7d60808601606087016126b4565b610e8e610100870160e088016126b4565b6040518060400160405280886020016020810190610eac91906126b4565b610ebc60608b0160408c01612adc565b610ec960208c018c6126b4565b604051602001610edb93929190612bc1565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611860565b91508260c00135821115610f4e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b090612d3b565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600055919050565b60008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610fe157600080fd5b505afa158015610ff5573d6000803e3d6000fd5b505050506040513d602081101561100b57600080fd5b505190508281101561107e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b801561108f5761108f848383611a1c565b50505050565b6000821180156110a6575060648211155b6110af57600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561111857600080fd5b505afa15801561112c573d6000803e3d6000fd5b505050506040513d602081101561114257600080fd5b50519050848110156111b557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e7420746f6b656e0000000000000000000000000000604482015290519081900360640190fd5b80156109785760006127106111ca83866117e6565b816111d157fe5b04905080156111e5576111e5878483611a1c565b6111f28786838503611a1c565b50505050505050565b600081604001358061120b61165c565b111561127857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5472616e73616374696f6e20746f6f206f6c6400000000000000000000000000604482015290519081900360640190fd5b6112eb606084013561129060408601602087016126b4565b60408051808201909152600090806112a88980612dfa565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525033602090910152611860565b5060005491508260800135821115610f4e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104b090612d3b565b604080517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018790526064810186905260ff8516608482015260a4810184905260c48101839052905173ffffffffffffffffffffffffffffffffffffffff88169163d505accf9160e480830192600092919082900301818387803b15801561055f57600080fd5b60008413806113d65750600083135b6113df57600080fd5b60006113ed82840184612a4c565b905060008060006114018460000151611bf1565b9250925092506114337f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f984848484611c22565b5060008060008a13611474578473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610896114a5565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16108a5b9150915081156114c4576114bf8587602001513384611c41565b610573565b85516114cf90611810565b156114f45785516114df9061182b565b86526114ee8133600089611860565b50610573565b806000819055508394506105738587602001513384611c41565b6040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff84169083906040518082805190602001908083835b6020831061158557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611548565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146115e7576040519150601f19603f3d011682016040523d82523d6000602084013e6115ec565b606091505b505090508061074057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354450000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b4290565b600073ffffffffffffffffffffffffffffffffffffffff8416611681573093505b60008060006116938560000151611bf1565b9194509250905073ffffffffffffffffffffffffffffffffffffffff808316908416106000806116c4868686611e1f565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088b856116ea8f611e5d565b73ffffffffffffffffffffffffffffffffffffffff8e161561170c578d611732565b8761172b5773fffd8963efd1fc6a506488495d951d5263988d25611732565b6401000276a45b8d6040516020016117439190612da9565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611772959493929190612c58565b6040805180830381600087803b15801561178b57600080fd5b505af115801561179f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c39190612845565b91509150826117d257816117d4565b805b6000039b9a5050505050505050505050565b6000821580611801575050818102818382816117fe57fe5b04145b61180a57600080fd5b92915050565b8051604211155b919050565b606061180a826000602b611e8f565b805160609061180a9083906017907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe901611e8f565b600073ffffffffffffffffffffffffffffffffffffffff8416611881573093505b60008060006118938560000151611bf1565b9194509250905073ffffffffffffffffffffffffffffffffffffffff808416908316106000806118c4858786611e1f565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088b856118ea8f611e5d565b60000373ffffffffffffffffffffffffffffffffffffffff8e161561190f578d611935565b8761192e5773fffd8963efd1fc6a506488495d951d5263988d25611935565b6401000276a45b8d6040516020016119469190612da9565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611975959493929190612c58565b6040805180830381600087803b15801561198e57600080fd5b505af11580156119a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c69190612845565b915091506000836119db5781836000036119e1565b82826000035b909850905073ffffffffffffffffffffffffffffffffffffffff8a16611a0d578b8114611a0d57600080fd5b50505050505050949350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001781529251825160009485949389169392918291908083835b60208310611af157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611ab4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611b53576040519150601f19603f3d011682016040523d82523d6000602084013e611b58565b606091505b5091509150818015611b86575080511580611b865750808060200190516020811015611b8357600080fd5b50515b61097a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600260248201527f5354000000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b60008080611bff8482612076565b9250611c0c846014612176565b9050611c19846017612076565b91509193909250565b6000611c3885611c33868686612266565b6122e3565b95945050505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148015611c9c5750804710155b15611de5577f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d0957600080fd5b505af1158015611d1d573d6000803e3d6000fd5b50505050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611db357600080fd5b505af1158015611dc7573d6000803e3d6000fd5b505050506040513d6020811015611ddd57600080fd5b5061108f9050565b73ffffffffffffffffffffffffffffffffffffffff8316301415611e1357611e0e848383611a1c565b61108f565b61108f84848484612313565b6000611e557f0000000000000000000000001f98431c8ad98523631ae4a59f267346ea31f984611e50868686612266565b6124f0565b949350505050565b60007f80000000000000000000000000000000000000000000000000000000000000008210611e8b57600080fd5b5090565b60608182601f011015611f0357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b828284011015611f7457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f736c6963655f6f766572666c6f77000000000000000000000000000000000000604482015290519081900360640190fd5b81830184511015611fe657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f736c6963655f6f75744f66426f756e6473000000000000000000000000000000604482015290519081900360640190fd5b606082158015612005576040519150600082526020820160405261206d565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561203e578051835260209283019201612026565b5050858452601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016604052505b50949350505050565b6000818260140110156120ea57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f746f416464726573735f6f766572666c6f770000000000000000000000000000604482015290519081900360640190fd5b816014018351101561215d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f416464726573735f6f75744f66426f756e64730000000000000000000000604482015290519081900360640190fd5b5001602001516c01000000000000000000000000900490565b6000818260030110156121ea57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f746f55696e7432345f6f766572666c6f77000000000000000000000000000000604482015290519081900360640190fd5b816003018351101561225d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f746f55696e7432345f6f75744f66426f756e6473000000000000000000000000604482015290519081900360640190fd5b50016003015190565b61226e612626565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1611156122a6579192915b506040805160608101825273ffffffffffffffffffffffffffffffffffffffff948516815292909316602083015262ffffff169181019190915290565b60006122ef83836124f0565b90503373ffffffffffffffffffffffffffffffffffffffff82161461180a57600080fd5b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000178152925182516000948594938a169392918291908083835b602083106123f057805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016123b3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612452576040519150601f19603f3d011682016040523d82523d6000602084013e612457565b606091505b5091509150818015612485575080511580612485575080806020019051602081101561248257600080fd5b50515b61097857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600360248201527f5354460000000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161061253257600080fd5b508051602080830151604093840151845173ffffffffffffffffffffffffffffffffffffffff94851681850152939091168385015262ffffff166060808401919091528351808403820181526080840185528051908301207fff0000000000000000000000000000000000000000000000000000000000000060a085015294901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660a183015260b58201939093527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460d5808301919091528251808303909101815260f5909101909152805191012090565b604080516060810182526000808252602082018190529181019190915290565b803561181781612ef4565b600082601f830112612661578081fd5b813561267461266f82612e88565b612e64565b818152846020838601011115612688578283fd5b816020850160208301379081016020019190915292915050565b600061010082840312156104b9578081fd5b6000602082840312156126c5578081fd5b81356126d081612ef4565b9392505050565b6000806000606084860312156126eb578182fd5b83356126f681612ef4565b925060208401359150604084013561270d81612ef4565b809150509250925092565b600080600080600060a0868803121561272f578081fd5b853561273a81612ef4565b945060208601359350604086013561275181612ef4565b925060608601359150608086013561276881612ef4565b809150509295509295909350565b60008060008060008060c0878903121561278e578081fd5b863561279981612ef4565b95506020870135945060408701359350606087013560ff811681146127bc578182fd5b9598949750929560808101359460a0909101359350915050565b600080602083850312156127e8578182fd5b823567ffffffffffffffff808211156127ff578384fd5b818501915085601f830112612812578384fd5b813581811115612820578485fd5b8660208083028501011115612833578485fd5b60209290920196919550909350505050565b60008060408385031215612857578182fd5b505080516020909101519092909150565b6000806000806060858703121561287d578182fd5b8435935060208501359250604085013567ffffffffffffffff808211156128a2578384fd5b818701915087601f8301126128b5578384fd5b8135818111156128c3578485fd5b8860208285010111156128d4578485fd5b95989497505060200194505050565b6000602082840312156128f4578081fd5b815167ffffffffffffffff81111561290a578182fd5b8201601f8101841361291a578182fd5b805161292861266f82612e88565b81815285602083850101111561293c578384fd5b611c38826020830160208601612ec8565b60006020828403121561295e578081fd5b813567ffffffffffffffff80821115612975578283fd5b9083019060a08286031215612988578283fd5b60405160a08101818110838211171561299d57fe5b6040528235828111156129ae578485fd5b6129ba87828601612651565b8252506129c960208401612646565b602082015260408301356040820152606083013560608201526080830135608082015280935050505092915050565b60006101008284031215612a0a578081fd5b6126d083836126a2565b600060208284031215612a25578081fd5b813567ffffffffffffffff811115612a3b578182fd5b820160a081850312156126d0578182fd5b600060208284031215612a5d578081fd5b813567ffffffffffffffff80821115612a74578283fd5b9083019060408286031215612a87578283fd5b604051604081018181108382111715612a9c57fe5b604052823582811115612aad578485fd5b612ab987828601612651565b82525060208301359250612acc83612ef4565b6020810192909252509392505050565b600060208284031215612aed578081fd5b813562ffffff811681146126d0578182fd5b60008060408385031215612b11578182fd5b823591506020830135612b2381612ef4565b809150509250929050565b60008060008060808587031215612b43578182fd5b843593506020850135612b5581612ef4565b9250604085013591506060850135612b6c81612ef4565b939692955090935050565b60008151808452612b8f816020860160208601612ec8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b606093841b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000908116825260e89390931b7fffffff0000000000000000000000000000000000000000000000000000000000166014820152921b166017820152602b0190565b6000828483379101908152919050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b600073ffffffffffffffffffffffffffffffffffffffff8088168352861515602084015285604084015280851660608401525060a06080830152612c9f60a0830184612b77565b979650505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015612d1b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612d09858351612b77565b94509285019290850190600101612ccf565b5092979650505050505050565b6000602082526126d06020830184612b77565b60208082526012908201527f546f6f206d756368207265717565737465640000000000000000000000000000604082015260600190565b60208082526013908201527f546f6f206c6974746c6520726563656976656400000000000000000000000000604082015260600190565b600060208252825160406020840152612dc56060840182612b77565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401528091505092915050565b90815260200190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612e2e578283fd5b83018035915067ffffffffffffffff821115612e48578283fd5b602001915036819003821315612e5d57600080fd5b9250929050565b60405181810167ffffffffffffffff81118282101715612e8057fe5b604052919050565b600067ffffffffffffffff821115612e9c57fe5b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60005b83811015612ee3578181015183820152602001612ecb565b8381111561108f5750506000910152565b73ffffffffffffffffffffffffffffffffffffffff81168114612f1657600080fd5b5056fea164736f6c6343000706000a" - ] - ], - "storage": [ - [ - { - "block_no": 5702743, - "address": "0x3c31cdb4d84ca36f17a4a3215b1a56d2569daed8", - "key": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "0x0" - ], - [ - { - "block_no": 5702743, - "address": "0x44b48fd72becefe030c1b62fadbfe6a7b3465d19", - "key": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "0x2a" - ], - [ - { - "block_no": 5702743, - "address": "0xf9617c4744c85c04f85d40e4eb119ac52740f9a5", - "key": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "0x2a" - ], - [ - { - "block_no": 19493153, - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "key": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "0x1000190019000cafd04f500000000000000000003c2101678675ef61742ad" - ], - [ - { - "block_no": 19493153, - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "key": "0x0000000000000000000000000000000000000000000000000000000000000002" - }, - "0xa64880bf553c2f0ca89ecae66704" - ], - [ - { - "block_no": 19493153, - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "key": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - "0x60e805d8f13ebdca" - ], - [ - { - "block_no": 19493153, - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "key": "0x00000000000000000000000000000000000000000000000000000000000000d2" - }, - "0x10000000000000009af681fbae06a6a026262ff31ffef7e4911b30165fe06df" - ], - [ - { - "block_no": 19493153, - "address": "0x11b815efb8f581194ae79006d24e0d814b7697f6", - "key": "0x51e86470d074b2eb973e9c895b2858f9860cc48a7abc1578969424279e898438" - }, - "0xfdefffffffdf9d31da40414bc4805ed142011d80124080c0c04007001e9a0001" - ], - [ - { - "block_no": 19493153, - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "key": "0x0cb865ff1951c90111975d77bc75fa8312f25b08bb19b908f6b9c43691ac0caf" - }, - "0x1969a8ffaf84aaeb3aa" - ], - [ - { - "block_no": 19493153, - "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "key": "0x98be5cb53bc8c144acf7451f10098b397ac1c9626286fa6ac9782d3ae4d7a49b" - }, - "0x1055d788f1f035bd1e" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "0xc6cde7c39eb2f0f0095f41570af89efc2c1ea828" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x0000000000000000000000000000000000000000000000000000000000000003" - }, - "0x0" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x0000000000000000000000000000000000000000000000000000000000000004" - }, - "0x0" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x000000000000000000000000000000000000000000000000000000000000000a" - }, - "0x0" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x0be16d71963429204d70543701f859c43526c316ac005c10114f4694ca405f36" - }, - "0xaa87bee538000" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x169228ca33ea854d54aa1e506e59ec687f618a41074f5f5de937a0e9c6343e5a" - }, - "0x10bce9b5d9c2" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x6f9cb8e37a2476be4d2303222000061c25157672c2487eaae4d8e4399bbc15b8" - }, - "0x80683379cb" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x798780bf00cc81b39c0aae120a71d0848e69206d511bb237a63bfc8243990d32" - }, - "0x0" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x7ea29a65f431835045c27ccf1699b8986f6310efc5565f53bae18a1b1075bb1b" - }, - "0x38d7ea4c68000" - ], - [ - { - "block_no": 19493153, - "address": "0xdac17f958d2ee523a2206206994597c13d831ec7", - "key": "0x9da0b11d802ea7d5f343d316fe8b1f884d871565b3589b4b5d6f6f07d1419c9d" - }, - "0x56bc6b88d147733de" - ], - [ - { - "block_no": 19493153, - "address": "0xe592427a0aece92de3edee1f18e0157c05861564", - "key": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ] - ] -} \ No newline at end of file diff --git a/steel/tests/steel.rs b/steel/tests/steel.rs index 795a3682..4fc58db0 100644 --- a/steel/tests/steel.rs +++ b/steel/tests/steel.rs @@ -36,7 +36,7 @@ mod common; const STEEL_TEST_CONTRACT: Address = address!("5fbdb2315678afecb367f032d93f642f64180aa3"); alloy::sol!( - #[sol(rpc, bytecode="60e060405234801561000f575f80fd5b505f60405161001d906100c4565b908152602001604051809103905ff08015801561003c573d5f803e3d5ffd5b506001600160a01b0316608052604051602a90610058906100c4565b908152602001604051809103905ff080158015610077573d5f803e3d5ffd5b506001600160a01b031660a052604051602a90610093906100c4565b908152602001604051809103905ff0801580156100b2573d5f803e3d5ffd5b506001600160a01b031660c0526100d0565b60c98061041e83390190565b60805160a05160c0516103256100f95f395f60de01525f61015e01525f6101de01526103255ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063445bda4311610058578063445bda43146100ba5780637d732b5f146100c25780639f6f32aa146100c8578063ab8fd80c146100d0575f80fd5b80630692d13c146100895780632e8bde391461009f57806330e49663146100ad57806341317185146100b3575b5f80fd5b5f3b5b6040519081526020015b60405180910390f35b604051328152602001610096565b3a61008c565b443b61008c565b61008c6100db565b4661008c565b61008c610275565b4360fe19014061008c565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610138573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061015c91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101dc91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610238573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025c91906102b3565b61026691906102ca565b61027091906102ca565b905090565b6040515f906002906020818481855afa158015610294573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061027091905b5f602082840312156102c3575f80fd5b5051919050565b808201808211156102e957634e487b7160e01b5f52601160045260245ffd5b9291505056fea264697066735822122017cd88097c7ec4827d02d5b993a5a0735d07aaa06059c5e6c23f0ee89f66264b64736f6c634300081900336080604052348015600e575f80fd5b5060405160c938038060c9833981016040819052602991602f565b5f556045565b5f60208284031215603e575f80fd5b5051919050565b60798060505f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3fea2646970667358221220fb757efaa1a5b5711adfcca5d02365b7e8408bfa6624b2b9bf549a8fa2f4f1fc64736f6c63430008190033")] + #[sol(rpc, bytecode="60e060405234801561000f575f80fd5b505f60405161001d906100c4565b908152602001604051809103905ff08015801561003c573d5f803e3d5ffd5b506001600160a01b0316608052604051602a90610058906100c4565b908152602001604051809103905ff080158015610077573d5f803e3d5ffd5b506001600160a01b031660a052604051602a90610093906100c4565b908152602001604051809103905ff0801580156100b2573d5f803e3d5ffd5b506001600160a01b031660c0526100d0565b60c98061041e83390190565b60805160a05160c0516103256100f95f395f60de01525f61015e01525f6101de01526103255ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063445bda4311610058578063445bda43146100ba5780637d732b5f146100c25780639f6f32aa146100c8578063ab8fd80c146100d0575f80fd5b80630692d13c146100895780632e8bde391461009f57806330e49663146100ad57806341317185146100b3575b5f80fd5b5f3b5b6040519081526020015b60405180910390f35b604051328152602001610096565b3a61008c565b443b61008c565b61008c6100db565b4661008c565b61008c610275565b4360ff19014061008c565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610138573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061015c91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101dc91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610238573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025c91906102b3565b61026691906102ca565b61027091906102ca565b905090565b6040515f906002906020818481855afa158015610294573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061027091905b5f602082840312156102c3575f80fd5b5051919050565b808201808211156102e957634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220193bf7ba8b1afe2d8e735c81e13a2034829eae79d36eac8db076b92ff6308ba564736f6c634300081900336080604052348015600e575f80fd5b5060405160c938038060c9833981016040819052602991602f565b5f556045565b5f60208284031215603e575f80fd5b5051919050565b60798060505f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3fea2646970667358221220c28e11a00819347c873d20f4ecc0a120e64201cb1a824335d007cf34e8c3ff8164736f6c63430008190033")] #[derive(Debug, PartialEq, Eq)] contract SteelTest { Value internal immutable VALUE0; @@ -67,7 +67,7 @@ alloy::sol!( /// Tests the blockhash opcode. function testBlockhash() external view returns (bytes32 h) { - assembly { h := blockhash(sub(number(), 255)) } + assembly { h := blockhash(sub(number(), 256)) } } /// Tests retrieving the chain ID. @@ -157,7 +157,7 @@ async fn blockhash() { let block_hash = provider.anvil_node_info().await.unwrap().current_block_hash; // mine more blocks to assure that the chain is long enough provider - .anvil_mine(Some(U256::from(255)), None) + .anvil_mine(Some(U256::from(256)), None) .await .unwrap(); From 913bc316bf08c550293c9a0d7ca554d07170589e Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 31 Jul 2024 10:47:37 +0200 Subject: [PATCH 14/30] make commitment explicit --- .../methods/guest/src/bin/balance_of.rs | 2 +- examples/erc20/host/src/main.rs | 2 +- examples/erc20/methods/guest/src/main.rs | 2 +- examples/token-stats/host/src/main.rs | 2 +- .../token-stats/methods/guest/src/main.rs | 2 +- steel/src/host/mod.rs | 11 ++--- steel/src/lib.rs | 44 +++++++++++++------ steel/tests/common/mod.rs | 2 +- 8 files changed, 43 insertions(+), 24 deletions(-) diff --git a/examples/erc20-counter/methods/guest/src/bin/balance_of.rs b/examples/erc20-counter/methods/guest/src/bin/balance_of.rs index 747f33b0..a052b03d 100644 --- a/examples/erc20-counter/methods/guest/src/bin/balance_of.rs +++ b/examples/erc20-counter/methods/guest/src/bin/balance_of.rs @@ -62,7 +62,7 @@ fn main() { // Commit the block hash and number used when deriving `view_call_env` to the journal. let journal = Journal { - commitment: env.block_commitment(), + commitment: env.into_commitment(), tokenAddress: contract, }; env::commit_slice(&journal.abi_encode()); diff --git a/examples/erc20/host/src/main.rs b/examples/erc20/host/src/main.rs index 39aeda24..15ecd99a 100644 --- a/examples/erc20/host/src/main.rs +++ b/examples/erc20/host/src/main.rs @@ -79,7 +79,7 @@ async fn main() -> Result<()> { returns._0 ); // Get the commitment to verify execution later. - let commitment = env.block_commitment(); + let commitment = env.commitment().clone(); // Finally, construct the input from the environment. let input = env.into_input().await?; diff --git a/examples/erc20/methods/guest/src/main.rs b/examples/erc20/methods/guest/src/main.rs index 99b6d141..22c060f6 100644 --- a/examples/erc20/methods/guest/src/main.rs +++ b/examples/erc20/methods/guest/src/main.rs @@ -53,7 +53,7 @@ fn main() { // header provided in the input. let env = input.into_env().with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); // Commit the block hash and number used when deriving `EvmEnv` to the journal. - env::commit_slice(&env.block_commitment().abi_encode()); + env::commit_slice(&env.commitment().abi_encode()); // Execute the view call; it returns the result in the type generated by the `sol!` macro. let contract = Contract::new(CONTRACT, &env); diff --git a/examples/token-stats/host/src/main.rs b/examples/token-stats/host/src/main.rs index 602d41e1..099dd622 100644 --- a/examples/token-stats/host/src/main.rs +++ b/examples/token-stats/host/src/main.rs @@ -75,7 +75,7 @@ async fn main() -> Result<()> { rate ); // Get the commitment to verify execution later. - let commitment = env.block_commitment(); + let commitment = env.commitment().clone(); // Finally, construct the input from the environment. let input = env.into_input().await?; diff --git a/examples/token-stats/methods/guest/src/main.rs b/examples/token-stats/methods/guest/src/main.rs index bbe876d7..59ed016b 100644 --- a/examples/token-stats/methods/guest/src/main.rs +++ b/examples/token-stats/methods/guest/src/main.rs @@ -54,7 +54,7 @@ fn main() { // This commits the APR at current utilization rate for this given block. let journal = APRCommitment { - commitment: env.block_commitment(), + commitment: env.into_commitment(), annualSupplyRate: annual_supply_rate, }; env::commit_slice(&journal.abi_encode()); diff --git a/steel/src/host/mod.rs b/steel/src/host/mod.rs index d593983e..53c6710b 100644 --- a/steel/src/host/mod.rs +++ b/steel/src/host/mod.rs @@ -168,16 +168,17 @@ where storage_tries.iter().map(|t| t.size()).sum::() ); debug!("contracts: {}", contracts.len()); - debug!("blocks: {}", ancestors.len()); + debug!("ancestor blocks: {}", ancestors.len()); - let header = self.header.into_inner(); - Ok(EvmInput { - header, + let input = EvmInput { + header: self.header.into_inner(), state_trie, storage_tries, contracts, ancestors, - }) + }; + + Ok(input) } } diff --git a/steel/src/lib.rs b/steel/src/lib.rs index a90b2b93..be262384 100644 --- a/steel/src/lib.rs +++ b/steel/src/lib.rs @@ -15,11 +15,10 @@ #![cfg_attr(not(doctest), doc = include_str!("../README.md"))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -use std::fmt::Debug; - use ::serde::{Deserialize, Serialize}; use alloy_primitives::{BlockNumber, Bytes, Sealable, Sealed, B256, U256}; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg, HashMap, SpecId}; +use state::StateDb; pub mod config; mod contract; @@ -34,7 +33,7 @@ pub use contract::{CallBuilder, Contract}; pub use mpt::MerkleTrie; /// The serializable input to derive and validate a [EvmEnv]. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct EvmInput { header: H, state_trie: MerkleTrie, @@ -65,7 +64,7 @@ impl EvmInput { assert_eq!( previous_header.parent_hash(), &ancestor_hash, - "Invalid chain: block {} is not the parent of block {}", + "Invalid ancestor chain: block {} is not the parent of block {}", ancestor.number(), previous_header.number() ); @@ -98,7 +97,17 @@ mod private { /// Solidity struct representing the committed block used for validation. pub use private::Commitment as SolCommitment; -use state::StateDb; + +impl SolCommitment { + /// Constructs a commitment from a sealed [EvmBlockHeader]. + #[inline] + fn from_header(header: &Sealed) -> Self { + SolCommitment { + blockNumber: U256::from(header.number()), + blockHash: header.seal(), + } + } +} /// Alias for readability, do not make public. pub(crate) type GuestEvmEnv = EvmEnv; @@ -108,6 +117,7 @@ pub struct EvmEnv { db: Option, cfg_env: CfgEnvWithHandlerCfg, header: Sealed, + commitment: SolCommitment, } impl EvmEnv { @@ -115,11 +125,15 @@ impl EvmEnv { /// It uses the default configuration for the latest specification. pub fn new(db: D, header: Sealed) -> Self { let cfg_env = CfgEnvWithHandlerCfg::new_with_spec_id(Default::default(), SpecId::LATEST); + let commitment = SolCommitment::from_header(&header); + #[cfg(feature = "host")] + log::info!("Commitment to block {}", commitment.blockHash); Self { db: Some(db), cfg_env, header, + commitment, } } @@ -132,19 +146,23 @@ impl EvmEnv { self } - /// Returns the [SolCommitment] used to validate the environment. - pub fn block_commitment(&self) -> SolCommitment { - SolCommitment { - blockHash: self.header.seal(), - blockNumber: U256::from(self.header.number()), - } - } - /// Returns the header of the environment. #[inline] pub fn header(&self) -> &H { self.header.inner() } + + /// Returns the [SolCommitment] used to validate the environment. + #[inline] + pub fn commitment(&self) -> &SolCommitment { + &self.commitment + } + + /// Consumes and returns the [SolCommitment] used to validate the environment. + #[inline] + pub fn into_commitment(self) -> SolCommitment { + self.commitment + } } /// An EVM abstraction of a block header. diff --git a/steel/tests/common/mod.rs b/steel/tests/common/mod.rs index ce4c189e..93d04f3d 100644 --- a/steel/tests/common/mod.rs +++ b/steel/tests/common/mod.rs @@ -56,7 +56,7 @@ where let input = env.into_input().await.unwrap(); let env = input.into_env().with_chain_spec(&ANVIL_CHAIN_SPEC); - let commitment = env.block_commitment(); + let commitment = env.commitment(); assert_eq!(commitment.blockHash, block_hash, "invalid commitment"); assert_eq!(commitment.blockNumber, block_number, "invalid commitment"); From dea78259293998c74c3dbf5536ce6f483f31b5f0 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 31 Jul 2024 11:41:24 +0200 Subject: [PATCH 15/30] do not use eth_getProof in alloyDb --- steel/src/host/db/alloy.rs | 77 ++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/steel/src/host/db/alloy.rs b/steel/src/host/db/alloy.rs index 1ae2595c..27d2036f 100644 --- a/steel/src/host/db/alloy.rs +++ b/steel/src/host/db/alloy.rs @@ -34,14 +34,14 @@ use tokio::runtime::{self, Handle, Runtime}; /// immediate context is only synchronous, but a transitive caller is async, use /// [tokio::task::spawn_blocking] around the calls that need to be blocked. pub struct AlloyDb> { - /// The provider to fetch the data from. + /// Provider to fetch the data from. provider: P, - /// The block number on which the queries will be based on. + /// Block number on which the queries will be based on. block_number: BlockNumber, - /// handle to the tokio runtime + /// Handle to the tokio runtime runtime_handle: HandleOrRuntime, - /// Cache for code hashes to contract addresses. - code_hashes: HashMap, + /// Bytecode cache to allow querying by code hash instead of address. + contracts: HashMap, _marker: PhantomData (T, N)>, } @@ -70,15 +70,18 @@ impl> AlloyDb { provider, block_number, runtime_handle, - code_hashes: HashMap::new(), + contracts: HashMap::new(), _marker: PhantomData, } } - pub(crate) fn provider(&self) -> &P { + /// Returns the underlying provider. + pub fn provider(&self) -> &P { &self.provider } - pub(crate) fn block_number(&self) -> BlockNumber { + + /// Returns the block number used for the queries. + pub fn block_number(&self) -> BlockNumber { self.block_number } @@ -96,27 +99,41 @@ impl> Database for AlloyDb Result, Self::Error> { - // use `eth_getProof` to get all the account info with a single call - let proof = self.block_on( - self.provider - .get_proof(address, vec![]) - .number(self.block_number) - .into_future(), - )?; - // for non-existent accounts, the code hash is zero - // see https://github.com/ethereum/go-ethereum/issues/28441 - if proof.code_hash == B256::ZERO { + let f = async { + let get_nonce = self + .provider + .get_transaction_count(address) + .number(self.block_number); + let get_balance = self.provider.get_balance(address).number(self.block_number); + let get_code = self.provider.get_code_at(address).number(self.block_number); + + tokio::join!( + get_nonce.into_future(), + get_balance.into_future(), + get_code.into_future() + ) + }; + let (nonce, balance, code) = self.block_on(f); + + let nonce = nonce?; + let balance = balance?; + let code = Bytecode::new_raw(code?.0.into()); + + // if the account is empty return None + // in the EVM emptiness is treated as equivalent to nonexistence + if nonce == 0 && balance.is_zero() && code.is_empty() { return Ok(None); } + // cache the code hash to address mapping, so we can later retrieve the code - self.code_hashes - .insert(proof.code_hash.0.into(), proof.address); + let code_hash = code.hash_slow(); + self.contracts.insert(code_hash, code); Ok(Some(AccountInfo { - nonce: proof.nonce, - balance: proof.balance, - code_hash: proof.code_hash, - code: None, + nonce, + balance, + code_hash, + code: None, // will be queried later using code_by_hash })) } @@ -127,18 +144,12 @@ impl> Database for AlloyDb Result { From 3728acffaff6cd41c7414b6ee7cab23aaf20f511 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Thu, 1 Aug 2024 15:56:58 +0200 Subject: [PATCH 16/30] add changelog --- steel/CHANGELOG.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 steel/CHANGELOG.md diff --git a/steel/CHANGELOG.md b/steel/CHANGELOG.md new file mode 100644 index 00000000..1c0d9e8b --- /dev/null +++ b/steel/CHANGELOG.md @@ -0,0 +1,45 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [Unreleased] + +### ⚡️ Features + +- Replace `ethers` dependency completely with `alloy`. +- Make `host` functions `async`. +- Add support to build `EvmEnv` from any `alloy` provider. +- Add more efficient RLP-based serialization for the header. + +### 🛠 Fixes + +- Store the commitment inside the `EvmEnv`. +- Use `eth_getTransactionCount` and `eth_getBalance` instead of `eth_getProof` to query basic account information. +- Switch tests from pre-recorded RPC responses to `Anvil`. + +### 🚨 Breaking Changes + +- `EthEvmEnv::from_rpc` now takes an `Url` instead of a `&str`. +- `EvmEnv::from_provider`now takes an `alloy` provider, the `u64` block number was changed to a `BlockNumberOrTag`. +- `CachedProvider` is no longer available: + - During tests the fork mode of `Anvil` can be used for a similar effect, or + - use the upcoming cache feature of `alloy`. +- `EvmEnv::sol_commitment` has been changed to `EvmEnv::commitment` to get a reference, or `EvmEnv::into_commitment`. +- `ETH_SEPOLIA_CHAIN_SPEC` and `ETH_MAINNET_CHAIN_SPEC` have been moved to the `ethereum` module. +- The host functions are now `async` instead of blocking: +```rust +// Create an EVM environment from an RPC endpoint and a block number or tag. +let mut env = EthEvmEnv::from_rpc(args.rpc_url, BlockNumberOrTag::Latest).await?; +// The `with_chain_spec` method is used to specify the chain configuration. +env = env.with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); + +// Preflight the call to prepare the input that is required to execute the function in +// the guest without RPC access. It also returns the result of the call. +let mut contract = Contract::preflight(CONTRACT, &mut env); +let returns = contract.call_builder(&CALL).from(CALLER).call().await?; + +// Finally, construct the input from the environment. +let input = env.into_input().await?; +``` + +## [0.11.1](https://github.com/risc0/risc0-ethereum/releases/tag/steel-v0.11.1) - 2024-06-25 \ No newline at end of file From 6e84c9a727deb72d52ede1bf8127f9ddec52ceb7 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Mon, 5 Aug 2024 18:25:53 +0200 Subject: [PATCH 17/30] upgrade alloy to v0.2.1 --- Cargo.toml | 4 ++-- examples/erc20-counter/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6312013..89544017 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,14 +22,14 @@ risc0-zkp = { git = "https://github.com/risc0/risc0", branch = "main", default-f risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default-features = false } # Alloy guest dependencies -alloy-consensus = { git = "https://github.com/alloy-rs/alloy.git", rev = "067cc464bd1357e745653709db051707b949cc6b" } +alloy-consensus = { version = "0.2.1" } alloy-primitives = { version = "0.7", features = ["serde", "rlp", "std"] } alloy-rlp = { version = "0.3.7", default-features = false } alloy-rlp-derive = { version = "0.3.7", default-features = false } alloy-sol-types = { version = "0.7" } # Alloy host dependencies -alloy = { git = "https://github.com/alloy-rs/alloy.git", rev = "067cc464bd1357e745653709db051707b949cc6b", features = ["full"] } +alloy = { version = "0.2.1", features = ["full"] } alloy-trie = { version = "0.4.0" } anyhow = { version = "1.0" } diff --git a/examples/erc20-counter/Cargo.toml b/examples/erc20-counter/Cargo.toml index f7e02c17..b148b208 100644 --- a/examples/erc20-counter/Cargo.toml +++ b/examples/erc20-counter/Cargo.toml @@ -18,7 +18,7 @@ risc0-build = { git = "https://github.com/risc0/risc0", branch = "main", feature 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 = { git = "https://github.com/alloy-rs/alloy.git", rev = "067cc464bd1357e745653709db051707b949cc6b", features = ["full"] } +alloy = { version = "0.2.1", features = ["full"] } alloy-primitives = { version = "0.7", features = ["rlp", "serde", "std"] } alloy-sol-types = { version = "0.7" } anyhow = { version = "1.0.75" } From 3c845558cbc1ccba122b8b7255feb2302b97cd7c Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Mon, 5 Aug 2024 19:23:21 +0200 Subject: [PATCH 18/30] cleanup AlloyDb --- steel/src/host/db/alloy.rs | 50 ++++++++++---------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/steel/src/host/db/alloy.rs b/steel/src/host/db/alloy.rs index 27d2036f..70c38c2d 100644 --- a/steel/src/host/db/alloy.rs +++ b/steel/src/host/db/alloy.rs @@ -24,7 +24,7 @@ use revm::{ primitives::{AccountInfo, Bytecode, HashMap, KECCAK_EMPTY}, Database, }; -use tokio::runtime::{self, Handle, Runtime}; +use tokio::runtime::Handle; /// A revm [Database] backed by an alloy [Provider]. /// @@ -38,40 +38,25 @@ pub struct AlloyDb> { provider: P, /// Block number on which the queries will be based on. block_number: BlockNumber, - /// Handle to the tokio runtime - runtime_handle: HandleOrRuntime, - /// Bytecode cache to allow querying by code hash instead of address. + /// Handle to the Tokio runtime. + handle: Handle, + /// Bytecode cache to allow querying bytecode by hash instead of address. contracts: HashMap, - _marker: PhantomData (T, N)>, -} - -/// Holds a tokio runtime handle or full runtime -#[derive(Debug)] -enum HandleOrRuntime { - Handle(Handle), - Runtime(Runtime), + phantom: PhantomData (T, N)>, } impl> AlloyDb { + /// Create a new AlloyDb instance, with a [Provider] and a block. + /// + /// This will panic if called outside the context of a Tokio runtime. pub fn new(provider: P, block_number: BlockNumber) -> Self { - let runtime_handle = match Handle::try_current() { - Ok(handle) => HandleOrRuntime::Handle(handle), - Err(_) => { - let runtime = runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap(); - HandleOrRuntime::Runtime(runtime) - } - }; - Self { provider, block_number, - runtime_handle, + handle: Handle::current(), contracts: HashMap::new(), - _marker: PhantomData, + phantom: PhantomData, } } @@ -84,15 +69,6 @@ impl> AlloyDb { pub fn block_number(&self) -> BlockNumber { self.block_number } - - /// internal utility function to call tokio feature and wait for output - #[inline] - fn block_on(&self, f: F) -> F::Output { - match &self.runtime_handle { - HandleOrRuntime::Handle(handle) => handle.block_on(f), - HandleOrRuntime::Runtime(rt) => rt.block_on(f), - } - } } impl> Database for AlloyDb { @@ -113,7 +89,7 @@ impl> Database for AlloyDb> Database for AlloyDb Result { - let storage = self.block_on( + let storage = self.handle.block_on( self.provider .get_storage_at(address, index) .number(self.block_number) @@ -165,7 +141,7 @@ impl> Database for AlloyDb Result { // SAFETY: We know number <= u64::MAX, so we can safely convert it to u64 - let block = self.block_on( + let block = self.handle.block_on( self.provider .get_block_by_number(number.to::().into(), false), )?; From f668c8a2bbb375a0b52a9b76b3b724dd8822b46b Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Mon, 5 Aug 2024 20:01:20 +0200 Subject: [PATCH 19/30] update README --- examples/erc20-counter/README.md | 29 ++++--------------- examples/erc20/README.md | 48 +++++++++++++------------------- examples/token-stats/README.md | 37 ++++++++++-------------- 3 files changed, 40 insertions(+), 74 deletions(-) diff --git a/examples/erc20-counter/README.md b/examples/erc20-counter/README.md index 2ca6b630..4a853afb 100644 --- a/examples/erc20-counter/README.md +++ b/examples/erc20-counter/README.md @@ -34,26 +34,10 @@ The contract includes functionality to query the current value of the counter at ## Dependencies -First, [install Rust] and [Foundry], and then restart your terminal. - -```sh -# Install Rust -curl https://sh.rustup.rs -sSf | sh -# Install Foundry -curl -L https://foundry.paradigm.xyz | bash -``` - -Next, you will need to install the `cargo risczero` tool. -We'll use [`cargo binstall`][cargo-binstall] to get `cargo-risczero` installed, and then install the `risc0` toolchain. -See [RISC Zero installation] for more details. - -```sh -cargo install cargo-binstall -cargo binstall cargo-risczero -cargo risczero install -``` - -Now you have all the tools you need to develop and deploy an application with [RISC Zero]. +To get started, you need to have the following installed: +- [Rust] +- [Foundry] +- [RISC Zero] ### Configuring Bonsai @@ -73,11 +57,10 @@ When you're ready, follow the [deployment guide] to get your application running [Foundry]: https://getfoundry.sh/ [Groth16 SNARK proof]: https://www.risczero.com/news/on-chain-verification -[RISC Zero installation]: https://dev.risczero.com/api/zkvm/install -[RISC Zero]: https://www.risczero.com/ +[RISC Zero]: https://dev.risczero.com/api/zkvm/install [Sepolia]: https://www.alchemy.com/overviews/sepolia-testnet [cargo-binstall]: https://github.com/cargo-bins/cargo-binstall#cargo-binaryinstall [deployment guide]: ./deployment-guide.md -[install Rust]: https://doc.rust-lang.org/cargo/getting-started/installation.html +[Rust]: https://doc.rust-lang.org/cargo/getting-started/installation.html [Counter]: ./contracts/Counter.sol [Steel]: https://www.risczero.com/blog/introducing-steel diff --git a/examples/erc20/README.md b/examples/erc20/README.md index 1d7184d6..8b638b24 100644 --- a/examples/erc20/README.md +++ b/examples/erc20/README.md @@ -6,40 +6,31 @@ To get started, you need to have Rust installed. If you haven't done so, follow the instructions [here][install-rust]. -Next, install the `cargo risczero` tool. We'll use `cargo binstall` to facilitate this. Detailed instructions can be found at [cargo-binstall]. +Next, you will also need to have the `cargo-risczero` tool installed following the instructions [here][install-risczero]. -```bash -cargo install cargo-binstall -cargo binstall cargo-risczero -``` - -Finally, install the `risc0` toolchain with the following command: - -```bash -cargo risczero install -``` - -You'll also need access to an Ethereum RPC node, such as through [Alchemy](www.alchemy.com). +You'll also need access to an Ethereum Sepolia RPC endpoint. You can for example use [ethereum-sepolia-rpc.publicnode.com](https://ethereum-sepolia-rpc.publicnode.com) or a commercial RPC provider like [Alchemy](www.alchemy.com). ## Run the example -To run the example, which queries the USDT balance of `0x9737100D2F42a196DE56ED0d1f6fF598a250E7E4` on Sepolia, execute the following command: +To run the example, which queries the USDT balance of [`0x9737100D2F42a196DE56ED0d1f6fF598a250E7E4`](https://sepolia.etherscan.io/token/0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0?a=0x9737100d2f42a196de56ed0d1f6ff598a250e7e4) on Sepolia, execute the following command: ```bash -RPC_URL=https://eth-sepolia.g.alchemy.com/v2/ RUST_LOG=info cargo run --release +RPC_URL=https://ethereum-sepolia-rpc.publicnode.com RUST_LOG=info cargo run --release ``` The output should resemble the following: ```text -2024-06-04T09:32:22.119650Z INFO risc0_steel::contract: Executing preflight for 'balanceOf(address)' on contract 0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0 -For block 6037045 `balanceOf(address)` returns: 399534748753251 -Running the guest with the constructed input: +2024-08-05T17:29:56.020271Z INFO risc0_steel::host: Environment initialized for block 6442962 +2024-08-05T17:29:56.020499Z INFO risc0_steel: Commitment to block 0x9905cc8a33f5705b3ab32f9fcf5dca433a7b172695943e0df285dde98530d7e7 +2024-08-05T17:29:56.021170Z INFO risc0_steel::contract: Executing preflight calling 'balanceOf(address)' on 0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0 +Call balanceOf(address) Function by 0xf08A…1715 on 0xaA8E…33D0 returns: 399534748753251 +Running the guest with the constructed input... View call result: 399534748753251 -2024-06-04T09:32:24.152552Z INFO executor: risc0_zkvm::host::server::exec::executor: execution time: 218.576666ms -2024-06-04T09:32:24.152578Z INFO executor: risc0_zkvm::host::server::session: number of segments: 5 -2024-06-04T09:32:24.152581Z INFO executor: risc0_zkvm::host::server::session: total cycles: 5242880 -2024-06-04T09:32:24.152583Z INFO executor: risc0_zkvm::host::server::session: user cycles: 4126244 +2024-08-05T17:29:58.002719Z INFO executor: risc0_zkvm::host::server::exec::executor: execution time: 115.07675ms +2024-08-05T17:29:58.002737Z INFO executor: risc0_zkvm::host::server::session: number of segments: 6 +2024-08-05T17:29:58.002740Z INFO executor: risc0_zkvm::host::server::session: total cycles: 5767168 +2024-08-05T17:29:58.002742Z INFO executor: risc0_zkvm::host::server::session: user cycles: 4307081 ``` ### Guest Code @@ -75,7 +66,7 @@ fn main() { // header provided in the input. let env = input.into_env().with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); // Commit the block hash and number used when deriving `EvmEnv` to the journal. - env::commit_slice(&env.block_commitment().abi_encode()); + env::commit_slice(&env.commitment().abi_encode()); // Execute the view call; it returns the result in the type generated by the `sol!` macro. let contract = Contract::new(CONTRACT, &env); @@ -89,20 +80,19 @@ fn main() { Here is a snippet to the [relevant code](./host/src/main.rs) on the host, it requires the same arguments as the guest: ```rust -// Create an EVM environment from an RPC endpoint and a block number. If no block number is -// provided, the latest block is used. -let mut env = EthEvmEnv::from_rpc(&args.rpc_url, None)?; +// Create an EVM environment from an RPC endpoint and a block number or tag. +let mut env = EthEvmEnv::from_rpc(args.rpc_url, BlockNumberOrTag::Latest).await?; // The `with_chain_spec` method is used to specify the chain configuration. env = env.with_chain_spec(Ð_SEPOLIA_CHAIN_SPEC); // Preflight the call to prepare the input that is required to execute the function in // the guest without RPC access. It also returns the result of the call. let mut contract = Contract::preflight(CONTRACT, &mut env); -let returns = contract.call_builder(&CALL).from(CALLER).call()?; +let returns = contract.call_builder(&CALL).from(CALLER).call().await?; // Finally, construct the input from the environment. -let input = env.into_input()?; +let input = env.into_input().await?; ``` [install-rust]: https://doc.rust-lang.org/cargo/getting-started/installation.html -[cargo-binstall]: https://github.com/cargo-bins/cargo-binstall#cargo-binaryinstall +[install-risczero]: https://dev.risczero.com/api/zkvm/install diff --git a/examples/token-stats/README.md b/examples/token-stats/README.md index deac5305..45a336b8 100644 --- a/examples/token-stats/README.md +++ b/examples/token-stats/README.md @@ -6,24 +6,13 @@ To get started, you need to have Rust installed. If you haven't done so, follow the instructions [here][install-rust]. -Next, install the `cargo risczero` tool. We'll use `cargo binstall` to facilitate this. Detailed instructions can be found at [cargo-binstall]. +Next, you will also need to have the `cargo-risczero` tool installed following the instructions [here][install-risczero]. -```bash -cargo install cargo-binstall -cargo binstall cargo-risczero -``` - -Finally, install the `risc0` toolchain with the following command: - -```bash -cargo risczero install -``` - -You'll also need access to an Ethereum RPC node, such as through [Alchemy](www.alchemy.com). +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](www.alchemy.com). ## Run the example -To run the example, which computes the current APR of the Compound USDC Token `0xc3d688B66703497DAA19211EEdff47f25384cdc3` on Ethereum, execute the following command: +To run the example, which computes the current APR of the Compound USDC Token [`0xc3d688B66703497DAA19211EEdff47f25384cdc3`](https://etherscan.io/token/0xc3d688B66703497DAA19211EEdff47f25384cdc3) on Ethereum, execute the following command: ```bash RPC_URL=https://ethereum-rpc.publicnode.com RUST_LOG=info cargo run --release @@ -32,15 +21,19 @@ RPC_URL=https://ethereum-rpc.publicnode.com RUST_LOG=info cargo run --release The output should resemble the following: ```text -2024-06-04T20:47:18.785315Z INFO risc0_steel::contract: Executing preflight for 'getUtilization()' on contract 0xc3d688B66703497DAA19211EEdff47f25384cdc3 -2024-06-04T20:47:20.979605Z INFO risc0_steel::contract: Executing preflight for 'getSupplyRate(uint256)' on contract 0xc3d688B66703497DAA19211EEdff47f25384cdc3 +2024-08-05T17:58:28.709271Z INFO risc0_steel::host: Environment initialized for block 20464007 +2024-08-05T17:58:28.709406Z INFO risc0_steel: Commitment to block 0xba19f4d5d1aabd1e4ddca7263f1307cfdec1252041395edfc1d8507eaf142cf8 +2024-08-05T17:58:28.709502Z INFO risc0_steel::contract: Executing preflight calling 'getUtilization()' on 0xc3d688B66703497DAA19211EEdff47f25384cdc3 +Call getUtilization() Function on 0xc3d6…cdc3 returns: 715303307067353898 +2024-08-05T17:58:29.974428Z INFO risc0_steel::contract: Executing preflight calling 'getSupplyRate(uint256)' on 0xc3d688B66703497DAA19211EEdff47f25384cdc3 +Call getSupplyRate(uint256) Function on 0xc3d6…cdc3 returns: 1179470191 Running the guest with the constructed input: -2024-06-04T20:47:23.011329Z INFO executor: risc0_zkvm::host::server::exec::executor: execution time: 443.8825ms -2024-06-04T20:47:23.011368Z INFO executor: risc0_zkvm::host::server::session: number of segments: 11 -2024-06-04T20:47:23.011371Z INFO executor: risc0_zkvm::host::server::session: total cycles: 11534336 -2024-06-04T20:47:23.011373Z INFO executor: risc0_zkvm::host::server::session: user cycles: 8945420 -Proven APR calculated is: 6.7249996533936% +2024-08-05T17:58:31.587359Z INFO executor: risc0_zkvm::host::server::exec::executor: execution time: 196.721584ms +2024-08-05T17:58:31.587385Z INFO executor: risc0_zkvm::host::server::session: number of segments: 11 +2024-08-05T17:58:31.587388Z INFO executor: risc0_zkvm::host::server::session: total cycles: 11534336 +2024-08-05T17:58:31.587390Z INFO executor: risc0_zkvm::host::server::session: user cycles: 8885255 +Proven APR calculated is: 3.7195771943376% ``` [install-rust]: https://doc.rust-lang.org/cargo/getting-started/installation.html -[cargo-binstall]: https://github.com/cargo-bins/cargo-binstall#cargo-binaryinstall +[install-risczero]: https://dev.risczero.com/api/zkvm/install From 9fa83a4925299e4e210ee7545de5b8e35e33961f Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 6 Aug 2024 11:20:48 +0200 Subject: [PATCH 20/30] update alloy-rlp --- Cargo.toml | 7 +++---- steel/Cargo.toml | 1 - steel/src/mpt.rs | 30 ++++++------------------------ steel/src/serde.rs | 10 ++-------- 4 files changed, 11 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 89544017..36c58b22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,9 +23,9 @@ risc0-zkvm = { git = "https://github.com/risc0/risc0", branch = "main", default- # Alloy guest dependencies alloy-consensus = { version = "0.2.1" } -alloy-primitives = { version = "0.7", features = ["serde", "rlp", "std"] } -alloy-rlp = { version = "0.3.7", default-features = false } -alloy-rlp-derive = { version = "0.3.7", default-features = false } +alloy-primitives = { version = "0.7", features = ["rlp", "std"] } +alloy-rlp = { version = "0.3.8", default-features = false } +alloy-rlp-derive = { version = "0.3.8", default-features = false } alloy-sol-types = { version = "0.7" } # Alloy host dependencies @@ -42,7 +42,6 @@ revm = { version = "10.0", default-features = false, features = ["std"] } serde = "1.0" serde_json = "1.0" test-log = "0.2.15" -thiserror = "1.0" tokio = { version = "1.35" } tracing-subscriber = { version = "0.3", features = ["env-filter"] } url = { version = "2.5" } diff --git a/steel/Cargo.toml b/steel/Cargo.toml index 602ea7ed..817875cc 100644 --- a/steel/Cargo.toml +++ b/steel/Cargo.toml @@ -25,7 +25,6 @@ once_cell = { workspace = true } revm = { workspace = true, features = ["serde"] } serde = { workspace = true } serde_json = { workspace = true, optional = true } -thiserror = { workspace = true } tokio = { workspace = true, optional = true } url = { workspace = true } diff --git a/steel/src/mpt.rs b/steel/src/mpt.rs index 62346d78..54823f4e 100644 --- a/steel/src/mpt.rs +++ b/steel/src/mpt.rs @@ -19,24 +19,11 @@ use alloy_rlp::{BufMut, Decodable, Encodable, Header, PayloadView, EMPTY_STRING_ use nybbles::Nibbles; use revm::primitives::HashMap; use serde::{Deserialize, Serialize}; -use thiserror::Error as ThisError; /// Root hash of an empty Merkle Patricia trie, i.e. `keccak256(RLP(""))`. pub const EMPTY_ROOT_HASH: B256 = b256!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); -/// The error type that is returned when parsing a [MerkleTrie] node. -#[derive(Debug, ThisError)] -pub enum ParseNodeError { - // Error that occurs when a node has data after its RLP encoding. - #[error("Node has additional bytes")] - AdditionalBytes, - - /// Error that occurs when parsing the RLP encoding of a node. - #[error("RLP error")] - Rlp(#[from] alloy_rlp::Error), -} - /// A sparse Merkle Patricia trie storing byte values. #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct MerkleTrie(Node); @@ -89,7 +76,7 @@ impl MerkleTrie { /// that the root hash can be computed and matches the root hash of the fully resolved trie. pub fn from_rlp_nodes>( nodes: impl IntoIterator, - ) -> Result { + ) -> alloy_rlp::Result { let mut nodes_by_hash = HashMap::new(); let mut root_node_opt = None; @@ -222,12 +209,12 @@ impl Decodable for Node { // branch node: 17-item node [ v0 ... v15, value ] 17 => { let mut children: [Option>; 16] = Default::default(); - for (i, mut node_rlp) in items.into_iter().enumerate() { + for (i, node_rlp) in items.into_iter().enumerate() { if node_rlp != [EMPTY_STRING_CODE] { if i == 16 { return Err(alloy_rlp::Error::Custom("branch node with value")); } else { - children[i] = Some(Box::new(Node::decode(&mut node_rlp)?)); + children[i] = Some(Box::new(alloy_rlp::decode_exact(node_rlp)?)); } } } @@ -242,7 +229,7 @@ impl Decodable for Node { let value = Header::decode_bytes(&mut items[1], false)?; Ok(Node::Leaf(path, value.into())) } else { - let node = Node::decode(&mut items[1])?; + let node = alloy_rlp::decode_exact(items[1])?; if node == Node::Null { return Err(alloy_rlp::Error::Custom("extension node with null child")); } @@ -338,14 +325,9 @@ fn decode_path(buf: &mut &[u8]) -> alloy_rlp::Result<(Nibbles, bool)> { } /// Returns the decoded node and its RLP hash. -fn parse_node(rlp: impl AsRef<[u8]>) -> Result<(Option, Node), ParseNodeError> { +fn parse_node(rlp: impl AsRef<[u8]>) -> alloy_rlp::Result<(Option, Node)> { let rlp = rlp.as_ref(); - // decode the node without advancing - let mut buf = rlp; - let node = Node::decode(&mut buf)?; - if !buf.is_empty() { - return Err(ParseNodeError::AdditionalBytes); - } + let node = alloy_rlp::decode_exact(rlp)?; // the hash is only needed for RLP length >= 32 Ok(((rlp.len() >= 32).then(|| keccak256(rlp)), node)) diff --git a/steel/src/serde.rs b/steel/src/serde.rs index 5fc8aa19..7730889e 100644 --- a/steel/src/serde.rs +++ b/steel/src/serde.rs @@ -103,16 +103,10 @@ impl<'de, H: Encodable + Decodable> Deserialize<'de> for RlpHeader { } 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 mut buf = rlp.as_slice(); - let header = H::decode(&mut buf).map_err(de::Error::custom)?; - if !buf.is_empty() { - return Err(de::Error::custom("trailing bytes")); - } + let inner = alloy_rlp::decode_exact(&rlp).map_err(de::Error::custom)?; Ok(RlpHeader { - inner: header, + inner, rlp: Some(rlp), }) } From 3b6b162540323aef44110646189358940ec3675e Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 6 Aug 2024 11:23:21 +0200 Subject: [PATCH 21/30] add comment --- steel/src/serde.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/steel/src/serde.rs b/steel/src/serde.rs index 7730889e..1fcbfca8 100644 --- a/steel/src/serde.rs +++ b/steel/src/serde.rs @@ -103,6 +103,8 @@ impl<'de, H: Encodable + Decodable> Deserialize<'de> for RlpHeader { } 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 { From 75f57181a01467cdf653d1ee12f723a076653591 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 6 Aug 2024 12:48:04 +0200 Subject: [PATCH 22/30] enable logging for blockhash --- steel/tests/steel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/steel/tests/steel.rs b/steel/tests/steel.rs index 4fc58db0..60079c02 100644 --- a/steel/tests/steel.rs +++ b/steel/tests/steel.rs @@ -151,7 +151,7 @@ async fn eoa_account() { assert_eq!(result.size, uint!(0_U256)); } -#[tokio::test] // Anvil crashes, if logging is enabled +#[test(tokio::test)] async fn blockhash() { let provider = test_provider().await; let block_hash = provider.anvil_node_info().await.unwrap().current_block_hash; From b2d6071c59975a9d2fed420272cc410a41544cfe Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 6 Aug 2024 16:03:58 +0200 Subject: [PATCH 23/30] chain spec cleanup --- steel/src/config.rs | 85 ++++++++++++++----------------------------- steel/src/ethereum.rs | 9 ++--- 2 files changed, 30 insertions(+), 64 deletions(-) diff --git a/steel/src/config.rs b/steel/src/config.rs index 2be675ca..6612b4b1 100644 --- a/steel/src/config.rs +++ b/steel/src/config.rs @@ -49,10 +49,8 @@ impl ForkCondition { pub struct ChainSpec { /// Chain identifier. pub chain_id: ChainId, - /// ID of the latest supported revm specification. - pub max_spec_id: SpecId, /// Map revm specification IDs to their respective activation condition. - pub hard_forks: BTreeMap, + pub forks: BTreeMap, } impl ChainSpec { @@ -60,80 +58,51 @@ impl ChainSpec { pub fn new_single(chain_id: ChainId, spec_id: SpecId) -> Self { ChainSpec { chain_id, - max_spec_id: spec_id, - hard_forks: BTreeMap::from([(spec_id, ForkCondition::Block(0))]), + forks: BTreeMap::from([(spec_id, ForkCondition::Block(0))]), } } + /// Returns the network chain ID. + #[inline] pub fn chain_id(&self) -> ChainId { self.chain_id } - /// Validates a [SpecId]. - pub fn validate_spec_id(&self, spec_id: SpecId) -> anyhow::Result<()> { - let (min_spec_id, _) = self.hard_forks.first_key_value().unwrap(); - if spec_id < *min_spec_id { - bail!("expected >= {:?}, got {:?}", min_spec_id, spec_id); - } - if spec_id > self.max_spec_id { - bail!("expected <= {:?}, got {:?}", self.max_spec_id, spec_id); - } - Ok(()) - } - /// Returns the [SpecId] for a given block number and timestamp or an error if not - /// supported. - pub fn active_fork(&self, block_number: BlockNumber, timestamp: u64) -> anyhow::Result { - match self.spec_id(block_number, timestamp) { - Some(spec_id) => { - if spec_id > self.max_spec_id { - bail!("expected <= {:?}, got {:?}", self.max_spec_id, spec_id); - } else { - Ok(spec_id) - } - } - None => bail!("no supported fork for block {}", block_number), - } - } - fn spec_id(&self, block_number: BlockNumber, timestamp: u64) -> Option { - for (spec_id, fork) in self.hard_forks.iter().rev() { + /// Returns the [SpecId] for a given block number and timestamp or an error if not supported. + pub fn active_fork(&self, block_number: BlockNumber, timestamp: u64) -> anyhow::Result { + for (spec_id, fork) in self.forks.iter().rev() { if fork.active(block_number, timestamp) { - return Some(*spec_id); + return Ok(*spec_id); } } - None + bail!("no supported fork for block {}", block_number) } } #[cfg(test)] mod tests { - use super::*; - - use once_cell::sync::Lazy; + use std::u64; - static ETH_MAINNET_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { - chain_id: 1, - max_spec_id: SpecId::CANCUN, - hard_forks: BTreeMap::from([ - (SpecId::MERGE, ForkCondition::Block(15537394)), - (SpecId::SHANGHAI, ForkCondition::Timestamp(1681338455)), - (SpecId::CANCUN, ForkCondition::Timestamp(1710338135)), - ]), - }); + use super::*; #[test] - fn spec_id() { - assert_eq!(ETH_MAINNET_CHAIN_SPEC.spec_id(15537393, 0), None); - assert_eq!( - ETH_MAINNET_CHAIN_SPEC.spec_id(15537394, 0), - Some(SpecId::MERGE) - ); - assert_eq!( - ETH_MAINNET_CHAIN_SPEC.spec_id(17034869, 0), - Some(SpecId::MERGE) - ); + fn active_fork() { + let spec = ChainSpec { + chain_id: 1, + forks: BTreeMap::from([ + (SpecId::MERGE, ForkCondition::Block(2)), + (SpecId::CANCUN, ForkCondition::Timestamp(60)), + (SpecId::PRAGUE, ForkCondition::TBD), + ]), + }; + + assert!(spec.active_fork(0, 0).is_err()); + assert_eq!(spec.active_fork(2, 0).unwrap(), SpecId::MERGE); + assert_eq!(spec.active_fork(u64::MAX, 59).unwrap(), SpecId::MERGE); + assert_eq!(spec.active_fork(0, 60).unwrap(), SpecId::CANCUN); assert_eq!( - ETH_MAINNET_CHAIN_SPEC.spec_id(0, 1681338455), - Some(SpecId::SHANGHAI) + spec.active_fork(u64::MAX, u64::MAX).unwrap(), + SpecId::CANCUN ); } } diff --git a/steel/src/ethereum.rs b/steel/src/ethereum.rs index 2dc7bfd8..0dd9156d 100644 --- a/steel/src/ethereum.rs +++ b/steel/src/ethereum.rs @@ -27,8 +27,7 @@ use revm::primitives::{BlockEnv, SpecId}; /// The Ethereum Sepolia [ChainSpec]. pub static ETH_SEPOLIA_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { chain_id: 11155111, - max_spec_id: SpecId::CANCUN, - hard_forks: BTreeMap::from([ + forks: BTreeMap::from([ (SpecId::MERGE, ForkCondition::Block(1735371)), (SpecId::SHANGHAI, ForkCondition::Timestamp(1677557088)), (SpecId::CANCUN, ForkCondition::Timestamp(1706655072)), @@ -38,8 +37,7 @@ pub static ETH_SEPOLIA_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { /// The Ethereum Holešky [ChainSpec]. pub static ETH_HOLESKY_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { chain_id: 17000, - max_spec_id: SpecId::CANCUN, - hard_forks: BTreeMap::from([ + forks: BTreeMap::from([ (SpecId::MERGE, ForkCondition::Block(0)), (SpecId::SHANGHAI, ForkCondition::Timestamp(1696000704)), (SpecId::CANCUN, ForkCondition::Timestamp(1707305664)), @@ -49,8 +47,7 @@ pub static ETH_HOLESKY_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { /// The Ethereum Mainnet [ChainSpec]. pub static ETH_MAINNET_CHAIN_SPEC: Lazy = Lazy::new(|| ChainSpec { chain_id: 1, - max_spec_id: SpecId::CANCUN, - hard_forks: BTreeMap::from([ + forks: BTreeMap::from([ (SpecId::MERGE, ForkCondition::Block(15537394)), (SpecId::SHANGHAI, ForkCondition::Timestamp(1681338455)), (SpecId::CANCUN, ForkCondition::Timestamp(1710338135)), From f4e7e7f550730439370c6d508fbb99d20988d1f4 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 6 Aug 2024 23:29:07 +0200 Subject: [PATCH 24/30] add solc compile instructions --- steel/tests/erc20.rs | 1 + steel/tests/steel.rs | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/steel/tests/erc20.rs b/steel/tests/erc20.rs index 1357ffad..496e445a 100644 --- a/steel/tests/erc20.rs +++ b/steel/tests/erc20.rs @@ -26,6 +26,7 @@ mod common; const USDT_MAINNET_ADDRESS: Address = address!("dAC17F958D2ee523a2206206994597C13D831ec7"); alloy::sol!( + // https://etherscan.io/address/0xdAC17F958D2ee523a2206206994597C13D831ec7#code #[sol(rpc, deployed_bytecode="0x606060405260043610610196576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461019b5780630753c30c14610229578063095ea7b3146102625780630e136b19146102a45780630ecb93c0146102d157806318160ddd1461030a57806323b872dd1461033357806326976e3f1461039457806327e235e3146103e9578063313ce56714610436578063353907141461045f5780633eaaf86b146104885780633f4ba83a146104b157806359bf1abe146104c65780635c658165146105175780635c975abb1461058357806370a08231146105b05780638456cb59146105fd578063893d20e8146106125780638da5cb5b1461066757806395d89b41146106bc578063a9059cbb1461074a578063c0324c771461078c578063cc872b66146107b8578063db006a75146107db578063dd62ed3e146107fe578063dd644f721461086a578063e47d606014610893578063e4997dc5146108e4578063e5b5019a1461091d578063f2fde38b14610946578063f3bdc2281461097f575b600080fd5b34156101a657600080fd5b6101ae6109b8565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101ee5780820151818401526020810190506101d3565b50505050905090810190601f16801561021b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561023457600080fd5b610260600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a56565b005b341561026d57600080fd5b6102a2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b73565b005b34156102af57600080fd5b6102b7610cc1565b604051808215151515815260200191505060405180910390f35b34156102dc57600080fd5b610308600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cd4565b005b341561031557600080fd5b61031d610ded565b6040518082815260200191505060405180910390f35b341561033e57600080fd5b610392600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610ebd565b005b341561039f57600080fd5b6103a761109d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f457600080fd5b610420600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506110c3565b6040518082815260200191505060405180910390f35b341561044157600080fd5b6104496110db565b6040518082815260200191505060405180910390f35b341561046a57600080fd5b6104726110e1565b6040518082815260200191505060405180910390f35b341561049357600080fd5b61049b6110e7565b6040518082815260200191505060405180910390f35b34156104bc57600080fd5b6104c46110ed565b005b34156104d157600080fd5b6104fd600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506111ab565b604051808215151515815260200191505060405180910390f35b341561052257600080fd5b61056d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611201565b6040518082815260200191505060405180910390f35b341561058e57600080fd5b610596611226565b604051808215151515815260200191505060405180910390f35b34156105bb57600080fd5b6105e7600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611239565b6040518082815260200191505060405180910390f35b341561060857600080fd5b610610611348565b005b341561061d57600080fd5b610625611408565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561067257600080fd5b61067a611431565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156106c757600080fd5b6106cf611456565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561070f5780820151818401526020810190506106f4565b50505050905090810190601f16801561073c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561075557600080fd5b61078a600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506114f4565b005b341561079757600080fd5b6107b6600480803590602001909190803590602001909190505061169e565b005b34156107c357600080fd5b6107d96004808035906020019091905050611783565b005b34156107e657600080fd5b6107fc600480803590602001909190505061197a565b005b341561080957600080fd5b610854600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611b0d565b6040518082815260200191505060405180910390f35b341561087557600080fd5b61087d611c52565b6040518082815260200191505060405180910390f35b341561089e57600080fd5b6108ca600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611c58565b604051808215151515815260200191505060405180910390f35b34156108ef57600080fd5b61091b600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611c78565b005b341561092857600080fd5b610930611d91565b6040518082815260200191505060405180910390f35b341561095157600080fd5b61097d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611db5565b005b341561098a57600080fd5b6109b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611e8a565b005b60078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a4e5780601f10610a2357610100808354040283529160200191610a4e565b820191906000526020600020905b815481529060010190602001808311610a3157829003601f168201915b505050505081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ab157600080fd5b6001600a60146101000a81548160ff02191690831515021790555080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcc358699805e9a8b7f77b522628c7cb9abd07d9efb86b6fb616af1609036a99e81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b604060048101600036905010151515610b8b57600080fd5b600a60149054906101000a900460ff1615610cb157600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663aee92d333385856040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1515610c9857600080fd5b6102c65a03f11515610ca957600080fd5b505050610cbc565b610cbb838361200e565b5b505050565b600a60149054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d2f57600080fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507f42e160154868087d6bfdc0ca23d96a1c1cfa32f1b72ba9ba27b69b98a0d819dc81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b6000600a60149054906101000a900460ff1615610eb457600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610e9257600080fd5b6102c65a03f11515610ea357600080fd5b505050604051805190509050610eba565b60015490505b90565b600060149054906101000a900460ff16151515610ed957600080fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515610f3257600080fd5b600a60149054906101000a900460ff161561108c57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638b477adb338585856040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050600060405180830381600087803b151561107357600080fd5b6102c65a03f1151561108457600080fd5b505050611098565b6110978383836121ab565b5b505050565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60026020528060005260406000206000915090505481565b60095481565b60045481565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561114857600080fd5b600060149054906101000a900460ff16151561116357600080fd5b60008060146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6005602052816000526040600020602052806000526040600020600091509150505481565b600060149054906101000a900460ff1681565b6000600a60149054906101000a900460ff161561133757600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231836000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561131557600080fd5b6102c65a03f1151561132657600080fd5b505050604051805190509050611343565b61134082612652565b90505b919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113a357600080fd5b600060149054906101000a900460ff161515156113bf57600080fd5b6001600060146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60088054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114ec5780601f106114c1576101008083540402835291602001916114ec565b820191906000526020600020905b8154815290600101906020018083116114cf57829003601f168201915b505050505081565b600060149054906101000a900460ff1615151561151057600080fd5b600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561156957600080fd5b600a60149054906101000a900460ff161561168f57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e18980a3384846040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b151561167657600080fd5b6102c65a03f1151561168757600080fd5b50505061169a565b611699828261269b565b5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116f957600080fd5b60148210151561170857600080fd5b60328110151561171757600080fd5b81600381905550611736600954600a0a82612a0390919063ffffffff16565b6004819055507fb044a1e409eac5c48e5af22d4af52670dd1a99059537a78b31b48c6500a6354e600354600454604051808381526020018281526020019250505060405180910390a15050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156117de57600080fd5b60015481600154011115156117f257600080fd5b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011115156118c257600080fd5b80600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550806001600082825401925050819055507fcb8241adb0c3fdb35b70c24ce35c5eb0c17af7431c99f827d44a445ca624176a816040518082815260200191505060405180910390a150565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156119d557600080fd5b80600154101515156119e657600080fd5b80600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515611a5557600080fd5b8060016000828254039250508190555080600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507f702d5967f45f6513a38ffc42d6ba9bf230bd40e8f53b16363c7eb4fd2deb9a44816040518082815260200191505060405180910390a150565b6000600a60149054906101000a900460ff1615611c3f57600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b1515611c1d57600080fd5b6102c65a03f11515611c2e57600080fd5b505050604051805190509050611c4c565b611c498383612a3e565b90505b92915050565b60035481565b60066020528060005260406000206000915054906101000a900460ff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611cd357600080fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fd7e9ec6e6ecd65492dce6bf513cd6867560d49544421d0783ddf06e76c24470c81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611e1057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515611e8757806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611ee757600080fd5b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611f3f57600080fd5b611f4882611239565b90506000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550806001600082825403925050819055507f61e6e66b0d6339b2980aecc6ccc0039736791f0ccde9ed512e789a7fbdd698c68282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15050565b60406004810160003690501015151561202657600080fd5b600082141580156120b457506000600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b1515156120c057600080fd5b81600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a3505050565b60008060006060600481016000369050101515156121c857600080fd5b600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054935061227061271061226260035488612a0390919063ffffffff16565b612ac590919063ffffffff16565b92506004548311156122825760045492505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84101561233e576122bd8585612ae090919063ffffffff16565b600560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6123518386612ae090919063ffffffff16565b91506123a585600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ae090919063ffffffff16565b600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061243a82600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060008311156125e4576124f983600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b8573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000806040600481016000369050101515156126b657600080fd5b6126df6127106126d160035487612a0390919063ffffffff16565b612ac590919063ffffffff16565b92506004548311156126f15760045492505b6127048385612ae090919063ffffffff16565b915061275884600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612ae090919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506127ed82600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000831115612997576128ac83600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054612af990919063ffffffff16565b600260008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b8473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a35050505050565b6000806000841415612a185760009150612a37565b8284029050828482811515612a2957fe5b04141515612a3357fe5b8091505b5092915050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000808284811515612ad357fe5b0490508091505092915050565b6000828211151515612aee57fe5b818303905092915050565b6000808284019050838110151515612b0d57fe5b80915050929150505600a165627a7a72305820645ee12d73db47fd78ba77fa1f824c3c8f9184061b3b10386beb4dc9236abb280029")] #[derive(Debug, PartialEq, Eq)] interface IERC20 { diff --git a/steel/tests/steel.rs b/steel/tests/steel.rs index 60079c02..1faedca3 100644 --- a/steel/tests/steel.rs +++ b/steel/tests/steel.rs @@ -36,7 +36,8 @@ mod common; const STEEL_TEST_CONTRACT: Address = address!("5fbdb2315678afecb367f032d93f642f64180aa3"); alloy::sol!( - #[sol(rpc, bytecode="60e060405234801561000f575f80fd5b505f60405161001d906100c4565b908152602001604051809103905ff08015801561003c573d5f803e3d5ffd5b506001600160a01b0316608052604051602a90610058906100c4565b908152602001604051809103905ff080158015610077573d5f803e3d5ffd5b506001600160a01b031660a052604051602a90610093906100c4565b908152602001604051809103905ff0801580156100b2573d5f803e3d5ffd5b506001600160a01b031660c0526100d0565b60c98061041e83390190565b60805160a05160c0516103256100f95f395f60de01525f61015e01525f6101de01526103255ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063445bda4311610058578063445bda43146100ba5780637d732b5f146100c25780639f6f32aa146100c8578063ab8fd80c146100d0575f80fd5b80630692d13c146100895780632e8bde391461009f57806330e49663146100ad57806341317185146100b3575b5f80fd5b5f3b5b6040519081526020015b60405180910390f35b604051328152602001610096565b3a61008c565b443b61008c565b61008c6100db565b4661008c565b61008c610275565b4360ff19014061008c565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610138573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061015c91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101dc91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610238573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025c91906102b3565b61026691906102ca565b61027091906102ca565b905090565b6040515f906002906020818481855afa158015610294573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061027091905b5f602082840312156102c3575f80fd5b5051919050565b808201808211156102e957634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220193bf7ba8b1afe2d8e735c81e13a2034829eae79d36eac8db076b92ff6308ba564736f6c634300081900336080604052348015600e575f80fd5b5060405160c938038060c9833981016040819052602991602f565b5f556045565b5f60208284031215603e575f80fd5b5051919050565b60798060505f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3fea2646970667358221220c28e11a00819347c873d20f4ecc0a120e64201cb1a824335d007cf34e8c3ff8164736f6c63430008190033")] + // docker run -i ethereum/solc:0.8.26 - --optimize --bin + #[sol(rpc, bytecode="60e060405234801561000f575f80fd5b505f60405161001d906100c4565b908152602001604051809103905ff08015801561003c573d5f803e3d5ffd5b506001600160a01b0316608052604051602a90610058906100c4565b908152602001604051809103905ff080158015610077573d5f803e3d5ffd5b506001600160a01b031660a052604051602a90610093906100c4565b908152602001604051809103905ff0801580156100b2573d5f803e3d5ffd5b506001600160a01b031660c0526100d0565b60c98061041e83390190565b60805160a05160c0516103256100f95f395f60de01525f61015e01525f6101de01526103255ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c8063445bda4311610058578063445bda43146100ba5780637d732b5f146100c25780639f6f32aa146100c8578063ab8fd80c146100d0575f80fd5b80630692d13c146100895780632e8bde391461009f57806330e49663146100ad57806341317185146100b3575b5f80fd5b5f3b5b6040519081526020015b60405180910390f35b604051328152602001610096565b3a61008c565b443b61008c565b61008c6100db565b4661008c565b61008c610275565b4360ff19014061008c565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610138573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061015c91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101dc91906102b3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633fa4f2456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610238573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025c91906102b3565b61026691906102ca565b61027091906102ca565b905090565b6040515f906002906020818481855afa158015610294573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061027091905b5f602082840312156102c3575f80fd5b5051919050565b808201808211156102e957634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220da3a26098dd43c05acc2240a43d0fc9fcbddfefe20da8b1b7b298a9deb28c08f64736f6c634300081a00336080604052348015600e575f80fd5b5060405160c938038060c9833981016040819052602991602f565b5f556045565b5f60208284031215603e575f80fd5b5051919050565b60798060505f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80633fa4f24514602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3fea2646970667358221220ae38f162affb03bb6f61ae063b82ed619bbef90cd2349cf62045b42e5366a10064736f6c634300081a0033")] #[derive(Debug, PartialEq, Eq)] contract SteelTest { Value internal immutable VALUE0; @@ -90,6 +91,14 @@ alloy::sol!( return VALUE0.value() + VALUE42A.value() + VALUE42B.value(); } } + + contract Value { + uint256 public value; + + constructor(uint256 _value) { + value = _value; + } + } ); type TestProvider = FillProvider< From eded136a25ff400e3f108da9ad17ae51e4c86fbd Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Tue, 6 Aug 2024 23:34:58 +0200 Subject: [PATCH 25/30] fix fmt --- steel/tests/steel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/steel/tests/steel.rs b/steel/tests/steel.rs index 1faedca3..cc5058af 100644 --- a/steel/tests/steel.rs +++ b/steel/tests/steel.rs @@ -94,7 +94,7 @@ alloy::sol!( contract Value { uint256 public value; - + constructor(uint256 _value) { value = _value; } From a42c5e31983ac27817e1e0ebc9552d75f1aef0af Mon Sep 17 00:00:00 2001 From: Angelo Capossele Date: Wed, 7 Aug 2024 09:32:51 +0100 Subject: [PATCH 26/30] Improve groth16 encode API (#179) Pending #185 Attempt at solving #174 and #176. Closes #174 Closes #176 --------- Co-authored-by: Victor Graf --- .github/workflows/main.yml | 8 ++-- contracts/Cargo.toml | 6 +-- contracts/build.rs | 41 ----------------- contracts/src/groth16.rs | 20 ++++++--- contracts/src/lib.rs | 44 +++++++++++++++---- .../erc20-counter/apps/src/bin/publisher.rs | 6 +-- .../erc20-counter/script/DeployCounter.s.sol | 7 ++- ffi/Cargo.toml | 2 +- ffi/src/main.rs | 23 +++------- 9 files changed, 67 insertions(+), 90 deletions(-) delete mode 100644 contracts/build.rs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e8ff498f..712cb4ab 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -73,15 +73,15 @@ jobs: strategy: fail-fast: false matrix: - os: [Linux, macOS] - feature: [default] - device: [cpu] include: + - os: Linux + feature: default + device: cpu - os: Linux feature: cuda device: nvidia_rtx_a5000 - os: macOS - feature: metal + feature: default device: apple_m2_pro env: FEATURE: ${{ matrix.feature }} diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index e2555e46..e008f0af 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -11,14 +11,14 @@ repository = { workspace = true } anyhow = "1.0" [dependencies] -alloy-sol-types = { workspace = true } +alloy = { workspace = true, features = ["sol-types", "contract"] } anyhow = { workspace = true } -ethers = { version = "2.0", features = ["rustls", "ws"] } risc0-zkvm = { workspace = true } [dev-dependencies] +hex = "0.4" regex = "1.10" -tokio = { version = "1", features = ["macros", "rt"] } +tokio = { workspace = true, features = ["macros", "rt"] } [lib] doctest = false diff --git a/contracts/build.rs b/contracts/build.rs deleted file mode 100644 index ced35e6c..00000000 --- a/contracts/build.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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. - -//! Build Solidity contracts with Foundry when `cargo build` is invoked. - -use std::process::Command; - -use anyhow::Context; - -fn main() -> anyhow::Result<()> { - let out_dir = std::env::var("OUT_DIR").unwrap(); - let out_dir = std::path::Path::new(&out_dir); - let cache_dir = out_dir.join(".cache"); - - let mut forge_build = Command::new("forge") - .arg("build") - .arg("--cache-path") - .arg(cache_dir) - .arg("--out") - .arg(out_dir) - .spawn() - .context("failed to start `forge build`")?; - - let status = forge_build.wait().context("failed to run `forge build`")?; - if !status.success() { - anyhow::bail!("`forge build` exited with failed status: {}", status); - } - - Ok(()) -} diff --git a/contracts/src/groth16.rs b/contracts/src/groth16.rs index 832f9423..b1e30a6f 100644 --- a/contracts/src/groth16.rs +++ b/contracts/src/groth16.rs @@ -12,23 +12,30 @@ // See the License for the specific language governing permissions and // limitations under the License. -use alloy_sol_types::SolValue; +use alloy::sol_types::SolValue; use anyhow::Result; use risc0_zkvm::{sha::Digestible, Groth16ReceiptVerifierParameters}; /// ABI encoding of the seal. -pub fn abi_encode(seal: Vec) -> Result> { +pub fn abi_encode(seal: impl AsRef<[u8]>) -> Result> { Ok(encode(seal)?.abi_encode()) } -/// encoding of the seal with selector. -pub fn encode(seal: Vec) -> Result> { +/// Encoding of a Groth16 seal by prefixing it with the verifier selector. +/// +/// The verifier selector is determined from the first 4 bytes of the hash of the verifier +/// parameters including the Groth16 verification key and the control IDs that commit to the RISC +/// Zero circuits. +/// +/// NOTE: Selector value of the current zkVM version is used. If you need to use a selector from a +/// different version of the zkVM, use the [encode_seal] method instead. +pub fn encode(seal: impl AsRef<[u8]>) -> Result> { let verifier_parameters_digest = Groth16ReceiptVerifierParameters::default().digest(); let selector = &verifier_parameters_digest.as_bytes()[..4]; // Create a new vector with the capacity to hold both selector and seal - let mut selector_seal = Vec::with_capacity(selector.len() + seal.len()); + let mut selector_seal = Vec::with_capacity(selector.len() + seal.as_ref().len()); selector_seal.extend_from_slice(selector); - selector_seal.extend_from_slice(&seal); + selector_seal.extend_from_slice(seal.as_ref()); Ok(selector_seal) } @@ -36,7 +43,6 @@ pub fn encode(seal: Vec) -> Result> { #[cfg(test)] mod tests { use anyhow::anyhow; - use ethers::utils::hex; use regex::Regex; use super::*; diff --git a/contracts/src/lib.rs b/contracts/src/lib.rs index 112c39c8..7670d634 100644 --- a/contracts/src/lib.rs +++ b/contracts/src/lib.rs @@ -12,15 +12,41 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ethers::prelude::*; - -abigen!( - IRiscZeroVerifier, - "$OUT_DIR/IRiscZeroVerifier.sol/IRiscZeroVerifier.json" -); -abigen!( - RiscZeroGroth16Verifier, - "$OUT_DIR/RiscZeroGroth16Verifier.sol/RiscZeroGroth16Verifier.json" +alloy::sol!( + #![sol(rpc, all_derives)] + "src/IRiscZeroVerifier.sol" ); pub mod groth16; + +use anyhow::{bail, Result}; +use risc0_zkvm::{sha::Digestible, InnerReceipt}; + +/// Encode the seal of the given receipt for use with EVM smart contract verifiers. +/// +/// Appends the verifier selector, determined from the first 4 bytes of the verifier parameters +/// including the Groth16 verification key and the control IDs that commit to the RISC Zero +/// circuits. +pub fn encode_seal(receipt: &risc0_zkvm::Receipt) -> Result> { + let seal = match receipt.inner.clone() { + InnerReceipt::Fake(receipt) => { + let seal = receipt.claim.digest().as_bytes().to_vec(); + let selector = &[0u8; 4]; + // Create a new vector with the capacity to hold both selector and seal + let mut selector_seal = Vec::with_capacity(selector.len() + seal.len()); + selector_seal.extend_from_slice(selector); + selector_seal.extend_from_slice(&seal); + selector_seal + } + InnerReceipt::Groth16(receipt) => { + let selector = &receipt.verifier_parameters.as_bytes()[..4]; + // Create a new vector with the capacity to hold both selector and seal + let mut selector_seal = Vec::with_capacity(selector.len() + receipt.seal.len()); + selector_seal.extend_from_slice(selector); + selector_seal.extend_from_slice(receipt.seal.as_ref()); + selector_seal + } + _ => bail!("Unsupported receipt type"), + }; + Ok(seal) +} diff --git a/examples/erc20-counter/apps/src/bin/publisher.rs b/examples/erc20-counter/apps/src/bin/publisher.rs index 25298452..47bcb6ab 100644 --- a/examples/erc20-counter/apps/src/bin/publisher.rs +++ b/examples/erc20-counter/apps/src/bin/publisher.rs @@ -26,7 +26,7 @@ use alloy_primitives::Address; use anyhow::{ensure, Context, Result}; use clap::Parser; use erc20_counter_methods::BALANCE_OF_ELF; -use risc0_ethereum_contracts::groth16::encode; +use risc0_ethereum_contracts::encode_seal; use risc0_steel::{ ethereum::{EthEvmEnv, ETH_SEPOLIA_CHAIN_SPEC}, host::BlockNumberOrTag, @@ -134,13 +134,11 @@ async fn main() -> Result<()> { .await? .context("failed to create proof")?; let receipt = prove_info.receipt; + let seal = encode_seal(&receipt)?; // Create an alloy instance of the Counter contract. let contract = ICounter::new(args.contract, provider); - // Encode the groth16 seal with the selector and call the increment function of the contract. - let seal = encode(receipt.inner.groth16()?.seal.clone())?; - // Call the increment function of the contract and wait for confirmation. println!( "Sending Tx calling {} Function of {:#}...", diff --git a/examples/erc20-counter/script/DeployCounter.s.sol b/examples/erc20-counter/script/DeployCounter.s.sol index 266fc1bf..b4159688 100644 --- a/examples/erc20-counter/script/DeployCounter.s.sol +++ b/examples/erc20-counter/script/DeployCounter.s.sol @@ -19,7 +19,7 @@ pragma solidity ^0.8.20; import {Script} from "forge-std/Script.sol"; import {console2} from "forge-std/console2.sol"; import {IRiscZeroVerifier} from "risc0/IRiscZeroVerifier.sol"; -import {ControlID, RiscZeroGroth16Verifier} from "risc0/groth16/RiscZeroGroth16Verifier.sol"; +import {RiscZeroCheats} from "risc0/test/RiscZeroCheats.sol"; import {Counter} from "../contracts/Counter.sol"; import {ERC20} from "../contracts/ERC20.sol"; @@ -30,7 +30,7 @@ import {ERC20} from "../contracts/ERC20.sol"; /// /// See the Foundry documentation for more information about Solidity scripts. /// https://book.getfoundry.sh/tutorials/solidity-scripting -contract CounterrDeploy is Script { +contract CounterDeploy is Script, RiscZeroCheats { function run() external { uint256 deployerKey = uint256(vm.envBytes32("ETH_WALLET_PRIVATE_KEY")); @@ -39,8 +39,7 @@ contract CounterrDeploy is Script { ERC20 toyken = new ERC20("TOYKEN", "TOY", 0); console2.log("Deployed ERC20 TOYKEN to", address(toyken)); - IRiscZeroVerifier verifier = new RiscZeroGroth16Verifier(ControlID.CONTROL_ROOT, ControlID.BN254_CONTROL_ID); - console2.log("Deployed RiscZeroGroth16Verifier to", address(verifier)); + IRiscZeroVerifier verifier = deployRiscZeroVerifier(); Counter counter = new Counter(verifier, address(toyken)); console2.log("Deployed Counter to", address(counter)); diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index 6785d59a..3813399b 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -8,9 +8,9 @@ homepage = { workspace = true } repository = { workspace = true } [dependencies] +alloy = { workspace = true } anyhow = { workspace = true } clap = { version = "4.5", features = ["derive", "env"] } -ethers = { version = "2.0" } hex = { version = "0.4" } risc0-ethereum-contracts = { workspace = true } risc0-zkvm = { workspace = true, features = ["client"] } diff --git a/ffi/src/main.rs b/ffi/src/main.rs index db88376d..86b5802f 100644 --- a/ffi/src/main.rs +++ b/ffi/src/main.rs @@ -14,13 +14,11 @@ use std::io::Write; +use alloy::{primitives::Bytes, sol_types::SolValue}; use anyhow::{Context, Result}; use clap::Parser; -use ethers::abi::Token; -use risc0_ethereum_contracts::groth16::encode; -use risc0_zkvm::{ - default_prover, is_dev_mode, sha::Digestible, ExecutorEnv, ProverOpts, VerifierContext, -}; +use risc0_ethereum_contracts::encode_seal; +use risc0_zkvm::{default_prover, ExecutorEnv, ProverOpts, VerifierContext}; #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] @@ -54,8 +52,8 @@ pub fn main() -> Result<()> { fn prove_ffi(elf_path: String, input: Vec) -> Result<()> { let elf = std::fs::read(elf_path).unwrap(); let (journal, seal) = prove(&elf, &input)?; - let calldata = vec![Token::Bytes(journal), Token::Bytes(seal)]; - let output = hex::encode(ethers::abi::encode(&calldata)); + let calldata = vec![Bytes(journal.into()), Bytes(seal.into())]; + let output = hex::encode(calldata.abi_encode()); // Forge test FFI calls expect hex encoded bytes sent to stdout print!("{output}"); @@ -77,15 +75,6 @@ fn prove(elf: &[u8], input: &[u8]) -> Result<(Vec, Vec)> { .receipt; let journal = receipt.clone().journal.bytes; - - let seal = match is_dev_mode() { - true => { - let mut seal = Vec::new(); - seal.extend(vec![0u8; 4]); - seal.extend(receipt.claim()?.digest().as_bytes()); - seal - } - false => encode(receipt.inner.groth16()?.seal.clone())?, - }; + let seal = encode_seal(&receipt)?; Ok((journal, seal)) } From 519bf45636ead52ec52a70e9582a9a89ef0731a0 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 7 Aug 2024 11:25:30 +0200 Subject: [PATCH 27/30] improve doc --- steel/src/host/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/steel/src/host/mod.rs b/steel/src/host/mod.rs index 53c6710b..3a67defc 100644 --- a/steel/src/host/mod.rs +++ b/steel/src/host/mod.rs @@ -43,7 +43,7 @@ pub type BlockNumberOrTag = alloy::rpc::types::BlockNumberOrTag; pub(crate) type HostEvmEnv = EvmEnv, H>; impl EthEvmEnv, Ethereum, RootProvider>>>> { - /// Creates a new provable [EvmEnv] for Ethereum from an RPC endpoint. + /// Creates a new provable [EvmEnv] for Ethereum from an HTTP RPC endpoint. pub async fn from_rpc(url: Url, number: BlockNumberOrTag) -> anyhow::Result { let provider = ProviderBuilder::new().on_http(url); EvmEnv::from_provider(provider, number).await From 76af6338ddf944dacd2ce19f44b9264f39cb624d Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 7 Aug 2024 11:25:53 +0200 Subject: [PATCH 28/30] fix clippy warnings --- steel/src/config.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/steel/src/config.rs b/steel/src/config.rs index 6612b4b1..2d2eaaa7 100644 --- a/steel/src/config.rs +++ b/steel/src/config.rs @@ -81,8 +81,6 @@ impl ChainSpec { #[cfg(test)] mod tests { - use std::u64; - use super::*; #[test] From d2d2fa30161e5f8c107d413fcca7f045855671fc Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 7 Aug 2024 11:57:41 +0200 Subject: [PATCH 29/30] make url dependency optional --- steel/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/steel/Cargo.toml b/steel/Cargo.toml index 817875cc..731cd8d4 100644 --- a/steel/Cargo.toml +++ b/steel/Cargo.toml @@ -26,7 +26,7 @@ revm = { workspace = true, features = ["serde"] } serde = { workspace = true } serde_json = { workspace = true, optional = true } tokio = { workspace = true, optional = true } -url = { workspace = true } +url = { workspace = true, optional = true } [dev-dependencies] alloy = { workspace = true, features = ["node-bindings"] } @@ -37,4 +37,4 @@ test-log = { workspace = true } [features] default = [] -host = ["dep:alloy", "dep:log", "dep:serde_json", "dep:tokio"] +host = ["dep:alloy", "dep:log", "dep:serde_json", "dep:tokio", "dep:url"] From 26ec759542899e0847882abae8bf746fc72d6ab3 Mon Sep 17 00:00:00 2001 From: Wolfgang Welz Date: Wed, 7 Aug 2024 11:58:53 +0200 Subject: [PATCH 30/30] improve CHANGELOG.md --- steel/CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/steel/CHANGELOG.md b/steel/CHANGELOG.md index 1c0d9e8b..427f3132 100644 --- a/steel/CHANGELOG.md +++ b/steel/CHANGELOG.md @@ -19,13 +19,13 @@ All notable changes to this project will be documented in this file. ### 🚨 Breaking Changes -- `EthEvmEnv::from_rpc` now takes an `Url` instead of a `&str`. -- `EvmEnv::from_provider`now takes an `alloy` provider, the `u64` block number was changed to a `BlockNumberOrTag`. -- `CachedProvider` is no longer available: - - During tests the fork mode of `Anvil` can be used for a similar effect, or - - use the upcoming cache feature of `alloy`. -- `EvmEnv::sol_commitment` has been changed to `EvmEnv::commitment` to get a reference, or `EvmEnv::into_commitment`. +- `EthEvmEnv::from_rpc` now accepts a `Url` instead of a `&str` for the HTTP RPC endpoint. +- `EvmEnv::from_provider` now requires an `alloy` provider, and the block number parameter has been changed to a `BlockNumberOrTag`. +- `EvmEnv::sol_commitment` has been replaced with `EvmEnv::commitment` (to get a reference), or `EvmEnv::into_commitment` (to consume and return the commitment). - `ETH_SEPOLIA_CHAIN_SPEC` and `ETH_MAINNET_CHAIN_SPEC` have been moved to the `ethereum` module. +- `CachedProvider` has been removed completely. As alternatives, you can: + - Use `anvil --fork-url https://ethereum-rpc.publicnode.com@20475759` to create a cached fork for block `20475759`. + - Cache the RPC responses on an HTTP level using [Tower](https://crates.io/crates/tower) or a caching forward proxy. - The host functions are now `async` instead of blocking: ```rust // Create an EVM environment from an RPC endpoint and a block number or tag.