feat: add support for Geth built-in tracer and config (#2121)

* feat: add 4byteTracer

* feat: add prestateTracer

* feat: add noopTracer

* refactor: geth tracer layout

* feat: call tracer config

* fix: compatible with legacy call trace

* feat: pre state tracer config

* test: serialize/deserialize tracer

* refactor: deserialize type

* style: update refs

* chore: update CHANGELOG.md

* style: json string to object
This commit is contained in:
YuFei Wang 2023-02-08 02:50:44 +08:00 committed by GitHub
parent e5e4da07c5
commit 14be402f40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 460 additions and 24 deletions

View File

@ -13,6 +13,7 @@
- Add abigen support for hardhat generated bytecode json format [#2012](https://github.com/gakonst/ethers-rs/pull/2012)
- Fix typo in `RwClient` docs for `write_client` method.
- Add support for Geth `debug_traceCall` [#1949](https://github.com/gakonst/ethers-rs/pull/1949)
- Add support for Geth built-in tracer and config [#2121](https://github.com/gakonst/ethers-rs/pull/2121)
- Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815)
- `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers.
- An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract.

View File

@ -1,5 +1,16 @@
mod call;
mod four_byte;
mod noop;
mod pre_state;
pub use self::{
call::{CallConfig, CallFrame},
four_byte::FourByteFrame,
noop::NoopFrame,
pre_state::{PreStateConfig, PreStateFrame},
};
use crate::{
types::{Address, Bytes, NameOrAddress, H256, U256},
types::{Bytes, H256, U256},
utils::from_int_or_hex,
};
use serde::{Deserialize, Serialize};
@ -40,34 +51,14 @@ pub struct StructLog {
pub storage: Option<BTreeMap<H256, H256>>,
}
// https://github.com/ethereum/go-ethereum/blob/a9ef135e2dd53682d106c6a2aede9187026cc1de/eth/tracers/native/call.go#L37
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CallFrame {
#[serde(rename = "type")]
pub typ: String,
pub from: Address,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub to: Option<NameOrAddress>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub value: Option<U256>,
#[serde(deserialize_with = "from_int_or_hex")]
pub gas: U256,
#[serde(deserialize_with = "from_int_or_hex", rename = "gasUsed")]
pub gas_used: U256,
pub input: Bytes,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub output: Option<Bytes>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub calls: Option<Vec<CallFrame>>,
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum GethTraceFrame {
Default(DefaultFrame),
NoopTracer(NoopFrame),
FourByteTracer(FourByteFrame),
CallTracer(CallFrame),
PreStateTracer(PreStateFrame),
}
impl From<DefaultFrame> for GethTraceFrame {
@ -76,12 +67,30 @@ impl From<DefaultFrame> for GethTraceFrame {
}
}
impl From<FourByteFrame> for GethTraceFrame {
fn from(value: FourByteFrame) -> Self {
GethTraceFrame::FourByteTracer(value)
}
}
impl From<CallFrame> for GethTraceFrame {
fn from(value: CallFrame) -> Self {
GethTraceFrame::CallTracer(value)
}
}
impl From<PreStateFrame> for GethTraceFrame {
fn from(value: PreStateFrame) -> Self {
GethTraceFrame::PreStateTracer(value)
}
}
impl From<NoopFrame> for GethTraceFrame {
fn from(value: NoopFrame) -> Self {
GethTraceFrame::NoopTracer(value)
}
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum GethTrace {
@ -106,8 +115,21 @@ impl From<Value> for GethTrace {
/// See <https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers>
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
pub enum GethDebugBuiltInTracerType {
#[serde(rename = "4byteTracer")]
FourByteTracer,
#[serde(rename = "callTracer")]
CallTracer,
#[serde(rename = "prestateTracer")]
PreStateTracer,
#[serde(rename = "noopTracer")]
NoopTracer,
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum GethDebugBuiltInTracerConfig {
CallTracer(CallConfig),
PreStateTracer(PreStateConfig),
}
/// Available tracers
@ -123,6 +145,16 @@ pub enum GethDebugTracerType {
JsTracer(String),
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum GethDebugTracerConfig {
/// built-in tracer
BuiltInTracer(GethDebugBuiltInTracerConfig),
/// custom JS tracer
JsTracer(Value),
}
/// Bindings for additional `debug_traceTransaction` options
///
/// See <https://geth.ethereum.org/docs/rpc/ns-debug#debug_tracetransaction>
@ -139,6 +171,10 @@ pub struct GethDebugTracingOptions {
pub enable_return_data: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tracer: Option<GethDebugTracerType>,
/// tracerConfig is slated for Geth v1.11.0
/// See <https://github.com/ethereum/go-ethereum/issues/26513>
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tracer_config: Option<GethDebugTracerConfig>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timeout: Option<String>,
}

View File

@ -0,0 +1,87 @@
use crate::{
types::{Address, Bytes, NameOrAddress, H256, U256},
utils::from_int_or_hex,
};
use serde::{Deserialize, Serialize};
// https://github.com/ethereum/go-ethereum/blob/91cb6f863a965481e51d5d9c0e5ccd54796fd967/eth/tracers/native/call.go#L44
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CallFrame {
#[serde(rename = "type")]
pub typ: String,
pub from: Address,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub to: Option<NameOrAddress>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub value: Option<U256>,
#[serde(default, deserialize_with = "from_int_or_hex")]
pub gas: U256,
#[serde(default, deserialize_with = "from_int_or_hex", rename = "gasUsed")]
pub gas_used: U256,
pub input: Bytes,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub output: Option<Bytes>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub calls: Option<Vec<CallFrame>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub logs: Option<Vec<CallLogFrame>>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct CallLogFrame {
#[serde(default, skip_serializing_if = "Option::is_none")]
address: Option<Address>,
#[serde(default, skip_serializing_if = "Option::is_none")]
topics: Option<Vec<H256>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
data: Option<Bytes>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CallConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub only_top_call: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub with_log: Option<bool>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::*;
// See <https://github.com/ethereum/go-ethereum/tree/master/eth/tracers/internal/tracetest/testdata>
const DEFAULT: &str = include_str!("./test_data/call_tracer/default.json");
const LEGACY: &str = include_str!("./test_data/call_tracer/legacy.json");
const ONLY_TOP_CALL: &str = include_str!("./test_data/call_tracer/only_top_call.json");
const WITH_LOG: &str = include_str!("./test_data/call_tracer/with_log.json");
#[test]
fn test_serialize_call_trace() {
let mut opts = GethDebugTracingCallOptions::default();
opts.tracing_options.disable_storage = Some(false);
opts.tracing_options.tracer =
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::CallTracer));
opts.tracing_options.tracer_config =
Some(GethDebugTracerConfig::BuiltInTracer(GethDebugBuiltInTracerConfig::CallTracer(
CallConfig { only_top_call: Some(true), with_log: Some(true) },
)));
assert_eq!(
serde_json::to_string(&opts).unwrap(),
r#"{"disableStorage":false,"tracer":"callTracer","tracerConfig":{"onlyTopCall":true,"withLog":true}}"#
);
}
#[test]
fn test_deserialize_call_trace() {
let _trace: CallFrame = serde_json::from_str(DEFAULT).unwrap();
let _trace: CallFrame = serde_json::from_str(LEGACY).unwrap();
let _trace: CallFrame = serde_json::from_str(ONLY_TOP_CALL).unwrap();
let trace: CallFrame = serde_json::from_str(WITH_LOG).unwrap();
let _logs = trace.logs.unwrap();
}
}

View File

@ -0,0 +1,34 @@
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
// https://github.com/ethereum/go-ethereum/blob/91cb6f863a965481e51d5d9c0e5ccd54796fd967/eth/tracers/native/4byte.go#L48
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct FourByteFrame(pub BTreeMap<String, u64>);
#[cfg(test)]
mod tests {
use super::*;
use crate::types::*;
const DEFAULT: &str = r#"{
"0x27dc297e-128": 1,
"0x38cc4831-0": 2,
"0x524f3889-96": 1,
"0xadf59f99-288": 1,
"0xc281d19e-0": 1
}"#;
#[test]
fn test_serialize_four_byte_trace() {
let mut opts = GethDebugTracingCallOptions::default();
opts.tracing_options.tracer =
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::FourByteTracer));
assert_eq!(serde_json::to_string(&opts).unwrap(), r#"{"tracer":"4byteTracer"}"#);
}
#[test]
fn test_deserialize_four_byte_trace() {
let _trace: FourByteFrame = serde_json::from_str(DEFAULT).unwrap();
}
}

View File

@ -0,0 +1,30 @@
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
// https://github.com/ethereum/go-ethereum/blob/91cb6f863a965481e51d5d9c0e5ccd54796fd967/eth/tracers/native/noop.go#L34
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct NoopFrame(BTreeMap<Null, Null>);
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
struct Null;
#[cfg(test)]
mod tests {
use super::*;
use crate::types::*;
const DEFAULT: &str = r#"{}"#;
#[test]
fn test_serialize_noop_trace() {
let mut opts = GethDebugTracingCallOptions::default();
opts.tracing_options.tracer =
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::NoopTracer));
assert_eq!(serde_json::to_string(&opts).unwrap(), r#"{"tracer":"noopTracer"}"#);
}
#[test]
fn test_deserialize_noop_trace() {
let _trace: NoopFrame = serde_json::from_str(DEFAULT).unwrap();
}
}

View File

@ -0,0 +1,92 @@
use crate::{
types::{Address, H256, U256},
utils::from_int_or_hex_opt,
};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
// https://github.com/ethereum/go-ethereum/blob/91cb6f863a965481e51d5d9c0e5ccd54796fd967/eth/tracers/native/prestate.go#L38
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum PreStateFrame {
Default(PreStateMode),
Diff(DiffMode),
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct PreStateMode(pub BTreeMap<Address, AccountState>);
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct DiffMode {
pub pre: BTreeMap<Address, AccountState>,
pub post: BTreeMap<Address, AccountState>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct AccountState {
#[serde(
default,
deserialize_with = "from_int_or_hex_opt",
skip_serializing_if = "Option::is_none"
)]
pub balance: Option<U256>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub code: Option<String>,
#[serde(
default,
deserialize_with = "from_int_or_hex_opt",
skip_serializing_if = "Option::is_none"
)]
pub nonce: Option<U256>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub storage: Option<BTreeMap<H256, H256>>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PreStateConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub diff_mode: Option<bool>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::*;
// See <https://github.com/ethereum/go-ethereum/tree/master/eth/tracers/internal/tracetest/testdata>
const DEFAULT: &str = include_str!("./test_data/pre_state_tracer/default.json");
const LEGACY: &str = include_str!("./test_data/pre_state_tracer/legacy.json");
const DIFF_MODE: &str = include_str!("./test_data/pre_state_tracer/diff_mode.json");
#[test]
fn test_serialize_pre_state_trace() {
let mut opts = GethDebugTracingCallOptions::default();
opts.tracing_options.disable_storage = Some(false);
opts.tracing_options.tracer =
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::PreStateTracer));
opts.tracing_options.tracer_config = Some(GethDebugTracerConfig::BuiltInTracer(
GethDebugBuiltInTracerConfig::PreStateTracer(PreStateConfig { diff_mode: Some(true) }),
));
assert_eq!(
serde_json::to_string(&opts).unwrap(),
r#"{"disableStorage":false,"tracer":"prestateTracer","tracerConfig":{"diffMode":true}}"#
);
}
#[test]
fn test_deserialize_pre_state_trace() {
let trace: PreStateFrame = serde_json::from_str(DEFAULT).unwrap();
match trace {
PreStateFrame::Default(PreStateMode(_)) => {}
_ => unreachable!(),
}
let _trace: PreStateFrame = serde_json::from_str(LEGACY).unwrap();
let trace: PreStateFrame = serde_json::from_str(DIFF_MODE).unwrap();
match trace {
PreStateFrame::Diff(DiffMode { pre: _pre, post: _post }) => {}
_ => unreachable!(),
}
}
}

View File

@ -0,0 +1,21 @@
{
"calls": [
{
"from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
"gas": "0x6d05",
"gasUsed": "0x0",
"input": "0x",
"to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
"type": "CALL",
"value": "0x6f05b59d3b20000"
}
],
"from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
"gas": "0x10738",
"gasUsed": "0x9751",
"input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
"output": "0x0000000000000000000000000000000000000000000000000000000000000001",
"to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
"type": "CALL",
"value": "0x0"
}

View File

@ -0,0 +1,19 @@
{
"calls": [
{
"from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
"input": "0x",
"to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
"type": "CALL",
"value": "0x6f05b59d3b20000"
}
],
"from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
"gas": "0x10738",
"gasUsed": "0x9751",
"input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
"output": "0x0000000000000000000000000000000000000000000000000000000000000001",
"to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
"type": "CALL",
"value": "0x0"
}

View File

@ -0,0 +1,10 @@
{
"from": "0x4f5777744b500616697cb655dcb02ee6cd51deb5",
"gas": "0x2dced",
"gasUsed": "0x1a9e5",
"to": "0x200edd17f30485a8735878661960cd7a9a95733f",
"input": "0xba51a6df0000000000000000000000000000000000000000000000000000000000000000",
"output": "0xba51a6df00000000000000000000000000000000000000000000000000000000",
"value": "0x8ac7230489e80000",
"type": "CALL"
}

View File

@ -0,0 +1,20 @@
{
"from": "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
"gas": "0x1f36d",
"gasUsed": "0xc6a5",
"to": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd",
"input": "0xa9059cbb000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb0000000000000000000000000000000000000000000000000000000000989680",
"logs": [
{
"address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
"0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb"
],
"data": "0x0000000000000000000000000000000000000000000000000000000000989680"
}
],
"value": "0x0",
"type": "CALL"
}

View File

@ -0,0 +1,20 @@
{
"0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": {
"balance": "0xc820f93200f4000",
"nonce": 94
},
"0x332b656504f4eabb44c8617a42af37461a34e9dc": {
"balance": "0x11faea4f35e5af80000",
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": {
"balance": "0xbf681825be002ac452",
"nonce": 28922
},
"0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": {
"balance": "0xb3d0ac5cb94df6f6b0",
"nonce": 1
}
}

View File

@ -0,0 +1,41 @@
{
"pre": {
"0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
"balance": "0x0",
"nonce": 22
},
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
"balance": "0x0"
},
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
"balance": "0x4d87094125a369d9bd5",
"nonce": 1,
"code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
}
},
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
"balance": "0x1780d77678137ac1b775",
"nonce": 29072
}
},
"post": {
"0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
"balance": "0x6f05b59d3b20000"
},
"0x1585936b53834b021f68cc13eeefdec2efc8e724": {
"balance": "0x420eed1bd6c00"
},
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
"balance": "0x4d869a3b70062eb9bd5",
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b95e"
}
},
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
"balance": "0x1780d7725724a9044b75",
"nonce": 29073
}
}
}

View File

@ -0,0 +1,25 @@
{
"0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
"balance": "0x0",
"code": "0x",
"nonce": 22,
"storage": {}
},
"0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
"balance": "0x4d87094125a369d9bd5",
"code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
"nonce": 1,
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
"0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
"0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
}
},
"0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
"balance": "0x1780d77678137ac1b775",
"code": "0x",
"nonce": 29072,
"storage": {}
}
}