diff --git a/ethcore/src/types/account_diff.rs b/ethcore/src/types/account_diff.rs
new file mode 100644
index 000000000..49fc51110
--- /dev/null
+++ b/ethcore/src/types/account_diff.rs
@@ -0,0 +1,135 @@
+// Copyright 2015, 2016 Ethcore (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+//! Diff between two accounts.
+
+use util::*;
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+/// Diff type for specifying a change (or not).
+pub enum Diff where T: Eq {
+ /// Both sides are the same.
+ Same,
+ /// Left (pre, source) side doesn't include value, right side (post, destination) does.
+ Born(T),
+ /// Both sides include data; it chaged value between them.
+ Changed(T, T),
+ /// Left (pre, source) side does include value, right side (post, destination) does not.
+ Died(T),
+}
+
+impl Diff where T: Eq {
+ /// Construct new object with given `pre` and `post`.
+ pub fn new(pre: T, post: T) -> Self { if pre == post { Diff::Same } else { Diff::Changed(pre, post) } }
+
+ /// Get the before value, if there is one.
+ pub fn pre(&self) -> Option<&T> { match *self { Diff::Died(ref x) | Diff::Changed(ref x, _) => Some(x), _ => None } }
+
+ /// Get the after value, if there is one.
+ pub fn post(&self) -> Option<&T> { match *self { Diff::Born(ref x) | Diff::Changed(_, ref x) => Some(x), _ => None } }
+
+ /// Determine whether there was a change or not.
+ pub fn is_same(&self) -> bool { match *self { Diff::Same => true, _ => false }}
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+/// Account diff.
+pub struct AccountDiff {
+ /// Change in balance, allowed to be `Diff::Same`.
+ pub balance: Diff,
+ /// Change in nonce, allowed to be `Diff::Same`.
+ pub nonce: Diff, // Allowed to be Same
+ /// Change in code, allowed to be `Diff::Same`.
+ pub code: Diff, // Allowed to be Same
+ /// Change in storage, values are not allowed to be `Diff::Same`.
+ pub storage: BTreeMap>,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+/// Change in existance type.
+// TODO: include other types of change.
+pub enum Existance {
+ /// Item came into existance.
+ Born,
+ /// Item stayed in existance.
+ Alive,
+ /// Item went out of existance.
+ Died,
+}
+
+impl fmt::Display for Existance {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Existance::Born => try!(write!(f, "+++")),
+ Existance::Alive => try!(write!(f, "***")),
+ Existance::Died => try!(write!(f, "XXX")),
+ }
+ Ok(())
+ }
+}
+
+impl AccountDiff {
+ /// Get `Existance` projection.
+ pub fn existance(&self) -> Existance {
+ match self.balance {
+ Diff::Born(_) => Existance::Born,
+ Diff::Died(_) => Existance::Died,
+ _ => Existance::Alive,
+ }
+ }
+}
+
+// TODO: refactor into something nicer.
+fn interpreted_hash(u: &H256) -> String {
+ if u <= &H256::from(0xffffffff) {
+ format!("{} = 0x{:x}", U256::from(u.as_slice()).low_u32(), U256::from(u.as_slice()).low_u32())
+ } else if u <= &H256::from(u64::max_value()) {
+ format!("{} = 0x{:x}", U256::from(u.as_slice()).low_u64(), U256::from(u.as_slice()).low_u64())
+// } else if u <= &H256::from("0xffffffffffffffffffffffffffffffffffffffff") {
+// format!("@{}", Address::from(u))
+ } else {
+ format!("#{}", u)
+ }
+}
+
+impl fmt::Display for AccountDiff {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.nonce {
+ Diff::Born(ref x) => try!(write!(f, " non {}", x)),
+ Diff::Changed(ref pre, ref post) => try!(write!(f, "#{} ({} {} {})", post, pre, if pre > post {"-"} else {"+"}, *max(pre, post) - * min(pre, post))),
+ _ => {},
+ }
+ match self.balance {
+ Diff::Born(ref x) => try!(write!(f, " bal {}", x)),
+ Diff::Changed(ref pre, ref post) => try!(write!(f, "${} ({} {} {})", post, pre, if pre > post {"-"} else {"+"}, *max(pre, post) - *min(pre, post))),
+ _ => {},
+ }
+ if let Diff::Born(ref x) = self.code {
+ try!(write!(f, " code {}", x.pretty()));
+ }
+ try!(write!(f, "\n"));
+ for (k, dv) in &self.storage {
+ match *dv {
+ Diff::Born(ref v) => try!(write!(f, " + {} => {}\n", interpreted_hash(k), interpreted_hash(v))),
+ Diff::Changed(ref pre, ref post) => try!(write!(f, " * {} => {} (was {})\n", interpreted_hash(k), interpreted_hash(post), interpreted_hash(pre))),
+ Diff::Died(_) => try!(write!(f, " X {}\n", interpreted_hash(k))),
+ _ => {},
+ }
+ }
+ Ok(())
+ }
+}
+
diff --git a/ethcore/src/types/state_diff.rs b/ethcore/src/types/state_diff.rs
new file mode 100644
index 000000000..4257d5b07
--- /dev/null
+++ b/ethcore/src/types/state_diff.rs
@@ -0,0 +1,49 @@
+// Copyright 2015, 2016 Ethcore (UK) Ltd.
+// This file is part of Parity.
+
+// Parity is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity. If not, see .
+
+//! State diff module.
+
+use util::*;
+use account_diff::*;
+
+#[derive(Debug, PartialEq, Eq, Clone)]
+/// Expression for the delta between two system states. Encoded the
+/// delta of every altered account.
+pub struct StateDiff (pub BTreeMap);
+
+impl StateDiff {
+ /// Get the actual data.
+ pub fn get(&self) -> &BTreeMap {
+ &self.0
+ }
+}
+
+impl fmt::Display for StateDiff {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ for (add, acc) in &self.0 {
+ try!(write!(f, "{} {}: {}", acc.existance(), add, acc));
+ }
+ Ok(())
+ }
+}
+
+impl Deref for StateDiff {
+ type Target = BTreeMap;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}