├── proof_data ├── sp1 │ └── .gitkeep └── risc0 │ └── .gitkeep ├── workspaces ├── risc0 │ ├── host │ │ ├── .gitkeep │ │ ├── src │ │ │ ├── rsa2048-pub.der │ │ │ ├── rsa2048-priv.der │ │ │ └── main.rs │ │ ├── lib │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── lib.rs │ │ └── Cargo.toml │ ├── .gitignore │ ├── methods │ │ ├── build.rs │ │ ├── src │ │ │ └── lib.rs │ │ └── Cargo.toml │ ├── rust-toolchain.toml │ └── Cargo.toml ├── sp1 │ ├── script │ │ ├── src │ │ │ ├── .gitkeep │ │ │ └── main.rs │ │ ├── build.rs │ │ └── Cargo.toml │ └── program │ │ ├── elf │ │ └── riscv32im-succinct-zkvm-elf │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs └── base_files │ ├── sp1 │ ├── cargo_guest │ ├── cargo_host │ └── host │ └── risc0 │ ├── cargo_guest │ ├── cargo_host │ └── host ├── assets └── zkRust_execution_flow.png ├── examples ├── rsa │ ├── src │ │ ├── rsa2048-priv.der │ │ ├── rsa2048-pub.der │ │ └── main.rs │ └── Cargo.toml ├── json │ ├── lib │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── sha │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── Cargo.lock ├── is_even │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── regex │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── zkquiz │ ├── Cargo.toml │ └── src │ │ ├── utils.rs │ │ └── main.rs ├── fibonacci │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── ecdsa │ ├── Cargo.toml │ └── src │ │ └── main.rs └── tendermint │ ├── Cargo.toml │ └── src │ ├── utils.rs │ ├── main.rs │ └── files │ ├── block_2279100.json │ └── block_2279130.json ├── rust-toolchain.toml ├── zk_rust_io ├── Cargo.toml └── src │ └── lib.rs ├── .gitignore ├── Cargo.toml ├── Makefile ├── install_zkrust.sh ├── src ├── sp1.rs ├── risc0.rs ├── lib.rs ├── main.rs └── utils.rs └── README.md /proof_data/sp1/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /proof_data/risc0/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workspaces/risc0/host/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workspaces/sp1/script/src/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workspaces/risc0/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | methods/guest/ 3 | target/ 4 | -------------------------------------------------------------------------------- /workspaces/risc0/methods/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | risc0_build::embed_methods(); 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/risc0/methods/src/lib.rs: -------------------------------------------------------------------------------- 1 | include!(concat!(env!("OUT_DIR"), "/methods.rs")); 2 | -------------------------------------------------------------------------------- /assets/zkRust_execution_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetanotherco/zkRust/HEAD/assets/zkRust_execution_flow.png -------------------------------------------------------------------------------- /examples/rsa/src/rsa2048-priv.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetanotherco/zkRust/HEAD/examples/rsa/src/rsa2048-priv.der -------------------------------------------------------------------------------- /examples/rsa/src/rsa2048-pub.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetanotherco/zkRust/HEAD/examples/rsa/src/rsa2048-pub.der -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2024-04-20" 3 | targets = ["riscv32i-unknown-none-elf"] 4 | 5 | -------------------------------------------------------------------------------- /workspaces/sp1/script/build.rs: -------------------------------------------------------------------------------- 1 | use sp1_helper::build_program; 2 | 3 | fn main() { 4 | build_program("../program") 5 | } 6 | -------------------------------------------------------------------------------- /workspaces/risc0/host/src/rsa2048-pub.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetanotherco/zkRust/HEAD/workspaces/risc0/host/src/rsa2048-pub.der -------------------------------------------------------------------------------- /workspaces/risc0/host/src/rsa2048-priv.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetanotherco/zkRust/HEAD/workspaces/risc0/host/src/rsa2048-priv.der -------------------------------------------------------------------------------- /workspaces/risc0/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | components = ["rustfmt", "rust-src"] 4 | profile = "minimal" 5 | -------------------------------------------------------------------------------- /examples/json/lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lib" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | serde = "1.0.196" 8 | -------------------------------------------------------------------------------- /zk_rust_io/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "zk_rust_io" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | serde = "1.0.204" 8 | -------------------------------------------------------------------------------- /workspaces/risc0/host/lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lib" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | serde = "1.0.196" 8 | -------------------------------------------------------------------------------- /workspaces/sp1/program/elf/riscv32im-succinct-zkvm-elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yetanotherco/zkRust/HEAD/workspaces/sp1/program/elf/riscv32im-succinct-zkvm-elf -------------------------------------------------------------------------------- /examples/sha/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sha" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [workspace] 7 | 8 | [dependencies] 9 | sha2 = "0.10.6" 10 | -------------------------------------------------------------------------------- /examples/is_even/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "is-even" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 8 | -------------------------------------------------------------------------------- /examples/regex/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "regex" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | regex = "1.10.3" 8 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 9 | -------------------------------------------------------------------------------- /workspaces/base_files/sp1/cargo_guest: -------------------------------------------------------------------------------- 1 | [workspace] 2 | [package] 3 | version = "0.1.0" 4 | name = "method" 5 | edition = "2021" 6 | 7 | [dependencies] 8 | sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git", tag = "v1.0.1" } 9 | -------------------------------------------------------------------------------- /examples/zkquiz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "zkquiz" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | regex = "1.10.3" 8 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 9 | tiny-keccak = { version = "2.0.2", features = ["sha3"] } 10 | -------------------------------------------------------------------------------- /workspaces/risc0/methods/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "methods" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [build-dependencies] 7 | risc0-build = { git = "https://github.com/risc0/risc0", tag = "v1.0.1" } 8 | 9 | [package.metadata.risc0] 10 | methods = ["guest"] 11 | -------------------------------------------------------------------------------- /workspaces/risc0/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = ["host", "methods"] 4 | 5 | # Always optimize; building and running the guest takes much longer without optimization. 6 | [profile.dev] 7 | opt-level = 3 8 | 9 | [profile.release] 10 | debug = 1 11 | lto = true 12 | -------------------------------------------------------------------------------- /workspaces/base_files/risc0/cargo_guest: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "method" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [workspace] 7 | 8 | [dependencies] 9 | risc0-zkvm = { git = "https://github.com/risc0/risc0", features = [ 10 | "std", 11 | "getrandom", 12 | ], tag = "v1.0.1" } 13 | -------------------------------------------------------------------------------- /workspaces/sp1/program/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | [package] 3 | version = "0.1.0" 4 | name = "method" 5 | edition = "2021" 6 | 7 | [dependencies] 8 | sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git", tag = "v1.0.1" } 9 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 10 | -------------------------------------------------------------------------------- /examples/fibonacci/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fibonacci" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 10 | -------------------------------------------------------------------------------- /workspaces/sp1/script/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | [package] 3 | version = "0.1.0" 4 | name = "method" 5 | edition = "2021" 6 | 7 | [build-dependencies] 8 | sp1-helper = "1.0.1" 9 | 10 | [dependencies] 11 | sp1-sdk = { git = "https://github.com/succinctlabs/sp1.git", tag = "v1.0.1" } 12 | bincode = "1.3.3" 13 | -------------------------------------------------------------------------------- /workspaces/base_files/sp1/cargo_host: -------------------------------------------------------------------------------- 1 | [workspace] 2 | [package] 3 | version = "0.1.0" 4 | name = "method" 5 | edition = "2021" 6 | 7 | [build-dependencies] 8 | sp1-helper = "1.0.1" 9 | 10 | [dependencies] 11 | sp1-sdk = { git = "https://github.com/succinctlabs/sp1.git", tag = "v1.0.1" } 12 | bincode = "1.3.3" 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/* 2 | target 3 | .tmp_guest 4 | .tmp_guest/* 5 | 6 | workspaces/* 7 | !workspaces/base_files/ 8 | !workspaces/risc0/ 9 | !workspaces/sp1/ 10 | 11 | proof_data/sp1/* 12 | !proof_data/sp1/.gitkeep 13 | proof_data/risc0/* 14 | !proof_data/risc0/.gitkeep 15 | 16 | aligned_verification_data/* 17 | 18 | .DS_Store 19 | **/.DS_Store 20 | -------------------------------------------------------------------------------- /examples/sha/src/main.rs: -------------------------------------------------------------------------------- 1 | //For acceleration we require the user defines the respective crate import since they are specific and needed to compile 2 | use sha2::{Digest, Sha256}; 3 | 4 | fn main() { 5 | let data: String = "RISCV IS COOL!!!".to_string(); 6 | let digest = Sha256::digest(&data.as_bytes()); 7 | println!("{:?}", &digest.as_slice()); 8 | } 9 | -------------------------------------------------------------------------------- /examples/json/lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Serialize, Deserialize, Debug, Default)] 4 | pub struct Transaction { 5 | pub from: String, 6 | pub to: String, 7 | pub amount: u32, 8 | } 9 | 10 | #[derive(Serialize, Deserialize, Debug, Default)] 11 | pub struct Account { 12 | pub account_name: String, 13 | pub balance: u32, 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/risc0/host/lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Serialize, Deserialize, Debug, Default)] 4 | pub struct Transaction { 5 | pub from: String, 6 | pub to: String, 7 | pub amount: u32, 8 | } 9 | 10 | #[derive(Serialize, Deserialize, Debug, Default)] 11 | pub struct Account { 12 | pub account_name: String, 13 | pub balance: u32, 14 | } 15 | -------------------------------------------------------------------------------- /zk_rust_io/src/lib.rs: -------------------------------------------------------------------------------- 1 | use serde::{de::DeserializeOwned, Serialize}; 2 | 3 | #[inline(never)] 4 | pub fn read() -> T { 5 | T::default() 6 | } 7 | #[inline(never)] 8 | pub fn commit(_value: &T) {} 9 | #[inline(never)] 10 | pub fn write(_buf: &T) {} 11 | #[inline(never)] 12 | pub fn out() -> T{ 13 | T::default() 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/base_files/risc0/cargo_host: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "host" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | methods = { path = "../methods" } 8 | risc0-zkvm = { git = "https://github.com/risc0/risc0", tag = "v1.0.1", default-features = false, features = [ 9 | "prove", 10 | ] } 11 | tracing-subscriber = { version = "0.3", features = ["env-filter"] } 12 | bincode = "1.3.3" 13 | -------------------------------------------------------------------------------- /examples/json/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "json" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | serde = { version = "1.0.196", features = ["derive"] } 10 | serde_json = "1.0.114" 11 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 12 | lib = { path = "lib" } 13 | -------------------------------------------------------------------------------- /examples/is_even/src/main.rs: -------------------------------------------------------------------------------- 1 | use zk_rust_io; 2 | 3 | fn main() { 4 | let n: u32 = zk_rust_io::read(); 5 | zk_rust_io::commit(&n); 6 | 7 | let is_even: bool = n % 2 == 0; 8 | 9 | zk_rust_io::commit(&is_even); 10 | } 11 | 12 | fn input() { 13 | let n = 16u32; 14 | zk_rust_io::write(&n); 15 | } 16 | 17 | fn output() { 18 | let (n, is_even): (u32, bool) = zk_rust_io::out(); 19 | 20 | println!("is_even: {}", is_even); 21 | } 22 | -------------------------------------------------------------------------------- /examples/rsa/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rsa" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | digest = "0.10.7" 10 | rand = "0.8.5" 11 | rsa = "0.6.0" # Check for the latest version 12 | sha2 = "0.10.8" 13 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 14 | -------------------------------------------------------------------------------- /workspaces/sp1/program/src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | sp1_zkvm::entrypoint!(main); 3 | use zk_rust_io; 4 | pub fn main() { 5 | let n: u32 = sp1_zkvm::io::read(); 6 | sp1_zkvm::io::commit(&n); 7 | 8 | let mut a: u32 = 0; 9 | let mut b: u32 = 1; 10 | for _ in 0..n { 11 | let mut c = a + b; 12 | c %= 7919; // Modulus to prevent overflow. 13 | a = b; 14 | b = c; 15 | } 16 | 17 | sp1_zkvm::io::commit(&a); 18 | sp1_zkvm::io::commit(&b); 19 | } -------------------------------------------------------------------------------- /examples/ecdsa/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ecdsa" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | rand_core = "0.6.4" 10 | hex-literal = "0.4" 11 | k256 = { version = "=0.13.3", features = [ 12 | "arithmetic", 13 | "serde", 14 | "expose-field", 15 | "std", 16 | "ecdsa", 17 | ], default_features = false } 18 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 19 | -------------------------------------------------------------------------------- /examples/tendermint/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | [package] 3 | name = "tendermint-program" 4 | version = "1.1.0" 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | serde_json = { version = "1.0", default-features = false, features = ["alloc"] } 10 | serde = { version = "1.0", default-features = false, features = ["derive"] } 11 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 12 | tendermint-light-client-verifier = { version = "0.39.1", default-features = false, features = [ 13 | "rust-crypto", 14 | ] } 15 | serde_cbor = "0.11.2" 16 | -------------------------------------------------------------------------------- /workspaces/risc0/host/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "host" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | methods = { path = "../methods" } 8 | risc0-zkvm = { git = "https://github.com/risc0/risc0", tag = "v1.0.1" } 9 | tracing-subscriber = { version = "0.3", features = ["env-filter"] } 10 | bincode = "1.3.3" 11 | 12 | digest = "0.10.7" 13 | rand = "0.8.5" 14 | rsa = "0.6.0" # Check for the latest version 15 | sha2 = "0.10.8" 16 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git", branch = "feat/v2" } 17 | -------------------------------------------------------------------------------- /examples/fibonacci/src/main.rs: -------------------------------------------------------------------------------- 1 | use zk_rust_io; 2 | 3 | fn main() { 4 | let n: u32 = zk_rust_io::read(); 5 | zk_rust_io::commit(&n); 6 | 7 | let mut a: u32 = 0; 8 | let mut b: u32 = 1; 9 | for _ in 0..n { 10 | let mut c = a + b; 11 | c %= 7919; // Modulus to prevent overflow. 12 | a = b; 13 | b = c; 14 | } 15 | 16 | zk_rust_io::commit(&a); 17 | zk_rust_io::commit(&b); 18 | } 19 | 20 | fn input() { 21 | let n = 1000u32; 22 | zk_rust_io::write(&n); 23 | } 24 | 25 | fn output() { 26 | let (n, a, b): (u32, u32, u32) = zk_rust_io::out(); 27 | 28 | println!("n: {}", n); 29 | println!("a: {}", a); 30 | println!("b: {}", b); 31 | } 32 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "zkRust" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "4.5.4", features = ["derive"] } 10 | regex = "1.10.5" 11 | anyhow = "1.0.86" 12 | hex = "0.4.3" 13 | tokio = "1.38.0" 14 | zk_rust_io = { path = "./zk_rust_io" } 15 | 16 | # Sp1 17 | sp1-sdk = { git = "https://github.com/succinctlabs/sp1.git", tag = "v1.0.1" } 18 | 19 | # Risc 0 20 | risc0-zkvm = { git = "https://github.com/risc0/risc0.git", tag = "v1.0.1" } 21 | 22 | # Aligned SDK 23 | aligned-sdk = { git = "https://github.com/yetanotherco/aligned_layer", tag = "v0.10.2" } 24 | ethers = { tag = "v2.0.15-fix-reconnections", features = [ 25 | "ws", 26 | "rustls", 27 | ], git = "https://github.com/yetanotherco/ethers-rs.git" } 28 | 29 | dialoguer = "0.11.0" 30 | bincode = "1.3.3" 31 | rpassword = "7.3.1" 32 | env_logger = "0.11.3" 33 | log = "0.4.22" 34 | # std::env::dir is deprecated on windows 35 | dirs = "5.0.0" 36 | serde_json = "1.0.117" -------------------------------------------------------------------------------- /examples/zkquiz/src/utils.rs: -------------------------------------------------------------------------------- 1 | pub fn ask_question(question: &str, answers: &[&str]) -> char { 2 | println!("{}", question); 3 | for (i, answer) in answers.iter().enumerate() { 4 | println!("{}. {}", (b'a' + i as u8) as char, answer); 5 | } 6 | 7 | read_answer() 8 | } 9 | 10 | fn is_valid_answer(answer: char) -> bool { 11 | answer == 'a' || answer == 'b' || answer == 'c' 12 | } 13 | 14 | fn read_answer() -> char { 15 | loop { 16 | let mut answer = String::new(); 17 | 18 | std::io::stdin() 19 | .read_line(&mut answer) 20 | .expect("Failed to read from stdin"); 21 | 22 | answer = answer.trim().to_string(); 23 | if answer.len() != 1 { 24 | println!("Please enter a valid answer (a, b or c)"); 25 | continue; 26 | } 27 | 28 | let c = answer.chars().next().unwrap(); 29 | if !is_valid_answer(c) { 30 | println!("Please enter a valid answer (a, b or c)"); 31 | continue; 32 | } 33 | 34 | return c; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/regex/src/main.rs: -------------------------------------------------------------------------------- 1 | use regex::Regex; 2 | use zk_rust_io; 3 | 4 | pub fn main() { 5 | // Read two inputs from the prover: a regex pattern and a target string. 6 | let pattern: String = zk_rust_io::read(); 7 | let target_string: String = zk_rust_io::read(); 8 | 9 | // Try to compile the regex pattern. If it fails, write `false` as output and return. 10 | let regex = match Regex::new(&pattern) { 11 | Ok(regex) => regex, 12 | Err(_) => { 13 | panic!("Invalid regex pattern"); 14 | } 15 | }; 16 | 17 | // Perform the regex search on the target string. 18 | let result = regex.is_match(&target_string); 19 | 20 | // Write the result (true or false) to the output. 21 | zk_rust_io::commit(&result); 22 | } 23 | 24 | pub fn input() { 25 | let pattern = "a+".to_string(); 26 | let target_string = "an era of truth, not trust".to_string(); 27 | 28 | // Write in a simple regex pattern. 29 | zk_rust_io::write(&pattern); 30 | zk_rust_io::write(&target_string); 31 | } 32 | 33 | pub fn output() { 34 | // Read the output. 35 | let res: bool = zk_rust_io::out(); 36 | println!("res: {}", res); 37 | } 38 | -------------------------------------------------------------------------------- /examples/tendermint/src/utils.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | use std::error::Error; 3 | 4 | use std::time::Duration; 5 | use std::{fs::File, io::Read}; 6 | 7 | use tendermint_light_client_verifier::{options::Options, types::LightBlock}; 8 | use tendermint_light_client_verifier::{ProdVerifier, Verdict, Verifier}; 9 | 10 | pub const BLOCK_2279100: &[u8] = include_bytes!("./files/block_2279100.json"); 11 | pub const BLOCK_2279130: &[u8] = include_bytes!("./files/block_2279130.json"); 12 | 13 | pub fn verify_blocks(light_block_1: LightBlock, light_block_2: LightBlock) -> Verdict { 14 | let vp = ProdVerifier::default(); 15 | let opt = Options { 16 | trust_threshold: Default::default(), 17 | trusting_period: Duration::from_secs(500), 18 | clock_drift: Default::default(), 19 | }; 20 | let verify_time = light_block_2.time() + Duration::from_secs(20); 21 | vp.verify_update_header( 22 | light_block_2.as_untrusted_state(), 23 | light_block_1.as_trusted_state(), 24 | &opt, 25 | verify_time.unwrap(), 26 | ) 27 | } 28 | 29 | pub fn get_light_blocks() -> (LightBlock, LightBlock) { 30 | //let light_block_1 = load_light_block(2279100).expect("Failed to generate light block 1"); 31 | let light_block_1 = serde_json::from_slice(&BLOCK_2279100).unwrap(); 32 | //let light_block_2 = load_light_block(2279130).expect("Failed to generate light block 2"); 33 | let light_block_2 = serde_json::from_slice(&BLOCK_2279130).unwrap(); 34 | (light_block_1, light_block_2) 35 | } 36 | -------------------------------------------------------------------------------- /examples/zkquiz/src/main.rs: -------------------------------------------------------------------------------- 1 | use tiny_keccak::{Hasher, Sha3}; 2 | use utils::ask_question; 3 | pub mod utils; 4 | use zk_rust_io; 5 | 6 | pub fn main() { 7 | let answers: String = zk_rust_io::read(); 8 | let mut sha3 = Sha3::v256(); 9 | let mut output = [0u8; 32]; 10 | 11 | sha3.update(&answers.as_bytes()); 12 | 13 | sha3.finalize(&mut output); 14 | 15 | if output 16 | != [ 17 | 232, 202, 155, 157, 82, 242, 126, 73, 75, 22, 197, 34, 41, 170, 163, 190, 22, 29, 192, 18 | 5, 99, 134, 186, 25, 77, 128, 188, 154, 238, 70, 245, 229, 19 | ] 20 | { 21 | panic!("Answers do not match"); 22 | } 23 | } 24 | 25 | pub fn input() { 26 | println!("Welcome to the quiz! Please answer the following questions to generate a proof for the program."); 27 | println!( 28 | "You will be asked 3 questions. Please answer with the corresponding letter (a, b or c)." 29 | ); 30 | 31 | let mut user_answers = "".to_string(); 32 | let question1 = "Who invented bitcoin"; 33 | let answers1 = ["Sreeram Kannan", "Vitalik Buterin", "Satoshi Nakamoto"]; 34 | user_answers.push(ask_question(question1, &answers1)); 35 | 36 | let question2 = "What is the largest ocean on Earth?"; 37 | let answers2 = ["Atlantic", "Indian", "Pacific"]; 38 | user_answers.push(ask_question(question2, &answers2)); 39 | 40 | let question3 = "What is the most aligned color"; 41 | let answers3 = ["Green", "Red", "Blue"]; 42 | user_answers.push(ask_question(question3, &answers3)); 43 | 44 | zk_rust_io::write(&user_answers); 45 | } 46 | 47 | pub fn output() {} 48 | -------------------------------------------------------------------------------- /workspaces/base_files/sp1/host: -------------------------------------------------------------------------------- 1 | use sp1_sdk::{ProverClient, SP1Stdin}; 2 | 3 | /// The ELF (executable and linkable format) file for the Succinct RISC-V zkVM. 4 | /// 5 | /// This file is generated by running `cargo prove build` inside the `program` directory. 6 | pub const METHOD_ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf"); 7 | 8 | fn main() { 9 | let args: Vec = std::env::args().collect(); 10 | let current_dir = std::path::PathBuf::from(args[1].clone()); 11 | // Setup the logger. 12 | sp1_sdk::utils::setup_logger(); 13 | 14 | // Setup the inputs. 15 | let mut stdin = SP1Stdin::new(); 16 | 17 | // INPUT // 18 | 19 | let client = ProverClient::new(); 20 | let (pk, vk) = client.setup(METHOD_ELF); 21 | let mut proof = client 22 | .prove(&pk, stdin) 23 | .compressed() 24 | .run() 25 | .expect("failed to generate proof"); 26 | 27 | // OUTPUT // 28 | 29 | // Verify the proof. 30 | client.verify(&proof, &vk).expect("Failed to verify proof"); 31 | 32 | std::fs::create_dir_all(¤t_dir.join("proof_data/sp1")).expect("Failed to create proof_data/sp1"); 33 | let proof_data = bincode::serialize(&proof).expect("Failed to serialize proof"); 34 | std::fs::write(¤t_dir.join("proof_data/sp1/sp1.proof"), proof_data).expect("Failed to save SP1 Proof file"); 35 | std::fs::write(¤t_dir.join("proof_data/sp1/sp1.elf"), METHOD_ELF).expect("Failed to create SP1 elf file"); 36 | std::fs::write(¤t_dir.join("proof_data/sp1/sp1.pub"), proof.public_values) 37 | .expect("Failed to save SP1 public input"); 38 | } 39 | -------------------------------------------------------------------------------- /workspaces/sp1/script/src/main.rs: -------------------------------------------------------------------------------- 1 | use sp1_sdk::{ProverClient, SP1Stdin}; 2 | 3 | /// The ELF (executable and linkable format) file for the Succinct RISC-V zkVM. 4 | /// 5 | /// This file is generated by running `cargo prove build` inside the `program` directory. 6 | pub const METHOD_ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf"); 7 | 8 | fn main() { 9 | let args: Vec = std::env::args().collect(); 10 | let current_dir = std::path::PathBuf::from(args[1].clone()); 11 | // Setup the logger. 12 | sp1_sdk::utils::setup_logger(); 13 | 14 | // Setup the inputs. 15 | let mut stdin = SP1Stdin::new(); 16 | 17 | // INPUT // 18 | 19 | let client = ProverClient::new(); 20 | let (pk, vk) = client.setup(METHOD_ELF); 21 | let mut proof = client 22 | .prove(&pk, stdin) 23 | .compressed() 24 | .run() 25 | .expect("failed to generate proof"); 26 | 27 | // OUTPUT // 28 | 29 | // Verify the proof. 30 | client.verify(&proof, &vk).expect("Failed to verify proof"); 31 | 32 | std::fs::create_dir_all(¤t_dir.join("proof_data/sp1")).expect("Failed to create proof_data/sp1"); 33 | let proof_data = bincode::serialize(&proof).expect("Failed to serialize proof"); 34 | std::fs::write(¤t_dir.join("proof_data/sp1/sp1.proof"), proof_data).expect("Failed to save SP1 Proof file"); 35 | std::fs::write(¤t_dir.join("proof_data/sp1/sp1.elf"), METHOD_ELF).expect("Failed to create SP1 elf file"); 36 | std::fs::write(¤t_dir.join("proof_data/sp1/sp1_fibonacci.pub"), proof.public_values) 37 | .expect("Failed to save SP1 public input"); 38 | } 39 | -------------------------------------------------------------------------------- /examples/ecdsa/src/main.rs: -------------------------------------------------------------------------------- 1 | use k256::{ 2 | ecdsa::{ 3 | signature::{Signer, Verifier}, 4 | Signature, SigningKey, VerifyingKey, 5 | }, 6 | EncodedPoint, 7 | }; 8 | use rand_core::OsRng; 9 | 10 | fn main() { 11 | // Generate a random secp256k1 keypair and sign the message. 12 | let encoded_verifying_key: EncodedPoint = zk_rust_io::read(); // Serialize with `::to_bytes()` 13 | let message: Vec = zk_rust_io::read(); 14 | let signature: Signature = zk_rust_io::read(); 15 | 16 | let verifying_key = VerifyingKey::from_encoded_point(&encoded_verifying_key).unwrap(); 17 | 18 | // Verify the signature, panicking if verification fails. 19 | verifying_key 20 | .verify(&message, &signature) 21 | .expect("ECDSA signature verification failed"); 22 | 23 | zk_rust_io::commit(&(encoded_verifying_key, message)); 24 | } 25 | 26 | fn input() { 27 | let signing_key = SigningKey::random(&mut OsRng); // Serialize with `::to_bytes()` 28 | let message = b"This is a message that will be signed, and verified within the zkVM".to_vec(); 29 | let signature: Signature = signing_key.sign(&message); 30 | let vk = signing_key.verifying_key().to_encoded_point(true); 31 | zk_rust_io::write(&vk); 32 | zk_rust_io::write(&message); 33 | zk_rust_io::write(&signature); 34 | } 35 | 36 | fn output() { 37 | let (receipt_verifying_key, receipt_message): (EncodedPoint, Vec) = zk_rust_io::out(); 38 | 39 | println!( 40 | "Verified the signature over message {:?} with key {}", 41 | std::str::from_utf8(&receipt_message[..]).unwrap(), 42 | receipt_verifying_key, 43 | ); 44 | } 45 | -------------------------------------------------------------------------------- /workspaces/base_files/risc0/host: -------------------------------------------------------------------------------- 1 | // These constants represent the RISC-V ELF and the image ID generated by risc0-build. 2 | // The ELF is used for proving and the ID is used for verification. 3 | use methods::{METHOD_ELF, METHOD_ID}; 4 | use risc0_zkvm::{default_prover, ExecutorEnv}; 5 | 6 | fn main() { 7 | let args: Vec = std::env::args().collect(); 8 | let current_dir = std::path::PathBuf::from(args[1].clone()); 9 | 10 | // INPUT // 11 | 12 | let env = ExecutorEnv::builder().build().unwrap(); 13 | 14 | // Obtain the default prover. 15 | let prover = default_prover(); 16 | 17 | // Produce a receipt by proving the specified ELF binary. 18 | let receipt = prover.prove(env, METHOD_ELF).unwrap().receipt; 19 | 20 | receipt.verify(METHOD_ID).unwrap(); 21 | 22 | // OUTPUT // 23 | 24 | let serialized = bincode::serialize(&receipt).unwrap(); 25 | 26 | //TODO(pat): remove expects 27 | std::fs::create_dir_all(current_dir.join("proof_data/risc0")).expect("Failed to create proof_data/sp1"); 28 | std::fs::write(¤t_dir.join("proof_data/risc0/risc0.proof"), &serialized).expect("Failed to create Risc0 proof file"); 29 | std::fs::write(¤t_dir.join("proof_data/risc0/risc0.imageid"), &convert(&METHOD_ID)).expect("Failed to create Risc0 Image ID file"); 30 | std::fs::write(¤t_dir.join("proof_data/risc0/risc0.pub"), &receipt.journal.bytes).expect("Failed to create Risc0 public input file"); 31 | } 32 | 33 | pub fn convert(data: &[u32; 8]) -> [u8; 32] { 34 | let mut res = [0; 32]; 35 | for i in 0..8 { 36 | res[4 * i..4 * (i + 1)].copy_from_slice(&data[i].to_le_bytes()); 37 | } 38 | res 39 | } 40 | -------------------------------------------------------------------------------- /workspaces/risc0/host/src/main.rs: -------------------------------------------------------------------------------- 1 | // These constants represent the RISC-V ELF and the image ID generated by risc0-build. 2 | // The ELF is used for proving and the ID is used for verification. 3 | use methods::{METHOD_ELF, METHOD_ID}; 4 | use risc0_zkvm::{default_prover, ExecutorEnv}; 5 | 6 | fn main() { 7 | let args: Vec = std::env::args().collect(); 8 | let current_dir = std::path::PathBuf::from(args[1].clone()); 9 | 10 | // INPUT // 11 | 12 | let env = ExecutorEnv::builder().build().unwrap(); 13 | 14 | // Obtain the default prover. 15 | let prover = default_prover(); 16 | 17 | // Produce a receipt by proving the specified ELF binary. 18 | let receipt = prover.prove(env, METHOD_ELF).unwrap().receipt; 19 | 20 | receipt.verify(METHOD_ID).unwrap(); 21 | 22 | // OUTPUT // 23 | 24 | let serialized = bincode::serialize(&receipt).unwrap(); 25 | 26 | //TODO(pat): remove expects 27 | std::fs::create_dir_all(current_dir.join("proof_data/risc0")).expect("Failed to create proof_data/sp1"); 28 | std::fs::write(¤t_dir.join("proof_data/risc0/risc0.proof"), &serialized).expect("Failed to create Risc0 proof file"); 29 | std::fs::write(¤t_dir.join("proof_data/risc0/risc0.imageid"), &convert(&METHOD_ID)).expect("Failed to create Risc0 Image ID file"); 30 | std::fs::write(¤t_dir.join("proof_data/risc0/risc0.pub"), &receipt.journal.bytes).expect("Failed to create Risc0 public input file"); 31 | } 32 | 33 | pub fn convert(data: &[u32; 8]) -> [u8; 32] { 34 | let mut res = [0; 32]; 35 | for i in 0..8 { 36 | res[4 * i..4 * (i + 1)].copy_from_slice(&data[i].to_le_bytes()); 37 | } 38 | res 39 | } 40 | -------------------------------------------------------------------------------- /examples/json/src/main.rs: -------------------------------------------------------------------------------- 1 | use lib::{Account, Transaction}; 2 | use serde::{Deserialize, Serialize}; 3 | use serde_json::Value; 4 | 5 | fn main() { 6 | let data_str: String = zk_rust_io::read(); 7 | let key: String = zk_rust_io::read(); 8 | 9 | // read custom struct example inputs. 10 | let mut old_account_state: Account = zk_rust_io::read(); 11 | let txs: Vec = zk_rust_io::read(); 12 | 13 | let v: Value = serde_json::from_str(&data_str).unwrap(); 14 | println!("net_worth {:?}", v[key]); 15 | 16 | let new_account_state = &mut old_account_state; 17 | for tx in txs { 18 | if tx.from == new_account_state.account_name { 19 | new_account_state.balance -= tx.amount; 20 | } 21 | if tx.to == new_account_state.account_name { 22 | new_account_state.balance += tx.amount; 23 | } 24 | } 25 | } 26 | 27 | fn input() { 28 | let data_str = r#" 29 | { 30 | "name": "Jane Doe", 31 | "age": "25", 32 | "net_worth" : "$1000000" 33 | }"# 34 | .to_string(); 35 | let key = "net_worth".to_string(); 36 | 37 | let mut account_state = Account { 38 | account_name: "Bill".to_string(), 39 | balance: 200, 40 | }; 41 | let txs = vec![ 42 | Transaction { 43 | from: "Bill".to_string(), 44 | to: "Tom".to_string(), 45 | amount: 50, 46 | }, 47 | Transaction { 48 | from: "Bill".to_string(), 49 | to: "Tom".to_string(), 50 | amount: 100, 51 | }, 52 | ]; 53 | 54 | zk_rust_io::write(&data_str); 55 | zk_rust_io::write(&key); 56 | zk_rust_io::write(&account_state); 57 | zk_rust_io::write(&txs); 58 | } 59 | 60 | fn output() { 61 | let account_state: Account = zk_rust_io::out(); 62 | println!( 63 | "Final account state: {}", 64 | serde_json::to_string(&account_state).unwrap() 65 | ); 66 | } 67 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := $(shell echo $$SHELL) 2 | 3 | # Find the profile directory based on the shell 4 | ifeq ($(findstring bash,$(SHELL)),bash) 5 | PROFILE := ~/.bashrc 6 | else ifeq ($(findstring zsh,$(SHELL)),zsh) 7 | PROFILE := ~/.zshenv 8 | else ifeq ($(findstring fish,$(SHELL)),fish) 9 | PROFILE := ~/.config/fish/config.fish 10 | else ifeq ($(findstring sh,$(SHELL)),sh) 11 | PROFILE := ~/.profile 12 | else 13 | echo "zkrust: could not detect shell, manually add ${ZKRUST_BIN_DIR} to your PATH." 14 | exit 1 15 | endif 16 | 17 | install: install_zkRust 18 | 19 | install_zkRust: 20 | @curl -L https://raw.githubusercontent.com/yetanotherco/zkRust/main/install_zkrust.sh | bash 21 | 22 | install_sp1: 23 | @curl -L https://sp1.succinct.xyz | bash 24 | @source $(PROFILE) 25 | @sp1up 26 | @cargo prove --version 27 | 28 | install_risc0: 29 | @curl -L https://risczero.com/install | bash 30 | @rzup install 31 | @cargo risczero --version 32 | 33 | all: install 34 | 35 | __EXAMPLES__: 36 | 37 | # RISC0 38 | prove_risc0_fibonacci: 39 | @RUST_LOG=info cargo run --release -- prove-risc0 examples/fibonacci 40 | 41 | prove_risc0_rsa: 42 | @RUST_LOG=info cargo run --release -- prove-risc0 examples/rsa 43 | 44 | prove_risc0_ecdsa: 45 | @RUST_LOG=info cargo run --release -- prove-risc0 examples/ecdsa 46 | 47 | prove_risc0_json: 48 | @RUST_LOG=info cargo run --release -- prove-risc0 examples/json 49 | 50 | prove_risc0_regex: 51 | @RUST_LOG=info cargo run --release -- prove-risc0 examples/regex 52 | 53 | prove_risc0_sha: 54 | @RUST_LOG=info cargo run --release -- prove-risc0 examples/sha 55 | 56 | prove_risc0_tendermint: 57 | @RUST_LOG=info cargo run --release -- prove-risc0 examples/tendermint 58 | 59 | prove_risc0_zkquiz: 60 | @RUST_LOG=info cargo run --release -- prove-risc0 examples/zkquiz 61 | 62 | # SP1 63 | prove_sp1_fibonacci: 64 | @RUST_LOG=info cargo run --release -- prove-sp1 examples/fibonacci 65 | 66 | prove_sp1_rsa: 67 | @RUST_LOG=info cargo run --release -- prove-sp1 examples/rsa 68 | 69 | prove_sp1_ecdsa: 70 | @RUST_LOG=info cargo run --release -- prove-sp1 examples/ecdsa 71 | 72 | prove_sp1_json: 73 | @RUST_LOG=info cargo run --release -- prove-sp1 examples/json 74 | 75 | prove_sp1_regex: 76 | @RUST_LOG=info cargo run --release -- prove-sp1 examples/regex 77 | 78 | prove_sp1_sha: 79 | @RUST_LOG=info cargo run --release -- prove-sp1 examples/sha 80 | 81 | prove_sp1_tendermint: 82 | @RUST_LOG=info cargo run --release -- prove-sp1 examples/tendermint 83 | 84 | prove_sp1_zkquiz: 85 | @RUST_LOG=info cargo run --release -- prove-sp1 examples/zkquiz 86 | -------------------------------------------------------------------------------- /examples/sha/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "block-buffer" 7 | version = "0.10.4" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 10 | dependencies = [ 11 | "generic-array", 12 | ] 13 | 14 | [[package]] 15 | name = "cfg-if" 16 | version = "1.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 19 | 20 | [[package]] 21 | name = "cpufeatures" 22 | version = "0.2.13" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" 25 | dependencies = [ 26 | "libc", 27 | ] 28 | 29 | [[package]] 30 | name = "crypto-common" 31 | version = "0.1.6" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 34 | dependencies = [ 35 | "generic-array", 36 | "typenum", 37 | ] 38 | 39 | [[package]] 40 | name = "digest" 41 | version = "0.10.7" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 44 | dependencies = [ 45 | "block-buffer", 46 | "crypto-common", 47 | ] 48 | 49 | [[package]] 50 | name = "generic-array" 51 | version = "0.14.7" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 54 | dependencies = [ 55 | "typenum", 56 | "version_check", 57 | ] 58 | 59 | [[package]] 60 | name = "libc" 61 | version = "0.2.158" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" 64 | 65 | [[package]] 66 | name = "sha" 67 | version = "0.1.0" 68 | dependencies = [ 69 | "sha2", 70 | ] 71 | 72 | [[package]] 73 | name = "sha2" 74 | version = "0.10.8" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 77 | dependencies = [ 78 | "cfg-if", 79 | "cpufeatures", 80 | "digest", 81 | ] 82 | 83 | [[package]] 84 | name = "typenum" 85 | version = "1.17.0" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 88 | 89 | [[package]] 90 | name = "version_check" 91 | version = "0.9.5" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 94 | -------------------------------------------------------------------------------- /examples/rsa/src/main.rs: -------------------------------------------------------------------------------- 1 | use rsa::{ 2 | pkcs8::{DecodePrivateKey, DecodePublicKey}, 3 | PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey, 4 | }; 5 | use sha2::{Digest, Sha256}; 6 | use std::vec; 7 | 8 | fn main() { 9 | let pk_der: Vec = zk_rust_io::read(); 10 | let message: Vec = zk_rust_io::read(); 11 | let signature: Vec = zk_rust_io::read(); 12 | 13 | let public_key = RsaPublicKey::from_public_key_der(&pk_der).unwrap(); 14 | 15 | let mut hasher = Sha256::new(); 16 | hasher.update(message); 17 | let hashed_msg = hasher.finalize(); 18 | 19 | let padding = PaddingScheme::new_pkcs1v15_sign(Some(rsa::Hash::SHA2_256)); 20 | let verification = public_key.verify(padding, &hashed_msg, &signature); 21 | 22 | match verification { 23 | Ok(_) => { 24 | println!("Signature verified successfully."); 25 | true 26 | } 27 | Err(e) => { 28 | println!("Failed to verify signature: {:?}", e); 29 | false 30 | } 31 | }; 32 | } 33 | 34 | fn input() { 35 | const RSA_2048_PRIV: &[u8] = include_bytes!("rsa2048-priv.der"); 36 | const RSA_2048_PUB: &[u8] = include_bytes!("rsa2048-pub.der"); 37 | 38 | let message = b"Hello world!".to_vec(); 39 | let signature: Vec = vec![ 40 | 32, 121, 247, 109, 107, 249, 210, 178, 234, 149, 136, 242, 34, 135, 250, 127, 150, 225, 43, 41 | 137, 241, 39, 139, 78, 179, 49, 169, 111, 200, 96, 183, 227, 70, 15, 46, 227, 114, 103, 42 | 169, 170, 57, 107, 214, 102, 222, 13, 19, 216, 241, 134, 26, 124, 96, 202, 29, 185, 69, 4, 43 | 204, 78, 223, 61, 124, 41, 179, 255, 84, 58, 47, 137, 242, 102, 161, 37, 45, 20, 39, 129, 44 | 67, 55, 210, 164, 105, 82, 214, 223, 194, 201, 143, 114, 99, 237, 157, 42, 73, 50, 175, 45 | 160, 145, 95, 138, 242, 157, 90, 100, 170, 206, 39, 80, 49, 65, 55, 202, 214, 17, 19, 183, 46 | 244, 184, 17, 108, 171, 54, 178, 242, 137, 215, 67, 185, 198, 122, 234, 132, 240, 73, 42, 47 | 123, 46, 201, 19, 197, 248, 9, 122, 16, 86, 67, 250, 237, 245, 43, 199, 65, 62, 153, 160, 48 | 44, 108, 21, 125, 197, 154, 231, 115, 225, 38, 238, 229, 143, 203, 159, 65, 147, 18, 9, 49 | 224, 14, 43, 58, 16, 7, 148, 2, 187, 97, 95, 70, 174, 68, 149, 7, 79, 223, 124, 207, 57, 50 | 214, 242, 126, 2, 7, 3, 198, 202, 26, 136, 237, 106, 205, 11, 227, 120, 162, 104, 22, 167, 51 | 192, 124, 239, 39, 201, 157, 45, 85, 147, 247, 1, 240, 217, 220, 218, 79, 238, 135, 100, 52 | 22, 44, 88, 95, 9, 64, 224, 101, 57, 54, 171, 218, 6, 160, 137, 97, 114, 90, 32, 47, 184, 53 | ]; 54 | 55 | let private_key = RsaPrivateKey::from_pkcs8_der(RSA_2048_PRIV).unwrap(); 56 | let public_key = RsaPublicKey::from_public_key_der(RSA_2048_PUB).unwrap(); 57 | println!("{:?} \n\n{:?}", private_key, public_key); 58 | 59 | zk_rust_io::write(&RSA_2048_PUB); 60 | zk_rust_io::write(&message); 61 | zk_rust_io::write(&signature); 62 | } 63 | 64 | fn output() {} 65 | -------------------------------------------------------------------------------- /install_zkrust.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 4 | 5 | echo "Installing zkRust..." 6 | 7 | BASE_DIR=$HOME 8 | ZKRUST_DIR="${ZKRUST_DIR-"$BASE_DIR/.zkRust"}" 9 | ZKRUST_BIN_DIR="$ZKRUST_DIR/bin" 10 | ZKRUST_BIN_PATH="$ZKRUST_BIN_DIR/zkRust" 11 | ZKRUST_GIT_REPO_URL="https://github.com/yetanotherco/zkRust.git" 12 | CURRENT_TAG=$(curl -s -L \ 13 | -H "Accept: application/vnd.github+json" \ 14 | -H "X-GitHub-Api-Version: 2022-11-28" \ 15 | https://api.github.com/repos/yetanotherco/zkRust/releases/latest \ 16 | | grep '"tag_name":' | awk -F'"' '{print $4}') 17 | RELEASE_URL="https://github.com/yetanotherco/zkRust/releases/download/$CURRENT_TAG/" 18 | ARCH=$(uname -m) 19 | 20 | if [ "$ARCH" == "x86_64" ]; then 21 | FILE="zkRust-x86" 22 | elif [ "$ARCH" == "arm64" ]; then 23 | FILE="zkRust-arm64" 24 | else 25 | echo "Unsupported architecture: $ARCH" 26 | exit 1 27 | fi 28 | 29 | mkdir -p "$ZKRUST_BIN_DIR" 30 | if curl -sSf -L "$RELEASE_URL$FILE" -o "$ZKRUST_BIN_PATH"; then 31 | echo "zkRust downloaded successful, installing..." 32 | else 33 | echo "Error: Failed to download $RELEASE_URL$FILE" 34 | exit 1 35 | fi 36 | chmod +x "$ZKRUST_BIN_PATH" 37 | 38 | # Store the correct profile file (i.e. .profile for bash or .zshenv for ZSH). 39 | case $SHELL in 40 | */zsh) 41 | PROFILE="${ZDOTDIR-"$HOME"}/.zshenv" 42 | PREF_SHELL=zsh 43 | ;; 44 | */bash) 45 | PROFILE=$HOME/.bashrc 46 | PREF_SHELL=bash 47 | ;; 48 | */fish) 49 | PROFILE=$HOME/.config/fish/config.fish 50 | PREF_SHELL=fish 51 | ;; 52 | */ash) 53 | PROFILE=$HOME/.profile 54 | PREF_SHELL=ash 55 | ;; 56 | *) 57 | echo "zkrust: could not detect shell, manually add ${ZKRUST_BIN_DIR} to your PATH." 58 | exit 1 59 | esac 60 | 61 | # Only add aligned if it isn't already in PATH. 62 | if [[ ":$PATH:" != *":${ZKRUST_BIN_DIR}:"* ]]; then 63 | # Add the aligned directory to the path and ensure the old PATH variables remain. 64 | # If the shell is fish, echo fish_add_path instead of export. 65 | if [[ "$PREF_SHELL" == "fish" ]]; then 66 | echo >> "$PROFILE" && echo "fish_add_path -a $ZKRUST_BIN_DIR" >> "$PROFILE" 67 | else 68 | echo >> "$PROFILE" && echo "export PATH=\"\$PATH:$ZKRUST_BIN_DIR\"" >> "$PROFILE" 69 | fi 70 | fi 71 | 72 | echo "zkRust installed successfully in $ZKRUST_BIN_PATH." 73 | echo "Detected your preferred shell is $PREF_SHELL and added aligned to PATH." 74 | echo "Installing zkVM toolchains" 75 | 76 | # Install risc0 toolchain 77 | curl -L https://risczero.com/install | bash 78 | rzup install 79 | cargo risczero --version 80 | echo "Risc0 Toolchain Installed" 81 | 82 | # Install sp1 toolchain 83 | curl -L https://sp1.succinct.xyz | bash 84 | source $PROFILE 85 | sp1up 86 | cargo prove --version 87 | echo "Sp1 Toolchain Installed" 88 | 89 | # Clone the specific directory structure from the Git repository 90 | 91 | echo "Cloning Workspaces..." 92 | git clone "$ZKRUST_GIT_REPO_URL" "$ZKRUST_DIR/zkRust" 93 | 94 | # Copy the directory structure from the cloned repository to the .zkRust folder 95 | cp -r "$ZKRUST_DIR/zkRust/workspaces" "$ZKRUST_DIR/." 96 | 97 | # Clean up the cloned repository 98 | rm -rf "$ZKRUST_DIR/zkRust" 99 | 100 | echo "Run 'source $PROFILE' or start a new terminal session to use zkRust!" 101 | -------------------------------------------------------------------------------- /src/sp1.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fs, 3 | io::{self, Write}, 4 | path::PathBuf, 5 | process::{Command, ExitStatus}, 6 | }; 7 | 8 | use crate::utils; 9 | 10 | /// SP1 workspace directories 11 | pub const SP1_SCRIPT_DIR: &str = "workspaces/sp1/script"; 12 | pub const SP1_SRC_DIR: &str = "workspaces/sp1/program"; 13 | pub const SP1_GUEST_MAIN: &str = "workspaces/sp1/program/src/main.rs"; 14 | pub const SP1_HOST_MAIN: &str = "workspaces/sp1/script/src/main.rs"; 15 | pub const SP1_BASE_GUEST_CARGO_TOML: &str = "workspaces/base_files/sp1/cargo_guest"; 16 | pub const SP1_BASE_HOST_CARGO_TOML: &str = "workspaces/base_files/sp1/cargo_host"; 17 | pub const SP1_BASE_HOST: &str = "workspaces/base_files/sp1/host"; 18 | pub const SP1_BASE_HOST_FILE: &str = "workspaces/base_files/sp1/host"; 19 | pub const SP1_GUEST_CARGO_TOML: &str = "workspaces/sp1/program/Cargo.toml"; 20 | 21 | // Proof data generation paths 22 | pub const SP1_ELF_PATH: &str = "./proof_data/sp1/sp1.elf"; 23 | pub const SP1_PROOF_PATH: &str = "./proof_data/sp1/sp1.proof"; 24 | pub const SP1_PUB_INPUT_PATH: &str = "./proof_data/sp1/sp1.pub"; 25 | 26 | /// SP1 header added to programs for generating proofs of their execution 27 | pub const SP1_GUEST_PROGRAM_HEADER: &str = "#![no_main]\nsp1_zkvm::entrypoint!(main);\n"; 28 | 29 | /// SP1 Cargo patch for accelerated SHA-256, K256, and bigint-multiplication circuits 30 | pub const SP1_ACCELERATION_IMPORT: &str = "\n[patch.crates-io]\nsha2 = { git = \"https://github.com/sp1-patches/RustCrypto-hashes\", package = \"sha2\", branch = \"patch-sha2-v0.10.6\" }\nsha3 = { git = \"https://github.com/sp1-patches/RustCrypto-hashes\", package = \"sha3\", branch = \"patch-sha3-v0.10.8\" }\ncrypto-bigint = { git = \"https://github.com/sp1-patches/RustCrypto-bigint\", branch = \"patch-v0.5.5\" }\ntiny-keccak = { git = \"https://github.com/sp1-patches/tiny-keccak\", branch = \"patch-v2.0.2\" }\ned25519-consensus = { git = \"https://github.com/sp1-patches/ed25519-consensus\", branch = \"patch-v2.1.0\" }\necdsa-core = { git = \"https://github.com/sp1-patches/signatures\", package = \"ecdsa\", branch = \"patch-ecdsa-v0.16.9\" }\n"; 31 | 32 | /// SP1 User I/O 33 | // Host 34 | pub const SP1_HOST_WRITE: &str = "stdin.write"; 35 | pub const SP1_HOST_READ: &str = "proof.public_values.read();"; 36 | 37 | // Guest 38 | pub const SP1_IO_READ: &str = "sp1_zkvm::io::read();"; 39 | pub const SP1_IO_COMMIT: &str = "sp1_zkvm::io::commit"; 40 | 41 | pub fn prepare_host( 42 | input: &str, 43 | output: &str, 44 | imports: &str, 45 | host_dir: &PathBuf, 46 | host_main: &PathBuf, 47 | ) -> io::Result<()> { 48 | let mut host_program = imports.to_string(); 49 | let contents = fs::read_to_string(host_dir)?; 50 | 51 | host_program.push_str(&contents); 52 | 53 | // Insert input body 54 | let host_program = host_program.replace(utils::HOST_INPUT, input); 55 | // Insert output body 56 | let host_program = host_program.replace(utils::HOST_OUTPUT, output); 57 | 58 | // replace zkRust::write 59 | let host_program = host_program.replace(utils::IO_WRITE, SP1_HOST_WRITE); 60 | // replace zkRust::out() 61 | let host_program = host_program.replace(utils::IO_OUT, SP1_HOST_READ); 62 | 63 | // Write to host 64 | let mut file = fs::File::create(host_main)?; 65 | file.write_all(host_program.as_bytes())?; 66 | Ok(()) 67 | } 68 | 69 | /// Generates SP1 proof and ELF 70 | pub fn generate_sp1_proof(script_dir: &PathBuf, current_dir: &PathBuf) -> io::Result { 71 | Command::new("cargo") 72 | .arg("run") 73 | .arg("--release") 74 | .arg("--") 75 | .arg(current_dir) 76 | .current_dir(script_dir) 77 | .status() 78 | } -------------------------------------------------------------------------------- /examples/tendermint/src/main.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::{get_light_blocks, verify_blocks}; 2 | use tendermint_light_client_verifier::{ 3 | options::Options, types::LightBlock, ProdVerifier, Verdict, Verifier, 4 | }; 5 | mod utils; 6 | use zk_rust_io; 7 | 8 | pub fn main() { 9 | println!("cycle-tracker-start: io"); 10 | println!("cycle-tracker-start: reading bytes"); 11 | let encoded_1: Vec = zk_rust_io::read(); 12 | let encoded_2: Vec = zk_rust_io::read(); 13 | println!("cycle-tracker-end: reading bytes"); 14 | println!("first 10 bytes: {:?}", &encoded_1[..10]); 15 | println!("first 10 bytes: {:?}", &encoded_2[..10]); 16 | 17 | println!("cycle-tracker-start: serde"); 18 | let light_block_1: LightBlock = serde_cbor::from_slice(&encoded_1).unwrap(); 19 | let light_block_2: LightBlock = serde_cbor::from_slice(&encoded_2).unwrap(); 20 | println!("cycle-tracker-end: serde"); 21 | println!("cycle-tracker-end: io"); 22 | 23 | println!( 24 | "LightBlock1 number of validators: {}", 25 | light_block_1.validators.validators().len() 26 | ); 27 | println!( 28 | "LightBlock2 number of validators: {}", 29 | light_block_2.validators.validators().len() 30 | ); 31 | 32 | println!("cycle-tracker-start: header hash"); 33 | let header_hash_1 = light_block_1.signed_header.header.hash(); 34 | let header_hash_2 = light_block_2.signed_header.header.hash(); 35 | println!("cycle-tracker-end: header hash"); 36 | 37 | println!("cycle-tracker-start: public input headers"); 38 | zk_rust_io::commit(&header_hash_1.as_bytes()); 39 | zk_rust_io::commit(&header_hash_2.as_bytes()); 40 | println!("cycle-tracker-end: public input headers"); 41 | 42 | println!("cycle-tracker-start: verify"); 43 | let vp = ProdVerifier::default(); 44 | let opt = Options { 45 | trust_threshold: Default::default(), 46 | trusting_period: std::time::Duration::from_secs(500), 47 | clock_drift: Default::default(), 48 | }; 49 | let verify_time = light_block_2.time() + std::time::Duration::from_secs(20); 50 | let verdict = vp.verify_update_header( 51 | light_block_2.as_untrusted_state(), 52 | light_block_1.as_trusted_state(), 53 | &opt, 54 | verify_time.unwrap(), 55 | ); 56 | println!("cycle-tracker-end: verify"); 57 | 58 | println!("cycle-tracker-start: public inputs verdict"); 59 | let verdict_encoded = serde_cbor::to_vec(&verdict).unwrap(); 60 | zk_rust_io::commit(&verdict_encoded.as_slice()); 61 | println!("cycle-tracker-end: public inputs verdict"); 62 | 63 | match verdict { 64 | Verdict::Success => { 65 | println!("success"); 66 | } 67 | v => panic!("expected success, got: {:?}", v), 68 | } 69 | } 70 | 71 | pub fn input() { 72 | let (light_block_1, light_block_2) = get_light_blocks(); 73 | 74 | let expected_verdict = verify_blocks(light_block_1.clone(), light_block_2.clone()); 75 | 76 | let encoded_1 = serde_cbor::to_vec(&light_block_1).unwrap(); 77 | let encoded_2 = serde_cbor::to_vec(&light_block_2).unwrap(); 78 | 79 | zk_rust_io::write(&encoded_1); 80 | zk_rust_io::write(&encoded_2); 81 | } 82 | 83 | pub fn output() { 84 | let (light_block_1, light_block_2) = get_light_blocks(); 85 | // Verify the public values 86 | let mut expected_public_values: Vec = Vec::new(); 87 | expected_public_values.extend(light_block_1.signed_header.header.hash().as_bytes()); 88 | expected_public_values.extend(light_block_2.signed_header.header.hash().as_bytes()); 89 | expected_public_values.extend(serde_cbor::to_vec(&expected_verdict).unwrap()); 90 | 91 | let public_inputs: Vec = zk_rust_io::out(); 92 | 93 | assert_eq!(public_inputs.as_ref(), expected_public_values); 94 | } 95 | -------------------------------------------------------------------------------- /src/risc0.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fs, 3 | io::{self, Write}, 4 | path::PathBuf, 5 | process::{Command, ExitStatus}, 6 | }; 7 | 8 | use crate::utils; 9 | 10 | /// RISC0 workspace directories 11 | pub const RISC0_WORKSPACE_DIR: &str = "workspaces/risc0/"; 12 | pub const RISC0_SRC_DIR: &str = "workspaces/risc0/methods/guest"; 13 | pub const RISC0_GUEST_MAIN: &str = "workspaces/risc0/methods/guest/src/main.rs"; 14 | pub const RISC0_HOST_MAIN: &str = "workspaces/risc0/host/src/main.rs"; 15 | pub const RISC0_BASE_HOST_CARGO_TOML: &str = "workspaces/base_files/risc0/cargo_host"; 16 | pub const RISC0_BASE_GUEST_CARGO_TOML: &str = "workspaces/base_files/risc0/cargo_guest"; 17 | pub const RISC0_BASE_HOST: &str = "workspaces/base_files/risc0/host"; 18 | pub const RISC0_BASE_HOST_FILE: &str = "workspaces/base_files/risc0/host"; 19 | pub const RISC0_GUEST_CARGO_TOML: &str = "workspaces/risc0/methods/guest/Cargo.toml"; 20 | 21 | // Proof data generation paths 22 | pub const PROOF_FILE_PATH: &str = "./proof_data/risc0/risc0.proof"; 23 | pub const IMAGE_ID_FILE_PATH: &str = "./proof_data/risc0/risc0.imageid"; 24 | pub const PUBLIC_INPUT_FILE_PATH: &str = "./proof_data/risc0/risc0.pub"; 25 | 26 | //TODO: should we use std or no_std header 27 | /// RISC0 header added to programs for generating proofs of their execution 28 | pub const RISC0_GUEST_PROGRAM_HEADER: &str = "#![no_main]\n\nrisc0_zkvm::guest::entry!(main);\n"; 29 | 30 | /// RISC0 Cargo patch for accelerated SHA-256, K256, and bigint-multiplication circuits 31 | pub const RISC0_ACCELERATION_IMPORT: &str = "\n[patch.crates-io]\nsha2 = { git = \"https://github.com/risc0/RustCrypto-hashes\", tag = \"sha2-v0.10.6-risczero.0\" }\nk256 = { git = \"https://github.com/risc0/RustCrypto-elliptic-curves\", tag = \"k256/v0.13.1-risczero.1\" }\ncrypto-bigint = { git = \"https://github.com/risc0/RustCrypto-crypto-bigint\", tag = \"v0.5.5-risczero.0\" }"; 32 | 33 | /// RISC0 User I/O Markers 34 | // HOST 35 | pub const RISC0_ENV_BUILDER: &str = "let env = ExecutorEnv::builder()"; 36 | pub const RISC0_IO_HOST: &str = "risc0_zkvm::ExecutorEnv::builder()"; 37 | pub const RISC0_IO_HOST_BUILD: &str = ".build().unwrap();"; 38 | 39 | // GUEST 40 | pub const RISC0_IO_READ: &str = "risc0_zkvm::guest::env::read();"; 41 | pub const RISC0_IO_WRITE: &str = "risc0_zkvm::guest::env::write"; 42 | pub const RISC0_IO_COMMIT: &str = "risc0_zkvm::guest::env::commit"; 43 | pub const RISC0_IO_OUT: &str = "receipt.journal.decode().unwrap();"; 44 | 45 | pub fn prepare_host( 46 | input: &str, 47 | output: &str, 48 | imports: &str, 49 | host_dir: &PathBuf, 50 | host_main: &PathBuf, 51 | ) -> io::Result<()> { 52 | let mut host_program = imports.to_string(); 53 | let contents = fs::read_to_string(host_dir)?; 54 | host_program.push_str(&contents); 55 | 56 | // Insert input body 57 | let host_program = host_program.replace(utils::HOST_INPUT, input); 58 | // Insert output body 59 | let host_program = host_program.replace(utils::HOST_OUTPUT, output); 60 | 61 | // Extract Variable names from host and add them to the ExecutorEnv::builder() 62 | let values = utils::extract_regex( 63 | host_main, 64 | &format!("{}[(](.*?)[)]", regex::escape(utils::IO_WRITE)), 65 | )?; 66 | 67 | // Construct new Environment Builder 68 | let mut new_builder = RISC0_ENV_BUILDER.to_string(); 69 | for value in values { 70 | new_builder.push_str(&format!(".write({}).unwrap()", value)); 71 | } 72 | new_builder.push_str(".build().unwrap();"); 73 | 74 | // Replace environment builder in host with new one 75 | let host_program = host_program.replace( 76 | "let env = ExecutorEnv::builder().build().unwrap();", 77 | &new_builder, 78 | ); 79 | 80 | // replace zkRust::out() 81 | let host_program = host_program.replace(utils::IO_OUT, RISC0_IO_OUT); 82 | 83 | let mut file = fs::File::create(host_main)?; 84 | file.write_all(host_program.as_bytes())?; 85 | 86 | utils::remove_lines(host_main, "zk_rust_io::write(")?; 87 | Ok(()) 88 | } 89 | 90 | /// Generates RISC0 proof and image ID 91 | pub fn generate_risc0_proof(guest_path: &PathBuf, current_dir: &PathBuf) -> io::Result { 92 | Command::new("cargo") 93 | .arg("run") 94 | .arg("--release") 95 | .arg("--") 96 | .arg(current_dir) 97 | .current_dir(guest_path) 98 | .status() 99 | } 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zkRust 2 | 3 | `zkRust` is a CLI tool to simplify developing zk applications in Rust using zkVM's such as SP1 or Risc0. 4 | 5 | `zkRust` simplifies the development experience of using zkVM's by abstracting the complexity of using zkVM's from the developer and providing them the choice of which zkVM they would like to develop with. 6 | 7 | ## Installation: 8 | First make sure [Rust](https://www.rust-lang.org/tools/install) is installed on your machine. 9 | 10 | 11 | zkRust can also be installed directly by downloading the latest release binaries. 12 | 13 | ```sh 14 | curl -L https://raw.githubusercontent.com/yetanotherco/zkRust/main/install_zkrust.sh | bash 15 | ``` 16 | 17 | for local development install the repository dependencies. 18 | 19 | ```sh 20 | make install 21 | ``` 22 | 23 | ## Quickstart 24 | 25 | To get started you can create a workspace for your project in zkRust by running: 26 | 27 | ```sh 28 | cargo new 29 | ``` 30 | 31 | You can test zkRust for any of the examples in the `examples` folder. This include programs for: 32 | 33 | - Computing and reading the results of computing Fibonacci numbers. 34 | - Performing RSA key verification. 35 | - Performing ECDSA program. 36 | - Verification of a blockchain state diff. 37 | - Computing the Sha256 hash of a value. 38 | - Verifying a tendermint block. 39 | - Interacting with a user to answer a quiz. 40 | 41 | ## Usage: 42 | 43 | To use zkRust, users must specify a `main()` function whose execution is proven within the zkVM. This function must be defined within a `main.rs` file in a directory with the following structure: 44 | 45 | ``` 46 | . 47 | └── 48 | ├── Cargo.toml 49 | └── src 50 | └── main.rs 51 | ``` 52 | 53 | Projects can also store libraries in a separate `lib/` folder. 54 | 55 | ``` 56 | . 57 | └── 58 | ├── Cargo.toml 59 | ├── lib/ 60 | └── src 61 | └── main.rs 62 | ``` 63 | 64 | The user may also define a `input()`, `output()` functions, in addition to `main()`. The `input()` and `output()` functions define code that runs outside of the zkVM before and after the zkVM generates a proof of the users program. The `input()` function executes before the zkVM code is executed and allows the user to define inputs passed to the VM such as a deserialized Tx or data fetched from an external source at runtime. Within the `main()` (guest) function the user may write information from the computation performed in the zkVM to an output buffer to be used after proof generation. The `output()` defines code that allows the user to read the information written to that buffer of the and perform post-processing of that data. 65 | 66 | ![](./assets/zkRust_execution_flow.png) 67 | 68 | The user may specify (public) inputs into the VM (guest) code using `zk_rust_io::write()` as long on the type of Rust object they want to input into the VM implements [Serialize](https://docs.rs/serde/latest/serde/trait.Serialize.html). Within there `main()` function the user may read in these inputs to there program via `zk_rust_io::read()`. They can also output data computed during the execution phase of the code within the VM program by commiting it to the VM output via `zk_rust_io::commit()`. To read the output of the output of the VM program the user declares `zk_rust_io::out()`, which reads and deserializes the committed information from the VM output buffer. 69 | 70 | The `zk_rust_io` crate defines function headers that are not inlined and are purely used as compile time symbols to ensure a user can compile there Rust code before running it within one of the zkVM available in zkRust. 71 | 72 | To use the I/O imports import the `zk_rust_io` crate by adding the following to the `Cargo.toml` in your project directory. 73 | 74 | ```sh 75 | zk_rust_io = { git = "https://github.com/yetanotherco/zkRust.git" } 76 | ``` 77 | 78 | ### `input()`: 79 | 80 | ```rust 81 | use zk_rust_io; 82 | 83 | pub fn input() { 84 | let pattern = "a+".to_string(); 85 | let target_string = "an era of truth, not trust".to_string(); 86 | 87 | // Write in a simple regex pattern. 88 | zk_rust_io::write(&pattern); 89 | zk_rust_io::write(&target_string); 90 | } 91 | ``` 92 | 93 | ### `main()` 94 | 95 | ```rust 96 | use regex::Regex; 97 | use zk_rust_io; 98 | 99 | pub fn main() { 100 | // Read two inputs from the prover: a regex pattern and a target string. 101 | let pattern: String = zk_rust_io::read(); 102 | let target_string: String = zk_rust_io::read(); 103 | 104 | // Try to compile the regex pattern. If it fails, write `false` as output and return. 105 | let regex = match Regex::new(&pattern) { 106 | Ok(regex) => regex, 107 | Err(_) => { 108 | panic!("Invalid regex pattern"); 109 | } 110 | }; 111 | 112 | // Perform the regex search on the target string. 113 | let result = regex.is_match(&target_string); 114 | 115 | // Write the result (true or false) to the output. 116 | zk_rust_io::commit(&result); 117 | } 118 | ``` 119 | 120 | ### `output()`: 121 | 122 | ```rust 123 | use zk_rust_io; 124 | 125 | pub fn output() { 126 | // Read the output. 127 | let res: bool = zk_rust_io::out(); 128 | println!("res: {}", res); 129 | } 130 | ``` 131 | 132 | To generate a proof of the execution of your code run the following: 133 | 134 | - **SP1**: 135 | ```sh 136 | cargo run --release -- prove-sp1 137 | ``` 138 | - **Risc0**: 139 | ```sh 140 | cargo run --release -- prove-risc0 141 | ``` 142 | ***NOTE*** Currently Aligned supports verification of [Risc0](https://dev.risczero.com/api/zkvm/quickstart#1-install-the-risc-zero-toolchain) proofs from release version `v1.0.1`. 143 | 144 | To generate your proof and send it to [Aligned](https://github.com/yetanotherco/aligned_layer). First generate a local wallet keystore using `[cast](https://book.getfoundry.sh/cast/). 145 | 146 | ```sh 147 | cast wallet new-mnemonic 148 | ``` 149 | 150 | Then you can import your created keystore using: 151 | 152 | ```sh 153 | cast wallet import --interactive 154 | ``` 155 | 156 | Finally, to generate and send your proof of your programs execution to Aligned use the zkRust CLI with the `--submit-to-aligned` flag. 157 | 158 | ```sh 159 | cargo run --release -- prove-sp1 --submit-to-aligned --keystore-path 160 | ``` 161 | 162 | ### Flags: 163 | 164 | - `--submit-to-aligned`: Sends the proof to be verified on Aligned after proof generation. Requires an rpc url and keystore for a funded wallet specified via the `--rpc-url` and `--key_store` flags. 165 | 166 | - `--keystore-path`: Path to the keystore of the users wallet. Defaults to `~/keystore`. 167 | 168 | - `--rpc-url`: Specifies the rpc-url used for the user eth rpc-url. Defaults to `https://ethereum-holesky-rpc.publicnode.com`. 169 | 170 | - `--network`: Chain ID number of the ethereum chain Aligned is deployed on. Defaults to `holesky`. 171 | 172 | - `--precompiles`: Enables acceleration via precompiles for supported zkVM's. Specifying this flag allows for VM specific speedups for specific expensive operations such as SHA256, SHA3, bigint multiplication, and ed25519 signature verification. By specifying this flag proving operations for specific operations within the following rust crates are accelerated: 173 | 174 | - SP1: 175 | 176 | - sha2 v0.10.6 177 | - sha3 v0.10.8 178 | - crypto-bigint v0.5.5 179 | - tiny-keccak v2.0.2 180 | - ed25519-consensus v2.1.0 181 | - ecdsa-core v0.16.9 182 | 183 | - Risc0: 184 | - sha2 v0.10.6 185 | - k256 v0.13.1 186 | - crypto-bigint v0.5.5 187 | 188 | ## Support: 189 | 190 | For additional support using zkRust or questions please reach out via the [telegram support group](https://t.me/+JEiLahym_lRkNzM0). 191 | 192 | ## Examples: 193 | 194 | After installing the binary and required un one of the following commands to test zkRust. You can choose either Risc0 or SP1: 195 | 196 | **Fibonacci**: 197 | 198 | ```bash 199 | make prove_risc0_fibonacci 200 | ``` 201 | 202 | ```bash 203 | make prove_sp1_fibonacci 204 | ``` 205 | 206 | **RSA**: 207 | 208 | ```bash 209 | make prove_risc0_rsa 210 | ``` 211 | 212 | ```bash 213 | make prove_sp1_rsa 214 | ``` 215 | 216 | **ECDSA**: 217 | 218 | ```bash 219 | make prove_risc0_ecdsa 220 | ``` 221 | 222 | ```bash 223 | make prove_sp1_ecdsa 224 | ``` 225 | 226 | **Blockchain State Diff**: 227 | 228 | ```bash 229 | make prove_risc0_json 230 | ``` 231 | 232 | ```bash 233 | make prove_sp1_json 234 | ``` 235 | 236 | **Regex**: 237 | 238 | ```bash 239 | make prove_risc0_regex 240 | ``` 241 | 242 | ```bash 243 | make prove_sp1_regex 244 | ``` 245 | 246 | **Sha**: 247 | 248 | ```bash 249 | make prove_risc0_sha 250 | ``` 251 | 252 | ```bash 253 | make prove_sp1_sha 254 | ``` 255 | 256 | **Tendermint**: 257 | 258 | ```bash 259 | make prove_risc0_tendermint 260 | ``` 261 | 262 | ```bash 263 | make prove_sp1_tendermint 264 | ``` 265 | 266 | **Zk Quiz**: 267 | 268 | ```bash 269 | make prove_risc0_zkquiz 270 | ``` 271 | 272 | ```bash 273 | make prove_sp1_zkquiz 274 | ``` 275 | 276 | **NOTE**: for the precompiles to be included within the compilation step the crate version you are using must match the crate version above. 277 | 278 | # Acknowledgments: 279 | 280 | ZK Rust was intended and designed as a tool to make development on programs that use zkVM's easier and reduce deduplication of code for developers that want to experiment with zk on Aligned layer. We want to thank for the work and contributions of the SP1 and Risc0 teams to the field of Zero Knowledge Cryptography, and building the provers that work as the backbone of zkRust, and also for providing the examples ours are derived from. 281 | 282 | [SP1](https://github.com/succinctlabs/sp1.git) 283 | 284 | [Risc0](https://github.com/risc0/risc0.git) 285 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use aligned_sdk::core::errors::{AlignedError, SubmitError}; 2 | use ethers::utils::format_units; 3 | use log::{error, info}; 4 | use std::fs::File; 5 | use std::io::Write; 6 | use std::path::PathBuf; 7 | use serde_json::json; 8 | 9 | use aligned_sdk::core::types::{ 10 | AlignedVerificationData, Network, PriceEstimate, ProvingSystemId, VerificationData, 11 | }; 12 | use aligned_sdk::sdk::{ 13 | deposit_to_aligned, estimate_fee, get_balance_in_aligned, get_chain_id, get_next_nonce, 14 | submit_and_wait_verification, 15 | }; 16 | use clap::{Args, ValueEnum}; 17 | use dialoguer::Confirm; 18 | use ethers::prelude::*; 19 | use ethers::providers::Http; 20 | use ethers::signers::LocalWallet; 21 | 22 | pub mod risc0; 23 | pub mod sp1; 24 | pub mod utils; 25 | 26 | // Make proof_data path optional 27 | // Make keystore unneeded 28 | #[derive(Args, Debug)] 29 | pub struct ProofArgs { 30 | pub guest_path: String, 31 | #[clap(long = "submit-to-aligned")] 32 | pub submit_to_aligned: bool, 33 | #[clap( 34 | name = "Path to Wallet Key Store", 35 | long = "keystore-path", 36 | required_if_eq("submit_to_aligned", "true") 37 | )] 38 | pub keystore_path: Option, 39 | #[clap( 40 | name = "URL of an Ethereum RPC Node", 41 | long = "rpc-url", 42 | default_value("https://ethereum-holesky-rpc.publicnode.com") 43 | )] 44 | pub rpc_url: String, 45 | #[clap( 46 | name = "The working network's name", 47 | long = "network", 48 | default_value = "holesky" 49 | )] 50 | pub network: NetworkArg, 51 | #[clap( 52 | name = "Payment send to the BatcherServicContract to fund Proof submission (Wei)", 53 | long = "batcher-payment", 54 | default_value("4000000000000000") 55 | )] 56 | pub batcher_payment: u128, 57 | #[clap( 58 | name = "Enables zkVM Acceleration via VM Precompiles", 59 | long = "precompiles" 60 | )] 61 | pub precompiles: bool, 62 | #[arg( 63 | name = "Aligned verification data directory Path", 64 | long = "aligned-verification-data-path", 65 | default_value = "./aligned_verification_data/" 66 | )] 67 | pub batch_inclusion_data_directory_path: String, 68 | #[arg( 69 | name = "Proof data directory path", 70 | long = "proof-data-path", 71 | default_value = "./proof_data" 72 | )] 73 | pub proof_data_directory_path: String, 74 | #[clap( 75 | name = "URL of the Aligned Batcher", 76 | long = "batcher-url", 77 | default_value("wss://batcher.alignedlayer.com") 78 | )] 79 | pub batcher_url: String, 80 | } 81 | 82 | const MIN_FEE_PER_PROOF: u128 = 13_000 * 100_000_000; // gas_price = 0.1 Gwei = 0.0000000001 ether (low gas price) 83 | 84 | #[derive(Debug, Clone, ValueEnum, Copy)] 85 | pub enum NetworkArg { 86 | Devnet, 87 | Holesky, 88 | HoleskyStage, 89 | } 90 | 91 | impl From for Network { 92 | fn from(env_arg: NetworkArg) -> Self { 93 | match env_arg { 94 | NetworkArg::Devnet => Network::Devnet, 95 | NetworkArg::Holesky => Network::Holesky, 96 | NetworkArg::HoleskyStage => Network::HoleskyStage, 97 | } 98 | } 99 | } 100 | 101 | pub async fn submit_proof_to_aligned( 102 | proof_path: &str, 103 | elf_path: &str, 104 | pub_input_path: Option<&str>, 105 | args: &ProofArgs, 106 | proof_system_id: ProvingSystemId, 107 | ) -> Result<(), AlignedError> { 108 | let keystore_password = rpassword::prompt_password("Enter keystore password: ") 109 | .map_err(|e| AlignedError::SubmitError(SubmitError::WalletSignerError(e.to_string())))?; 110 | 111 | let network: Network = args.network.into(); 112 | let Some(keystore_path) = args.keystore_path.clone() else { 113 | return Err(SubmitError::GenericError( 114 | "Keystore path no found. Please supply path to your local wallet keystore.".to_string(), 115 | ))?; 116 | }; 117 | let local_wallet = LocalWallet::decrypt_keystore(&keystore_path, keystore_password) 118 | .map_err(|e| AlignedError::SubmitError(SubmitError::WalletSignerError(e.to_string())))?; 119 | let chain_id = get_chain_id(&args.rpc_url).await?; 120 | let wallet = local_wallet.with_chain_id(chain_id); 121 | 122 | let proof = std::fs::read(proof_path) 123 | .map_err(|e| AlignedError::SubmitError(SubmitError::GenericError(e.to_string())))?; 124 | 125 | let elf_data = std::fs::read(elf_path) 126 | .map_err(|e| AlignedError::SubmitError(SubmitError::GenericError(e.to_string())))?; 127 | 128 | // Public inputs are optional. 129 | let pub_input = pub_input_path 130 | .map(std::fs::read) 131 | .transpose() 132 | .map_err(|e| SubmitError::GenericError(e.to_string()))?; 133 | 134 | let provider = Provider::::try_from(&args.rpc_url) 135 | .map_err(|e| SubmitError::EthereumProviderError(e.to_string()))?; 136 | 137 | let signer = SignerMiddleware::new(provider.clone(), wallet.clone()); 138 | 139 | // TODO(pat): Add minimum mac fee check in aligned sdk and remove factor of 2 increase in holesky gas price. 140 | let mut max_fee = estimate_fee(&args.rpc_url, PriceEstimate::Instant).await?; 141 | 142 | // If estimated fee is below Minimum we use the minimum 143 | if max_fee < U256::from(MIN_FEE_PER_PROOF) { 144 | max_fee = U256::from(MIN_FEE_PER_PROOF); 145 | } 146 | 147 | let user_address = wallet.address(); 148 | //TODO: Need to implement Aligned Error for Balance Error 149 | let user_balance = get_balance_in_aligned(user_address, &args.rpc_url, network) 150 | .await 151 | .map_err(|_| { 152 | SubmitError::GenericError("Failed to retrieve user balance from Aligned".to_string()) 153 | })?; 154 | 155 | let format_max_fee = format_units(max_fee, "ether").map_err(|e| { 156 | error!("Unable to convert estimated proof submision price"); 157 | SubmitError::GenericError(e.to_string()) 158 | })?; 159 | 160 | let format_user_balance = format_units(user_balance, "ether").map_err(|e| { 161 | error!("Unable to convert estimated proof submision price"); 162 | SubmitError::GenericError(e.to_string()) 163 | })?; 164 | 165 | if user_balance < max_fee { 166 | info!( 167 | "Insufficient balance for {:?}: User Balance {:?} eth < Proof Submission Fee {:?} eth", 168 | user_address, format_user_balance, format_max_fee 169 | ); 170 | if Confirm::with_theme(&dialoguer::theme::ColorfulTheme::default()) 171 | .with_prompt(format!( 172 | "Would you like to deposit {:?} eth into Aligned to fund proof submission?", 173 | format_max_fee 174 | )) 175 | .interact() 176 | .map_err(|e| { 177 | error!("Failed to read user input"); 178 | SubmitError::GenericError(e.to_string()) 179 | })? 180 | { 181 | info!("Submitting deposit to Batcher"); 182 | let Ok(tx_receipt) = 183 | deposit_to_aligned(max_fee, signer, network).await 184 | else { 185 | return Err(SubmitError::GenericError( 186 | "Failed to Deposit Funds into the Batcher".to_string(), 187 | ))?; 188 | }; 189 | info!( 190 | "Funds deposited successfully to Batcher payment contract. Tx: 0x{:x}", 191 | tx_receipt.transaction_hash 192 | ); 193 | } else { 194 | info!("Batcher Payment Cancelled"); 195 | return Err(SubmitError::GenericError( 196 | "Insufficient user balance on Aligned".to_string(), 197 | ))?; 198 | } 199 | } 200 | 201 | if !Confirm::with_theme(&dialoguer::theme::ColorfulTheme::default()) 202 | .with_prompt(format!( 203 | "Would you like to pay {:?} eth to submit your proof to Aligned?", 204 | format_max_fee 205 | )) 206 | .interact() 207 | .map_err(|e| { 208 | error!("Failed to read user input"); 209 | SubmitError::GenericError(e.to_string()) 210 | })? 211 | { 212 | info!("User declined to pay submission cost"); 213 | return Err(SubmitError::GenericError( 214 | "User declined to pay submission cost".to_string(), 215 | ))?; 216 | } 217 | 218 | let verification_data = VerificationData { 219 | proving_system: proof_system_id, 220 | proof, 221 | proof_generator_addr: wallet.address(), 222 | vm_program_code: Some(elf_data), 223 | verification_key: None, 224 | pub_input: pub_input.clone(), 225 | }; 226 | 227 | let nonce = get_next_nonce(&args.rpc_url, wallet.address(), network) 228 | .await?; 229 | 230 | info!("Submitting proof to Aligned for Verification"); 231 | 232 | let aligned_verification_data = submit_and_wait_verification( 233 | &args.batcher_url, 234 | &args.rpc_url, 235 | network, 236 | &verification_data, 237 | max_fee, 238 | wallet, 239 | nonce, 240 | ) 241 | .await?; 242 | 243 | info!("Proof Submitted to Aligned!"); 244 | info!( 245 | "https://explorer.alignedlayer.com/batches/0x{}", 246 | hex::encode(aligned_verification_data.batch_merkle_root) 247 | ); 248 | 249 | // If pub_input is None return empty 250 | let pub_input = pub_input.unwrap_or(vec![]); 251 | save_response( 252 | PathBuf::from(&args.batch_inclusion_data_directory_path), 253 | &aligned_verification_data, 254 | &pub_input 255 | )?; 256 | info!( 257 | "Aligned Verification Data saved {:?}", 258 | args.batch_inclusion_data_directory_path 259 | ); 260 | Ok(()) 261 | } 262 | 263 | fn save_response( 264 | batch_inclusion_data_directory_path: PathBuf, 265 | aligned_verification_data: &AlignedVerificationData, 266 | pub_input: &[u8], 267 | ) -> Result<(), SubmitError> { 268 | std::fs::create_dir_all(&batch_inclusion_data_directory_path) 269 | .map_err(|e| SubmitError::IoError(batch_inclusion_data_directory_path.clone(), e))?; 270 | 271 | let batch_merkle_root = &hex::encode(aligned_verification_data.batch_merkle_root)[..8]; 272 | let batch_inclusion_data_file_name = batch_merkle_root.to_owned() 273 | + "_" 274 | + &aligned_verification_data.index_in_batch.to_string() 275 | + ".json"; 276 | 277 | let batch_inclusion_data_path = 278 | batch_inclusion_data_directory_path.join(batch_inclusion_data_file_name); 279 | 280 | let merkle_proof = aligned_verification_data 281 | .batch_inclusion_proof 282 | .merkle_path 283 | .iter() 284 | .map(hex::encode) 285 | .collect::>() 286 | .join(""); 287 | let data = json!({ 288 | "proof_commitment": hex::encode(aligned_verification_data.verification_data_commitment.proof_commitment), 289 | "pub_input_commitment": hex::encode(aligned_verification_data.verification_data_commitment.pub_input_commitment), 290 | "program_id_commitment": hex::encode(aligned_verification_data.verification_data_commitment.proving_system_aux_data_commitment), 291 | "proof_generator_addr": hex::encode(aligned_verification_data.verification_data_commitment.proof_generator_addr), 292 | "batch_merkle_root": hex::encode(aligned_verification_data.batch_merkle_root), 293 | "pub_input": hex::encode(pub_input), 294 | "verification_data_batch_index": aligned_verification_data.index_in_batch, 295 | "merkle_proof": merkle_proof, 296 | }); 297 | 298 | let mut file = File::create(&batch_inclusion_data_path) 299 | .map_err(|e| SubmitError::IoError(batch_inclusion_data_path.clone(), e))?; 300 | file.write_all(serde_json::to_string_pretty(&data).unwrap().as_bytes()) 301 | .map_err(|e| SubmitError::IoError(batch_inclusion_data_path.clone(), e))?; 302 | let current_dir = std::env::current_dir().map_err(|_| SubmitError::GenericError("Failed to get current directory".to_string()))?; 303 | 304 | info!( 305 | "Saved batch inclusion data to {:?}", 306 | current_dir.join(batch_inclusion_data_path) 307 | ); 308 | 309 | Ok(()) 310 | } -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use aligned_sdk::core::types::ProvingSystemId; 2 | use clap::{Parser, Subcommand}; 3 | use env_logger::Env; 4 | use log::error; 5 | use log::info; 6 | use std::fs::OpenOptions; 7 | use std::io::Write; 8 | use std::path::PathBuf; 9 | use tokio::io; 10 | use zkRust::{risc0, sp1, submit_proof_to_aligned, utils, ProofArgs}; 11 | 12 | #[derive(Parser)] 13 | #[command(version, about, long_about = None)] 14 | #[command(propagate_version = true)] 15 | struct Cli { 16 | #[command(subcommand)] 17 | command: Commands, 18 | } 19 | 20 | #[derive(Subcommand)] 21 | enum Commands { 22 | #[clap(about = "Generate a proof of execution of a program using SP1")] 23 | ProveSp1(ProofArgs), 24 | #[clap(about = "Generate a proof of execution of a program using RISC0")] 25 | ProveRisc0(ProofArgs), 26 | } 27 | 28 | #[tokio::main] 29 | async fn main() -> io::Result<()> { 30 | env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); 31 | let cli = Cli::parse(); 32 | 33 | match &cli.command { 34 | Commands::ProveSp1(args) => { 35 | info!("Proving with SP1, program in: {}", args.guest_path); 36 | // Perform sanitation checks on directory 37 | let proof_data_dir = PathBuf::from(&args.proof_data_directory_path); 38 | if !proof_data_dir.exists() { 39 | std::fs::create_dir_all(proof_data_dir).unwrap_or(info!( 40 | "Saving Proofs to: {:?}", 41 | &args.proof_data_directory_path 42 | )); 43 | } 44 | if utils::validate_directory_structure(&args.guest_path) { 45 | let Some(home_dir) = dirs::home_dir() else { 46 | error!("Failed to locate home directory"); 47 | return Ok(()); 48 | }; 49 | let Ok(current_dir) = std::env::current_dir() else { 50 | error!("Failed to locate current directory"); 51 | return Ok(()); 52 | }; 53 | let home_dir = home_dir.join(".zkRust"); 54 | utils::prepare_workspace( 55 | &PathBuf::from(&args.guest_path), 56 | &home_dir.join(sp1::SP1_SRC_DIR), 57 | &home_dir.join(sp1::SP1_GUEST_CARGO_TOML), 58 | &home_dir.join("workspaces/sp1/script"), 59 | &home_dir.join("workspaces/sp1/script/Cargo.toml"), 60 | &home_dir.join(sp1::SP1_BASE_HOST_CARGO_TOML), 61 | &home_dir.join(sp1::SP1_BASE_GUEST_CARGO_TOML), 62 | )?; 63 | 64 | let Ok(imports) = utils::get_imports(&home_dir.join(sp1::SP1_GUEST_MAIN)) else { 65 | error!("Failed to extract imports"); 66 | return Ok(()); 67 | }; 68 | 69 | let main_path = home_dir.join(sp1::SP1_GUEST_MAIN); 70 | let Ok(function_bodies) = utils::extract_function_bodies( 71 | &main_path, 72 | vec![ 73 | "fn main()".to_string(), 74 | "fn input()".to_string(), 75 | "fn output()".to_string(), 76 | ], 77 | ) else { 78 | error!("Failed to extract function bodies"); 79 | return Ok(()); 80 | }; 81 | /* 82 | Adds header to the guest & replace I/O imports 83 | risc0: 84 | 85 | #![no_main] 86 | sp1_zkvm::entrypoint!(main); 87 | */ 88 | utils::prepare_guest( 89 | &imports, 90 | &function_bodies[0], 91 | sp1::SP1_GUEST_PROGRAM_HEADER, 92 | sp1::SP1_IO_READ, 93 | sp1::SP1_IO_COMMIT, 94 | &home_dir.join(sp1::SP1_GUEST_MAIN), 95 | )?; 96 | sp1::prepare_host( 97 | &function_bodies[1], 98 | &function_bodies[2], 99 | &imports, 100 | &home_dir.join(sp1::SP1_BASE_HOST), 101 | &home_dir.join(sp1::SP1_HOST_MAIN), 102 | )?; 103 | 104 | if args.precompiles { 105 | let mut toml_file = OpenOptions::new() 106 | .append(true) // Open the file in append mode 107 | .open(home_dir.join(sp1::SP1_GUEST_CARGO_TOML))?; 108 | 109 | writeln!(toml_file, "{}", sp1::SP1_ACCELERATION_IMPORT)?; 110 | } 111 | 112 | let script_dir = home_dir.join(sp1::SP1_SCRIPT_DIR); 113 | if sp1::generate_sp1_proof(&script_dir, ¤t_dir)?.success() { 114 | info!("SP1 proof and ELF generated"); 115 | 116 | utils::replace( 117 | &home_dir.join(sp1::SP1_GUEST_CARGO_TOML), 118 | sp1::SP1_ACCELERATION_IMPORT, 119 | "", 120 | )?; 121 | 122 | // Submit to aligned 123 | if args.submit_to_aligned { 124 | submit_proof_to_aligned( 125 | sp1::SP1_PROOF_PATH, 126 | sp1::SP1_ELF_PATH, 127 | Some(sp1::SP1_PUB_INPUT_PATH), 128 | args, 129 | ProvingSystemId::SP1, 130 | ) 131 | .await 132 | .map_err(|e| { 133 | error!("Proof not submitted to Aligned"); 134 | io::Error::other(e.to_string()) 135 | })?; 136 | info!("SP1 proof submitted and verified on Aligned"); 137 | } 138 | 139 | std::fs::copy( 140 | home_dir.join(sp1::SP1_BASE_HOST_FILE), 141 | home_dir.join(sp1::SP1_HOST_MAIN), 142 | ) 143 | .map_err(|e| { 144 | error!("Failed to clear SP1 host file"); 145 | e 146 | })?; 147 | return Ok(()); 148 | } 149 | info!("SP1 proof generation failed"); 150 | 151 | // Clear host 152 | std::fs::copy( 153 | home_dir.join(sp1::SP1_BASE_HOST_FILE), 154 | home_dir.join(sp1::SP1_HOST_MAIN), 155 | )?; 156 | return Ok(()); 157 | } else { 158 | error!("zkRust directory structure invalid please consult the README",); 159 | return Ok(()); 160 | } 161 | } 162 | 163 | Commands::ProveRisc0(args) => { 164 | info!("Proving with Risc0, program in: {}", args.guest_path); 165 | 166 | // Perform sanitation checks on directory 167 | if utils::validate_directory_structure(&args.guest_path) { 168 | let proof_data_dir = PathBuf::from(&args.proof_data_directory_path); 169 | if !proof_data_dir.exists() { 170 | std::fs::create_dir_all(proof_data_dir).unwrap_or(info!( 171 | "Saving generated proofs to: {:?}", 172 | &args.proof_data_directory_path 173 | )); 174 | } 175 | let Some(home_dir) = dirs::home_dir() else { 176 | error!("Failed to locate home directory"); 177 | return Ok(()); 178 | }; 179 | let Ok(current_dir) = std::env::current_dir() else { 180 | error!("Failed to locate current directory"); 181 | return Ok(()); 182 | }; 183 | let home_dir = home_dir.join(".zkRust"); 184 | utils::prepare_workspace( 185 | &PathBuf::from(&args.guest_path), 186 | &home_dir.join(risc0::RISC0_SRC_DIR), 187 | &home_dir.join(risc0::RISC0_GUEST_CARGO_TOML), 188 | &home_dir.join("workspaces/risc0/host"), 189 | &home_dir.join("workspaces/risc0/host/Cargo.toml"), 190 | &home_dir.join(risc0::RISC0_BASE_HOST_CARGO_TOML), 191 | &home_dir.join(risc0::RISC0_BASE_GUEST_CARGO_TOML), 192 | )?; 193 | 194 | let Ok(imports) = utils::get_imports(&home_dir.join(risc0::RISC0_GUEST_MAIN)) 195 | else { 196 | error!("Failed to extract imports"); 197 | return Ok(()); 198 | }; 199 | let main_path = home_dir.join(risc0::RISC0_GUEST_MAIN); 200 | let Ok(function_bodies) = utils::extract_function_bodies( 201 | &main_path, 202 | vec![ 203 | "fn main()".to_string(), 204 | "fn input()".to_string(), 205 | "fn output()".to_string(), 206 | ], 207 | ) else { 208 | error!("Failed to extract function bodies"); 209 | return Ok(()); 210 | }; 211 | 212 | /* 213 | Adds header to the guest & replace I/O imports 214 | risc0: 215 | 216 | #![no_main] 217 | risc0_zkvm::guest::entry!(main); 218 | */ 219 | utils::prepare_guest( 220 | &imports, 221 | &function_bodies[0], 222 | risc0::RISC0_GUEST_PROGRAM_HEADER, 223 | risc0::RISC0_IO_READ, 224 | risc0::RISC0_IO_COMMIT, 225 | &home_dir.join(risc0::RISC0_GUEST_MAIN), 226 | )?; 227 | risc0::prepare_host( 228 | &function_bodies[1], 229 | &function_bodies[2], 230 | &imports, 231 | &home_dir.join(risc0::RISC0_BASE_HOST), 232 | &home_dir.join(risc0::RISC0_HOST_MAIN), 233 | )?; 234 | 235 | if args.precompiles { 236 | let mut toml_file = OpenOptions::new() 237 | .append(true) 238 | .open(home_dir.join(risc0::RISC0_GUEST_CARGO_TOML))?; 239 | 240 | writeln!(toml_file, "{}", risc0::RISC0_ACCELERATION_IMPORT)?; 241 | } 242 | 243 | let workspace_dir = home_dir.join(risc0::RISC0_WORKSPACE_DIR); 244 | if risc0::generate_risc0_proof(&workspace_dir, ¤t_dir)?.success() { 245 | info!("Risc0 proof and Image ID generated"); 246 | 247 | utils::replace( 248 | &home_dir.join(risc0::RISC0_GUEST_CARGO_TOML), 249 | risc0::RISC0_ACCELERATION_IMPORT, 250 | "", 251 | )?; 252 | 253 | // Submit to aligned 254 | if args.submit_to_aligned { 255 | submit_proof_to_aligned( 256 | risc0::PROOF_FILE_PATH, 257 | risc0::IMAGE_ID_FILE_PATH, 258 | Some(risc0::PUBLIC_INPUT_FILE_PATH), 259 | args, 260 | ProvingSystemId::Risc0, 261 | ) 262 | .await 263 | .map_err(|e| { 264 | error!("Error submitting proofs to Aligned: {:?}", e); 265 | io::Error::other(e.to_string()) 266 | })?; 267 | 268 | info!("Risc0 proof submitted and verified on Aligned"); 269 | } 270 | 271 | // Clear Host file 272 | std::fs::copy( 273 | home_dir.join(risc0::RISC0_BASE_HOST_FILE), 274 | home_dir.join(risc0::RISC0_HOST_MAIN), 275 | ) 276 | .map_err(|e| { 277 | error!("Failed to clear Risc0 host file"); 278 | e 279 | })?; 280 | return Ok(()); 281 | } 282 | info!("Risc0 proof generation failed"); 283 | 284 | // Clear Host file 285 | std::fs::copy( 286 | home_dir.join(risc0::RISC0_BASE_HOST_FILE), 287 | home_dir.join(risc0::RISC0_HOST_MAIN), 288 | )?; 289 | return Ok(()); 290 | } else { 291 | error!("zkRust directory structure incorrect please consult the README",); 292 | return Ok(()); 293 | } 294 | } 295 | } 296 | } 297 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | use log::error; 2 | use regex::Regex; 3 | use std::{ 4 | fs::{self, File, OpenOptions}, 5 | io::{self, BufRead, BufReader, ErrorKind, Read, Seek, Write}, 6 | path::{Path, PathBuf}, 7 | }; 8 | 9 | // Host 10 | pub const IO_WRITE: &str = "zk_rust_io::write"; 11 | pub const IO_OUT: &str = "zk_rust_io::out();"; 12 | pub const HOST_INPUT: &str = "// INPUT //"; 13 | pub const HOST_OUTPUT: &str = "// OUTPUT //"; 14 | 15 | // I/O Markers 16 | pub const IO_READ: &str = "zk_rust_io::read();"; 17 | pub const IO_COMMIT: &str = "zk_rust_io::commit"; 18 | 19 | pub const OUTPUT_FUNC: &str = r"pub fn output() {"; 20 | pub const INPUT_FUNC: &str = r"pub fn input() {"; 21 | 22 | pub fn prepend(file_path: &str, text_to_prepend: &str) -> io::Result<()> { 23 | // Open the file in read mode to read its existing content 24 | let mut file = OpenOptions::new().read(true).write(true).open(file_path)?; 25 | 26 | // Read the existing content of the file 27 | let mut content = String::new(); 28 | file.read_to_string(&mut content)?; 29 | 30 | // Move the file cursor to the beginning of the file 31 | file.seek(io::SeekFrom::Start(0))?; 32 | 33 | // Write the text to prepend followed by the existing content back to the file 34 | file.write_all(text_to_prepend.as_bytes())?; 35 | file.write_all(content.as_bytes())?; 36 | file.flush()?; 37 | 38 | Ok(()) 39 | } 40 | 41 | pub fn replace(file_path: &PathBuf, search_string: &str, replace_string: &str) -> io::Result<()> { 42 | // Read the contents of the file 43 | let mut contents = String::new(); 44 | fs::File::open(file_path)?.read_to_string(&mut contents)?; 45 | 46 | // Replace all occurrences of the search string with the replace string 47 | let new_contents = contents.replace(search_string, replace_string); 48 | 49 | // Write the new contents back to the file 50 | let mut file = fs::File::create(file_path)?; 51 | file.write_all(new_contents.as_bytes())?; 52 | 53 | Ok(()) 54 | } 55 | 56 | fn copy_dir_all(src: &impl AsRef, dst: impl AsRef) -> io::Result<()> { 57 | fs::create_dir_all(&dst)?; 58 | for entry in fs::read_dir(src)? { 59 | let entry = entry?; 60 | let ty = entry.file_type()?; 61 | if ty.is_dir() { 62 | copy_dir_all(&entry.path(), dst.as_ref().join(entry.file_name()))?; 63 | } else { 64 | fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?; 65 | } 66 | } 67 | Ok(()) 68 | } 69 | 70 | pub fn insert(target_file: &str, text: &str, search_string: &str) -> io::Result<()> { 71 | // Read the contents of the target file 72 | let mut target_contents = String::new(); 73 | fs::File::open(target_file)?.read_to_string(&mut target_contents)?; 74 | 75 | // Find the position of the search string in the target file 76 | if let Some(pos) = target_contents.find(search_string) { 77 | // Split the target contents into two parts 78 | let (before, after) = target_contents.split_at(pos + search_string.len()); 79 | 80 | // Combine the parts with the insert contents 81 | let new_contents = format!("{}\n{}\n{}", before, text, after); 82 | 83 | // Write the new contents back to the target file 84 | let mut file = fs::File::create(target_file)?; 85 | file.write_all(new_contents.as_bytes())?; 86 | } else { 87 | println!("Search string not found in target file."); 88 | } 89 | 90 | Ok(()) 91 | } 92 | 93 | //Note: Works with a one off '{' not with '}' 94 | pub fn extract_function_bodies( 95 | file_path: &PathBuf, 96 | functions: Vec, 97 | ) -> io::Result> { 98 | // Read the contents of the target file 99 | let mut code = String::new(); 100 | fs::File::open(file_path)?.read_to_string(&mut code)?; 101 | 102 | let mut start_indices = vec![]; 103 | let mut index = 0; 104 | 105 | // Find all start indices of the function signature 106 | for keyword in functions { 107 | if let Some(start_index) = code[index..].find(&keyword) { 108 | let absolute_index = index + start_index; 109 | start_indices.push(absolute_index); 110 | index = absolute_index + keyword.len(); 111 | } 112 | } 113 | 114 | // Extract the code for each function 115 | let mut extracted_codes = vec![]; 116 | for &start_index in &start_indices { 117 | if let Some(start_brace_index) = code[start_index..].find('{') { 118 | let start_brace_index = start_index + start_brace_index; 119 | let mut stack = vec!["{"]; 120 | let mut end_index = start_brace_index; 121 | 122 | for (i, ch) in code[start_brace_index + 1..].chars().enumerate() { 123 | if handle_stack(ch, &mut stack) { 124 | end_index = start_brace_index + 1 + i; 125 | break; 126 | } 127 | } 128 | 129 | let extracted_code = &code[start_brace_index + 1..end_index].trim(); 130 | extracted_codes.push(extracted_code.to_string()); 131 | } 132 | } 133 | 134 | Ok(extracted_codes) 135 | } 136 | 137 | // Function that handles the stack and status when parsing the file to extract_function_bodies 138 | fn handle_stack(ch: char, stack: &mut Vec<&str>) -> bool { 139 | match stack.last() { 140 | Some(&"{") => return handle_char(ch, stack), 141 | Some(&"/") => match ch { 142 | '/' => { 143 | stack.pop(); 144 | stack.push("//comment"); 145 | } 146 | '*' => { 147 | stack.pop(); 148 | stack.push("/*comment*\\"); 149 | } 150 | _ => { 151 | stack.pop(); 152 | handle_char(ch, stack); 153 | } 154 | }, 155 | Some(&"//comment") => match ch { 156 | '\n' => { 157 | stack.pop(); 158 | } 159 | _ => {} 160 | }, 161 | Some(&"/*comment*\\") => match ch { 162 | '*' => { 163 | stack.push("*"); 164 | } 165 | _ => {} 166 | }, 167 | Some(&"*") => { 168 | match ch { 169 | '/' => { 170 | stack.pop(); //pop("*") 171 | stack.pop(); //pop("/*comment*\\") 172 | } 173 | _ => { 174 | stack.pop(); //pop("*"), back to "/*comment*\\" 175 | } 176 | } 177 | } 178 | Some(&"\"string\"") => match ch { 179 | '\"' => { 180 | stack.pop(); 181 | } 182 | _ => {} 183 | }, 184 | Some(&"\'c\'") => match ch { 185 | '\'' => { 186 | stack.pop(); 187 | } 188 | _ => {} 189 | }, 190 | _ => {} 191 | } 192 | false 193 | } 194 | // Function to handle characters when in normal status of the stack 195 | fn handle_char(ch: char, stack: &mut Vec<&str>) -> bool { 196 | match ch { 197 | '/' => { 198 | stack.push("/"); 199 | } 200 | '{' => stack.push("{"), 201 | '}' => { 202 | stack.pop(); 203 | if stack.is_empty() { 204 | return true; 205 | } 206 | } 207 | '\"' => { 208 | stack.push("\"string\""); 209 | } 210 | '\'' => { 211 | stack.push("\'c\'"); 212 | } 213 | _ => {} 214 | } 215 | false 216 | } 217 | 218 | fn copy_dependencies(toml_path: &Path, guest_toml_path: &Path) -> io::Result<()> { 219 | let mut toml = std::fs::File::open(toml_path)?; 220 | let mut content = String::new(); 221 | toml.read_to_string(&mut content)?; 222 | 223 | match content.find("[dependencies]") { 224 | Some(start_index) => { 225 | // Get all text after the search string 226 | let dependencies = &content[start_index + "[dependencies]".len()..]; 227 | // Open the output file in append mode 228 | let mut guest_toml = OpenOptions::new() 229 | .create(true) 230 | .append(true) 231 | .open(guest_toml_path)?; 232 | 233 | // Write the text after the search string to the output file 234 | guest_toml.write_all(dependencies.as_bytes()) 235 | } 236 | None => Err(io::Error::other( 237 | "Failed to find `[dependencies]` in project Cargo.toml", 238 | )), 239 | } 240 | } 241 | 242 | pub fn prepare_workspace( 243 | guest_path: &Path, 244 | workspace_guest_dir: &Path, 245 | program_toml_dir: &Path, 246 | workspace_host_dir: &Path, 247 | host_toml_dir: &Path, 248 | base_host_toml_dir: &Path, 249 | base_guest_toml_dir: &Path, 250 | ) -> io::Result<()> { 251 | let workspace_guest_src_dir = workspace_guest_dir.join("src"); 252 | let workspace_host_src_dir = workspace_host_dir.join("src"); 253 | if let Err(e) = fs::remove_dir_all(&workspace_guest_src_dir) { 254 | if e.kind() != ErrorKind::NotFound { 255 | return Err(e); 256 | } 257 | } 258 | if let Err(e) = fs::remove_dir_all(&workspace_host_src_dir) { 259 | if e.kind() != ErrorKind::NotFound { 260 | return Err(e); 261 | } 262 | } 263 | // Copy src/ directory 264 | let src_dir_path = guest_path.join("src"); 265 | copy_dir_all(&src_dir_path, workspace_guest_src_dir)?; 266 | copy_dir_all(&src_dir_path, workspace_host_src_dir)?; 267 | 268 | // Copy lib/ if present 269 | let lib_dir_path = guest_path.join("lib"); 270 | if Path::new(&lib_dir_path).exists() { 271 | let workspace_guest_lib_dir = workspace_guest_dir.join("lib"); 272 | let workspace_host_lib_dir = workspace_host_dir.join("lib"); 273 | copy_dir_all(&lib_dir_path, workspace_guest_lib_dir)?; 274 | copy_dir_all(&lib_dir_path, workspace_host_lib_dir)?; 275 | } 276 | 277 | // Copy Cargo.toml for zkVM 278 | fs::copy(base_guest_toml_dir, program_toml_dir)?; 279 | println!("{:?} {:?}", base_guest_toml_dir, program_toml_dir); 280 | fs::copy(base_host_toml_dir, host_toml_dir)?; 281 | 282 | // Select dependencies from the 283 | let toml_path = guest_path.join("Cargo.toml"); 284 | copy_dependencies(&toml_path, program_toml_dir)?; 285 | copy_dependencies(&toml_path, host_toml_dir)?; 286 | 287 | Ok(()) 288 | } 289 | 290 | //TODO: refactor this to eliminate the clone at each step. 291 | pub fn get_imports(filename: &PathBuf) -> io::Result { 292 | // Open the file 293 | let file = File::open(filename)?; 294 | let mut lines = BufReader::new(file).lines(); 295 | 296 | let mut imports = String::new(); 297 | 298 | // Read the file line by line 299 | while let Some(line) = lines.next() { 300 | let mut line = line?; 301 | // Check if the line starts with "use " 302 | if line.trim_start().starts_with("use ") 303 | || line.trim_start().starts_with("pub mod ") 304 | || line.trim_start().starts_with("mod ") 305 | { 306 | line.push('\n'); 307 | imports.push_str(&line.clone()); 308 | // check if line does not contains a use declarator and a ';' 309 | // if not continue reading till one is found this covers the case where import statements cover multiple lines 310 | if !line.contains(';') { 311 | // Iterate and continue adding lines to the import while line does not contain a ';' break if it does 312 | for line in lines.by_ref() { 313 | let mut line = line?; 314 | line.push('\n'); 315 | imports.push_str(&line.clone()); 316 | if line.contains(';') { 317 | break; 318 | } 319 | } 320 | } 321 | } 322 | } 323 | 324 | Ok(imports) 325 | } 326 | 327 | pub fn extract_regex(file_path: &PathBuf, regex: &str) -> io::Result> { 328 | let file = fs::File::open(file_path)?; 329 | let reader = io::BufReader::new(file); 330 | 331 | let mut values = Vec::new(); 332 | let regex = Regex::new(regex).map_err(io::Error::other)?; 333 | 334 | for line in reader.lines() { 335 | let line = line?; 336 | for cap in regex.captures_iter(&line) { 337 | if let Some(matched) = cap.get(1) { 338 | values.push(matched.as_str().to_string()); 339 | } 340 | } 341 | } 342 | 343 | Ok(values) 344 | } 345 | 346 | //Change to remove regex and remove the marker 347 | pub fn remove_lines(file_path: &PathBuf, target: &str) -> io::Result<()> { 348 | // Read the file line by line 349 | let file = fs::File::open(file_path)?; 350 | let reader = io::BufReader::new(file); 351 | 352 | // Collect lines that do not contain the target string 353 | let lines: Vec = reader 354 | .lines() 355 | .map_while(Result::ok) 356 | .filter(|line| !line.contains(target)) 357 | .collect(); 358 | 359 | // Write the filtered lines back to the file 360 | let mut file = fs::File::create(file_path)?; 361 | for line in lines { 362 | writeln!(file, "{}", line)?; 363 | } 364 | 365 | Ok(()) 366 | } 367 | 368 | pub fn validate_directory_structure(root: &str) -> bool { 369 | let root = Path::new(root); 370 | // Check if Cargo.toml exists in the root directory 371 | let cargo_toml = root.join("Cargo.toml"); 372 | if !cargo_toml.exists() { 373 | error!("Cargo.toml not found."); 374 | return false; 375 | } 376 | 377 | // Check if src/ and lib/ directories exist 378 | let src_dir = root.join("src"); 379 | 380 | if !src_dir.exists() { 381 | error!("src/ directory not found in root"); 382 | return false; 383 | } 384 | 385 | // Check if src/ contains main.rs file 386 | let main_rs = src_dir.join("main.rs"); 387 | if !main_rs.exists() { 388 | error!("main.rs not found in src/ directory in root"); 389 | return false; 390 | } 391 | 392 | true 393 | } 394 | 395 | pub fn prepare_guest( 396 | imports: &str, 397 | main_func_code: &str, 398 | program_header: &str, 399 | io_read_header: &str, 400 | io_commit_header: &str, 401 | guest_main_file_path: &PathBuf, 402 | ) -> io::Result<()> { 403 | let mut guest_program = program_header.to_string(); 404 | guest_program.push_str(imports); 405 | guest_program.push_str("pub fn main() {\n"); 406 | guest_program.push_str(main_func_code); 407 | guest_program.push_str("\n}"); 408 | 409 | // Replace zkRust::read() 410 | let guest_program = guest_program.replace(IO_READ, io_read_header); 411 | 412 | // Replace zkRust::commit() 413 | let guest_program = guest_program.replace(IO_COMMIT, io_commit_header); 414 | 415 | // Write to guest 416 | let mut file = fs::File::create(guest_main_file_path)?; 417 | file.write_all(guest_program.as_bytes())?; 418 | Ok(()) 419 | } 420 | -------------------------------------------------------------------------------- /examples/tendermint/src/files/block_2279100.json: -------------------------------------------------------------------------------- 1 | {"signed_header":{"header":{"version":{"block":"11","app":"1"},"chain_id":"mocha-4","height":"2279100","time":"2024-07-16T21:21:11.200637657Z","last_block_id":{"hash":"FBD753D2965760B76EB93BD4D2DBE2C40AFCEF5EDDA3A30D1CB3F19E635C055A","parts":{"total":11,"hash":"F842D166297F1D45302286EEC86CE778939672E72B3430F5631CB9232FC04890"}},"last_commit_hash":"9C9B62C4AB6D3DE0F2E490D24DF01DB2757E310F2E255F0995B3D9050FCCD7AC","data_hash":"F52F291DCC807A1F67CE134BF750DE2627A404D517BF39B144A162090D7EF874","validators_hash":"761B52540AA384D2B2CEB9D31F1619DB75498E9EE162949E30EFE10D14BC405A","next_validators_hash":"761B52540AA384D2B2CEB9D31F1619DB75498E9EE162949E30EFE10D14BC405A","consensus_hash":"C0B6A634B72AE9687EA53B6D277A73ABA1386BA3CFC6D0F26963602F7F6FFCD6","app_hash":"A66EABEC8662632A5120D8416A44C17630C791F7CE30C5103A57B088275A2DC9","last_results_hash":"D5353DA58080C25EB981F6702C3F528C7DA60C94DADC244EF8BDF91B09DAB08B","evidence_hash":"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855","proposer_address":"8FBEF0DBAAE51D918F9ABFD96653F4932171870E"},"commit":{"height":"2279100","round":0,"block_id":{"hash":"EF3FA80FE032E291DC94CF6F9912071A319E5042F078BE98184E3C3AC9FF97E7","parts":{"total":11,"hash":"354346DE3D8F76CAFD9EFD545AB336B57A8AE6D11E59EC9334B8DFD3CCA061FF"}},"signatures":[{"block_id_flag":2,"validator_address":"7619BFC85B72E319BF414A784D4DE40EE9B92C16","timestamp":"2024-07-16T21:21:23.579267519Z","signature":"QuNKNEqfip6ErAtO5NKkr3qowViFIVx7Hx9NQC0O2bT5aFWNXwa2u83rgL2dLtkDCCPe9/Y8QLBCrEzDZfRhBg=="},{"block_id_flag":2,"validator_address":"762CBA617226A799D898F134DD12661C7F1129EB","timestamp":"2024-07-16T21:21:23.455016236Z","signature":"zAZjNGb4aB42iRZpo4qGin/SHpo/rkj+evu6cT1Qr9phlE/cWpGxbVLdaiA4egpIJCylErEA2OAYNlb7htJhDQ=="},{"block_id_flag":2,"validator_address":"597944BC0AEDFA1D9DA7C2098FB05D7B6A2D4946","timestamp":"2024-07-16T21:21:23.471749864Z","signature":"j2Tq3SvwR+h9F/5q02u7Xutw2VXz/jUasDAiMeybdO3bOmI+PEl0Xthc07UzQ4CYyk7Okv4cNRwkqUdc+iVQCQ=="},{"block_id_flag":2,"validator_address":"7744C8CE6E06E67AB9721696AA752B951C93E9E0","timestamp":"2024-07-16T21:21:23.46842993Z","signature":"8fUxhlFNlwLxpMIDVmTgkBDbfhZa95hEJxccffMo5oWF/NGYnXIBocW8rRs0MtCC2Aa6yYY4Y6rggUhT7WvuDQ=="},{"block_id_flag":2,"validator_address":"8FBEF0DBAAE51D918F9ABFD96653F4932171870E","timestamp":"2024-07-16T21:21:23.16428668Z","signature":"Ro709XYYsikmZ9V8XkXmoMbcrbsqajxuFWzpd+jdHqCCCTEGBlHOtMjIi4J7h1qJP58GMOLsfyB5wmizKbuKBQ=="},{"block_id_flag":2,"validator_address":"0B76107110A486E8767FA1997EA0C4B40B7851AF","timestamp":"2024-07-16T21:21:23.537756988Z","signature":"qFP6owZcxA0b1wq1WbaeTtRgXzbjQn9ugiAcpAT6gaaoageXAqN2NUfxXmE0hbo4OIURj2HQZdjO0mg35CQOCw=="},{"block_id_flag":2,"validator_address":"D6E25B7E6E6C96D1B7135CF41FF03DF84DE2BA2C","timestamp":"2024-07-16T21:21:23.464472161Z","signature":"L8VjUL/6+rZtS76oz7+Lddi3DaOlUJVnYrIffYcrRf4RPmz7AN0w3wPHk6YEovn+zFm1AVNM5fJX2NoVHS3eCw=="},{"block_id_flag":2,"validator_address":"59158C19ED4DF57D59B54F80B07C0AFB37DAFF0D","timestamp":"2024-07-16T21:21:23.476167081Z","signature":"2UutyARhwy2LqSUooiI/e2ZQxsmMGSm8+CvzaVFt7rbfyVlGfsF2b+mgD7TqXKSDOn4FFXtlSGOn/OxWglI4AQ=="},{"block_id_flag":2,"validator_address":"91AB27CC321622AC4DC778D2F1FE367CFADAC665","timestamp":"2024-07-16T21:21:23.561794959Z","signature":"4sWtWQH3d/IAExjkHMauqfLafsd2J7IusxQk2dVq/hstJNtidwIAx6nYOpBAYCTPDl0SVicYGclUbgJxcsWrDg=="},{"block_id_flag":2,"validator_address":"C822706DA92B375B6793FEC5FCAD04BB5AFE142A","timestamp":"2024-07-16T21:21:23.528527525Z","signature":"sK7AHBVJdoyUhhh0oKTtCg9RTDoOhLB4cQpUoT+0wHqP2gUL8bwEmN5cxGQda0Vf1T2kOQBFmrHZEzVRxLS0BQ=="},{"block_id_flag":2,"validator_address":"FF73CE6FE36E313684457C855D7D25198B87C8A6","timestamp":"2024-07-16T21:21:23.530668252Z","signature":"2cePxvPUU30Tkz46CkExrGklJFyHHf1ImxfnvFC9KI4qey9eIOqkkTi1wfesZ5uPpU/EUatdJnIYqsomqrnECw=="},{"block_id_flag":2,"validator_address":"E1F1D0F31F8DB86B829C8502AD1F6F1576C08A6D","timestamp":"2024-07-16T21:21:23.516304185Z","signature":"NcpoI9JqnXyOUFaK6C0k5Ycvd7NhX1QRyJSUroJKCHUa2olCBOF9oAUazSnbQwS7276QfRP7P8qCnsq79P2iDg=="},{"block_id_flag":2,"validator_address":"13E610C20C1C6623A3C32AC058E9F8E76BBEEC16","timestamp":"2024-07-16T21:21:23.823864119Z","signature":"4+dFRDOMyHAtNjH1d8aNbzFOwjWi5gxinKR1ST+Wt1ztfVCORVpijNj8NAJ7UrLJDqfCzfP708H+uJ2vQEORAQ=="},{"block_id_flag":2,"validator_address":"EE927F115AD4FD4BC131CA311D332ADDAC62CCAC","timestamp":"2024-07-16T21:21:23.634950974Z","signature":"/iTorIxinKMccWIWt8uNtrMJV24zZlb+nvJIfBrxG5l4SEfnM0LchpK8SycRMd5yvh/uhTUJ8sZ09VTgyzV8Cw=="},{"block_id_flag":2,"validator_address":"97C24BFDC996F0BF40FDDA96CC22D417D0B8D0BA","timestamp":"2024-07-16T21:21:23.474688335Z","signature":"G32ovKXT2sPw0WvhYvXqlI1G3GHE1kY3dphK48olnnAfR2Dtp25sFQTyCLh2E5+yxFl5Pxvjx8dWs+ZkFZuHDA=="},{"block_id_flag":2,"validator_address":"9079C978817165244C051EFCE5AD163AAA905C6F","timestamp":"2024-07-16T21:21:23.47184029Z","signature":"Q/IXyPZZSdTo/gqnIkNfwNs8PPhujaeXpJKf00ep5ohKGcHmAH4hS0C25NIn6wFlXo0wWNW/9DxCivBBgFY1CQ=="},{"block_id_flag":2,"validator_address":"7EC8ADD79B454AC37625077453DF49FAC1BFD7E1","timestamp":"2024-07-16T21:21:23.92793085Z","signature":"RzthPealyMuYfnjc+ygyg1x6YOYrOVQlKvB6ucPLnsPK24P6km8dpoj5tds6DGTeJ9q3fwpHeLX7fOQ46cW2AA=="},{"block_id_flag":2,"validator_address":"11637B088406D4F3EFF52F2230C8068D230C7611","timestamp":"2024-07-16T21:21:23.540841956Z","signature":"5uSWAY4fbey9Nc8al6Y03e/oSpQ0U8e919Ws7QkmWJxARFVZpoMtV2fn3LaO6Aj4+WjCJk63VrsQYX0dJhy1CA=="},{"block_id_flag":2,"validator_address":"52E55D04CCD1C78D4FC520FE17AE4584FA2053A8","timestamp":"2024-07-16T21:21:23.5279986Z","signature":"v1P9WNSLXw4qu3U7r7fmaCYVV3MGRqGcSlPcPEbc0OI6w5SZ+aJkop4JleLwnB85nw23imhYYZr5mA5q6kDaDg=="},{"block_id_flag":2,"validator_address":"BB408FA902A7B6A938C788957B2A874153261EC5","timestamp":"2024-07-16T21:21:23.50745286Z","signature":"R9YS+NuQo9xwPGzZi08VvWK/+Sc0klAwFQ5NoZlLsoaKaH/DN5dYtewyns2Ntckj6+4XdmTZkhRbBPz7++HGDA=="},{"block_id_flag":2,"validator_address":"8C55B13AEE44C518E363DD328E2AB451D6569EAC","timestamp":"2024-07-16T21:21:24.34806458Z","signature":"G8M/13/DGebx2ysxm1M1r5yL06VaLJwuBeyv98RXicmkna946fMl5X0Vhg5L2QW2AWU7OqzzOu3HXOfcZuNdBA=="},{"block_id_flag":2,"validator_address":"F005689992F73B55B537461AC0AE0DF9694B36CF","timestamp":"2024-07-16T21:21:23.680163408Z","signature":"qvppGRrkSGOSpyAdqcLCCg7HuBuWsqqDurPEfdjG9Mtk/4gn5BO5tucJJR2sZccCXq2MgY5dJe2v/F9f3xsJBA=="},{"block_id_flag":2,"validator_address":"01458B61F0D7DE6E90798FE8C370413D718EB34C","timestamp":"2024-07-16T21:21:23.846054841Z","signature":"FTKKm2xLIxnJduGME1mA4pEZPQOnrKKQeVgsZ7f3RC93wUN6u3pUESRbPBowMysRdLKM0bh8qsdBwt0EkAMiAw=="},{"block_id_flag":2,"validator_address":"5AF159B8269B974F9274DAEA0F778ADD3B12707D","timestamp":"2024-07-16T21:21:23.718839237Z","signature":"zVbTVeE6u+G1CGGjQyisdIikqu1DW37ffSxN4dd3Ph2SPXXASNRNsSYpTVNAKfthymNOytokwAV2uFLH4SPtDg=="},{"block_id_flag":2,"validator_address":"98271A1B3690F4EC867C760DBCA3754684F485AC","timestamp":"2024-07-16T21:21:23.513090303Z","signature":"2dS+WiOIfsaZAdoJcgz7n77y2V9GmuyjJV1pUqzWRdwu5WVKCxKWpAK4toP3Z2D3pyAJ40inwf0IljC2nlfgAQ=="},{"block_id_flag":2,"validator_address":"969B1B7DCAFA313131620AC163E3A09A03B49BE6","timestamp":"2024-07-16T21:21:23.503530235Z","signature":"LJJAKRUO1Hex7aELqyjmCPWoRLN0H3zk1FGH6Y2xk4yscqGXInAX3FxKflRXTZ0p0ax+WWZmnvlU3ZaipSMvCw=="},{"block_id_flag":2,"validator_address":"4D5B4C1A687B13AAD96F9CED90F006DFF03CEC45","timestamp":"2024-07-16T21:21:23.851965372Z","signature":"nEz+oKZ/CXBCcizFuUEnu83zrkd/vUax8gVKDtDS0mHeAFUjXR/psu5ltk671c71I80W4W41wvfcNiVemp3KBA=="},{"block_id_flag":2,"validator_address":"3BFE2EF588102F19F40952DDDD3A89BA90D7351F","timestamp":"2024-07-16T21:21:23.505513775Z","signature":"1QhJoqmtDT6X/qpHWuU/qHwBc9mxu/AZrZRZHWYPo6R5MeWsToVCt7L2+ZopT8rpPhjAq0YlYwjQZ6EKTjLeBQ=="},{"block_id_flag":2,"validator_address":"28B6061D5E269B3585F019E1748E32CA9F34E739","timestamp":"2024-07-16T21:21:23.838542171Z","signature":"eFLe7+x+4MsosddknriNdGRY+JGfZP3HMZVOfIQ3qZHSPovt5+dBAyZcUH6b1fvuS8lOSqqAOESXHEO5gzLyBg=="},{"block_id_flag":2,"validator_address":"C8C62F1CF89BF5E852E252ED38CBA4A64787CF1B","timestamp":"2024-07-16T21:21:23.426821803Z","signature":"rR/Uwy1HzdhVE9KqTj5TlK1zFOho+zmUAWjS6IPlGyK/gvQjZU3svGAcriCvUm5cYDGs4GGEJoA7rEgytYlqBA=="},{"block_id_flag":2,"validator_address":"70A191EF78A0C8B9B69E005A685B064C254B1F33","timestamp":"2024-07-16T21:21:23.852693409Z","signature":"0jgYzIyUMZDc25zeQ8nDhCcJtN2OQCjCCO/MFiPBRo6cNHn5mbXJPdWKn6c1fz1lZR1AAMSIyfvQCf7gw68cBg=="},{"block_id_flag":2,"validator_address":"38CECDD91DAE3D8F536C080742A69FEBB6EFDBFF","timestamp":"2024-07-16T21:21:23.658016044Z","signature":"spDtXNYJdR1862NKeCtWqAugxfvJ7+KZCQMt82Z8wPGF+xBKEULm6s1OorNLzz5f4qzzN/QQOY4y7wGPiVi6Ag=="},{"block_id_flag":2,"validator_address":"0DC59C626E4753D889DE2D3262A9A613E754668A","timestamp":"2024-07-16T21:21:23.540652438Z","signature":"hAe29yKwWXTPAVguWsoRgCZ3jLJLa5YqwaxqOp6N3b9xEmFUDR02YL5ACeoIC5ZmGfa19B1XOgXgluw1wp3qAQ=="},{"block_id_flag":2,"validator_address":"1E7BA20AACF7EF2CDEA41CDFF8DCEDFBCF12F363","timestamp":"2024-07-16T21:21:23.576459403Z","signature":"XZMiVqN8N5B8sqI6IYmWHc8rHfzZA7axW/Lxuu1kysyIi17PO+NTATRs/aUDq8m4vqgXJrZJ2X4/Opo+sukEDg=="},{"block_id_flag":2,"validator_address":"346001263089D83465A72C6DB5EFBC32359111A3","timestamp":"2024-07-16T21:21:23.461801905Z","signature":"BM4E1zFKZC260NZqEDSgAXu6qvbdVKbk/0XME+GMaKZFCcj5yfbp8lGQoqZD8m905eYtlVlFWTEVpw/KYHzGAw=="},{"block_id_flag":2,"validator_address":"2F334E80D3EA0AE019D6498D8DD7E0EC472E5424","timestamp":"2024-07-16T21:21:23.51943268Z","signature":"y74YdG/Co/xDxyGhVG7BM+nwS5f09jOOes/q4zhCPx8lnhplR/2C5UMWTAjmUpLbfXCHYMhlbhJF+7uoqaCfDg=="},{"block_id_flag":2,"validator_address":"80726DCD4E975716843F213C7E5A36400ABCFDFE","timestamp":"2024-07-16T21:21:23.537635719Z","signature":"KKDf5Zr64bOUrFWHxJicD4tYrMtDvoqGRcghWLZtn8cKrjjoH5qnLw+l3Lrk+Ek3Wd7QW9ikmVe/1wyKwaKBAA=="},{"block_id_flag":2,"validator_address":"4520D7FA09B49EA0C0F39E6788E6EB3FD8065690","timestamp":"2024-07-16T21:21:23.767483941Z","signature":"pgtqx3hN4KUR//JRC5iRyEKZaA6IOVbSgypodSify9oPR4Zi+RVEj1JGRg8om+1ri6sf007dbn8iZ/ynYcoyBA=="},{"block_id_flag":2,"validator_address":"93CCD84A7302F5676465A1239C2544AD3140D7CB","timestamp":"2024-07-16T21:21:23.474144535Z","signature":"OHAFO/d2Di65F40/Pqecux3Z14VfsuKTdeTI3MDJSNFz0rVHZDaxHnP5xXI8TtZVhKgwGd2twqyRa+6Y1OLwBg=="},{"block_id_flag":2,"validator_address":"3824438082C68B36ED8F5199155CD78ABBBDA30C","timestamp":"2024-07-16T21:21:23.563890574Z","signature":"AGLrJ9QCDT0lxwgpEAwvBdjZxX5spPSKCTglgMXtWyjhbQ7ZeTZHhb4qo+bh4m+m2wIHxWrgQRu1wpRaawvoCQ=="},{"block_id_flag":2,"validator_address":"9B2FB5ABCB3B0289D03AF5A8577C76D9A37A32D3","timestamp":"2024-07-16T21:21:23.546958701Z","signature":"TUQF7E4iLXQOJn0neHL1btJ24TzX0fIJOj558+THXwVO6a2RwbAHTxrV/U8OSe8wXODyBDDRIjO32uITmUC2Ag=="},{"block_id_flag":2,"validator_address":"87D1611F9BA8ABF12C13B32F90469977B4C94F9A","timestamp":"2024-07-16T21:21:23.614438913Z","signature":"ayKmKh+/QKdQZRyGFkbLXX2tp2W5LqsvPNC4mWp16GbMVBp4Fs7fGpFN3WfLvPwxllw3PhoWSD5TkxT/kW6nDA=="},{"block_id_flag":2,"validator_address":"5E9EE98A3CBD523D0D3C3518048DF8C322BB67D5","timestamp":"2024-07-16T21:21:23.474611393Z","signature":"nB8VYOQNSxP61vmYkPDzENV0WybBUbYnj3g/HjXO5wLBybqkRtQiNMYnBy8Cizay8ZlG4qBUJ0bVrd8i6eQ4Ag=="},{"block_id_flag":2,"validator_address":"E309A8AFFF70D04126D04BB53071B6020580D104","timestamp":"2024-07-16T21:21:23.765986078Z","signature":"uLPBDKncUkTWK1WJ4PBio7nXoqB70v4rWOOozGZG/WdyHXRHSfTpPkmiJb6CEtfQuFB4UMdbI96CpbUNWJbkAg=="},{"block_id_flag":2,"validator_address":"3B0F1CAEEB84A5AF239580FB26D6199CB17CEB3A","timestamp":"2024-07-16T21:21:24.003360149Z","signature":"LBRwtTw9Wh5sWRvDSnORt3xGlTuqux1omxV3v53IjeWrt3YzolFFy13Xiw9xq6lj+oHAeAxOnZpXH/AxKT3SBg=="},{"block_id_flag":2,"validator_address":"14C590ADD4D238649F2CC7B198B52B8BDB63AC78","timestamp":"2024-07-16T21:21:23.793308637Z","signature":"fVjDE9nGS+3DpojDDfFt0wLVn7M783M7c8dmOEmlW+qGTAzvZBn5W+acCLI2Al4bvufvqkHLYAZNXke1yHUwAg=="},{"block_id_flag":2,"validator_address":"682EF7D2FB487050D6AD71173FCC7C983B031A4B","timestamp":"2024-07-16T21:21:23.565598211Z","signature":"Znhj7sBinOE/JpHE3rI2zvKtTteBP7V42mVqvW8gHhZyUqkNEcbTsKYKgoVxloYOPN+I71GrQThJzomvHywqBg=="},{"block_id_flag":2,"validator_address":"BEEE6DB44A01D8005CD59904F9AEE12BE9DBA6A3","timestamp":"2024-07-16T21:21:23.430017624Z","signature":"OeW4vJAF1RqshsjY87Jvjhk0lbDdKkMrJ8+hxOb7tWO9xUG1fF1V2jgPOVCkZHhtTaUmltJXTD03V9MZEvHIBA=="},{"block_id_flag":2,"validator_address":"88731522401F260D5C253222CF6EF71586A192D3","timestamp":"2024-07-16T21:21:23.485033667Z","signature":"TOqAysFwmBJ7oiSWJn7ZhKT4OGYd+tlejnCARy8KrhAk1v1f/MuYu/8tHxvJ1HkWhOhxx3agBBbwAWZ18tXYAQ=="},{"block_id_flag":2,"validator_address":"CD10B5095AC4541972E0C0FDE35A39CF92A040DA","timestamp":"2024-07-16T21:21:23.503845049Z","signature":"xYADEJDZ/MPwf/LMv4f1eYsdtN89k+n+8kU84w13ORyNJVOU24ZT2wTzQ+wfLTxCL0+qjEspmJIyZ0/pRy33AA=="},{"block_id_flag":2,"validator_address":"469CB700B5C1D9DE8905457AE5A7BD7E3FCB75EA","timestamp":"2024-07-16T21:21:23.806466666Z","signature":"r8iW5WbqERDo72kTuJNMSpXR3sRHi8YKSqMhaG191awvq1irVOsS5k7k6LVnYsP0psk6wBJSm0LoBCYHH8kTCw=="},{"block_id_flag":2,"validator_address":"5769499735A69F335467D419764A69FAFFE29607","timestamp":"2024-07-16T21:21:23.596707071Z","signature":"nhGT8rTsnRJLlzirYL02egruMZEEPZFJn4DZ1gG5o3G0msQHOfjib5y0HygZ4b5GKNBw1ZCRysXzJOF+GakECA=="},{"block_id_flag":2,"validator_address":"113388853F11E28044A4ED3B11DF745D00D709CD","timestamp":"2024-07-16T21:21:23.526604703Z","signature":"W9/nYv9mgtcr3VVwBqFyk3GkPh+ill+Xj6I5bWQj0S0rFMA4qpPYPd5RhzLeVwoWM5UC0s0s55r7o4f+wL5lBg=="},{"block_id_flag":2,"validator_address":"D92E949735CFD958FE2E1EA2F7ACCFBC981059B4","timestamp":"2024-07-16T21:21:23.653963489Z","signature":"25M6sGaVGk7XKRyZqdzCWV1qlmkYPlBC7et1pXGcfDrQ7StrQXFAEW1ThjLi2bwZmfSsxQ8jVrVX1ap58KYZBQ=="},{"block_id_flag":2,"validator_address":"F271741FA4B163F3204A5BC2570E74F146AA33D9","timestamp":"2024-07-16T21:21:23.530224992Z","signature":"2GBLidODTwViYh925W8ZiHfXMx3TbQauO6/rHysdOZl8va0nEzD433VoBNk/Bf44fNgJ+xJeVvDbdO25FGdPAA=="},{"block_id_flag":2,"validator_address":"B790E6ABE58DB7122F81FF52F7B2183AEEC41D6C","timestamp":"2024-07-16T21:21:23.643383029Z","signature":"4InDpW5RLvvpgweORc8eI/o15qPA06y7M8oRt2GhFa92MhT613/n5K6/bmD2NiWoDcenHauelgQB7iTCGukSDQ=="},{"block_id_flag":2,"validator_address":"924090B949A3A3A43AEE52C4DAE342332C57B684","timestamp":"2024-07-16T21:21:23.782023666Z","signature":"H3VpMn2KUix1v27wcpB+V5ygvDfPRJ8wo9k2pSIPpQQRUEKX9boRrN9UC/ciGTA2VxK9g7D+3ojWv8jnQNgDDA=="},{"block_id_flag":2,"validator_address":"6BB3BE6A41922712373BBCBA647B3A1486CF56B7","timestamp":"2024-07-16T21:21:23.504651498Z","signature":"NVBGneFLhhgrudyf7Mf3Qd74urlIoWcqVx7ckzA8+YNa+JxqqJgzyDBsHpGdIef+RUHtcYjs4cdEthBtgl6hCg=="},{"block_id_flag":2,"validator_address":"C8E66B2FB198544C40058986AFF7BFD9B1FD6442","timestamp":"2024-07-16T21:21:23.494596959Z","signature":"IGB1dqgIqZTFQRXeF/AcnCu4fzvjrhvEwTayUILRc9WvTbmd1PFfNDtYDlXTL4hsYQkAfu6ELl5PF5T+EUAaDQ=="},{"block_id_flag":2,"validator_address":"9AD672973AF0C5A606F1D2EE0F261AF5DD61DACE","timestamp":"2024-07-16T21:21:23.608258079Z","signature":"PcGK6TOeNGSlB8jYh0m9eMM7pTW1ztsplLXkLrwo/2O1p0WZ0uHceo0NT7hNhqwbH38BxWo5UgmNlT1U/dWzCQ=="},{"block_id_flag":2,"validator_address":"3511B17D31452B433E1392C75CC1D9A57FB769EE","timestamp":"2024-07-16T21:21:23.624828672Z","signature":"ePgY6GPnHPZ8g4+ne8NQpaMPl/ri7lmPv8i5h2fopewOerQugHGcl8Efjf0Xl3IY1179PxrWZ+1ukDjZ31KnDg=="},{"block_id_flag":2,"validator_address":"6C6F50C1E0E2A69BFC2AB7DABE0A3F091D17E666","timestamp":"2024-07-16T21:21:23.482581757Z","signature":"RTFTn6TtmUm4Fd+N6vn+L7g3vJqfpBHzxn7QJy8E0Yv+NgRxXToTAOClLRxndH+KHJsomowu5xo7nzq2qzYHAw=="},{"block_id_flag":2,"validator_address":"0FDB40C1B3ED17E49061B1F577393E5B91323C99","timestamp":"2024-07-16T21:21:23.566793176Z","signature":"x+J5juTAUYhpSypajf2usKWIVDS4DgcRiDznuIm9ZuqD8CtviZviuWKVGJ+asLj/MmtbfEhrrvfEecXDNquVBw=="},{"block_id_flag":2,"validator_address":"D5CABF35D9C01401B32540F938BE59FA2B044067","timestamp":"2024-07-16T21:21:23.499983379Z","signature":"1+Z6QhgD0303gW4zmHLnLklD6ClynSb4upPMUn0EUSIABReRjK1Rj9y98wWnmc3qheS9SK+WkpOluUFwcCqzAg=="},{"block_id_flag":2,"validator_address":"D6DFC3CD8487061C9612E5E42924FC4E5F622E23","timestamp":"2024-07-16T21:21:23.49133422Z","signature":"xRue/YvO+ZLuGJj+UEBk0Q7B3t/+uUgszC76yffYn4ff83fQ2fTSYzKN5SCknJCEtQ7tir2sELVPx/GrrsqEBw=="},{"block_id_flag":2,"validator_address":"F17C3F91E8237C9AE2806625904E8639AC9A3EA7","timestamp":"2024-07-16T21:21:23.602214615Z","signature":"V7qvwXHir854JYWJso6S1fH212YNuQzhQIyuWY7pncFpoURIBdLxwQBRzVyAxim8Nt+YXvOSf+NUuznO1T2FBA=="},{"block_id_flag":2,"validator_address":"2A8FB5C0567D3031B6A26243BF9F3D04E706548D","timestamp":"2024-07-16T21:21:23.466592821Z","signature":"BWM5b/UVD3OXlkQf69Vu8tkG6YjpV7Pjjoo8Cv+VMFGNGD/bRaNI0ykJ4SJhNQ0ajexFyUUdsuIbwNuyH1WxBw=="},{"block_id_flag":2,"validator_address":"1FEECDA6D9268908A1F84093F0F888F2F752A212","timestamp":"2024-07-16T21:21:23.762983695Z","signature":"JLY9gcz1vr9QWJKDbLyBO3+hB/0xgl/wBTqqzOzHTaJ9c18/R3v04iiidmaxt7tRST8MzfNHQ/ivdKveUnCZAw=="},{"block_id_flag":2,"validator_address":"2B4F222E08213F7F6839E0B2D85C0F56675BD2AB","timestamp":"2024-07-16T21:21:23.473640117Z","signature":"Es09yGUBUs3xf28ba8pNTIroR4zdsmaJHOuBu5VEuIQFdDcwn3cI76KjwpweB9KKCe2D3iL6u3QmbIeQ+KCFCw=="},{"block_id_flag":2,"validator_address":"C97A18C41B44DFC2F5FA1FCF8BC1BCFF5E649AE8","timestamp":"2024-07-16T21:21:23.495210694Z","signature":"v1zMMCdZOQxrp81ImEQGj3NCuFng4J2AYlEPIvbaDr638jX6ICRjeLTLWBjxcJKQB5JDAGQ9aZZpBAkgSO4/BA=="},{"block_id_flag":2,"validator_address":"E5183117268691950E77D53340C23857662CC908","timestamp":"2024-07-16T21:21:23.522131619Z","signature":"f+XTlcytLgF5XNswoXeCyVns5Gn7AoTZHntpRzZ7nQJ5zSVzXrrq1XKIq1K5X1TgWZvdiA49n4nX0Dd0FwF7DQ=="},{"block_id_flag":2,"validator_address":"EF8D6E39A9AA29C04D9D4F0F43EDAD5AB06F56F3","timestamp":"2024-07-16T21:21:23.682617846Z","signature":"6DeHBhT9dXktRnTX7YzY8qdOrC95yUO5izzIRx3T1rTHh9SEeOy0trAn3/r3TarwQmYaO/yOAIpmlagjf3TgDQ=="},{"block_id_flag":3,"validator_address":"E01B694AFE5D64691341E931A80ACF9D95E6C8C6","timestamp":"2024-07-16T21:21:23.900381101Z","signature":"0TwlMp2oBby+IBmFeT4O/FCwSoGCeFWne8plBlxKBSggCGKT8pstEKoOYGYHC6ZP0458998JY67HMTMiZpgPBw=="},{"block_id_flag":2,"validator_address":"633744F3BE877E6DF590E72E99425BA653156B93","timestamp":"2024-07-16T21:21:23.534458433Z","signature":"DZcJiZ1oBGiXcHE8z5xEfyuV7sp9Nn8m0tku/UigTx8tASWejhBC/izT6P+1OwjlL/9nWlqTY9hoDc4Y/oFyBQ=="},{"block_id_flag":2,"validator_address":"6A152D73CD9146A9C1DD4CF9FEF636E2235ECB7E","timestamp":"2024-07-16T21:21:23.487169737Z","signature":"G2y0UmDJdGL+mPfE/emshN1cp1/auCpEQ6YcwcUMlvIqDl888qbT1T/9s7N36ukWmDTY+K3lo/SL4jSfZppfCA=="},{"block_id_flag":2,"validator_address":"CD34D386E534320153E1A3B02DEFB4CE0773E462","timestamp":"2024-07-16T21:21:23.962492904Z","signature":"gTNyTYjhaCYmHy3a52VtNojj8JdzprBEjllLLdU5l8a8VC+LTYs7e/9gaLb47BJQEnor6bfUODA6FSydfrs4BA=="},{"block_id_flag":2,"validator_address":"A601B7BCB5172E302329CF3DB6B0E975C8A21D10","timestamp":"2024-07-16T21:21:23.530157162Z","signature":"DMVTh/LZvlE1E8hVBseOcKXgbeX/YGzSQQgB9DcJD9tVi9pAFr63z4HPuOXQp3FhxL8n8pGC7ra++y8SPcfMDg=="},{"block_id_flag":2,"validator_address":"CBA82E0DF6C639D320AC0A421238F6EF93373C94","timestamp":"2024-07-16T21:21:23.543027881Z","signature":"F/ALX4haTI2vxKgznLdKNbDBHh3EBwr4f3i9/lBaH3YQ72Cn7UQgxBeXAC5mdkgJrG8QLUIeiSDmCAjgDDvpAA=="},{"block_id_flag":2,"validator_address":"0D6EA92C96F4DA14C40B1CA7E2D82A811C9B2196","timestamp":"2024-07-16T21:21:23.644484055Z","signature":"5+/7MfCqc+Xk2zcvVX2Q73mRCzjfa6LfdJeOyxO7mzVp+/0oFivANHZ26hW5hTZ5IPYQ9aY9qD9t9pGsxROUAA=="},{"block_id_flag":2,"validator_address":"4A3918A6D02D25290B243A86618071374FADD87B","timestamp":"2024-07-16T21:21:23.552128685Z","signature":"aeDT3IfEpCvFhvK34uPN8tbnjljGOD7X2diFWN/R1ZwVpxZo15SMj12icUumWQ8sfAbOsha2Ba4qTZQgiaVEBQ=="},{"block_id_flag":2,"validator_address":"7BCC38AF8F5494F000D2B7B89EEB9D67B14A0F3F","timestamp":"2024-07-16T21:21:23.475724448Z","signature":"d6qBlfJ0hmtTbB+eTwJPPV1MyQ4gwY5g0vpsphVqzRpk0ZJBL6y77p3IOPslJ0JM73EOJls5t9/UM0HbkHkoDw=="},{"block_id_flag":2,"validator_address":"8536E9166685E936CAB4FBE1F3588F65623E9E81","timestamp":"2024-07-16T21:21:23.866761725Z","signature":"apiDIQUTr7cxQl0t523ZVT4WwhJtVF55YVY52rk46yrw1p5km2FFODtOrioBBEhD+YC5i0j22+Emm/NPVehtBQ=="},{"block_id_flag":2,"validator_address":"DC40C623F0EE6A10CC1E9134E9ADB955EDD319CA","timestamp":"2024-07-16T21:21:23.686982268Z","signature":"gQt19YMAQ4T57T/XMO6WXQYdxBIPpadv7hcPYaTCG28YLAezYQTvZjNpIg94PIHIqUwQx3XjgpElydZNeny7Dw=="},{"block_id_flag":2,"validator_address":"2131A959A819C085AFA86E560D5EC0DF1D632827","timestamp":"2024-07-16T21:21:23.553923065Z","signature":"lAxXd4WNPzlO5Sm1DRDvAG33Sqj6EgfC0JRSWOJ4LVo2RzrpjqXd7/RaOphUTJlKUfWAkLfts+noI1qvGTcIAg=="},{"block_id_flag":2,"validator_address":"A09C4BDCBE3718342A27BD9D420FD14C703C9965","timestamp":"2024-07-16T21:21:23.495858321Z","signature":"XPoMNk+Lb9d1FvSN75eLk3A3uHWqSwLr7wLG/SYkBNoaCldTceFgDCXfTA27ef2aIlTIdlc6zVnkJIPRUSJnAg=="},{"block_id_flag":2,"validator_address":"F7A4EEF357935737058F08804DE4DD03144E960D","timestamp":"2024-07-16T21:21:23.479350085Z","signature":"HeW7CilLMMEf2at/SUkmW0KG7RaNEPrrGPbTw1uJJSmC6OnNt3HsOEtcKgVFyFHbUyjuz1CKB1kdoxYKwWMRCA=="},{"block_id_flag":2,"validator_address":"0A957E96258B8BC5669C9A4DA146532C93E99242","timestamp":"2024-07-16T21:21:23.79076978Z","signature":"i6tLjkMNa9kikT2WcM8K/KNSouT6JZaWGAkazVOMcGzCApoXgc7nF5oHyMr6xM7QHqqZF/tkwosTF4xINYSrBA=="},{"block_id_flag":2,"validator_address":"B07503589534AAAAD60836B33245410AD11CCEB9","timestamp":"2024-07-16T21:21:23.65602061Z","signature":"imFwlNQXMHTNaZLnIdCrCgN767MAtVuvMoCOCZ3deQYhBSyRvybZDM5zhJ0/MGMEjgQpYS8xFMFnSvRML/FEAQ=="},{"block_id_flag":2,"validator_address":"5A806CC33FC21BCF9F2F47BE23B6586E04DED0D1","timestamp":"2024-07-16T21:21:23.546505693Z","signature":"sySj9zZRD0YPBD+DOFDNWOYXWfNeOiW4uHNliKS7mW1+5SdeOOj+Q+41IENj9rd/Yld84wJRUHuuTT1DszczDw=="},{"block_id_flag":2,"validator_address":"967B6B5C64615DEB574D88C1F07F23F77E6E7EBA","timestamp":"2024-07-16T21:21:23.57225231Z","signature":"gMMLwYuo+cEhTsuy6Jr7zjIO48qePdVkbJae0zbAQjiQA43msZgEpflmKwKmsIpvvL59MjNvp5sORLor7tq7BA=="},{"block_id_flag":2,"validator_address":"2DC2EF8D1059A7A90E9D4AD35DC8F4F8CD7EB772","timestamp":"2024-07-16T21:21:23.550171448Z","signature":"VApuEhFtVuArCQyKtjY+3eJk1IR/DOOucKYyexxYhWl1RSTtJL1tn8yRWneQgHLeg87e7DOnDroZ+MnhM1a0AA=="},{"block_id_flag":2,"validator_address":"F6D5482C2405A9844A1EB215148387AD18800D32","timestamp":"2024-07-16T21:21:23.46663226Z","signature":"6KiyP5lhzbAeFbuPt2BSN5isE7QmWmmKHwON5fBbyZXVWROjHQ90XqcwQ1nVViHbQabDglF3BiS/TBVMSTfcBg=="},{"block_id_flag":2,"validator_address":"473FB7626E52E54BD406A255DBA3B1822F8FC2EA","timestamp":"2024-07-16T21:21:24.019767633Z","signature":"MlKSa/fXWDSg0ObIaGp4OOcpz0sMJQaSNf5jE7OiGWqaeLVlwUNRUtJiwqIpmcL6NtlUqLIvhmzN8MjKj1oHAA=="},{"block_id_flag":2,"validator_address":"50922F9E58F64B3A219887F67117E4CF714AF490","timestamp":"2024-07-16T21:21:23.466652407Z","signature":"XInaT+nc5FsCDNTzjlnsk8sPm1MtbKO8Iv4dhutlM94CS2m50Q6FTk2iWtqZSbSKZNm0CNhb1DevjMzLcLABDw=="},{"block_id_flag":2,"validator_address":"E5C8264B472C5BD93BD9CA9CE99C221DE14B7EFB","timestamp":"2024-07-16T21:21:23.550851357Z","signature":"rlvtZrzBApdAZlFc1cQf48k7KIb/8UUFFsRnW9kRMcZ0AlBIVUQ+iyNfnfpDJvm680raPoJR3ZnY2oMgnM6UAg=="},{"block_id_flag":2,"validator_address":"FE6AE5C0EE214D1A1199387B06F7783F66DBC09B","timestamp":"2024-07-16T21:21:23.929327157Z","signature":"Z5rvX5lRdrZCE+0Oir3FkmORVE+4WxE0cazsxehXeTHSjZjYbLG4rMCzegoX7DMbdz8c6L2yhDCSl4nD6lwFBg=="},{"block_id_flag":2,"validator_address":"26EFB42C96DBFA42D740333C33E2713AA050FA77","timestamp":"2024-07-16T21:21:23.747233709Z","signature":"LcVTXYZdEv39zG8F0hHi1xZf1DAycVJEEv+bL9ixiI6NFYUDetmMe90DvNp3QxaxMFbHHuEXNgtAkiODArQ+Aw=="},{"block_id_flag":2,"validator_address":"D87DA6AD5B598E723EE3A03BE0A6F9AB07EB0E01","timestamp":"2024-07-16T21:21:23.537726306Z","signature":"Ze29TRdLmkbwYXyF4M1kC7KYtm86fPKkOGTS7snwN1A1y8kxgsKKRjsZbyAnxklkpiXOt2GTBFbyFkmA/cyfAw=="},{"block_id_flag":2,"validator_address":"E23A9173DF68A8BE51650807E55104E6101CA7CB","timestamp":"2024-07-16T21:21:23.476270783Z","signature":"jE2WU0Y6XAf0MXuNu0SqKbWEVyHrh00awsGb1hAaDZkThiNPwIru+7Stwd+dHQN6yOLCPyFuBXSleiHWNiQDBA=="},{"block_id_flag":2,"validator_address":"9E9F1F203A5AA77340B4BCE0472C3C24D3A061B3","timestamp":"2024-07-16T21:21:23.465283956Z","signature":"JdK7aEhrEybBCxGZlmK2GHyYwFSbziGV67TplKP8Gt7wyH3AKU1TJDnDFffcMfSIOzvO4eUgq+FvK/6kEvgsBw=="}]}},"validator_set":{"validators":[{"address":"7619BFC85B72E319BF414A784D4DE40EE9B92C16","pub_key":{"type":"tendermint/PubKeyEd25519","value":"l/qNaf4JDxnhP+6Pf+2OSAJYksSIkjyefYCDvZPoahA="},"power":"74052443","name":null},{"address":"762CBA617226A799D898F134DD12661C7F1129EB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"6bdjjKHELaN9colwYy/ad+xh3MUgOVq106ZFucK46LE="},"power":"70555622","name":null},{"address":"597944BC0AEDFA1D9DA7C2098FB05D7B6A2D4946","pub_key":{"type":"tendermint/PubKeyEd25519","value":"njq3L6yQabWMjmh9QjBobp2XOdNytaLPoxFgY2Qd3i8="},"power":"64650439","name":null},{"address":"7744C8CE6E06E67AB9721696AA752B951C93E9E0","pub_key":{"type":"tendermint/PubKeyEd25519","value":"259mAZKhNLksTkJ7qJZf+ZreaPMQtBY7NDeslqPRa9o="},"power":"28001060","name":null},{"address":"8FBEF0DBAAE51D918F9ABFD96653F4932171870E","pub_key":{"type":"tendermint/PubKeyEd25519","value":"J8wAKpZrD9kRbewJDMLQAuYkYNh33PhCg+wcdVcGxIw="},"power":"27553991","name":null},{"address":"0B76107110A486E8767FA1997EA0C4B40B7851AF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"D3wP4IWMZcMt9UHVzFP2J19FDCP/732nvtT/f3CIatQ="},"power":"25298561","name":null},{"address":"D6E25B7E6E6C96D1B7135CF41FF03DF84DE2BA2C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"2XKroLDmwSjW8Z0ZadGF/Co/6Bo5OreNldOxj9fl/Ww="},"power":"25000168","name":null},{"address":"59158C19ED4DF57D59B54F80B07C0AFB37DAFF0D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"3rvnDucNb0+ZSdhfQSzjdFSFiZWUGerlEt4hp1EyHKM="},"power":"25000019","name":null},{"address":"91AB27CC321622AC4DC778D2F1FE367CFADAC665","pub_key":{"type":"tendermint/PubKeyEd25519","value":"UEKnFx4sn4K1aIPxrCu4zE3+Vr4vMGgIeu2iFAQsUH8="},"power":"24714090","name":null},{"address":"C822706DA92B375B6793FEC5FCAD04BB5AFE142A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"i/Zow0IiKpVFWRNxOwN+Fqe9zVj9VY+Pn8+YsuSo9/E="},"power":"4066863","name":null},{"address":"FF73CE6FE36E313684457C855D7D25198B87C8A6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"B6H09N1cxmSXGgqTuAIphe7ESJsCj687/8CYiKBTh4w="},"power":"4050758","name":null},{"address":"E1F1D0F31F8DB86B829C8502AD1F6F1576C08A6D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"4TpozS4FflJmfBg3MYhLw12UeVUSELod0fdnX4tAQgs="},"power":"4048910","name":null},{"address":"13E610C20C1C6623A3C32AC058E9F8E76BBEEC16","pub_key":{"type":"tendermint/PubKeyEd25519","value":"LSpewjhpxXBs00/L2L6DQJabXcSoTzmjqZNTIw5DSCg="},"power":"4048857","name":null},{"address":"EE927F115AD4FD4BC131CA311D332ADDAC62CCAC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"SfFXATPCbIeRUsb9RP+BfdYOH0v7H2aGbPGx1HlR1I0="},"power":"4030218","name":null},{"address":"97C24BFDC996F0BF40FDDA96CC22D417D0B8D0BA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"h5QOLCS5zoZZGk7ZXnaU883fSQAhwneIvP98XcjOte8="},"power":"4023467","name":null},{"address":"9079C978817165244C051EFCE5AD163AAA905C6F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"fODnMY6gDPpnDlAsSQ2b6M5u3gjYNaKq1JL6LBFShzM="},"power":"4009700","name":null},{"address":"7EC8ADD79B454AC37625077453DF49FAC1BFD7E1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"jqBYsfBjFJhudulObGgaMawaeccpj+21nfs+Px6oNIY="},"power":"4002311","name":null},{"address":"11637B088406D4F3EFF52F2230C8068D230C7611","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gcI3uuOTA3ZAVCMsLawhjUt7cZc/EBJeipq9XGavEsg="},"power":"4002024","name":null},{"address":"52E55D04CCD1C78D4FC520FE17AE4584FA2053A8","pub_key":{"type":"tendermint/PubKeyEd25519","value":"wdZ6voJ0Kdh/iJvnzjS9oAiSRtr7A2S4mifU3xFfEXk="},"power":"4001100","name":null},{"address":"BB408FA902A7B6A938C788957B2A874153261EC5","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7rE47Ol0HqaZhnQQqlx5BD8rNGv6yTcRQANXtMY7y4g="},"power":"4001076","name":null},{"address":"8C55B13AEE44C518E363DD328E2AB451D6569EAC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Zj5o33wP8tFPM8qgoC4upsLQvrAc/DGT2J4JG+LhOJ4="},"power":"4001057","name":null},{"address":"F005689992F73B55B537461AC0AE0DF9694B36CF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"KgescyXaO/6YrE/GIuqmFdP0xXTqHUflMAH40HDm/20="},"power":"4000714","name":null},{"address":"01458B61F0D7DE6E90798FE8C370413D718EB34C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"LKwKvQPVTwxwW4UDpyIvGW8Sa9sUdaxhhhVdOigrEyA="},"power":"4000566","name":null},{"address":"5AF159B8269B974F9274DAEA0F778ADD3B12707D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ony9i2cN/h1wawOv0WN6Ql/9lDjDeLgOVCl1fRtuyDI="},"power":"4000504","name":null},{"address":"98271A1B3690F4EC867C760DBCA3754684F485AC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"k3zGTt9YVhopwi6iL+f/XYSj7cZRT+fcPlpwsojLsvg="},"power":"4000472","name":null},{"address":"969B1B7DCAFA313131620AC163E3A09A03B49BE6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"feFjsaWtjmxYp6N+1r/9Lnd4o29skxSJclmebnk49Ao="},"power":"4000469","name":null},{"address":"4D5B4C1A687B13AAD96F9CED90F006DFF03CEC45","pub_key":{"type":"tendermint/PubKeyEd25519","value":"y1QMroz50WA8c/IREfyr7Mm8S75gRCfuk0Ea4fokb4E="},"power":"4000103","name":null},{"address":"3BFE2EF588102F19F40952DDDD3A89BA90D7351F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ps6HB6/GSvuY4fKaszGLXMdHVk38ASzBcGBXeVVeDMo="},"power":"4000028","name":null},{"address":"28B6061D5E269B3585F019E1748E32CA9F34E739","pub_key":{"type":"tendermint/PubKeyEd25519","value":"CIc6ZcjHkdfYEzQqwXZBlYVTl13ZxAinYLLgHszHVgY="},"power":"4000012","name":null},{"address":"C8C62F1CF89BF5E852E252ED38CBA4A64787CF1B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"OKWb9Bw4pE6tfYtZiigi7A8ecGnCVBiJt2h1P7o1a7U="},"power":"4000008","name":null},{"address":"70A191EF78A0C8B9B69E005A685B064C254B1F33","pub_key":{"type":"tendermint/PubKeyEd25519","value":"jjLleXjmBwA66V5gejueapJUSYqb5W+oYSGXy/QLEQk="},"power":"4000007","name":null},{"address":"38CECDD91DAE3D8F536C080742A69FEBB6EFDBFF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"RYrMwDTpJWv67sFVwKtmS+UxlN7hljKGWJqOsutcB1s="},"power":"3991125","name":null},{"address":"0DC59C626E4753D889DE2D3262A9A613E754668A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"1UlN1J5cR4XlFifpA8IA7A+xa3NQ1sJ/1IhssJQ+xEM="},"power":"3961059","name":null},{"address":"1E7BA20AACF7EF2CDEA41CDFF8DCEDFBCF12F363","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ueUh8xh/b1zlBcCgblxHrZ9impMwKOkgyG5P3f1HkjE="},"power":"3961026","name":null},{"address":"346001263089D83465A72C6DB5EFBC32359111A3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"vdnWYA28lp43YkD0e2VExAcYPadTFh/Hpes0O0a4p20="},"power":"3960055","name":null},{"address":"2F334E80D3EA0AE019D6498D8DD7E0EC472E5424","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Fzeq1bTZn9T8Wev9O8/Huzs1nw/OXl0iTepDFRMUko8="},"power":"3960033","name":null},{"address":"80726DCD4E975716843F213C7E5A36400ABCFDFE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"sAD409SvbABZBr0vCmjL6JK6XVQgQP4RM7v/Oiz/f88="},"power":"3957948","name":null},{"address":"4520D7FA09B49EA0C0F39E6788E6EB3FD8065690","pub_key":{"type":"tendermint/PubKeyEd25519","value":"27PwyrHHY/ndxqNrL6SdHomL4hR3JAJ5QMdQFYRlS9I="},"power":"3881201","name":null},{"address":"93CCD84A7302F5676465A1239C2544AD3140D7CB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"a/BQji6ozSlxXzMhtW4RGybuZ81s6tQKSPhO2mGIU4c="},"power":"3000010","name":null},{"address":"3824438082C68B36ED8F5199155CD78ABBBDA30C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"dO71IfBvwwwJ6cEzc9oT1FqU0CUdckJV5F53kDYb22o="},"power":"2000006","name":null},{"address":"9B2FB5ABCB3B0289D03AF5A8577C76D9A37A32D3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"D9iPx6VTH+xeewFFWfnI+a7dM6Y5Y9h/5S4WHro5wUQ="},"power":"1003008","name":null},{"address":"87D1611F9BA8ABF12C13B32F90469977B4C94F9A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"BRvI8B8k+QrDeOgdBNb7mLCbNEMatJNqDyZttdGtQm0="},"power":"1001309","name":null},{"address":"5E9EE98A3CBD523D0D3C3518048DF8C322BB67D5","pub_key":{"type":"tendermint/PubKeyEd25519","value":"VXn41Fko8YeJ3vVvYy/yUtqfVbCv7FTivuDclSrw5Pc="},"power":"1000893","name":null},{"address":"E309A8AFFF70D04126D04BB53071B6020580D104","pub_key":{"type":"tendermint/PubKeyEd25519","value":"J0kLUI0gmvWfWvzoxHaqwzXF3+VARlAIMGCRfB6Yj8A="},"power":"1000210","name":null},{"address":"3B0F1CAEEB84A5AF239580FB26D6199CB17CEB3A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gN5Cln7uU3AVQYzT3QGgggv/3aN+eIewd6m5OfPpkTs="},"power":"1000042","name":null},{"address":"14C590ADD4D238649F2CC7B198B52B8BDB63AC78","pub_key":{"type":"tendermint/PubKeyEd25519","value":"F3RJktKCIoDGEBWXgpDl2+LgNbq5X0rS8eXnY+i3aIY="},"power":"1000038","name":null},{"address":"682EF7D2FB487050D6AD71173FCC7C983B031A4B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oRz4ydtLca6+HfffYIRv0PCsTm4xKBdYpx85lisMWng="},"power":"1000037","name":null},{"address":"BEEE6DB44A01D8005CD59904F9AEE12BE9DBA6A3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oYhHHoROhbAIzOuST8Qyua7O611uIr3NT2yyibK5x7Y="},"power":"1000020","name":null},{"address":"88731522401F260D5C253222CF6EF71586A192D3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"m9gm7H1kmxvPzyo5ubgkmqKGQbJFHst9My51FLe2HeM="},"power":"1000009","name":null},{"address":"CD10B5095AC4541972E0C0FDE35A39CF92A040DA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"cPgsoC0NIVUAe42qmzfbrLaznvYZCh1z92Q35D0KZOc="},"power":"990479","name":null},{"address":"469CB700B5C1D9DE8905457AE5A7BD7E3FCB75EA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"PRXS/zL6clsHN2Srl49mRV+W+eL/g7DgY1MG8eu/8K8="},"power":"990174","name":null},{"address":"5769499735A69F335467D419764A69FAFFE29607","pub_key":{"type":"tendermint/PubKeyEd25519","value":"HnEoblS3w9JRSFqXX/2RCippz7tQD/ShYts+tGHoSBM="},"power":"980425","name":null},{"address":"113388853F11E28044A4ED3B11DF745D00D709CD","pub_key":{"type":"tendermint/PubKeyEd25519","value":"61X0w6XUKooaWi4FYzZghd6kJDIFFifK+EpMJWTHSaI="},"power":"509044","name":null},{"address":"D92E949735CFD958FE2E1EA2F7ACCFBC981059B4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ba80uJncfcmlWoFM/AlzMI6Mut7SyDJTpbNV8kwMXl0="},"power":"502561","name":null},{"address":"F271741FA4B163F3204A5BC2570E74F146AA33D9","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Y0SMVwQK9FHbFi7ykZSwah3TG56saeI0uTMXYvyb9dY="},"power":"501737","name":null},{"address":"B790E6ABE58DB7122F81FF52F7B2183AEEC41D6C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"EiSlqpx/n3VMPFtuTAa++axavjZ9yZzlTa3HtCz+lsI="},"power":"501375","name":null},{"address":"924090B949A3A3A43AEE52C4DAE342332C57B684","pub_key":{"type":"tendermint/PubKeyEd25519","value":"cseuElK5A+VoeuKMvrm3AOTuzII46kf083lVMGpRLDo="},"power":"501271","name":null},{"address":"6BB3BE6A41922712373BBCBA647B3A1486CF56B7","pub_key":{"type":"tendermint/PubKeyEd25519","value":"QfqtiQS1sJXJKLIPYSoHTL1NtSfwm933fD1wOqgBxJI="},"power":"501058","name":null},{"address":"C8E66B2FB198544C40058986AFF7BFD9B1FD6442","pub_key":{"type":"tendermint/PubKeyEd25519","value":"h5bxQwVfFqo0YqTMKMIn0Kmm5SR8QsYGps/x9CUtbFI="},"power":"501050","name":null},{"address":"9AD672973AF0C5A606F1D2EE0F261AF5DD61DACE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"y1EE0IXUX+xqvd08toyjMekOX1kNMzEmY2FLNe00sUg="},"power":"500841","name":null},{"address":"3511B17D31452B433E1392C75CC1D9A57FB769EE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Wblv9P9x2vItElCo/uoJGPVcB+bMOExuq+fE8+rVfrk="},"power":"500423","name":null},{"address":"6C6F50C1E0E2A69BFC2AB7DABE0A3F091D17E666","pub_key":{"type":"tendermint/PubKeyEd25519","value":"N8ncRVbJpyffC98xo+mxWdqm/GamCJkVTB0YeM8gwkg="},"power":"500401","name":null},{"address":"0FDB40C1B3ED17E49061B1F577393E5B91323C99","pub_key":{"type":"tendermint/PubKeyEd25519","value":"GzwPkML4PmjOdcTvr2pm6rjO7cBHrckZR3oe2w4E+FA="},"power":"500018","name":null},{"address":"D5CABF35D9C01401B32540F938BE59FA2B044067","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Bcsbz2eNu1HWCUW9IkzHCZ6ACMxf/sepz12Q8YCdUDM="},"power":"500014","name":null},{"address":"D6DFC3CD8487061C9612E5E42924FC4E5F622E23","pub_key":{"type":"tendermint/PubKeyEd25519","value":"tF609cLwhEnpi3W93lYIxE1sG/VLbvFKRX0wOzAQxeg="},"power":"500009","name":null},{"address":"F17C3F91E8237C9AE2806625904E8639AC9A3EA7","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gmdjSSfvgwXEAJ7CEMDH0Tv+cQSEFujwSIFdR87tWZA="},"power":"500006","name":null},{"address":"2A8FB5C0567D3031B6A26243BF9F3D04E706548D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"MJlbI1M3aILcOMSigyPMolCpjfQPzEsagrtZTN+9z6E="},"power":"500005","name":null},{"address":"1FEECDA6D9268908A1F84093F0F888F2F752A212","pub_key":{"type":"tendermint/PubKeyEd25519","value":"DE8/atJOsW6TA3iDRklz5DdI8j3Tx95o0nOhwkbkvBQ="},"power":"500001","name":null},{"address":"2B4F222E08213F7F6839E0B2D85C0F56675BD2AB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Zv4/6wZv5pwxuovxaC72oHNW0TAfiH/N+vsilZfiyHc="},"power":"500001","name":null},{"address":"C97A18C41B44DFC2F5FA1FCF8BC1BCFF5E649AE8","pub_key":{"type":"tendermint/PubKeyEd25519","value":"vYKrsdaWTO7YnMgWoUGWKO+A3XwgvXYoB+HNVjBkWAA="},"power":"500001","name":null},{"address":"E5183117268691950E77D53340C23857662CC908","pub_key":{"type":"tendermint/PubKeyEd25519","value":"4k08zQEeKnu5auA0Zp3h5xfNfS6K5LfcN0vnAhNiyz8="},"power":"500001","name":null},{"address":"EF8D6E39A9AA29C04D9D4F0F43EDAD5AB06F56F3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"8yHvjPOugBmpP/D0FOfdpQ6oyiymtS1J+U3lNC/d/2U="},"power":"500001","name":null},{"address":"E01B694AFE5D64691341E931A80ACF9D95E6C8C6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"w5YcK+X1Uv6NVRKzY+4qaSw+Zum8CNDVC0+ip0NpQ5s="},"power":"496178","name":null},{"address":"633744F3BE877E6DF590E72E99425BA653156B93","pub_key":{"type":"tendermint/PubKeyEd25519","value":"rD+6Hqi0NsOsZgsjRAP2BbNtxWcieiDmmh3tng63xDQ="},"power":"495995","name":null},{"address":"6A152D73CD9146A9C1DD4CF9FEF636E2235ECB7E","pub_key":{"type":"tendermint/PubKeyEd25519","value":"XuXuQxuSJIdpW49/wAalXxyjvuV1aGlamnpg+PDyu/A="},"power":"476704","name":null},{"address":"CD34D386E534320153E1A3B02DEFB4CE0773E462","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ps7NCfnD+Nkvkgp8mtnh1S57i5OvVKymdrW1RDktbHk="},"power":"201075","name":null},{"address":"A601B7BCB5172E302329CF3DB6B0E975C8A21D10","pub_key":{"type":"tendermint/PubKeyEd25519","value":"wXe92Kj6b2uv5WP2yMffYDJ7naD3T08jneI8tQuohIM="},"power":"107519","name":null},{"address":"CBA82E0DF6C639D320AC0A421238F6EF93373C94","pub_key":{"type":"tendermint/PubKeyEd25519","value":"qgVzfy4FKDxIrJ/S0a31SHRL1OJZzsxkGMVEW8flsAs="},"power":"105245","name":null},{"address":"0D6EA92C96F4DA14C40B1CA7E2D82A811C9B2196","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Dq8TpiZCrf3fzg/sbMm6Ae5Ty3V1WPEtf1lKqFXVBU8="},"power":"102441","name":null},{"address":"4A3918A6D02D25290B243A86618071374FADD87B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"nuKCeeyYPNP/AwbavdBDum3sB8I7D4TCC4sFbPp7MPQ="},"power":"100448","name":null},{"address":"7BCC38AF8F5494F000D2B7B89EEB9D67B14A0F3F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"XB08MBTE4Rsf3/11MNd+vtdzv0xTvKzGc+7/28Z4En4="},"power":"100370","name":null},{"address":"8536E9166685E936CAB4FBE1F3588F65623E9E81","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7CT5oKkYGXFByTi8glX/46KCivpVffTBvic6gQL61G0="},"power":"100301","name":null},{"address":"DC40C623F0EE6A10CC1E9134E9ADB955EDD319CA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oJEFTe9oP7psA7onwhzs/17uEYyVi0FDqEZs2/9mGzM="},"power":"100226","name":null},{"address":"2131A959A819C085AFA86E560D5EC0DF1D632827","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Tac4dLmlfr+reh8jMPLQTGXYUBvY1cp1NtN2y1zDuDA="},"power":"100215","name":null},{"address":"A09C4BDCBE3718342A27BD9D420FD14C703C9965","pub_key":{"type":"tendermint/PubKeyEd25519","value":"g/lPk5YCZBxUxlLNgf5qzQN//wwNhIE9HH9w3QX1pMA="},"power":"100162","name":null},{"address":"F7A4EEF357935737058F08804DE4DD03144E960D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"yfV2cDweDavOEDVNWtOYuHcwONDP4jyC/ZG8TUruRD4="},"power":"100136","name":null},{"address":"0A957E96258B8BC5669C9A4DA146532C93E99242","pub_key":{"type":"tendermint/PubKeyEd25519","value":"dJdeXyHrKwqKAboLkSfsmvdQ+WRfYQTz+DbJQDeIFIs="},"power":"100130","name":null},{"address":"B07503589534AAAAD60836B33245410AD11CCEB9","pub_key":{"type":"tendermint/PubKeyEd25519","value":"NVy8f5VLbLWBLrnWMeP+sIkt0iVW4Q3ESepiMx0+j4E="},"power":"100125","name":null},{"address":"5A806CC33FC21BCF9F2F47BE23B6586E04DED0D1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"DP6+z/+64vbsAOx3O8Ej+C9iA572eU5nxlUfGoMB89M="},"power":"100121","name":null},{"address":"967B6B5C64615DEB574D88C1F07F23F77E6E7EBA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ZhjOncfNrailm0sDSE0Om3wqYKL5w+QwBowGnkwzBrA="},"power":"100105","name":null},{"address":"2DC2EF8D1059A7A90E9D4AD35DC8F4F8CD7EB772","pub_key":{"type":"tendermint/PubKeyEd25519","value":"lwSHuhiiooJGDeqHgh/cFoUudQv0zloyeiz400kyv8s="},"power":"100100","name":null},{"address":"F6D5482C2405A9844A1EB215148387AD18800D32","pub_key":{"type":"tendermint/PubKeyEd25519","value":"MwxKwbDR+Pfj2kb8e/mnRy7gLw4n2oJA4qe/E8K6A5E="},"power":"100085","name":null},{"address":"473FB7626E52E54BD406A255DBA3B1822F8FC2EA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"3IevyShLKCWeb5joXQjcpPDsvQWnk7bbHLqCd1td7sE="},"power":"100050","name":null},{"address":"50922F9E58F64B3A219887F67117E4CF714AF490","pub_key":{"type":"tendermint/PubKeyEd25519","value":"95WzrdnBvJzBBrOPjORQM0u/70LJnpyvZha6XAvS+T8="},"power":"100048","name":null},{"address":"E5C8264B472C5BD93BD9CA9CE99C221DE14B7EFB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7d0Y9SKn6bfYtn1J9buGsXImkkPHl/bQX8gI7J6Grjk="},"power":"100045","name":null},{"address":"FE6AE5C0EE214D1A1199387B06F7783F66DBC09B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"kWIFV6puc+0TvyMPwreUkcAJFHANXbWoLGcTJEDLQPQ="},"power":"100014","name":null},{"address":"26EFB42C96DBFA42D740333C33E2713AA050FA77","pub_key":{"type":"tendermint/PubKeyEd25519","value":"9FusyXhw+gECqAjvHefpCpSS+KQ/fDltXWFy+5HfPcE="},"power":"100011","name":null},{"address":"D87DA6AD5B598E723EE3A03BE0A6F9AB07EB0E01","pub_key":{"type":"tendermint/PubKeyEd25519","value":"lwJhFD9crCT0jEcZi7TXYGo5/tLfRrFGb9C5EYDlHRo="},"power":"100011","name":null},{"address":"E23A9173DF68A8BE51650807E55104E6101CA7CB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"WCwJZKhAwYmOH4Eo5TXvsS9W8KqEx1Oi8mj/gfyuQic="},"power":"100011","name":null},{"address":"9E9F1F203A5AA77340B4BCE0472C3C24D3A061B3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"sJQZYhdp6x/l6MQ40Pj2880J6Q/t3433EZglkk1yYaA="},"power":"100010","name":null}],"proposer":null,"total_voting_power":"511862423"},"next_validator_set":{"validators":[{"address":"7619BFC85B72E319BF414A784D4DE40EE9B92C16","pub_key":{"type":"tendermint/PubKeyEd25519","value":"l/qNaf4JDxnhP+6Pf+2OSAJYksSIkjyefYCDvZPoahA="},"power":"74052443","name":null},{"address":"762CBA617226A799D898F134DD12661C7F1129EB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"6bdjjKHELaN9colwYy/ad+xh3MUgOVq106ZFucK46LE="},"power":"70555622","name":null},{"address":"597944BC0AEDFA1D9DA7C2098FB05D7B6A2D4946","pub_key":{"type":"tendermint/PubKeyEd25519","value":"njq3L6yQabWMjmh9QjBobp2XOdNytaLPoxFgY2Qd3i8="},"power":"64650439","name":null},{"address":"7744C8CE6E06E67AB9721696AA752B951C93E9E0","pub_key":{"type":"tendermint/PubKeyEd25519","value":"259mAZKhNLksTkJ7qJZf+ZreaPMQtBY7NDeslqPRa9o="},"power":"28001060","name":null},{"address":"8FBEF0DBAAE51D918F9ABFD96653F4932171870E","pub_key":{"type":"tendermint/PubKeyEd25519","value":"J8wAKpZrD9kRbewJDMLQAuYkYNh33PhCg+wcdVcGxIw="},"power":"27553991","name":null},{"address":"0B76107110A486E8767FA1997EA0C4B40B7851AF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"D3wP4IWMZcMt9UHVzFP2J19FDCP/732nvtT/f3CIatQ="},"power":"25298561","name":null},{"address":"D6E25B7E6E6C96D1B7135CF41FF03DF84DE2BA2C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"2XKroLDmwSjW8Z0ZadGF/Co/6Bo5OreNldOxj9fl/Ww="},"power":"25000168","name":null},{"address":"59158C19ED4DF57D59B54F80B07C0AFB37DAFF0D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"3rvnDucNb0+ZSdhfQSzjdFSFiZWUGerlEt4hp1EyHKM="},"power":"25000019","name":null},{"address":"91AB27CC321622AC4DC778D2F1FE367CFADAC665","pub_key":{"type":"tendermint/PubKeyEd25519","value":"UEKnFx4sn4K1aIPxrCu4zE3+Vr4vMGgIeu2iFAQsUH8="},"power":"24714090","name":null},{"address":"C822706DA92B375B6793FEC5FCAD04BB5AFE142A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"i/Zow0IiKpVFWRNxOwN+Fqe9zVj9VY+Pn8+YsuSo9/E="},"power":"4066863","name":null},{"address":"FF73CE6FE36E313684457C855D7D25198B87C8A6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"B6H09N1cxmSXGgqTuAIphe7ESJsCj687/8CYiKBTh4w="},"power":"4050758","name":null},{"address":"E1F1D0F31F8DB86B829C8502AD1F6F1576C08A6D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"4TpozS4FflJmfBg3MYhLw12UeVUSELod0fdnX4tAQgs="},"power":"4048910","name":null},{"address":"13E610C20C1C6623A3C32AC058E9F8E76BBEEC16","pub_key":{"type":"tendermint/PubKeyEd25519","value":"LSpewjhpxXBs00/L2L6DQJabXcSoTzmjqZNTIw5DSCg="},"power":"4048857","name":null},{"address":"EE927F115AD4FD4BC131CA311D332ADDAC62CCAC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"SfFXATPCbIeRUsb9RP+BfdYOH0v7H2aGbPGx1HlR1I0="},"power":"4030218","name":null},{"address":"97C24BFDC996F0BF40FDDA96CC22D417D0B8D0BA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"h5QOLCS5zoZZGk7ZXnaU883fSQAhwneIvP98XcjOte8="},"power":"4023467","name":null},{"address":"9079C978817165244C051EFCE5AD163AAA905C6F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"fODnMY6gDPpnDlAsSQ2b6M5u3gjYNaKq1JL6LBFShzM="},"power":"4009700","name":null},{"address":"7EC8ADD79B454AC37625077453DF49FAC1BFD7E1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"jqBYsfBjFJhudulObGgaMawaeccpj+21nfs+Px6oNIY="},"power":"4002311","name":null},{"address":"11637B088406D4F3EFF52F2230C8068D230C7611","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gcI3uuOTA3ZAVCMsLawhjUt7cZc/EBJeipq9XGavEsg="},"power":"4002024","name":null},{"address":"52E55D04CCD1C78D4FC520FE17AE4584FA2053A8","pub_key":{"type":"tendermint/PubKeyEd25519","value":"wdZ6voJ0Kdh/iJvnzjS9oAiSRtr7A2S4mifU3xFfEXk="},"power":"4001100","name":null},{"address":"BB408FA902A7B6A938C788957B2A874153261EC5","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7rE47Ol0HqaZhnQQqlx5BD8rNGv6yTcRQANXtMY7y4g="},"power":"4001076","name":null},{"address":"8C55B13AEE44C518E363DD328E2AB451D6569EAC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Zj5o33wP8tFPM8qgoC4upsLQvrAc/DGT2J4JG+LhOJ4="},"power":"4001057","name":null},{"address":"F005689992F73B55B537461AC0AE0DF9694B36CF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"KgescyXaO/6YrE/GIuqmFdP0xXTqHUflMAH40HDm/20="},"power":"4000714","name":null},{"address":"01458B61F0D7DE6E90798FE8C370413D718EB34C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"LKwKvQPVTwxwW4UDpyIvGW8Sa9sUdaxhhhVdOigrEyA="},"power":"4000566","name":null},{"address":"5AF159B8269B974F9274DAEA0F778ADD3B12707D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ony9i2cN/h1wawOv0WN6Ql/9lDjDeLgOVCl1fRtuyDI="},"power":"4000504","name":null},{"address":"98271A1B3690F4EC867C760DBCA3754684F485AC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"k3zGTt9YVhopwi6iL+f/XYSj7cZRT+fcPlpwsojLsvg="},"power":"4000472","name":null},{"address":"969B1B7DCAFA313131620AC163E3A09A03B49BE6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"feFjsaWtjmxYp6N+1r/9Lnd4o29skxSJclmebnk49Ao="},"power":"4000469","name":null},{"address":"4D5B4C1A687B13AAD96F9CED90F006DFF03CEC45","pub_key":{"type":"tendermint/PubKeyEd25519","value":"y1QMroz50WA8c/IREfyr7Mm8S75gRCfuk0Ea4fokb4E="},"power":"4000103","name":null},{"address":"3BFE2EF588102F19F40952DDDD3A89BA90D7351F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ps6HB6/GSvuY4fKaszGLXMdHVk38ASzBcGBXeVVeDMo="},"power":"4000028","name":null},{"address":"28B6061D5E269B3585F019E1748E32CA9F34E739","pub_key":{"type":"tendermint/PubKeyEd25519","value":"CIc6ZcjHkdfYEzQqwXZBlYVTl13ZxAinYLLgHszHVgY="},"power":"4000012","name":null},{"address":"C8C62F1CF89BF5E852E252ED38CBA4A64787CF1B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"OKWb9Bw4pE6tfYtZiigi7A8ecGnCVBiJt2h1P7o1a7U="},"power":"4000008","name":null},{"address":"70A191EF78A0C8B9B69E005A685B064C254B1F33","pub_key":{"type":"tendermint/PubKeyEd25519","value":"jjLleXjmBwA66V5gejueapJUSYqb5W+oYSGXy/QLEQk="},"power":"4000007","name":null},{"address":"38CECDD91DAE3D8F536C080742A69FEBB6EFDBFF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"RYrMwDTpJWv67sFVwKtmS+UxlN7hljKGWJqOsutcB1s="},"power":"3991125","name":null},{"address":"0DC59C626E4753D889DE2D3262A9A613E754668A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"1UlN1J5cR4XlFifpA8IA7A+xa3NQ1sJ/1IhssJQ+xEM="},"power":"3961059","name":null},{"address":"1E7BA20AACF7EF2CDEA41CDFF8DCEDFBCF12F363","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ueUh8xh/b1zlBcCgblxHrZ9impMwKOkgyG5P3f1HkjE="},"power":"3961026","name":null},{"address":"346001263089D83465A72C6DB5EFBC32359111A3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"vdnWYA28lp43YkD0e2VExAcYPadTFh/Hpes0O0a4p20="},"power":"3960055","name":null},{"address":"2F334E80D3EA0AE019D6498D8DD7E0EC472E5424","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Fzeq1bTZn9T8Wev9O8/Huzs1nw/OXl0iTepDFRMUko8="},"power":"3960033","name":null},{"address":"80726DCD4E975716843F213C7E5A36400ABCFDFE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"sAD409SvbABZBr0vCmjL6JK6XVQgQP4RM7v/Oiz/f88="},"power":"3957948","name":null},{"address":"4520D7FA09B49EA0C0F39E6788E6EB3FD8065690","pub_key":{"type":"tendermint/PubKeyEd25519","value":"27PwyrHHY/ndxqNrL6SdHomL4hR3JAJ5QMdQFYRlS9I="},"power":"3881201","name":null},{"address":"93CCD84A7302F5676465A1239C2544AD3140D7CB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"a/BQji6ozSlxXzMhtW4RGybuZ81s6tQKSPhO2mGIU4c="},"power":"3000010","name":null},{"address":"3824438082C68B36ED8F5199155CD78ABBBDA30C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"dO71IfBvwwwJ6cEzc9oT1FqU0CUdckJV5F53kDYb22o="},"power":"2000006","name":null},{"address":"9B2FB5ABCB3B0289D03AF5A8577C76D9A37A32D3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"D9iPx6VTH+xeewFFWfnI+a7dM6Y5Y9h/5S4WHro5wUQ="},"power":"1003008","name":null},{"address":"87D1611F9BA8ABF12C13B32F90469977B4C94F9A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"BRvI8B8k+QrDeOgdBNb7mLCbNEMatJNqDyZttdGtQm0="},"power":"1001309","name":null},{"address":"5E9EE98A3CBD523D0D3C3518048DF8C322BB67D5","pub_key":{"type":"tendermint/PubKeyEd25519","value":"VXn41Fko8YeJ3vVvYy/yUtqfVbCv7FTivuDclSrw5Pc="},"power":"1000893","name":null},{"address":"E309A8AFFF70D04126D04BB53071B6020580D104","pub_key":{"type":"tendermint/PubKeyEd25519","value":"J0kLUI0gmvWfWvzoxHaqwzXF3+VARlAIMGCRfB6Yj8A="},"power":"1000210","name":null},{"address":"3B0F1CAEEB84A5AF239580FB26D6199CB17CEB3A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gN5Cln7uU3AVQYzT3QGgggv/3aN+eIewd6m5OfPpkTs="},"power":"1000042","name":null},{"address":"14C590ADD4D238649F2CC7B198B52B8BDB63AC78","pub_key":{"type":"tendermint/PubKeyEd25519","value":"F3RJktKCIoDGEBWXgpDl2+LgNbq5X0rS8eXnY+i3aIY="},"power":"1000038","name":null},{"address":"682EF7D2FB487050D6AD71173FCC7C983B031A4B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oRz4ydtLca6+HfffYIRv0PCsTm4xKBdYpx85lisMWng="},"power":"1000037","name":null},{"address":"BEEE6DB44A01D8005CD59904F9AEE12BE9DBA6A3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oYhHHoROhbAIzOuST8Qyua7O611uIr3NT2yyibK5x7Y="},"power":"1000020","name":null},{"address":"88731522401F260D5C253222CF6EF71586A192D3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"m9gm7H1kmxvPzyo5ubgkmqKGQbJFHst9My51FLe2HeM="},"power":"1000009","name":null},{"address":"CD10B5095AC4541972E0C0FDE35A39CF92A040DA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"cPgsoC0NIVUAe42qmzfbrLaznvYZCh1z92Q35D0KZOc="},"power":"990479","name":null},{"address":"469CB700B5C1D9DE8905457AE5A7BD7E3FCB75EA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"PRXS/zL6clsHN2Srl49mRV+W+eL/g7DgY1MG8eu/8K8="},"power":"990174","name":null},{"address":"5769499735A69F335467D419764A69FAFFE29607","pub_key":{"type":"tendermint/PubKeyEd25519","value":"HnEoblS3w9JRSFqXX/2RCippz7tQD/ShYts+tGHoSBM="},"power":"980425","name":null},{"address":"113388853F11E28044A4ED3B11DF745D00D709CD","pub_key":{"type":"tendermint/PubKeyEd25519","value":"61X0w6XUKooaWi4FYzZghd6kJDIFFifK+EpMJWTHSaI="},"power":"509044","name":null},{"address":"D92E949735CFD958FE2E1EA2F7ACCFBC981059B4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ba80uJncfcmlWoFM/AlzMI6Mut7SyDJTpbNV8kwMXl0="},"power":"502561","name":null},{"address":"F271741FA4B163F3204A5BC2570E74F146AA33D9","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Y0SMVwQK9FHbFi7ykZSwah3TG56saeI0uTMXYvyb9dY="},"power":"501737","name":null},{"address":"B790E6ABE58DB7122F81FF52F7B2183AEEC41D6C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"EiSlqpx/n3VMPFtuTAa++axavjZ9yZzlTa3HtCz+lsI="},"power":"501375","name":null},{"address":"924090B949A3A3A43AEE52C4DAE342332C57B684","pub_key":{"type":"tendermint/PubKeyEd25519","value":"cseuElK5A+VoeuKMvrm3AOTuzII46kf083lVMGpRLDo="},"power":"501271","name":null},{"address":"6BB3BE6A41922712373BBCBA647B3A1486CF56B7","pub_key":{"type":"tendermint/PubKeyEd25519","value":"QfqtiQS1sJXJKLIPYSoHTL1NtSfwm933fD1wOqgBxJI="},"power":"501058","name":null},{"address":"C8E66B2FB198544C40058986AFF7BFD9B1FD6442","pub_key":{"type":"tendermint/PubKeyEd25519","value":"h5bxQwVfFqo0YqTMKMIn0Kmm5SR8QsYGps/x9CUtbFI="},"power":"501050","name":null},{"address":"9AD672973AF0C5A606F1D2EE0F261AF5DD61DACE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"y1EE0IXUX+xqvd08toyjMekOX1kNMzEmY2FLNe00sUg="},"power":"500841","name":null},{"address":"3511B17D31452B433E1392C75CC1D9A57FB769EE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Wblv9P9x2vItElCo/uoJGPVcB+bMOExuq+fE8+rVfrk="},"power":"500423","name":null},{"address":"6C6F50C1E0E2A69BFC2AB7DABE0A3F091D17E666","pub_key":{"type":"tendermint/PubKeyEd25519","value":"N8ncRVbJpyffC98xo+mxWdqm/GamCJkVTB0YeM8gwkg="},"power":"500401","name":null},{"address":"0FDB40C1B3ED17E49061B1F577393E5B91323C99","pub_key":{"type":"tendermint/PubKeyEd25519","value":"GzwPkML4PmjOdcTvr2pm6rjO7cBHrckZR3oe2w4E+FA="},"power":"500018","name":null},{"address":"D5CABF35D9C01401B32540F938BE59FA2B044067","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Bcsbz2eNu1HWCUW9IkzHCZ6ACMxf/sepz12Q8YCdUDM="},"power":"500014","name":null},{"address":"D6DFC3CD8487061C9612E5E42924FC4E5F622E23","pub_key":{"type":"tendermint/PubKeyEd25519","value":"tF609cLwhEnpi3W93lYIxE1sG/VLbvFKRX0wOzAQxeg="},"power":"500009","name":null},{"address":"F17C3F91E8237C9AE2806625904E8639AC9A3EA7","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gmdjSSfvgwXEAJ7CEMDH0Tv+cQSEFujwSIFdR87tWZA="},"power":"500006","name":null},{"address":"2A8FB5C0567D3031B6A26243BF9F3D04E706548D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"MJlbI1M3aILcOMSigyPMolCpjfQPzEsagrtZTN+9z6E="},"power":"500005","name":null},{"address":"1FEECDA6D9268908A1F84093F0F888F2F752A212","pub_key":{"type":"tendermint/PubKeyEd25519","value":"DE8/atJOsW6TA3iDRklz5DdI8j3Tx95o0nOhwkbkvBQ="},"power":"500001","name":null},{"address":"2B4F222E08213F7F6839E0B2D85C0F56675BD2AB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Zv4/6wZv5pwxuovxaC72oHNW0TAfiH/N+vsilZfiyHc="},"power":"500001","name":null},{"address":"C97A18C41B44DFC2F5FA1FCF8BC1BCFF5E649AE8","pub_key":{"type":"tendermint/PubKeyEd25519","value":"vYKrsdaWTO7YnMgWoUGWKO+A3XwgvXYoB+HNVjBkWAA="},"power":"500001","name":null},{"address":"E5183117268691950E77D53340C23857662CC908","pub_key":{"type":"tendermint/PubKeyEd25519","value":"4k08zQEeKnu5auA0Zp3h5xfNfS6K5LfcN0vnAhNiyz8="},"power":"500001","name":null},{"address":"EF8D6E39A9AA29C04D9D4F0F43EDAD5AB06F56F3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"8yHvjPOugBmpP/D0FOfdpQ6oyiymtS1J+U3lNC/d/2U="},"power":"500001","name":null},{"address":"E01B694AFE5D64691341E931A80ACF9D95E6C8C6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"w5YcK+X1Uv6NVRKzY+4qaSw+Zum8CNDVC0+ip0NpQ5s="},"power":"496178","name":null},{"address":"633744F3BE877E6DF590E72E99425BA653156B93","pub_key":{"type":"tendermint/PubKeyEd25519","value":"rD+6Hqi0NsOsZgsjRAP2BbNtxWcieiDmmh3tng63xDQ="},"power":"495995","name":null},{"address":"6A152D73CD9146A9C1DD4CF9FEF636E2235ECB7E","pub_key":{"type":"tendermint/PubKeyEd25519","value":"XuXuQxuSJIdpW49/wAalXxyjvuV1aGlamnpg+PDyu/A="},"power":"476704","name":null},{"address":"CD34D386E534320153E1A3B02DEFB4CE0773E462","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ps7NCfnD+Nkvkgp8mtnh1S57i5OvVKymdrW1RDktbHk="},"power":"201075","name":null},{"address":"A601B7BCB5172E302329CF3DB6B0E975C8A21D10","pub_key":{"type":"tendermint/PubKeyEd25519","value":"wXe92Kj6b2uv5WP2yMffYDJ7naD3T08jneI8tQuohIM="},"power":"107519","name":null},{"address":"CBA82E0DF6C639D320AC0A421238F6EF93373C94","pub_key":{"type":"tendermint/PubKeyEd25519","value":"qgVzfy4FKDxIrJ/S0a31SHRL1OJZzsxkGMVEW8flsAs="},"power":"105245","name":null},{"address":"0D6EA92C96F4DA14C40B1CA7E2D82A811C9B2196","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Dq8TpiZCrf3fzg/sbMm6Ae5Ty3V1WPEtf1lKqFXVBU8="},"power":"102441","name":null},{"address":"4A3918A6D02D25290B243A86618071374FADD87B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"nuKCeeyYPNP/AwbavdBDum3sB8I7D4TCC4sFbPp7MPQ="},"power":"100448","name":null},{"address":"7BCC38AF8F5494F000D2B7B89EEB9D67B14A0F3F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"XB08MBTE4Rsf3/11MNd+vtdzv0xTvKzGc+7/28Z4En4="},"power":"100370","name":null},{"address":"8536E9166685E936CAB4FBE1F3588F65623E9E81","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7CT5oKkYGXFByTi8glX/46KCivpVffTBvic6gQL61G0="},"power":"100301","name":null},{"address":"DC40C623F0EE6A10CC1E9134E9ADB955EDD319CA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oJEFTe9oP7psA7onwhzs/17uEYyVi0FDqEZs2/9mGzM="},"power":"100226","name":null},{"address":"2131A959A819C085AFA86E560D5EC0DF1D632827","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Tac4dLmlfr+reh8jMPLQTGXYUBvY1cp1NtN2y1zDuDA="},"power":"100215","name":null},{"address":"A09C4BDCBE3718342A27BD9D420FD14C703C9965","pub_key":{"type":"tendermint/PubKeyEd25519","value":"g/lPk5YCZBxUxlLNgf5qzQN//wwNhIE9HH9w3QX1pMA="},"power":"100162","name":null},{"address":"F7A4EEF357935737058F08804DE4DD03144E960D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"yfV2cDweDavOEDVNWtOYuHcwONDP4jyC/ZG8TUruRD4="},"power":"100136","name":null},{"address":"0A957E96258B8BC5669C9A4DA146532C93E99242","pub_key":{"type":"tendermint/PubKeyEd25519","value":"dJdeXyHrKwqKAboLkSfsmvdQ+WRfYQTz+DbJQDeIFIs="},"power":"100130","name":null},{"address":"B07503589534AAAAD60836B33245410AD11CCEB9","pub_key":{"type":"tendermint/PubKeyEd25519","value":"NVy8f5VLbLWBLrnWMeP+sIkt0iVW4Q3ESepiMx0+j4E="},"power":"100125","name":null},{"address":"5A806CC33FC21BCF9F2F47BE23B6586E04DED0D1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"DP6+z/+64vbsAOx3O8Ej+C9iA572eU5nxlUfGoMB89M="},"power":"100121","name":null},{"address":"967B6B5C64615DEB574D88C1F07F23F77E6E7EBA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ZhjOncfNrailm0sDSE0Om3wqYKL5w+QwBowGnkwzBrA="},"power":"100105","name":null},{"address":"2DC2EF8D1059A7A90E9D4AD35DC8F4F8CD7EB772","pub_key":{"type":"tendermint/PubKeyEd25519","value":"lwSHuhiiooJGDeqHgh/cFoUudQv0zloyeiz400kyv8s="},"power":"100100","name":null},{"address":"F6D5482C2405A9844A1EB215148387AD18800D32","pub_key":{"type":"tendermint/PubKeyEd25519","value":"MwxKwbDR+Pfj2kb8e/mnRy7gLw4n2oJA4qe/E8K6A5E="},"power":"100085","name":null},{"address":"473FB7626E52E54BD406A255DBA3B1822F8FC2EA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"3IevyShLKCWeb5joXQjcpPDsvQWnk7bbHLqCd1td7sE="},"power":"100050","name":null},{"address":"50922F9E58F64B3A219887F67117E4CF714AF490","pub_key":{"type":"tendermint/PubKeyEd25519","value":"95WzrdnBvJzBBrOPjORQM0u/70LJnpyvZha6XAvS+T8="},"power":"100048","name":null},{"address":"E5C8264B472C5BD93BD9CA9CE99C221DE14B7EFB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7d0Y9SKn6bfYtn1J9buGsXImkkPHl/bQX8gI7J6Grjk="},"power":"100045","name":null},{"address":"FE6AE5C0EE214D1A1199387B06F7783F66DBC09B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"kWIFV6puc+0TvyMPwreUkcAJFHANXbWoLGcTJEDLQPQ="},"power":"100014","name":null},{"address":"26EFB42C96DBFA42D740333C33E2713AA050FA77","pub_key":{"type":"tendermint/PubKeyEd25519","value":"9FusyXhw+gECqAjvHefpCpSS+KQ/fDltXWFy+5HfPcE="},"power":"100011","name":null},{"address":"D87DA6AD5B598E723EE3A03BE0A6F9AB07EB0E01","pub_key":{"type":"tendermint/PubKeyEd25519","value":"lwJhFD9crCT0jEcZi7TXYGo5/tLfRrFGb9C5EYDlHRo="},"power":"100011","name":null},{"address":"E23A9173DF68A8BE51650807E55104E6101CA7CB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"WCwJZKhAwYmOH4Eo5TXvsS9W8KqEx1Oi8mj/gfyuQic="},"power":"100011","name":null},{"address":"9E9F1F203A5AA77340B4BCE0472C3C24D3A061B3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"sJQZYhdp6x/l6MQ40Pj2880J6Q/t3433EZglkk1yYaA="},"power":"100010","name":null}],"proposer":null,"total_voting_power":"511862423"},"provider":"726bc8d260387cf56ecfad3a6bf6fecd903e18a2"} -------------------------------------------------------------------------------- /examples/tendermint/src/files/block_2279130.json: -------------------------------------------------------------------------------- 1 | {"signed_header":{"header":{"version":{"block":"11","app":"1"},"chain_id":"mocha-4","height":"2279130","time":"2024-07-16T21:27:30.456198169Z","last_block_id":{"hash":"6CC4DB10A5D83E5635518FB0406BCDE908F7CF24A8D8FF25564A8E88E197A827","parts":{"total":11,"hash":"18A28290599679F2DEAA656F63419F1F0149E1CD9E8E351B8BC7DAB1F11E1346"}},"last_commit_hash":"2743E7BA347689BA49023C41E74C38FDDDC392F6D9EDAE701CB69825261D0013","data_hash":"8709D5ABEAA65D170726E12B038A583062443192C83C72259FF1688C5350866B","validators_hash":"761B52540AA384D2B2CEB9D31F1619DB75498E9EE162949E30EFE10D14BC405A","next_validators_hash":"761B52540AA384D2B2CEB9D31F1619DB75498E9EE162949E30EFE10D14BC405A","consensus_hash":"C0B6A634B72AE9687EA53B6D277A73ABA1386BA3CFC6D0F26963602F7F6FFCD6","app_hash":"73EE45EA6D30D5DF58D0EFA2CFAF04026EE7788FF2BD83E2387A4D642007D3F1","last_results_hash":"39D9A53FBF478B90F2ECD3B72EB0B7179B433823FD85ECC34D1FDA5F397F5AA6","evidence_hash":"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855","proposer_address":"4A3918A6D02D25290B243A86618071374FADD87B"},"commit":{"height":"2279130","round":0,"block_id":{"hash":"43BC5267791ADBA07AF7FFF36F91173B65E07F342E2D8EB69BEA7C11CA6D9470","parts":{"total":12,"hash":"D00584AABC61C2C37E86E8624DB8C3BDEB00349BCF69CB6881349776C39A65D5"}},"signatures":[{"block_id_flag":2,"validator_address":"7619BFC85B72E319BF414A784D4DE40EE9B92C16","timestamp":"2024-07-16T21:27:42.817717878Z","signature":"RuJSXCpXQbRfv3LnO7y7aNWFIKSa7kWN1rW+Mox7za9OZfmxPLCsEyacDh4h0gmPklP1xILIdpBPSqfZfZxkAQ=="},{"block_id_flag":2,"validator_address":"762CBA617226A799D898F134DD12661C7F1129EB","timestamp":"2024-07-16T21:27:42.615806652Z","signature":"hDZCIxLc+Z7jI0rMhOEoOxCXZb4N4xwtHFc8AsyA58ZT7gq3SdLCGtF/l6BlMNrFt05XbN1nbYLCI0DOtlJfDg=="},{"block_id_flag":2,"validator_address":"597944BC0AEDFA1D9DA7C2098FB05D7B6A2D4946","timestamp":"2024-07-16T21:27:42.650594215Z","signature":"rEkVGnXg2wqqnCJedlxmJ9g7Bk/H4cX8A+bpKnTkqIhF8I/DuRIlAeMVkYL82KoQME3YzTHVt37l0WfnIHEtCA=="},{"block_id_flag":2,"validator_address":"7744C8CE6E06E67AB9721696AA752B951C93E9E0","timestamp":"2024-07-16T21:27:42.638326721Z","signature":"8EeiWtzYiJ/UsJ+bEIrTlVKMXiTpNTJIo/947LdJC3VFOvH/VoI33upf5ogUD/Ffwkx8TNlQNTUJbxPlcjPtDQ=="},{"block_id_flag":2,"validator_address":"8FBEF0DBAAE51D918F9ABFD96653F4932171870E","timestamp":"2024-07-16T21:27:42.14850095Z","signature":"ux17F/FGhjyEXaoGprvRKaxiJ5F9sLzdjdHLuqwKzpDiONu2q5Lc/tworX5TG6LXmV6+vkLFGEWa07LlAWwECQ=="},{"block_id_flag":2,"validator_address":"0B76107110A486E8767FA1997EA0C4B40B7851AF","timestamp":"2024-07-16T21:27:42.68464798Z","signature":"NJh51JhEtOcqNBW8uzCOAU6Qn2/jtrw5Z7xjzAIK6u/Jd8DQO0aomxUj9fgvgZQ9ocy/QrKXxi3gxnpGNr3iAw=="},{"block_id_flag":2,"validator_address":"D6E25B7E6E6C96D1B7135CF41FF03DF84DE2BA2C","timestamp":"2024-07-16T21:27:42.561172825Z","signature":"MLoyaTTbXNAk55OxlmPj5RceNVmPHpmVNjt5b2CrMLF682niaaSDwN+xChZUTsl999Vt/SHy4ZMjaKHIcRIgDA=="},{"block_id_flag":2,"validator_address":"59158C19ED4DF57D59B54F80B07C0AFB37DAFF0D","timestamp":"2024-07-16T21:27:42.679828009Z","signature":"/FhVaTEyuvSDw1D3NR9e97YzUt1DK3g8XGBKZA1OJjvRV9+l8+NjYXXeCm8PSiu7Kl++tDMj5r9N81SaSstlBg=="},{"block_id_flag":2,"validator_address":"91AB27CC321622AC4DC778D2F1FE367CFADAC665","timestamp":"2024-07-16T21:27:42.637123387Z","signature":"SK4F3v96HJa20oLJq7M9tx7tOav8HI9qOvzoZQUaevZgk7SjYfXRMm62KljAuACmKtUMBk0qoiCDrkDcvhi7Dw=="},{"block_id_flag":2,"validator_address":"C822706DA92B375B6793FEC5FCAD04BB5AFE142A","timestamp":"2024-07-16T21:27:42.662381061Z","signature":"lZqtwUH+qqPJ4DZ9dNUDJYXbq5hckrRnCyygSPmp7JVK8V2DOQ3XxEkNdXrKXqsQLZjFkD1bWWaToZ1kBnpWCA=="},{"block_id_flag":2,"validator_address":"FF73CE6FE36E313684457C855D7D25198B87C8A6","timestamp":"2024-07-16T21:27:42.677602664Z","signature":"EfiQNIuAdBs/S3YjAAqeyahHuNmdYu+QSR0h0GloX9N6SjjXKHylOId+f7axO5PQZ1slRkloPkl5NH3dXb3uCw=="},{"block_id_flag":2,"validator_address":"E1F1D0F31F8DB86B829C8502AD1F6F1576C08A6D","timestamp":"2024-07-16T21:27:42.694508191Z","signature":"zaqYg5nbQmhES6zgFgjDyfel5frzZwogkcCNAnXsvbqPL5ASEIKus/jdSJIE4vpz+1ED+V7MBLBkkvdoAoQ4AA=="},{"block_id_flag":2,"validator_address":"13E610C20C1C6623A3C32AC058E9F8E76BBEEC16","timestamp":"2024-07-16T21:27:42.813717174Z","signature":"lRRzcN3tsomu1DwL6HVHPDOC4/FNks2xO/EI9zQrt3q1UObVeSMBuU9R4SiznHgqAtZQt7/EsF1Ql0wY2jjmDg=="},{"block_id_flag":2,"validator_address":"EE927F115AD4FD4BC131CA311D332ADDAC62CCAC","timestamp":"2024-07-16T21:27:42.842816403Z","signature":"7+KuOFHmW0HNhXg/UYBe/+UGo0pRpRa9QqvC4nWoY0ACo3PO2CcPVblX/60nTSC/LPo3Qxhbepy1wVe0Pua2CA=="},{"block_id_flag":2,"validator_address":"97C24BFDC996F0BF40FDDA96CC22D417D0B8D0BA","timestamp":"2024-07-16T21:27:42.737936119Z","signature":"JLjF+r/ES3e2xdpUnI3lAZ+cJ2jdwhxYXZq8a1CBRfqhfCrHGZGGM5TpjGMXAsGzl/FpCSG1INF4v+f3klCXDg=="},{"block_id_flag":2,"validator_address":"9079C978817165244C051EFCE5AD163AAA905C6F","timestamp":"2024-07-16T21:27:42.71952497Z","signature":"VIKo2y/y786DDl4S08ANsv7SN2iOGuGXXHhVay+p6Htmxj+9Zy1w6xLAnO5CuGyXI4iT7MTs5AAW+xkHiY11Bw=="},{"block_id_flag":2,"validator_address":"7EC8ADD79B454AC37625077453DF49FAC1BFD7E1","timestamp":"2024-07-16T21:27:42.802561542Z","signature":"SqY1Zx/qbtexqppYhvlFR49bFWfqrF9Pp0DUPtkJ1ppmXGpxqMFTDlGkvqSMVpg+85Ny2oNqTLOLozQMtDLXAQ=="},{"block_id_flag":2,"validator_address":"11637B088406D4F3EFF52F2230C8068D230C7611","timestamp":"2024-07-16T21:27:42.634522027Z","signature":"r/Di5BYzEeRouJQsogaaNQLsvgvplmQUe+WGCyGQJUi5cJBAINgSSHZftv1iBqt3JP39e4xYAXxzCaolg/mXBg=="},{"block_id_flag":2,"validator_address":"52E55D04CCD1C78D4FC520FE17AE4584FA2053A8","timestamp":"2024-07-16T21:27:42.661924157Z","signature":"gMmlHiJh873Mzqt2RiKVJwPz8jmvlDuGZEkj1V8tT2mjnNwQhfS/qHpOsqO/oO2B12oF9XkOK54wKohmfyNRAw=="},{"block_id_flag":2,"validator_address":"BB408FA902A7B6A938C788957B2A874153261EC5","timestamp":"2024-07-16T21:27:42.758642629Z","signature":"97+chYE68FLap/IgJ8DAIP2544sSE73hBd+ptrRsgyMAu3KR9It1YlQri1S6MEp/KDpud98AssMJuf76E1X3BQ=="},{"block_id_flag":2,"validator_address":"8C55B13AEE44C518E363DD328E2AB451D6569EAC","timestamp":"2024-07-16T21:27:42.630780569Z","signature":"dzk2o22xe6jYvvWsTpr5aqgjw+hITzuPrhSxEMa3qWEfqoy2itVBO0Q9Eq5K43fE1/pxO9o9lO5AE2OmoaNBBQ=="},{"block_id_flag":2,"validator_address":"F005689992F73B55B537461AC0AE0DF9694B36CF","timestamp":"2024-07-16T21:27:42.746670619Z","signature":"iilRB5G7zFoqbAepzLwvGI+O5+pbM4fk76m07JvQ3zluNeOAqwjW4UlouyNYOQmbE8UbJ6tqq0gIiRoyrhRjBw=="},{"block_id_flag":2,"validator_address":"01458B61F0D7DE6E90798FE8C370413D718EB34C","timestamp":"2024-07-16T21:27:42.845158495Z","signature":"TNqwHE3f/0qeb1Lcah6ZerIL5s07oZQWjz/iAPvwgxeJEktfvH7c+0TUJsX+C8QRJBLHAhv1OdWTn1P8XcHqBA=="},{"block_id_flag":2,"validator_address":"5AF159B8269B974F9274DAEA0F778ADD3B12707D","timestamp":"2024-07-16T21:27:42.809635737Z","signature":"cJwHa3k0a8YrDiaJWUsg1P8+IhuO6pblcUpTdP6CaJ0ZpF0K4mHWVkwfhEQ7N5GU1mGlqpIWtGUKYP4wBnRVDQ=="},{"block_id_flag":2,"validator_address":"98271A1B3690F4EC867C760DBCA3754684F485AC","timestamp":"2024-07-16T21:27:42.604498661Z","signature":"SjcFdtYEti7s6Nrwkd46MP68lHjk9EpiCMF+GoEHT3I4c6mXDfXA8KupBQ9dk6dMEgBiWhBEQDtj6Lm2kcafDg=="},{"block_id_flag":2,"validator_address":"969B1B7DCAFA313131620AC163E3A09A03B49BE6","timestamp":"2024-07-16T21:27:42.71762574Z","signature":"FFXZM3CyxS9cdVQma+w4hL4PpZLzgkyWhDbBcmhpjSM5PyP0moISFzyk4P/ZbhLxHoOGTqMwMZ92yTWoNWkNDA=="},{"block_id_flag":2,"validator_address":"4D5B4C1A687B13AAD96F9CED90F006DFF03CEC45","timestamp":"2024-07-16T21:27:42.834482154Z","signature":"q2YTYx5174wOyb8PdfuJoIYcww8/+RKUwLQFhnhdpZkf2Nqa8a40z4vN2tKye1Uc1JjFNhPyWwQ4C2zf/QuLBg=="},{"block_id_flag":2,"validator_address":"3BFE2EF588102F19F40952DDDD3A89BA90D7351F","timestamp":"2024-07-16T21:27:42.581614043Z","signature":"gleFu52vwH8NWA0zkk+t5dJgQgcpkMSPeXy+ndu9SOaGN5OfNEfrF25KcXiMsJe5ju+yC6UtA+zj+sSAinoiBQ=="},{"block_id_flag":2,"validator_address":"28B6061D5E269B3585F019E1748E32CA9F34E739","timestamp":"2024-07-16T21:27:42.805998384Z","signature":"zmam6GpEPW/Zjyq7vsKHReic4AGfXHCbS9DaxwcRNOPcxKSCWmK8VkpeutqI90n2oVEN2eYucL0E2taWb3wNBg=="},{"block_id_flag":2,"validator_address":"C8C62F1CF89BF5E852E252ED38CBA4A64787CF1B","timestamp":"2024-07-16T21:27:42.622604436Z","signature":"HbO7gktREZwnf9XHIgQexHHlng6w24GMtPmxPX+sNxBH+UpA/HoRzsy9BnQP26vtFBE/DIG6YQbBhVzO8tAfBw=="},{"block_id_flag":2,"validator_address":"70A191EF78A0C8B9B69E005A685B064C254B1F33","timestamp":"2024-07-16T21:27:42.817779881Z","signature":"JKem/x3QBFmMfiSvM6nR3gVZyOFnG9TJbbfnRmunuUWWd5c6kTS7aQ8fVZBoTFMxrp8PBsjDE3lwW4RGpfryAQ=="},{"block_id_flag":2,"validator_address":"38CECDD91DAE3D8F536C080742A69FEBB6EFDBFF","timestamp":"2024-07-16T21:27:42.739659876Z","signature":"XQqpQ8rV6nlfJj8Pf0cNpCTqU6mxOiTWTL1Q34QgUWhvRkW6AeywwBXumgCcTIztpqaTZ1qs4KLCGwVt4ojEDg=="},{"block_id_flag":2,"validator_address":"0DC59C626E4753D889DE2D3262A9A613E754668A","timestamp":"2024-07-16T21:27:42.701319253Z","signature":"z6LMv/Zq81TE7W6WRP1kfJL/CnQOMGzwtkXI3nL2W+nDdn29dc5y74BBwNDs5VYZ3148aAuJQl/+JvnJp/4FDA=="},{"block_id_flag":2,"validator_address":"1E7BA20AACF7EF2CDEA41CDFF8DCEDFBCF12F363","timestamp":"2024-07-16T21:27:42.773553762Z","signature":"2plDZ6TBtlsCnz8JH4XhKauvScQ70oqfZo3YaevIL/1UCE9uSz9Zq+Uax/IT905i8QTvYO0mdh2zrAymRARmDQ=="},{"block_id_flag":2,"validator_address":"346001263089D83465A72C6DB5EFBC32359111A3","timestamp":"2024-07-16T21:27:42.627266683Z","signature":"F7ruz20nyGDBKRkAAWRMW0t+LwzzJS4sFFn6DszJjPHgQIsommbL6539eLROAKo+Rm9W9PyYFUSedki8+UzLAw=="},{"block_id_flag":2,"validator_address":"2F334E80D3EA0AE019D6498D8DD7E0EC472E5424","timestamp":"2024-07-16T21:27:42.671734765Z","signature":"yofG9qeJcsq3EbPuZ9cxZhxhUDiAfBdmt5XbnwqU9RRQj7ICnZRgFxKEUId7k0J1Ak5ZfSQmZFgZ4kGF7I8FBw=="},{"block_id_flag":2,"validator_address":"80726DCD4E975716843F213C7E5A36400ABCFDFE","timestamp":"2024-07-16T21:27:42.594059674Z","signature":"whFdl7B67q4UJS+Nt+Ash2zVKxD7qWpzLESEXk3qLwifVqwpwYmb27OwEM3oVSvUNc1/vpGYxAQG3uvXMICKCA=="},{"block_id_flag":2,"validator_address":"4520D7FA09B49EA0C0F39E6788E6EB3FD8065690","timestamp":"2024-07-16T21:27:42.949247768Z","signature":"FEtEIWA7oQnksOWaEIS19a2FQeuKZuvQEmOMydGOEiGMgIf8jHw9adz8sKX2AaFU1Rimx8uURngzww2dwQIcAw=="},{"block_id_flag":2,"validator_address":"93CCD84A7302F5676465A1239C2544AD3140D7CB","timestamp":"2024-07-16T21:27:42.669478745Z","signature":"evsikNo9hEkh9heQD1swkYDDJy9l0ymwRidRMvvQtMN5FUCFUiavPUGMHEx7fM5ZwJMC4XmbLGF0PIroylavAA=="},{"block_id_flag":2,"validator_address":"3824438082C68B36ED8F5199155CD78ABBBDA30C","timestamp":"2024-07-16T21:27:42.748229507Z","signature":"k/Lz7ndpG9HuLGheNvg8eweluR9dSCXg3Ppgcx7/uO9T2qQsh1LwTvJyMVF3dvpN9uB4eMeQor5hb6tJZWJtBA=="},{"block_id_flag":2,"validator_address":"9B2FB5ABCB3B0289D03AF5A8577C76D9A37A32D3","timestamp":"2024-07-16T21:27:42.609439287Z","signature":"ro1IPDIx37i0syqiTnzAhkUCNd3G0NsqnKOn1x7OksA6Sg9+REOQbrrY8Y6d9zN/9IELeqCCG50IEiVLjEnkAw=="},{"block_id_flag":2,"validator_address":"87D1611F9BA8ABF12C13B32F90469977B4C94F9A","timestamp":"2024-07-16T21:27:42.616348324Z","signature":"wbsw2f2j2Hd0EvDhtiC/wqS6Tagh7msxHTojW1VCjMI89+pX15D4bkSoYE0DPPEspTWYhoLdQSu7dI29G7YPAQ=="},{"block_id_flag":2,"validator_address":"5E9EE98A3CBD523D0D3C3518048DF8C322BB67D5","timestamp":"2024-07-16T21:27:42.662591316Z","signature":"OPol6GuVBUKmdKqmTu1W+Rg11L8G7trmlcReK4uy+/TCdW2QEFk0WBJjXXKa7Ii9m66EIijp38obghR8wPmtBQ=="},{"block_id_flag":2,"validator_address":"E309A8AFFF70D04126D04BB53071B6020580D104","timestamp":"2024-07-16T21:27:42.74684106Z","signature":"5taMTnJreOQS490ODXB73Du26AVtWRPSpwlwwVo6gNUUDCifkobSYGQPdOGvhhRBw8nzFDPdxnRYTqGzjWR1CQ=="},{"block_id_flag":2,"validator_address":"3B0F1CAEEB84A5AF239580FB26D6199CB17CEB3A","timestamp":"2024-07-16T21:27:42.891890438Z","signature":"hK85hrUjzXiaaLsYUi9rkymahw/2JtQvB7JLKVbQUpWX/cEFBHJkeK8eJzDgaVUo9b1sfp1UaSmhe/nqD0lQAg=="},{"block_id_flag":2,"validator_address":"14C590ADD4D238649F2CC7B198B52B8BDB63AC78","timestamp":"2024-07-16T21:27:42.772064321Z","signature":"ToiJ9OWumG7Eog2urV3zWNKbqfEGJypEtZKCxIr6WQ1IxpTxfL/67DtIDb6AnwLwBWbfRQNGBmNT96eU3h95BA=="},{"block_id_flag":2,"validator_address":"682EF7D2FB487050D6AD71173FCC7C983B031A4B","timestamp":"2024-07-16T21:27:42.604920899Z","signature":"TJMhskHGfVxnrXJrGDvdZOE+AaBcSxRkGVYCUr8J/QY/Fy3ss+LmTq26Y2vP4rw1YeMjVImtTiHyedd54xr6AQ=="},{"block_id_flag":2,"validator_address":"BEEE6DB44A01D8005CD59904F9AEE12BE9DBA6A3","timestamp":"2024-07-16T21:27:42.607173997Z","signature":"Y7i80ahnI3jtH+2BSn5GfGpZPC1A2RHZztIwwYQVnMbkHm8cV0Qrz/sGzwWIDIwJGYcUGvucTa9tESNRcTDJDw=="},{"block_id_flag":2,"validator_address":"88731522401F260D5C253222CF6EF71586A192D3","timestamp":"2024-07-16T21:27:42.651391676Z","signature":"aTqiso8PlaTLDuSvLSl8qi+HLg7tBiB42MfGbLzxml6IMb26RxkbYBi7cRaDiIOt6Ma4NR7QxyH+GLc8HgkUDw=="},{"block_id_flag":2,"validator_address":"CD10B5095AC4541972E0C0FDE35A39CF92A040DA","timestamp":"2024-07-16T21:27:42.671710833Z","signature":"9W/yQf1s6aclXiPpgmNHv5JE4WWQghiLgOqcCGfkNzFhv8ShPn3MlmM1GX4fNPPynjsE638R4X++j5nWlmFfAg=="},{"block_id_flag":2,"validator_address":"469CB700B5C1D9DE8905457AE5A7BD7E3FCB75EA","timestamp":"2024-07-16T21:27:42.875372427Z","signature":"RgntpznN562psFOd4Wir/XI1UVwLYxhYRVVrsJcDP7RW4jwSMViaMrHyYKpUYxA/5aduvFvpZyq1zIqJ24QWDw=="},{"block_id_flag":2,"validator_address":"5769499735A69F335467D419764A69FAFFE29607","timestamp":"2024-07-16T21:27:43.332919397Z","signature":"5Lffb765q/KOTCT6gZxP/n5fIV7XJSv/71wAqKmo+InkQqDSnCP+2zZOqnPB4Su3cx0CzTOBV96rfqvZ8UCeCQ=="},{"block_id_flag":2,"validator_address":"113388853F11E28044A4ED3B11DF745D00D709CD","timestamp":"2024-07-16T21:27:42.737115319Z","signature":"qA1ZONgz0NyE8QGDn+9yaxnDTvxQ7BPAVhA+soMJFl2SViumkq0td5T8zLkWxZT5rTks7hEusOeXozwsBN1qAw=="},{"block_id_flag":2,"validator_address":"D92E949735CFD958FE2E1EA2F7ACCFBC981059B4","timestamp":"2024-07-16T21:27:42.691757904Z","signature":"guOnnW5g/ok9PpzK2nCZV/dkAgnYh1f5HOWsAj5Rti7ozCBXD4TNgsGJznLLM5IbGWdtuJnZm5WNlqK7ifNQDg=="},{"block_id_flag":2,"validator_address":"F271741FA4B163F3204A5BC2570E74F146AA33D9","timestamp":"2024-07-16T21:27:42.734542989Z","signature":"hR/3H8f7KVefcLf9obDuDGqrFZ2BvzX9njfCjARJypErmzfEQNnrpXsQ9mcY9FnCU3ayqszc+wWEGJ6tPZlCAg=="},{"block_id_flag":2,"validator_address":"B790E6ABE58DB7122F81FF52F7B2183AEEC41D6C","timestamp":"2024-07-16T21:27:42.607794468Z","signature":"1ZtTjE0U1HVVX/mPIv5ff0EanPZU3MU0NinUUy2T+OGsDANvNmZuU1TQykhV1jhNtgRubgvnh2SrfiG+d58mDQ=="},{"block_id_flag":2,"validator_address":"924090B949A3A3A43AEE52C4DAE342332C57B684","timestamp":"2024-07-16T21:27:42.855378125Z","signature":"pXd0AezBex8E2KWo/1mwA3VaYQN2vo89o5F9nkI4MmJrlBTPzeTw4PnnJ8CF/nlI3o3utt+urKUcjFGVd4CJDA=="},{"block_id_flag":2,"validator_address":"6BB3BE6A41922712373BBCBA647B3A1486CF56B7","timestamp":"2024-07-16T21:27:42.594052739Z","signature":"7SwSyH7DQTE0x39WPG1yUJ/1F5COg5Virx1LpISZj8V8AUsQTqeHBqTVuAbEHnw2y9Y6lqw72f9LpuIs/YXFDw=="},{"block_id_flag":2,"validator_address":"C8E66B2FB198544C40058986AFF7BFD9B1FD6442","timestamp":"2024-07-16T21:27:42.687953664Z","signature":"c2+pSZsP4iLR1/YD4JwzrFjdR8OYub7KtPPbg4+QELXFE8/97UZ9o1WeS1RzRkzw22QVCAIXQJwlDPfu+xk3Cg=="},{"block_id_flag":2,"validator_address":"9AD672973AF0C5A606F1D2EE0F261AF5DD61DACE","timestamp":"2024-07-16T21:27:42.666378122Z","signature":"L6GUOSw7BgF9uIM6w30BtiEv2j/vMIBtgzzkeoJ+SdGEy6l1Jx6vZIJrq2/qb2UhB7uES5i9EIRkSd0tBTiPCw=="},{"block_id_flag":2,"validator_address":"3511B17D31452B433E1392C75CC1D9A57FB769EE","timestamp":"2024-07-16T21:27:42.721239647Z","signature":"UD8osfhMrZuyAhyNvibpxlKT3PUfZMagbWtNvD48mg9iqVtjqW8wgY4as+lMt7rNHVxg5iM9UFXBjMBYud+oAg=="},{"block_id_flag":2,"validator_address":"6C6F50C1E0E2A69BFC2AB7DABE0A3F091D17E666","timestamp":"2024-07-16T21:27:42.66981356Z","signature":"eujyhI9a735LXrpJDc3nX/C3odhYxH/ZQVWxDn982VU+AtDCaSmRMl7d80GDOuOd2p3SM5VnUV6XQZaO94F1Bw=="},{"block_id_flag":2,"validator_address":"0FDB40C1B3ED17E49061B1F577393E5B91323C99","timestamp":"2024-07-16T21:27:42.668263232Z","signature":"kQ5Va5xknuX/Ze9RYie0ceAh6P3zUIAb1C+C0bcCSEBrDS8fvlgvjmpu8lib5KlfLCLf6rOInhfE/QoqDtCiBA=="},{"block_id_flag":2,"validator_address":"D5CABF35D9C01401B32540F938BE59FA2B044067","timestamp":"2024-07-16T21:27:42.697888521Z","signature":"9YACbk66pmlu7pEcZbALzJX4ENeA9migwpwb25zGAb+DTct+zVQ4EZsTQ8zRQKFGCy3tO5APp10ttTB+S49cCg=="},{"block_id_flag":2,"validator_address":"D6DFC3CD8487061C9612E5E42924FC4E5F622E23","timestamp":"2024-07-16T21:27:42.665532751Z","signature":"tsFgo13tIBiQfq2NTUUf1OFXS3kEdd6Loc3EFm/F+GTjeqPMPFyaLdrb3191SnjPcEb1rH7EQRPtsamiPwgyCw=="},{"block_id_flag":2,"validator_address":"F17C3F91E8237C9AE2806625904E8639AC9A3EA7","timestamp":"2024-07-16T21:27:42.679365167Z","signature":"FuH7QQ9kC5fDnHVlmdNZIFe24MSo2EvsNvM0rotgY4byoMNGw5S76R8s/w8eyY4G10v7ME8QL+AoTVyWT29CDw=="},{"block_id_flag":2,"validator_address":"2A8FB5C0567D3031B6A26243BF9F3D04E706548D","timestamp":"2024-07-16T21:27:42.680511146Z","signature":"QOkyatDyzo2H27pga05twnyMJiayEb+Xplkw5h+dJQZj3VDOfewY3R+bxvXSoeuXStlfz2mHbf2gYke+LiLQBw=="},{"block_id_flag":2,"validator_address":"1FEECDA6D9268908A1F84093F0F888F2F752A212","timestamp":"2024-07-16T21:27:42.784005371Z","signature":"vj7WMSuXvirqN2Vv8lB2blrZ+MIS2j6yRtv9I/0zs/pt5/yp+LfAtBOF0ggrG8IqF0x4DGuSkXIvUrbxFrVXBg=="},{"block_id_flag":2,"validator_address":"2B4F222E08213F7F6839E0B2D85C0F56675BD2AB","timestamp":"2024-07-16T21:27:42.733016807Z","signature":"FClvM+Wn1i8HAZqXvhft4wHoSjXgItCUryno6wHXFYCBXkzmsgjgKIW9Vtxdfvb+Pf0CZi5RAIP09wcs5FkOCg=="},{"block_id_flag":2,"validator_address":"C97A18C41B44DFC2F5FA1FCF8BC1BCFF5E649AE8","timestamp":"2024-07-16T21:27:42.693054768Z","signature":"dZhb5AkmCyXaV40Rqrw51EjS0QQyi0KjjLG5z/5q4jfXFNC1koYoczXUbUdkpZz1rAbebl79I9cla11S6quiAg=="},{"block_id_flag":2,"validator_address":"E5183117268691950E77D53340C23857662CC908","timestamp":"2024-07-16T21:27:42.718581508Z","signature":"VPlvr/uklbxSkGk05+/7a/QwNgr8Fk3hMj3gQAdOL/2YWZLQVfV+k5oRruHF7qcHxkwW82ydaef8Ad/IRfTqAg=="},{"block_id_flag":2,"validator_address":"EF8D6E39A9AA29C04D9D4F0F43EDAD5AB06F56F3","timestamp":"2024-07-16T21:27:42.780359836Z","signature":"Pdfdased2NXXjrLUUBvd21GNmrGwJh1djvK4Qwq7PIIEtBcFqXvUU45QL3AymOQYlMfrG728h1MnEFTx3qAHAg=="},{"block_id_flag":3,"validator_address":"E01B694AFE5D64691341E931A80ACF9D95E6C8C6","timestamp":"2024-07-16T21:27:43.00651579Z","signature":"u5iTTItheZiil9S9Wf1uPTDBSiEmJA285R1FiYa/n+b/p+C4FQU2+Tfyas/LcdhIK1DW4F9exgnVVzNqPFyAAQ=="},{"block_id_flag":2,"validator_address":"633744F3BE877E6DF590E72E99425BA653156B93","timestamp":"2024-07-16T21:27:42.69487624Z","signature":"ShpSUl6yzvMYOaMEcqaU1i0ukYmEwbzG+EOpjt/vkxp0POz1gWjvAdPctyw1zJRWD3LQDTGkWEV+p06Vr13cDA=="},{"block_id_flag":2,"validator_address":"6A152D73CD9146A9C1DD4CF9FEF636E2235ECB7E","timestamp":"2024-07-16T21:27:42.605252993Z","signature":"qw4jrVJuhBoRPyQPl9v7ipcoLZEI6i6yBdasXnppnnhdi1tHnh8vsORPAZozDwwvEitFGYd0jlUKEBD1p7IhAg=="},{"block_id_flag":2,"validator_address":"CD34D386E534320153E1A3B02DEFB4CE0773E462","timestamp":"2024-07-16T21:27:42.815040239Z","signature":"cAY37/xfrxZgXAkdexiYS4JK5ba4bL80wLmAKiFvLm8yHt8nrzDZr2qVwTJ8stZWOmKCXlV5ZmQ98IpSNjvKCw=="},{"block_id_flag":2,"validator_address":"A601B7BCB5172E302329CF3DB6B0E975C8A21D10","timestamp":"2024-07-16T21:27:42.718637841Z","signature":"+aeq5mkuWxDlGqzSzYJ0VDdiRggUG9WeykSKnRw8LRcm6GSsOiDF5bJYEmSZZvxRWhmMAJVH+nWegnI5YRdPDQ=="},{"block_id_flag":2,"validator_address":"CBA82E0DF6C639D320AC0A421238F6EF93373C94","timestamp":"2024-07-16T21:27:42.674844126Z","signature":"c/IrK2Waqe+22/i9cJ84Grp6MYxloBy09VCH2o80nL5adl+FRYWZzmNz4dakjeWfgCQ52gBEQh35yy+64Yp5DA=="},{"block_id_flag":2,"validator_address":"0D6EA92C96F4DA14C40B1CA7E2D82A811C9B2196","timestamp":"2024-07-16T21:27:42.8464723Z","signature":"6Jek20gZ+1YeRylo+rquS1LUKKfraYbqKkExpLS7lcGacx4kDLg4qmSaY3+fm5Dmo+fUSNse08D3qj2JmuIeDw=="},{"block_id_flag":2,"validator_address":"4A3918A6D02D25290B243A86618071374FADD87B","timestamp":"2024-07-16T21:27:42.627613636Z","signature":"5j0q5BIdj1sil7nh8eWZe5p0TZ4Go4Dh18P27Ykyi9W0ceLmzupoiGy9dI5h2A8dpysLD30vnieTV0iNPNx4BA=="},{"block_id_flag":2,"validator_address":"7BCC38AF8F5494F000D2B7B89EEB9D67B14A0F3F","timestamp":"2024-07-16T21:27:42.668259078Z","signature":"p3YA4xn9SV5YFVK8NQH7RXoMfEYJn2NFJA0fpYuv1YvT1Z/MmzSyGdvRnJICxGQfRH+TxoAJOCQlv+nqquGpAQ=="},{"block_id_flag":2,"validator_address":"8536E9166685E936CAB4FBE1F3588F65623E9E81","timestamp":"2024-07-16T21:27:42.87798495Z","signature":"liVlEw4yygy3idGY41gIuBzDJrYR/utzLQ3LcAPmrQmnBmtBcoi6aGx1zWcWf52cOeXHSPYMdCPkx8aeCDZNCA=="},{"block_id_flag":2,"validator_address":"DC40C623F0EE6A10CC1E9134E9ADB955EDD319CA","timestamp":"2024-07-16T21:27:43.039405455Z","signature":"ulyBK6y2Q/Rx4FqNaGUjXvv5kWyAW1Yi1DYlzMHjbOehQLkPaDThP5vKyVBCBb7RjKH1BQedRyCEcnhIIwzbDA=="},{"block_id_flag":2,"validator_address":"2131A959A819C085AFA86E560D5EC0DF1D632827","timestamp":"2024-07-16T21:27:42.748584137Z","signature":"VR/MRzaOExmn2okyCrIehx6F5KZ7tyIoQdkVU+X9PzXY0+QOcKKPV0vjLQAbvBjG7COLqmwuJO8OCoLD+92SBA=="},{"block_id_flag":2,"validator_address":"A09C4BDCBE3718342A27BD9D420FD14C703C9965","timestamp":"2024-07-16T21:27:42.633781846Z","signature":"Stz2eNqqpdEoElLoLCoUxKu48XyprThIilLaNdErmttMwhWoemZJMWFIZZ9T1G8gHKCvaNe+7+KHvamVQHPbDQ=="},{"block_id_flag":2,"validator_address":"F7A4EEF357935737058F08804DE4DD03144E960D","timestamp":"2024-07-16T21:27:42.683973642Z","signature":"PbnHGFpVlepTi5X3P/ARUVh+TJoh5aYlExhno14nf8YNg8qvMYmZAlUQgw6UVtJJpCNpf/EFzK7/pajTjpKMCw=="},{"block_id_flag":2,"validator_address":"0A957E96258B8BC5669C9A4DA146532C93E99242","timestamp":"2024-07-16T21:27:42.85109081Z","signature":"AWwilVhEMxDlOPkpR73u4jI6x6+ox9q7zWzmAH4ymdnyio9rm9TqA7R/wUee+lTaeCG0+2pxMs9h0aMaBLP2Dw=="},{"block_id_flag":2,"validator_address":"B07503589534AAAAD60836B33245410AD11CCEB9","timestamp":"2024-07-16T21:27:42.830991037Z","signature":"pjGW/lPycsJyN/uzUbWtJPKdI/nQo6a9mLBxfq7DzXEUFG6xBbr3/4Ne0bkx+c46Z9LhRfDKu604pMZ7A+JZDQ=="},{"block_id_flag":2,"validator_address":"5A806CC33FC21BCF9F2F47BE23B6586E04DED0D1","timestamp":"2024-07-16T21:27:42.755476369Z","signature":"VcJZSqIPlpmfkA7GBtZBTGNGCJuNPDdXelDH5TEZw/5qCLpkPWYnuIye3kYl2gTT/ppY1lXzS3+O9TxeHOrvCg=="},{"block_id_flag":2,"validator_address":"967B6B5C64615DEB574D88C1F07F23F77E6E7EBA","timestamp":"2024-07-16T21:27:42.635871409Z","signature":"NeM/tmLHyBGMDwwCTP9BepmeHlcbGgBdyj1qmJQBIPCZVZgayQR4PKDhBFUl7O2y4fUV0Xcr1aR8YAzi1UFYAQ=="},{"block_id_flag":2,"validator_address":"2DC2EF8D1059A7A90E9D4AD35DC8F4F8CD7EB772","timestamp":"2024-07-16T21:27:42.583667893Z","signature":"wuXfDO8iZB+woqK0Q85sZvyaAqtVduG5mcDctu/yaJzRBJJupG+sonkXOUbu8zJ2nh+I9TmOAKNTZ+flT2UvDw=="},{"block_id_flag":2,"validator_address":"F6D5482C2405A9844A1EB215148387AD18800D32","timestamp":"2024-07-16T21:27:42.679315572Z","signature":"Qm8aCWytX3xgyxR/ure1565Lk/f5dMvchvcbumazjM6ZnWvDZwuiN4t/dkSKnMskI+0hYUB16F5YuUTQFViuCQ=="},{"block_id_flag":2,"validator_address":"473FB7626E52E54BD406A255DBA3B1822F8FC2EA","timestamp":"2024-07-16T21:27:43.042595371Z","signature":"h//ym+Q998/Z4BQS9FU39tJJDQy1xup+IJBl7ooUDFykRwHbA9TJAQpTptr/acfxFrCFpm9wNcPnebK1Wd2pAw=="},{"block_id_flag":2,"validator_address":"50922F9E58F64B3A219887F67117E4CF714AF490","timestamp":"2024-07-16T21:27:42.65924118Z","signature":"vcEq8XYjKtp6gzWkCNplDMINF8/FhVGplpd8Fve731asCQC6L+asO+tqq12QO7kj1HaaikitCrM5aVQQ4/IwCg=="},{"block_id_flag":2,"validator_address":"E5C8264B472C5BD93BD9CA9CE99C221DE14B7EFB","timestamp":"2024-07-16T21:27:42.760201195Z","signature":"f7zAl2BDRtHxUS2cRx1ixwQ1Nz1aMbKTCBtyhYBL6VYojqSBMj/LGirVIylQLfDosIwMPFyosuKh/W5D3zrOAQ=="},{"block_id_flag":2,"validator_address":"FE6AE5C0EE214D1A1199387B06F7783F66DBC09B","timestamp":"2024-07-16T21:27:42.809612062Z","signature":"ZhJEjrDKVHzGurKmNTBsNTKeaEUbM+eYLWvBWe8dyR3P7EQZAZe8QReMnHv4xToXPjtSCCAI77LR97va3RfPCA=="},{"block_id_flag":2,"validator_address":"26EFB42C96DBFA42D740333C33E2713AA050FA77","timestamp":"2024-07-16T21:27:42.661590996Z","signature":"0La8rNK05xdFrpAFCb8K12fei7w9YVrjWLzVo8TIrHxAhzyRd0jgPg7IR0uRhspwyNKYFOC3GXNfGrl66imzDQ=="},{"block_id_flag":2,"validator_address":"D87DA6AD5B598E723EE3A03BE0A6F9AB07EB0E01","timestamp":"2024-07-16T21:27:42.69782694Z","signature":"7hs3yizgokm9Ziw9kIBhfrec2zjRVJL05lwD8X3IkKvOWQoR5z6O6L11IfUido2lnGdxbXWjisChO6rsdTZWBQ=="},{"block_id_flag":2,"validator_address":"E23A9173DF68A8BE51650807E55104E6101CA7CB","timestamp":"2024-07-16T21:27:42.699975594Z","signature":"dXlPPQQLGnitjjjtvy6nAmt+yDbnOP31RTnTFQQZmHaUJ1tkb7AeUcdG2yn8Nt5cj0TezKFJ3JyL2NFydwUzCA=="},{"block_id_flag":2,"validator_address":"9E9F1F203A5AA77340B4BCE0472C3C24D3A061B3","timestamp":"2024-07-16T21:27:42.707716624Z","signature":"D9z5Ive4H0WnIdbPpo9HT2rQ9pUKlWCXfOafcUk1GLouubKF8MzbtNZfIc7oD1cYa9HIWzTx2m0T3u62imHiAQ=="}]}},"validator_set":{"validators":[{"address":"7619BFC85B72E319BF414A784D4DE40EE9B92C16","pub_key":{"type":"tendermint/PubKeyEd25519","value":"l/qNaf4JDxnhP+6Pf+2OSAJYksSIkjyefYCDvZPoahA="},"power":"74052443","name":null},{"address":"762CBA617226A799D898F134DD12661C7F1129EB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"6bdjjKHELaN9colwYy/ad+xh3MUgOVq106ZFucK46LE="},"power":"70555622","name":null},{"address":"597944BC0AEDFA1D9DA7C2098FB05D7B6A2D4946","pub_key":{"type":"tendermint/PubKeyEd25519","value":"njq3L6yQabWMjmh9QjBobp2XOdNytaLPoxFgY2Qd3i8="},"power":"64650439","name":null},{"address":"7744C8CE6E06E67AB9721696AA752B951C93E9E0","pub_key":{"type":"tendermint/PubKeyEd25519","value":"259mAZKhNLksTkJ7qJZf+ZreaPMQtBY7NDeslqPRa9o="},"power":"28001060","name":null},{"address":"8FBEF0DBAAE51D918F9ABFD96653F4932171870E","pub_key":{"type":"tendermint/PubKeyEd25519","value":"J8wAKpZrD9kRbewJDMLQAuYkYNh33PhCg+wcdVcGxIw="},"power":"27553991","name":null},{"address":"0B76107110A486E8767FA1997EA0C4B40B7851AF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"D3wP4IWMZcMt9UHVzFP2J19FDCP/732nvtT/f3CIatQ="},"power":"25298561","name":null},{"address":"D6E25B7E6E6C96D1B7135CF41FF03DF84DE2BA2C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"2XKroLDmwSjW8Z0ZadGF/Co/6Bo5OreNldOxj9fl/Ww="},"power":"25000168","name":null},{"address":"59158C19ED4DF57D59B54F80B07C0AFB37DAFF0D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"3rvnDucNb0+ZSdhfQSzjdFSFiZWUGerlEt4hp1EyHKM="},"power":"25000019","name":null},{"address":"91AB27CC321622AC4DC778D2F1FE367CFADAC665","pub_key":{"type":"tendermint/PubKeyEd25519","value":"UEKnFx4sn4K1aIPxrCu4zE3+Vr4vMGgIeu2iFAQsUH8="},"power":"24714090","name":null},{"address":"C822706DA92B375B6793FEC5FCAD04BB5AFE142A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"i/Zow0IiKpVFWRNxOwN+Fqe9zVj9VY+Pn8+YsuSo9/E="},"power":"4066863","name":null},{"address":"FF73CE6FE36E313684457C855D7D25198B87C8A6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"B6H09N1cxmSXGgqTuAIphe7ESJsCj687/8CYiKBTh4w="},"power":"4050758","name":null},{"address":"E1F1D0F31F8DB86B829C8502AD1F6F1576C08A6D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"4TpozS4FflJmfBg3MYhLw12UeVUSELod0fdnX4tAQgs="},"power":"4048910","name":null},{"address":"13E610C20C1C6623A3C32AC058E9F8E76BBEEC16","pub_key":{"type":"tendermint/PubKeyEd25519","value":"LSpewjhpxXBs00/L2L6DQJabXcSoTzmjqZNTIw5DSCg="},"power":"4048857","name":null},{"address":"EE927F115AD4FD4BC131CA311D332ADDAC62CCAC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"SfFXATPCbIeRUsb9RP+BfdYOH0v7H2aGbPGx1HlR1I0="},"power":"4030218","name":null},{"address":"97C24BFDC996F0BF40FDDA96CC22D417D0B8D0BA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"h5QOLCS5zoZZGk7ZXnaU883fSQAhwneIvP98XcjOte8="},"power":"4023467","name":null},{"address":"9079C978817165244C051EFCE5AD163AAA905C6F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"fODnMY6gDPpnDlAsSQ2b6M5u3gjYNaKq1JL6LBFShzM="},"power":"4009700","name":null},{"address":"7EC8ADD79B454AC37625077453DF49FAC1BFD7E1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"jqBYsfBjFJhudulObGgaMawaeccpj+21nfs+Px6oNIY="},"power":"4002311","name":null},{"address":"11637B088406D4F3EFF52F2230C8068D230C7611","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gcI3uuOTA3ZAVCMsLawhjUt7cZc/EBJeipq9XGavEsg="},"power":"4002024","name":null},{"address":"52E55D04CCD1C78D4FC520FE17AE4584FA2053A8","pub_key":{"type":"tendermint/PubKeyEd25519","value":"wdZ6voJ0Kdh/iJvnzjS9oAiSRtr7A2S4mifU3xFfEXk="},"power":"4001100","name":null},{"address":"BB408FA902A7B6A938C788957B2A874153261EC5","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7rE47Ol0HqaZhnQQqlx5BD8rNGv6yTcRQANXtMY7y4g="},"power":"4001076","name":null},{"address":"8C55B13AEE44C518E363DD328E2AB451D6569EAC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Zj5o33wP8tFPM8qgoC4upsLQvrAc/DGT2J4JG+LhOJ4="},"power":"4001057","name":null},{"address":"F005689992F73B55B537461AC0AE0DF9694B36CF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"KgescyXaO/6YrE/GIuqmFdP0xXTqHUflMAH40HDm/20="},"power":"4000714","name":null},{"address":"01458B61F0D7DE6E90798FE8C370413D718EB34C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"LKwKvQPVTwxwW4UDpyIvGW8Sa9sUdaxhhhVdOigrEyA="},"power":"4000566","name":null},{"address":"5AF159B8269B974F9274DAEA0F778ADD3B12707D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ony9i2cN/h1wawOv0WN6Ql/9lDjDeLgOVCl1fRtuyDI="},"power":"4000504","name":null},{"address":"98271A1B3690F4EC867C760DBCA3754684F485AC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"k3zGTt9YVhopwi6iL+f/XYSj7cZRT+fcPlpwsojLsvg="},"power":"4000472","name":null},{"address":"969B1B7DCAFA313131620AC163E3A09A03B49BE6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"feFjsaWtjmxYp6N+1r/9Lnd4o29skxSJclmebnk49Ao="},"power":"4000469","name":null},{"address":"4D5B4C1A687B13AAD96F9CED90F006DFF03CEC45","pub_key":{"type":"tendermint/PubKeyEd25519","value":"y1QMroz50WA8c/IREfyr7Mm8S75gRCfuk0Ea4fokb4E="},"power":"4000103","name":null},{"address":"3BFE2EF588102F19F40952DDDD3A89BA90D7351F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ps6HB6/GSvuY4fKaszGLXMdHVk38ASzBcGBXeVVeDMo="},"power":"4000028","name":null},{"address":"28B6061D5E269B3585F019E1748E32CA9F34E739","pub_key":{"type":"tendermint/PubKeyEd25519","value":"CIc6ZcjHkdfYEzQqwXZBlYVTl13ZxAinYLLgHszHVgY="},"power":"4000012","name":null},{"address":"C8C62F1CF89BF5E852E252ED38CBA4A64787CF1B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"OKWb9Bw4pE6tfYtZiigi7A8ecGnCVBiJt2h1P7o1a7U="},"power":"4000008","name":null},{"address":"70A191EF78A0C8B9B69E005A685B064C254B1F33","pub_key":{"type":"tendermint/PubKeyEd25519","value":"jjLleXjmBwA66V5gejueapJUSYqb5W+oYSGXy/QLEQk="},"power":"4000007","name":null},{"address":"38CECDD91DAE3D8F536C080742A69FEBB6EFDBFF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"RYrMwDTpJWv67sFVwKtmS+UxlN7hljKGWJqOsutcB1s="},"power":"3991125","name":null},{"address":"0DC59C626E4753D889DE2D3262A9A613E754668A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"1UlN1J5cR4XlFifpA8IA7A+xa3NQ1sJ/1IhssJQ+xEM="},"power":"3961059","name":null},{"address":"1E7BA20AACF7EF2CDEA41CDFF8DCEDFBCF12F363","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ueUh8xh/b1zlBcCgblxHrZ9impMwKOkgyG5P3f1HkjE="},"power":"3961026","name":null},{"address":"346001263089D83465A72C6DB5EFBC32359111A3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"vdnWYA28lp43YkD0e2VExAcYPadTFh/Hpes0O0a4p20="},"power":"3960055","name":null},{"address":"2F334E80D3EA0AE019D6498D8DD7E0EC472E5424","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Fzeq1bTZn9T8Wev9O8/Huzs1nw/OXl0iTepDFRMUko8="},"power":"3960033","name":null},{"address":"80726DCD4E975716843F213C7E5A36400ABCFDFE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"sAD409SvbABZBr0vCmjL6JK6XVQgQP4RM7v/Oiz/f88="},"power":"3957948","name":null},{"address":"4520D7FA09B49EA0C0F39E6788E6EB3FD8065690","pub_key":{"type":"tendermint/PubKeyEd25519","value":"27PwyrHHY/ndxqNrL6SdHomL4hR3JAJ5QMdQFYRlS9I="},"power":"3881201","name":null},{"address":"93CCD84A7302F5676465A1239C2544AD3140D7CB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"a/BQji6ozSlxXzMhtW4RGybuZ81s6tQKSPhO2mGIU4c="},"power":"3000010","name":null},{"address":"3824438082C68B36ED8F5199155CD78ABBBDA30C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"dO71IfBvwwwJ6cEzc9oT1FqU0CUdckJV5F53kDYb22o="},"power":"2000006","name":null},{"address":"9B2FB5ABCB3B0289D03AF5A8577C76D9A37A32D3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"D9iPx6VTH+xeewFFWfnI+a7dM6Y5Y9h/5S4WHro5wUQ="},"power":"1003008","name":null},{"address":"87D1611F9BA8ABF12C13B32F90469977B4C94F9A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"BRvI8B8k+QrDeOgdBNb7mLCbNEMatJNqDyZttdGtQm0="},"power":"1001309","name":null},{"address":"5E9EE98A3CBD523D0D3C3518048DF8C322BB67D5","pub_key":{"type":"tendermint/PubKeyEd25519","value":"VXn41Fko8YeJ3vVvYy/yUtqfVbCv7FTivuDclSrw5Pc="},"power":"1000893","name":null},{"address":"E309A8AFFF70D04126D04BB53071B6020580D104","pub_key":{"type":"tendermint/PubKeyEd25519","value":"J0kLUI0gmvWfWvzoxHaqwzXF3+VARlAIMGCRfB6Yj8A="},"power":"1000210","name":null},{"address":"3B0F1CAEEB84A5AF239580FB26D6199CB17CEB3A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gN5Cln7uU3AVQYzT3QGgggv/3aN+eIewd6m5OfPpkTs="},"power":"1000042","name":null},{"address":"14C590ADD4D238649F2CC7B198B52B8BDB63AC78","pub_key":{"type":"tendermint/PubKeyEd25519","value":"F3RJktKCIoDGEBWXgpDl2+LgNbq5X0rS8eXnY+i3aIY="},"power":"1000038","name":null},{"address":"682EF7D2FB487050D6AD71173FCC7C983B031A4B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oRz4ydtLca6+HfffYIRv0PCsTm4xKBdYpx85lisMWng="},"power":"1000037","name":null},{"address":"BEEE6DB44A01D8005CD59904F9AEE12BE9DBA6A3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oYhHHoROhbAIzOuST8Qyua7O611uIr3NT2yyibK5x7Y="},"power":"1000020","name":null},{"address":"88731522401F260D5C253222CF6EF71586A192D3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"m9gm7H1kmxvPzyo5ubgkmqKGQbJFHst9My51FLe2HeM="},"power":"1000009","name":null},{"address":"CD10B5095AC4541972E0C0FDE35A39CF92A040DA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"cPgsoC0NIVUAe42qmzfbrLaznvYZCh1z92Q35D0KZOc="},"power":"990479","name":null},{"address":"469CB700B5C1D9DE8905457AE5A7BD7E3FCB75EA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"PRXS/zL6clsHN2Srl49mRV+W+eL/g7DgY1MG8eu/8K8="},"power":"990174","name":null},{"address":"5769499735A69F335467D419764A69FAFFE29607","pub_key":{"type":"tendermint/PubKeyEd25519","value":"HnEoblS3w9JRSFqXX/2RCippz7tQD/ShYts+tGHoSBM="},"power":"980425","name":null},{"address":"113388853F11E28044A4ED3B11DF745D00D709CD","pub_key":{"type":"tendermint/PubKeyEd25519","value":"61X0w6XUKooaWi4FYzZghd6kJDIFFifK+EpMJWTHSaI="},"power":"509044","name":null},{"address":"D92E949735CFD958FE2E1EA2F7ACCFBC981059B4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ba80uJncfcmlWoFM/AlzMI6Mut7SyDJTpbNV8kwMXl0="},"power":"502561","name":null},{"address":"F271741FA4B163F3204A5BC2570E74F146AA33D9","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Y0SMVwQK9FHbFi7ykZSwah3TG56saeI0uTMXYvyb9dY="},"power":"501737","name":null},{"address":"B790E6ABE58DB7122F81FF52F7B2183AEEC41D6C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"EiSlqpx/n3VMPFtuTAa++axavjZ9yZzlTa3HtCz+lsI="},"power":"501375","name":null},{"address":"924090B949A3A3A43AEE52C4DAE342332C57B684","pub_key":{"type":"tendermint/PubKeyEd25519","value":"cseuElK5A+VoeuKMvrm3AOTuzII46kf083lVMGpRLDo="},"power":"501271","name":null},{"address":"6BB3BE6A41922712373BBCBA647B3A1486CF56B7","pub_key":{"type":"tendermint/PubKeyEd25519","value":"QfqtiQS1sJXJKLIPYSoHTL1NtSfwm933fD1wOqgBxJI="},"power":"501058","name":null},{"address":"C8E66B2FB198544C40058986AFF7BFD9B1FD6442","pub_key":{"type":"tendermint/PubKeyEd25519","value":"h5bxQwVfFqo0YqTMKMIn0Kmm5SR8QsYGps/x9CUtbFI="},"power":"501050","name":null},{"address":"9AD672973AF0C5A606F1D2EE0F261AF5DD61DACE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"y1EE0IXUX+xqvd08toyjMekOX1kNMzEmY2FLNe00sUg="},"power":"500841","name":null},{"address":"3511B17D31452B433E1392C75CC1D9A57FB769EE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Wblv9P9x2vItElCo/uoJGPVcB+bMOExuq+fE8+rVfrk="},"power":"500423","name":null},{"address":"6C6F50C1E0E2A69BFC2AB7DABE0A3F091D17E666","pub_key":{"type":"tendermint/PubKeyEd25519","value":"N8ncRVbJpyffC98xo+mxWdqm/GamCJkVTB0YeM8gwkg="},"power":"500401","name":null},{"address":"0FDB40C1B3ED17E49061B1F577393E5B91323C99","pub_key":{"type":"tendermint/PubKeyEd25519","value":"GzwPkML4PmjOdcTvr2pm6rjO7cBHrckZR3oe2w4E+FA="},"power":"500018","name":null},{"address":"D5CABF35D9C01401B32540F938BE59FA2B044067","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Bcsbz2eNu1HWCUW9IkzHCZ6ACMxf/sepz12Q8YCdUDM="},"power":"500014","name":null},{"address":"D6DFC3CD8487061C9612E5E42924FC4E5F622E23","pub_key":{"type":"tendermint/PubKeyEd25519","value":"tF609cLwhEnpi3W93lYIxE1sG/VLbvFKRX0wOzAQxeg="},"power":"500009","name":null},{"address":"F17C3F91E8237C9AE2806625904E8639AC9A3EA7","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gmdjSSfvgwXEAJ7CEMDH0Tv+cQSEFujwSIFdR87tWZA="},"power":"500006","name":null},{"address":"2A8FB5C0567D3031B6A26243BF9F3D04E706548D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"MJlbI1M3aILcOMSigyPMolCpjfQPzEsagrtZTN+9z6E="},"power":"500005","name":null},{"address":"1FEECDA6D9268908A1F84093F0F888F2F752A212","pub_key":{"type":"tendermint/PubKeyEd25519","value":"DE8/atJOsW6TA3iDRklz5DdI8j3Tx95o0nOhwkbkvBQ="},"power":"500001","name":null},{"address":"2B4F222E08213F7F6839E0B2D85C0F56675BD2AB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Zv4/6wZv5pwxuovxaC72oHNW0TAfiH/N+vsilZfiyHc="},"power":"500001","name":null},{"address":"C97A18C41B44DFC2F5FA1FCF8BC1BCFF5E649AE8","pub_key":{"type":"tendermint/PubKeyEd25519","value":"vYKrsdaWTO7YnMgWoUGWKO+A3XwgvXYoB+HNVjBkWAA="},"power":"500001","name":null},{"address":"E5183117268691950E77D53340C23857662CC908","pub_key":{"type":"tendermint/PubKeyEd25519","value":"4k08zQEeKnu5auA0Zp3h5xfNfS6K5LfcN0vnAhNiyz8="},"power":"500001","name":null},{"address":"EF8D6E39A9AA29C04D9D4F0F43EDAD5AB06F56F3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"8yHvjPOugBmpP/D0FOfdpQ6oyiymtS1J+U3lNC/d/2U="},"power":"500001","name":null},{"address":"E01B694AFE5D64691341E931A80ACF9D95E6C8C6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"w5YcK+X1Uv6NVRKzY+4qaSw+Zum8CNDVC0+ip0NpQ5s="},"power":"496178","name":null},{"address":"633744F3BE877E6DF590E72E99425BA653156B93","pub_key":{"type":"tendermint/PubKeyEd25519","value":"rD+6Hqi0NsOsZgsjRAP2BbNtxWcieiDmmh3tng63xDQ="},"power":"495995","name":null},{"address":"6A152D73CD9146A9C1DD4CF9FEF636E2235ECB7E","pub_key":{"type":"tendermint/PubKeyEd25519","value":"XuXuQxuSJIdpW49/wAalXxyjvuV1aGlamnpg+PDyu/A="},"power":"476704","name":null},{"address":"CD34D386E534320153E1A3B02DEFB4CE0773E462","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ps7NCfnD+Nkvkgp8mtnh1S57i5OvVKymdrW1RDktbHk="},"power":"201075","name":null},{"address":"A601B7BCB5172E302329CF3DB6B0E975C8A21D10","pub_key":{"type":"tendermint/PubKeyEd25519","value":"wXe92Kj6b2uv5WP2yMffYDJ7naD3T08jneI8tQuohIM="},"power":"107519","name":null},{"address":"CBA82E0DF6C639D320AC0A421238F6EF93373C94","pub_key":{"type":"tendermint/PubKeyEd25519","value":"qgVzfy4FKDxIrJ/S0a31SHRL1OJZzsxkGMVEW8flsAs="},"power":"105245","name":null},{"address":"0D6EA92C96F4DA14C40B1CA7E2D82A811C9B2196","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Dq8TpiZCrf3fzg/sbMm6Ae5Ty3V1WPEtf1lKqFXVBU8="},"power":"102441","name":null},{"address":"4A3918A6D02D25290B243A86618071374FADD87B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"nuKCeeyYPNP/AwbavdBDum3sB8I7D4TCC4sFbPp7MPQ="},"power":"100448","name":null},{"address":"7BCC38AF8F5494F000D2B7B89EEB9D67B14A0F3F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"XB08MBTE4Rsf3/11MNd+vtdzv0xTvKzGc+7/28Z4En4="},"power":"100370","name":null},{"address":"8536E9166685E936CAB4FBE1F3588F65623E9E81","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7CT5oKkYGXFByTi8glX/46KCivpVffTBvic6gQL61G0="},"power":"100301","name":null},{"address":"DC40C623F0EE6A10CC1E9134E9ADB955EDD319CA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oJEFTe9oP7psA7onwhzs/17uEYyVi0FDqEZs2/9mGzM="},"power":"100226","name":null},{"address":"2131A959A819C085AFA86E560D5EC0DF1D632827","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Tac4dLmlfr+reh8jMPLQTGXYUBvY1cp1NtN2y1zDuDA="},"power":"100215","name":null},{"address":"A09C4BDCBE3718342A27BD9D420FD14C703C9965","pub_key":{"type":"tendermint/PubKeyEd25519","value":"g/lPk5YCZBxUxlLNgf5qzQN//wwNhIE9HH9w3QX1pMA="},"power":"100162","name":null},{"address":"F7A4EEF357935737058F08804DE4DD03144E960D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"yfV2cDweDavOEDVNWtOYuHcwONDP4jyC/ZG8TUruRD4="},"power":"100136","name":null},{"address":"0A957E96258B8BC5669C9A4DA146532C93E99242","pub_key":{"type":"tendermint/PubKeyEd25519","value":"dJdeXyHrKwqKAboLkSfsmvdQ+WRfYQTz+DbJQDeIFIs="},"power":"100130","name":null},{"address":"B07503589534AAAAD60836B33245410AD11CCEB9","pub_key":{"type":"tendermint/PubKeyEd25519","value":"NVy8f5VLbLWBLrnWMeP+sIkt0iVW4Q3ESepiMx0+j4E="},"power":"100125","name":null},{"address":"5A806CC33FC21BCF9F2F47BE23B6586E04DED0D1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"DP6+z/+64vbsAOx3O8Ej+C9iA572eU5nxlUfGoMB89M="},"power":"100121","name":null},{"address":"967B6B5C64615DEB574D88C1F07F23F77E6E7EBA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ZhjOncfNrailm0sDSE0Om3wqYKL5w+QwBowGnkwzBrA="},"power":"100105","name":null},{"address":"2DC2EF8D1059A7A90E9D4AD35DC8F4F8CD7EB772","pub_key":{"type":"tendermint/PubKeyEd25519","value":"lwSHuhiiooJGDeqHgh/cFoUudQv0zloyeiz400kyv8s="},"power":"100100","name":null},{"address":"F6D5482C2405A9844A1EB215148387AD18800D32","pub_key":{"type":"tendermint/PubKeyEd25519","value":"MwxKwbDR+Pfj2kb8e/mnRy7gLw4n2oJA4qe/E8K6A5E="},"power":"100085","name":null},{"address":"473FB7626E52E54BD406A255DBA3B1822F8FC2EA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"3IevyShLKCWeb5joXQjcpPDsvQWnk7bbHLqCd1td7sE="},"power":"100050","name":null},{"address":"50922F9E58F64B3A219887F67117E4CF714AF490","pub_key":{"type":"tendermint/PubKeyEd25519","value":"95WzrdnBvJzBBrOPjORQM0u/70LJnpyvZha6XAvS+T8="},"power":"100048","name":null},{"address":"E5C8264B472C5BD93BD9CA9CE99C221DE14B7EFB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7d0Y9SKn6bfYtn1J9buGsXImkkPHl/bQX8gI7J6Grjk="},"power":"100045","name":null},{"address":"FE6AE5C0EE214D1A1199387B06F7783F66DBC09B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"kWIFV6puc+0TvyMPwreUkcAJFHANXbWoLGcTJEDLQPQ="},"power":"100014","name":null},{"address":"26EFB42C96DBFA42D740333C33E2713AA050FA77","pub_key":{"type":"tendermint/PubKeyEd25519","value":"9FusyXhw+gECqAjvHefpCpSS+KQ/fDltXWFy+5HfPcE="},"power":"100011","name":null},{"address":"D87DA6AD5B598E723EE3A03BE0A6F9AB07EB0E01","pub_key":{"type":"tendermint/PubKeyEd25519","value":"lwJhFD9crCT0jEcZi7TXYGo5/tLfRrFGb9C5EYDlHRo="},"power":"100011","name":null},{"address":"E23A9173DF68A8BE51650807E55104E6101CA7CB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"WCwJZKhAwYmOH4Eo5TXvsS9W8KqEx1Oi8mj/gfyuQic="},"power":"100011","name":null},{"address":"9E9F1F203A5AA77340B4BCE0472C3C24D3A061B3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"sJQZYhdp6x/l6MQ40Pj2880J6Q/t3433EZglkk1yYaA="},"power":"100010","name":null}],"proposer":null,"total_voting_power":"511862423"},"next_validator_set":{"validators":[{"address":"7619BFC85B72E319BF414A784D4DE40EE9B92C16","pub_key":{"type":"tendermint/PubKeyEd25519","value":"l/qNaf4JDxnhP+6Pf+2OSAJYksSIkjyefYCDvZPoahA="},"power":"74052443","name":null},{"address":"762CBA617226A799D898F134DD12661C7F1129EB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"6bdjjKHELaN9colwYy/ad+xh3MUgOVq106ZFucK46LE="},"power":"70555622","name":null},{"address":"597944BC0AEDFA1D9DA7C2098FB05D7B6A2D4946","pub_key":{"type":"tendermint/PubKeyEd25519","value":"njq3L6yQabWMjmh9QjBobp2XOdNytaLPoxFgY2Qd3i8="},"power":"64650439","name":null},{"address":"7744C8CE6E06E67AB9721696AA752B951C93E9E0","pub_key":{"type":"tendermint/PubKeyEd25519","value":"259mAZKhNLksTkJ7qJZf+ZreaPMQtBY7NDeslqPRa9o="},"power":"28001060","name":null},{"address":"8FBEF0DBAAE51D918F9ABFD96653F4932171870E","pub_key":{"type":"tendermint/PubKeyEd25519","value":"J8wAKpZrD9kRbewJDMLQAuYkYNh33PhCg+wcdVcGxIw="},"power":"27553991","name":null},{"address":"0B76107110A486E8767FA1997EA0C4B40B7851AF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"D3wP4IWMZcMt9UHVzFP2J19FDCP/732nvtT/f3CIatQ="},"power":"25298561","name":null},{"address":"D6E25B7E6E6C96D1B7135CF41FF03DF84DE2BA2C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"2XKroLDmwSjW8Z0ZadGF/Co/6Bo5OreNldOxj9fl/Ww="},"power":"25000168","name":null},{"address":"59158C19ED4DF57D59B54F80B07C0AFB37DAFF0D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"3rvnDucNb0+ZSdhfQSzjdFSFiZWUGerlEt4hp1EyHKM="},"power":"25000019","name":null},{"address":"91AB27CC321622AC4DC778D2F1FE367CFADAC665","pub_key":{"type":"tendermint/PubKeyEd25519","value":"UEKnFx4sn4K1aIPxrCu4zE3+Vr4vMGgIeu2iFAQsUH8="},"power":"24714090","name":null},{"address":"C822706DA92B375B6793FEC5FCAD04BB5AFE142A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"i/Zow0IiKpVFWRNxOwN+Fqe9zVj9VY+Pn8+YsuSo9/E="},"power":"4066863","name":null},{"address":"FF73CE6FE36E313684457C855D7D25198B87C8A6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"B6H09N1cxmSXGgqTuAIphe7ESJsCj687/8CYiKBTh4w="},"power":"4050758","name":null},{"address":"E1F1D0F31F8DB86B829C8502AD1F6F1576C08A6D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"4TpozS4FflJmfBg3MYhLw12UeVUSELod0fdnX4tAQgs="},"power":"4048910","name":null},{"address":"13E610C20C1C6623A3C32AC058E9F8E76BBEEC16","pub_key":{"type":"tendermint/PubKeyEd25519","value":"LSpewjhpxXBs00/L2L6DQJabXcSoTzmjqZNTIw5DSCg="},"power":"4048857","name":null},{"address":"EE927F115AD4FD4BC131CA311D332ADDAC62CCAC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"SfFXATPCbIeRUsb9RP+BfdYOH0v7H2aGbPGx1HlR1I0="},"power":"4030218","name":null},{"address":"97C24BFDC996F0BF40FDDA96CC22D417D0B8D0BA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"h5QOLCS5zoZZGk7ZXnaU883fSQAhwneIvP98XcjOte8="},"power":"4023467","name":null},{"address":"9079C978817165244C051EFCE5AD163AAA905C6F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"fODnMY6gDPpnDlAsSQ2b6M5u3gjYNaKq1JL6LBFShzM="},"power":"4009700","name":null},{"address":"7EC8ADD79B454AC37625077453DF49FAC1BFD7E1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"jqBYsfBjFJhudulObGgaMawaeccpj+21nfs+Px6oNIY="},"power":"4002311","name":null},{"address":"11637B088406D4F3EFF52F2230C8068D230C7611","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gcI3uuOTA3ZAVCMsLawhjUt7cZc/EBJeipq9XGavEsg="},"power":"4002024","name":null},{"address":"52E55D04CCD1C78D4FC520FE17AE4584FA2053A8","pub_key":{"type":"tendermint/PubKeyEd25519","value":"wdZ6voJ0Kdh/iJvnzjS9oAiSRtr7A2S4mifU3xFfEXk="},"power":"4001100","name":null},{"address":"BB408FA902A7B6A938C788957B2A874153261EC5","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7rE47Ol0HqaZhnQQqlx5BD8rNGv6yTcRQANXtMY7y4g="},"power":"4001076","name":null},{"address":"8C55B13AEE44C518E363DD328E2AB451D6569EAC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Zj5o33wP8tFPM8qgoC4upsLQvrAc/DGT2J4JG+LhOJ4="},"power":"4001057","name":null},{"address":"F005689992F73B55B537461AC0AE0DF9694B36CF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"KgescyXaO/6YrE/GIuqmFdP0xXTqHUflMAH40HDm/20="},"power":"4000714","name":null},{"address":"01458B61F0D7DE6E90798FE8C370413D718EB34C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"LKwKvQPVTwxwW4UDpyIvGW8Sa9sUdaxhhhVdOigrEyA="},"power":"4000566","name":null},{"address":"5AF159B8269B974F9274DAEA0F778ADD3B12707D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ony9i2cN/h1wawOv0WN6Ql/9lDjDeLgOVCl1fRtuyDI="},"power":"4000504","name":null},{"address":"98271A1B3690F4EC867C760DBCA3754684F485AC","pub_key":{"type":"tendermint/PubKeyEd25519","value":"k3zGTt9YVhopwi6iL+f/XYSj7cZRT+fcPlpwsojLsvg="},"power":"4000472","name":null},{"address":"969B1B7DCAFA313131620AC163E3A09A03B49BE6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"feFjsaWtjmxYp6N+1r/9Lnd4o29skxSJclmebnk49Ao="},"power":"4000469","name":null},{"address":"4D5B4C1A687B13AAD96F9CED90F006DFF03CEC45","pub_key":{"type":"tendermint/PubKeyEd25519","value":"y1QMroz50WA8c/IREfyr7Mm8S75gRCfuk0Ea4fokb4E="},"power":"4000103","name":null},{"address":"3BFE2EF588102F19F40952DDDD3A89BA90D7351F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ps6HB6/GSvuY4fKaszGLXMdHVk38ASzBcGBXeVVeDMo="},"power":"4000028","name":null},{"address":"28B6061D5E269B3585F019E1748E32CA9F34E739","pub_key":{"type":"tendermint/PubKeyEd25519","value":"CIc6ZcjHkdfYEzQqwXZBlYVTl13ZxAinYLLgHszHVgY="},"power":"4000012","name":null},{"address":"C8C62F1CF89BF5E852E252ED38CBA4A64787CF1B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"OKWb9Bw4pE6tfYtZiigi7A8ecGnCVBiJt2h1P7o1a7U="},"power":"4000008","name":null},{"address":"70A191EF78A0C8B9B69E005A685B064C254B1F33","pub_key":{"type":"tendermint/PubKeyEd25519","value":"jjLleXjmBwA66V5gejueapJUSYqb5W+oYSGXy/QLEQk="},"power":"4000007","name":null},{"address":"38CECDD91DAE3D8F536C080742A69FEBB6EFDBFF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"RYrMwDTpJWv67sFVwKtmS+UxlN7hljKGWJqOsutcB1s="},"power":"3991125","name":null},{"address":"0DC59C626E4753D889DE2D3262A9A613E754668A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"1UlN1J5cR4XlFifpA8IA7A+xa3NQ1sJ/1IhssJQ+xEM="},"power":"3961059","name":null},{"address":"1E7BA20AACF7EF2CDEA41CDFF8DCEDFBCF12F363","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ueUh8xh/b1zlBcCgblxHrZ9impMwKOkgyG5P3f1HkjE="},"power":"3961026","name":null},{"address":"346001263089D83465A72C6DB5EFBC32359111A3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"vdnWYA28lp43YkD0e2VExAcYPadTFh/Hpes0O0a4p20="},"power":"3960055","name":null},{"address":"2F334E80D3EA0AE019D6498D8DD7E0EC472E5424","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Fzeq1bTZn9T8Wev9O8/Huzs1nw/OXl0iTepDFRMUko8="},"power":"3960033","name":null},{"address":"80726DCD4E975716843F213C7E5A36400ABCFDFE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"sAD409SvbABZBr0vCmjL6JK6XVQgQP4RM7v/Oiz/f88="},"power":"3957948","name":null},{"address":"4520D7FA09B49EA0C0F39E6788E6EB3FD8065690","pub_key":{"type":"tendermint/PubKeyEd25519","value":"27PwyrHHY/ndxqNrL6SdHomL4hR3JAJ5QMdQFYRlS9I="},"power":"3881201","name":null},{"address":"93CCD84A7302F5676465A1239C2544AD3140D7CB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"a/BQji6ozSlxXzMhtW4RGybuZ81s6tQKSPhO2mGIU4c="},"power":"3000010","name":null},{"address":"3824438082C68B36ED8F5199155CD78ABBBDA30C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"dO71IfBvwwwJ6cEzc9oT1FqU0CUdckJV5F53kDYb22o="},"power":"2000006","name":null},{"address":"9B2FB5ABCB3B0289D03AF5A8577C76D9A37A32D3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"D9iPx6VTH+xeewFFWfnI+a7dM6Y5Y9h/5S4WHro5wUQ="},"power":"1003008","name":null},{"address":"87D1611F9BA8ABF12C13B32F90469977B4C94F9A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"BRvI8B8k+QrDeOgdBNb7mLCbNEMatJNqDyZttdGtQm0="},"power":"1001309","name":null},{"address":"5E9EE98A3CBD523D0D3C3518048DF8C322BB67D5","pub_key":{"type":"tendermint/PubKeyEd25519","value":"VXn41Fko8YeJ3vVvYy/yUtqfVbCv7FTivuDclSrw5Pc="},"power":"1000893","name":null},{"address":"E309A8AFFF70D04126D04BB53071B6020580D104","pub_key":{"type":"tendermint/PubKeyEd25519","value":"J0kLUI0gmvWfWvzoxHaqwzXF3+VARlAIMGCRfB6Yj8A="},"power":"1000210","name":null},{"address":"3B0F1CAEEB84A5AF239580FB26D6199CB17CEB3A","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gN5Cln7uU3AVQYzT3QGgggv/3aN+eIewd6m5OfPpkTs="},"power":"1000042","name":null},{"address":"14C590ADD4D238649F2CC7B198B52B8BDB63AC78","pub_key":{"type":"tendermint/PubKeyEd25519","value":"F3RJktKCIoDGEBWXgpDl2+LgNbq5X0rS8eXnY+i3aIY="},"power":"1000038","name":null},{"address":"682EF7D2FB487050D6AD71173FCC7C983B031A4B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oRz4ydtLca6+HfffYIRv0PCsTm4xKBdYpx85lisMWng="},"power":"1000037","name":null},{"address":"BEEE6DB44A01D8005CD59904F9AEE12BE9DBA6A3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oYhHHoROhbAIzOuST8Qyua7O611uIr3NT2yyibK5x7Y="},"power":"1000020","name":null},{"address":"88731522401F260D5C253222CF6EF71586A192D3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"m9gm7H1kmxvPzyo5ubgkmqKGQbJFHst9My51FLe2HeM="},"power":"1000009","name":null},{"address":"CD10B5095AC4541972E0C0FDE35A39CF92A040DA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"cPgsoC0NIVUAe42qmzfbrLaznvYZCh1z92Q35D0KZOc="},"power":"990479","name":null},{"address":"469CB700B5C1D9DE8905457AE5A7BD7E3FCB75EA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"PRXS/zL6clsHN2Srl49mRV+W+eL/g7DgY1MG8eu/8K8="},"power":"990174","name":null},{"address":"5769499735A69F335467D419764A69FAFFE29607","pub_key":{"type":"tendermint/PubKeyEd25519","value":"HnEoblS3w9JRSFqXX/2RCippz7tQD/ShYts+tGHoSBM="},"power":"980425","name":null},{"address":"113388853F11E28044A4ED3B11DF745D00D709CD","pub_key":{"type":"tendermint/PubKeyEd25519","value":"61X0w6XUKooaWi4FYzZghd6kJDIFFifK+EpMJWTHSaI="},"power":"509044","name":null},{"address":"D92E949735CFD958FE2E1EA2F7ACCFBC981059B4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ba80uJncfcmlWoFM/AlzMI6Mut7SyDJTpbNV8kwMXl0="},"power":"502561","name":null},{"address":"F271741FA4B163F3204A5BC2570E74F146AA33D9","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Y0SMVwQK9FHbFi7ykZSwah3TG56saeI0uTMXYvyb9dY="},"power":"501737","name":null},{"address":"B790E6ABE58DB7122F81FF52F7B2183AEEC41D6C","pub_key":{"type":"tendermint/PubKeyEd25519","value":"EiSlqpx/n3VMPFtuTAa++axavjZ9yZzlTa3HtCz+lsI="},"power":"501375","name":null},{"address":"924090B949A3A3A43AEE52C4DAE342332C57B684","pub_key":{"type":"tendermint/PubKeyEd25519","value":"cseuElK5A+VoeuKMvrm3AOTuzII46kf083lVMGpRLDo="},"power":"501271","name":null},{"address":"6BB3BE6A41922712373BBCBA647B3A1486CF56B7","pub_key":{"type":"tendermint/PubKeyEd25519","value":"QfqtiQS1sJXJKLIPYSoHTL1NtSfwm933fD1wOqgBxJI="},"power":"501058","name":null},{"address":"C8E66B2FB198544C40058986AFF7BFD9B1FD6442","pub_key":{"type":"tendermint/PubKeyEd25519","value":"h5bxQwVfFqo0YqTMKMIn0Kmm5SR8QsYGps/x9CUtbFI="},"power":"501050","name":null},{"address":"9AD672973AF0C5A606F1D2EE0F261AF5DD61DACE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"y1EE0IXUX+xqvd08toyjMekOX1kNMzEmY2FLNe00sUg="},"power":"500841","name":null},{"address":"3511B17D31452B433E1392C75CC1D9A57FB769EE","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Wblv9P9x2vItElCo/uoJGPVcB+bMOExuq+fE8+rVfrk="},"power":"500423","name":null},{"address":"6C6F50C1E0E2A69BFC2AB7DABE0A3F091D17E666","pub_key":{"type":"tendermint/PubKeyEd25519","value":"N8ncRVbJpyffC98xo+mxWdqm/GamCJkVTB0YeM8gwkg="},"power":"500401","name":null},{"address":"0FDB40C1B3ED17E49061B1F577393E5B91323C99","pub_key":{"type":"tendermint/PubKeyEd25519","value":"GzwPkML4PmjOdcTvr2pm6rjO7cBHrckZR3oe2w4E+FA="},"power":"500018","name":null},{"address":"D5CABF35D9C01401B32540F938BE59FA2B044067","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Bcsbz2eNu1HWCUW9IkzHCZ6ACMxf/sepz12Q8YCdUDM="},"power":"500014","name":null},{"address":"D6DFC3CD8487061C9612E5E42924FC4E5F622E23","pub_key":{"type":"tendermint/PubKeyEd25519","value":"tF609cLwhEnpi3W93lYIxE1sG/VLbvFKRX0wOzAQxeg="},"power":"500009","name":null},{"address":"F17C3F91E8237C9AE2806625904E8639AC9A3EA7","pub_key":{"type":"tendermint/PubKeyEd25519","value":"gmdjSSfvgwXEAJ7CEMDH0Tv+cQSEFujwSIFdR87tWZA="},"power":"500006","name":null},{"address":"2A8FB5C0567D3031B6A26243BF9F3D04E706548D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"MJlbI1M3aILcOMSigyPMolCpjfQPzEsagrtZTN+9z6E="},"power":"500005","name":null},{"address":"1FEECDA6D9268908A1F84093F0F888F2F752A212","pub_key":{"type":"tendermint/PubKeyEd25519","value":"DE8/atJOsW6TA3iDRklz5DdI8j3Tx95o0nOhwkbkvBQ="},"power":"500001","name":null},{"address":"2B4F222E08213F7F6839E0B2D85C0F56675BD2AB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Zv4/6wZv5pwxuovxaC72oHNW0TAfiH/N+vsilZfiyHc="},"power":"500001","name":null},{"address":"C97A18C41B44DFC2F5FA1FCF8BC1BCFF5E649AE8","pub_key":{"type":"tendermint/PubKeyEd25519","value":"vYKrsdaWTO7YnMgWoUGWKO+A3XwgvXYoB+HNVjBkWAA="},"power":"500001","name":null},{"address":"E5183117268691950E77D53340C23857662CC908","pub_key":{"type":"tendermint/PubKeyEd25519","value":"4k08zQEeKnu5auA0Zp3h5xfNfS6K5LfcN0vnAhNiyz8="},"power":"500001","name":null},{"address":"EF8D6E39A9AA29C04D9D4F0F43EDAD5AB06F56F3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"8yHvjPOugBmpP/D0FOfdpQ6oyiymtS1J+U3lNC/d/2U="},"power":"500001","name":null},{"address":"E01B694AFE5D64691341E931A80ACF9D95E6C8C6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"w5YcK+X1Uv6NVRKzY+4qaSw+Zum8CNDVC0+ip0NpQ5s="},"power":"496178","name":null},{"address":"633744F3BE877E6DF590E72E99425BA653156B93","pub_key":{"type":"tendermint/PubKeyEd25519","value":"rD+6Hqi0NsOsZgsjRAP2BbNtxWcieiDmmh3tng63xDQ="},"power":"495995","name":null},{"address":"6A152D73CD9146A9C1DD4CF9FEF636E2235ECB7E","pub_key":{"type":"tendermint/PubKeyEd25519","value":"XuXuQxuSJIdpW49/wAalXxyjvuV1aGlamnpg+PDyu/A="},"power":"476704","name":null},{"address":"CD34D386E534320153E1A3B02DEFB4CE0773E462","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ps7NCfnD+Nkvkgp8mtnh1S57i5OvVKymdrW1RDktbHk="},"power":"201075","name":null},{"address":"A601B7BCB5172E302329CF3DB6B0E975C8A21D10","pub_key":{"type":"tendermint/PubKeyEd25519","value":"wXe92Kj6b2uv5WP2yMffYDJ7naD3T08jneI8tQuohIM="},"power":"107519","name":null},{"address":"CBA82E0DF6C639D320AC0A421238F6EF93373C94","pub_key":{"type":"tendermint/PubKeyEd25519","value":"qgVzfy4FKDxIrJ/S0a31SHRL1OJZzsxkGMVEW8flsAs="},"power":"105245","name":null},{"address":"0D6EA92C96F4DA14C40B1CA7E2D82A811C9B2196","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Dq8TpiZCrf3fzg/sbMm6Ae5Ty3V1WPEtf1lKqFXVBU8="},"power":"102441","name":null},{"address":"4A3918A6D02D25290B243A86618071374FADD87B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"nuKCeeyYPNP/AwbavdBDum3sB8I7D4TCC4sFbPp7MPQ="},"power":"100448","name":null},{"address":"7BCC38AF8F5494F000D2B7B89EEB9D67B14A0F3F","pub_key":{"type":"tendermint/PubKeyEd25519","value":"XB08MBTE4Rsf3/11MNd+vtdzv0xTvKzGc+7/28Z4En4="},"power":"100370","name":null},{"address":"8536E9166685E936CAB4FBE1F3588F65623E9E81","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7CT5oKkYGXFByTi8glX/46KCivpVffTBvic6gQL61G0="},"power":"100301","name":null},{"address":"DC40C623F0EE6A10CC1E9134E9ADB955EDD319CA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"oJEFTe9oP7psA7onwhzs/17uEYyVi0FDqEZs2/9mGzM="},"power":"100226","name":null},{"address":"2131A959A819C085AFA86E560D5EC0DF1D632827","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Tac4dLmlfr+reh8jMPLQTGXYUBvY1cp1NtN2y1zDuDA="},"power":"100215","name":null},{"address":"A09C4BDCBE3718342A27BD9D420FD14C703C9965","pub_key":{"type":"tendermint/PubKeyEd25519","value":"g/lPk5YCZBxUxlLNgf5qzQN//wwNhIE9HH9w3QX1pMA="},"power":"100162","name":null},{"address":"F7A4EEF357935737058F08804DE4DD03144E960D","pub_key":{"type":"tendermint/PubKeyEd25519","value":"yfV2cDweDavOEDVNWtOYuHcwONDP4jyC/ZG8TUruRD4="},"power":"100136","name":null},{"address":"0A957E96258B8BC5669C9A4DA146532C93E99242","pub_key":{"type":"tendermint/PubKeyEd25519","value":"dJdeXyHrKwqKAboLkSfsmvdQ+WRfYQTz+DbJQDeIFIs="},"power":"100130","name":null},{"address":"B07503589534AAAAD60836B33245410AD11CCEB9","pub_key":{"type":"tendermint/PubKeyEd25519","value":"NVy8f5VLbLWBLrnWMeP+sIkt0iVW4Q3ESepiMx0+j4E="},"power":"100125","name":null},{"address":"5A806CC33FC21BCF9F2F47BE23B6586E04DED0D1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"DP6+z/+64vbsAOx3O8Ej+C9iA572eU5nxlUfGoMB89M="},"power":"100121","name":null},{"address":"967B6B5C64615DEB574D88C1F07F23F77E6E7EBA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ZhjOncfNrailm0sDSE0Om3wqYKL5w+QwBowGnkwzBrA="},"power":"100105","name":null},{"address":"2DC2EF8D1059A7A90E9D4AD35DC8F4F8CD7EB772","pub_key":{"type":"tendermint/PubKeyEd25519","value":"lwSHuhiiooJGDeqHgh/cFoUudQv0zloyeiz400kyv8s="},"power":"100100","name":null},{"address":"F6D5482C2405A9844A1EB215148387AD18800D32","pub_key":{"type":"tendermint/PubKeyEd25519","value":"MwxKwbDR+Pfj2kb8e/mnRy7gLw4n2oJA4qe/E8K6A5E="},"power":"100085","name":null},{"address":"473FB7626E52E54BD406A255DBA3B1822F8FC2EA","pub_key":{"type":"tendermint/PubKeyEd25519","value":"3IevyShLKCWeb5joXQjcpPDsvQWnk7bbHLqCd1td7sE="},"power":"100050","name":null},{"address":"50922F9E58F64B3A219887F67117E4CF714AF490","pub_key":{"type":"tendermint/PubKeyEd25519","value":"95WzrdnBvJzBBrOPjORQM0u/70LJnpyvZha6XAvS+T8="},"power":"100048","name":null},{"address":"E5C8264B472C5BD93BD9CA9CE99C221DE14B7EFB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"7d0Y9SKn6bfYtn1J9buGsXImkkPHl/bQX8gI7J6Grjk="},"power":"100045","name":null},{"address":"FE6AE5C0EE214D1A1199387B06F7783F66DBC09B","pub_key":{"type":"tendermint/PubKeyEd25519","value":"kWIFV6puc+0TvyMPwreUkcAJFHANXbWoLGcTJEDLQPQ="},"power":"100014","name":null},{"address":"26EFB42C96DBFA42D740333C33E2713AA050FA77","pub_key":{"type":"tendermint/PubKeyEd25519","value":"9FusyXhw+gECqAjvHefpCpSS+KQ/fDltXWFy+5HfPcE="},"power":"100011","name":null},{"address":"D87DA6AD5B598E723EE3A03BE0A6F9AB07EB0E01","pub_key":{"type":"tendermint/PubKeyEd25519","value":"lwJhFD9crCT0jEcZi7TXYGo5/tLfRrFGb9C5EYDlHRo="},"power":"100011","name":null},{"address":"E23A9173DF68A8BE51650807E55104E6101CA7CB","pub_key":{"type":"tendermint/PubKeyEd25519","value":"WCwJZKhAwYmOH4Eo5TXvsS9W8KqEx1Oi8mj/gfyuQic="},"power":"100011","name":null},{"address":"9E9F1F203A5AA77340B4BCE0472C3C24D3A061B3","pub_key":{"type":"tendermint/PubKeyEd25519","value":"sJQZYhdp6x/l6MQ40Pj2880J6Q/t3433EZglkk1yYaA="},"power":"100010","name":null}],"proposer":null,"total_voting_power":"511862423"},"provider":"726bc8d260387cf56ecfad3a6bf6fecd903e18a2"} --------------------------------------------------------------------------------