diff --git a/Cargo.lock b/Cargo.lock
index 1d44e501bbc512aa87f34fe71a9eb8b4430a323b..0b4444798383eaf1f6a355dd8a39fe9f28e7cdfa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -34,12 +34,12 @@ version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bitflags"
-version = "1.0.1"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -49,7 +49,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cfg-if"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -67,7 +67,7 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -80,7 +80,7 @@ name = "crossbeam-utils"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -90,6 +90,7 @@ dependencies = [
  "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -101,8 +102,9 @@ dependencies = [
  "duniter-crypto 0.1.2",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -112,8 +114,8 @@ dependencies = [
  "bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -126,7 +128,7 @@ name = "fuchsia-zircon"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -183,7 +185,7 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "0.3.6"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -194,7 +196,7 @@ name = "quote"
 version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -245,19 +247,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "regex"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.5.5"
+version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -292,35 +294,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.43"
+version = "1.0.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde_derive"
-version = "1.0.43"
+version = "1.0.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "serde_derive_internals"
-version = "0.23.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "syn"
-version = "0.13.1"
+version = "0.13.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -397,9 +389,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
 "checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d"
 "checksum bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9a6301db0b49fb63551bc15b5ae348147101cdf323242b93ec7546d5002ff1af"
-"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
+"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
 "checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
-"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
+"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
@@ -414,23 +406,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
 "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
-"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
+"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
 "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
 "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
 "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
 "checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
 "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
 "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
-"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb"
-"checksum regex-syntax 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bd90079345f4a4c3409214734ae220fd773c6f2e8a543d07370c6c1c369cfbfb"
+"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
+"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
 "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
-"checksum serde 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "0c855d888276f20d140223bd06515e5bf1647fd6d02593cb5792466d9a8ec2d0"
-"checksum serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)" = "aa113e5fc4b008a626ba2bbd41330b56c9987d667f79f7b243e5a2d03d91ed1c"
-"checksum serde_derive_internals 0.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d30c4596450fd7bbda79ef15559683f9a79ac0193ea819db90000d7e1cae794"
-"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
+"checksum serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "428d3d818cb94ee037a17bf4f2200db2552e19b1825d33df2196624290716f92"
+"checksum serde_derive 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "ee76093b16868c4c9c8e5329c3d30745833e35390624019738472bd13e996e79"
+"checksum syn 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "61b8f1b737f929c6516ba46a3133fd6d5215ad8a62f66760f851f7048aebedfb"
 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
 "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
 "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml
index eb02b40032768fac856cc3ecc744fe9f4e223be6..3cb39c12d4eb7e7fcfc80f160c6285ea26559ce8 100644
--- a/crypto/Cargo.toml
+++ b/crypto/Cargo.toml
@@ -15,6 +15,7 @@ path = "lib.rs"
 base58 = "0.1.0"
 base64 = "0.8.0"
 rust-crypto = "0.2.36"
+serde = "1.0.24"
 
 [features]
 # Treat warnings as a build error.
diff --git a/crypto/keys/ed25519.rs b/crypto/keys/ed25519.rs
index 0446123d96a381193f82b0b897b7e15716ebb720..9fe98d04b8ecb5c2f280bc4510a01e45977ce8dc 100644
--- a/crypto/keys/ed25519.rs
+++ b/crypto/keys/ed25519.rs
@@ -19,6 +19,8 @@
 //!
 //! [`KeyPairGenerator`]: struct.KeyPairGenerator.html
 
+extern crate serde;
+
 use std::collections::hash_map::DefaultHasher;
 use std::fmt::Debug;
 use std::fmt::Display;
@@ -26,6 +28,7 @@ use std::fmt::Error;
 use std::fmt::Formatter;
 use std::hash::{Hash, Hasher};
 
+use self::serde::ser::{Serialize, Serializer};
 use base58::{FromBase58, FromBase58Error, ToBase58};
 use base64;
 use base64::DecodeError;
@@ -123,6 +126,15 @@ impl Debug for PublicKey {
     }
 }
 
+impl Serialize for PublicKey {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.serialize_str(&format!("{}", self))
+    }
+}
+
 impl super::PublicKey for PublicKey {
     type Signature = Signature;
 
diff --git a/documents/Cargo.toml b/documents/Cargo.toml
index de28ba5ffb6f71c5b8f200a0b9aed21e7b33a34a..cc0e5620497b6697d20bf9e23ebfbea93510f16a 100644
--- a/documents/Cargo.toml
+++ b/documents/Cargo.toml
@@ -12,13 +12,14 @@ license = "AGPL-3.0"
 path = "lib.rs"
 
 [dependencies]
-rust-crypto = "0.2.36"
-linked-hash-map = "0.5.0"
 base58 = "0.1.0"
 base64 = "0.8.0"
+duniter-crypto = { path = "../crypto" }
 lazy_static = "1.0.0"
+linked-hash-map = "0.5.0"
 regex = "0.2"
-duniter-crypto = { path = "../crypto" }
+rust-crypto = "0.2.36"
+serde = "1.0.24"
 
 [features]
 # Treat warnings as a build error.
diff --git a/documents/blockchain/mod.rs b/documents/blockchain/mod.rs
index dee4005a95245c05687b01dc9189c7c10ab5a20d..ff070ebabeaab0aa48fb8feec7057bde65684026 100644
--- a/documents/blockchain/mod.rs
+++ b/documents/blockchain/mod.rs
@@ -19,6 +19,8 @@ use std::fmt::Debug;
 
 use duniter_crypto::keys::{PrivateKey, PublicKey};
 
+use super::Blockstamp;
+
 pub mod v10;
 
 /// List of blockchain protocol versions.
@@ -48,6 +50,9 @@ pub trait Document: Debug + Clone {
     /// Get document currency.
     fn currency(&self) -> &Self::CurrencyType;
 
+    /// Get document blockstamp
+    fn blockstamp(&self) -> Blockstamp;
+
     /// Iterate over document issuers.
     fn issuers(&self) -> &Vec<Self::PublicKey>;
 
@@ -160,6 +165,10 @@ mod tests {
             unimplemented!()
         }
 
+        fn blockstamp(&self) -> Blockstamp {
+            unimplemented!()
+        }
+
         fn issuers(&self) -> &Vec<ed25519::PublicKey> {
             &self.issuers
         }
diff --git a/documents/blockchain/v10/documents/block.rs b/documents/blockchain/v10/documents/block.rs
index 1473d4ae3b119038ec8013a2cb3bd39562b12533..0305af99761abe685cafcc3d3c8d1f2c839398b5 100644
--- a/documents/blockchain/v10/documents/block.rs
+++ b/documents/blockchain/v10/documents/block.rs
@@ -81,78 +81,75 @@ pub struct BlockParameters {
 #[derive(Debug, Clone)]
 pub struct BlockDocument {
     /// Nonce
-    nonce: u64,
+    pub nonce: u64,
     /// number
-    number: BlockId,
+    pub number: BlockId,
     /// Minimal proof of work difficulty
-    pow_min: usize,
+    pub pow_min: usize,
     /// Local time of the block issuer
-    time: u64,
+    pub time: u64,
     /// Average time
-    median_time: u64,
+    pub median_time: u64,
     /// Members count
-    members_count: usize,
+    pub members_count: usize,
     /// Monetary mass
-    monetary_mass: usize,
+    pub monetary_mass: usize,
     /// Unit base (power of ten)
-    unit_base: usize,
+    pub unit_base: usize,
     /// Number of compute members in the current frame
-    issuers_count: usize,
+    pub issuers_count: usize,
     /// Current frame size (in blocks)
-    issuers_frame: isize,
+    pub issuers_frame: isize,
     /// Current frame variation buffer
-    issuers_frame_var: isize,
+    pub issuers_frame_var: isize,
     /// Currency.
-    currency: String,
+    pub currency: String,
     /// Document issuer (there should be only one).
-    issuers: Vec<ed25519::PublicKey>,
+    pub issuers: Vec<ed25519::PublicKey>,
     /// Document signature (there should be only one).
     /// This vector is empty, when the block is generated but the proof of work has not yet started
-    signatures: Vec<ed25519::Signature>,
+    pub signatures: Vec<ed25519::Signature>,
     /// The hash is None, when the block is generated but the proof of work has not yet started
-    hash: Option<BlockHash>,
+    pub hash: Option<BlockHash>,
     /// Currency parameters (only in genesis block)
-    parameters: Option<BlockParameters>,
+    pub parameters: Option<BlockParameters>,
     /// Hash of the previous block
-    previous_hash: Option<Hash>,
+    pub previous_hash: Hash,
     /// Issuer of the previous block
-    previous_issuer: Option<ed25519::PublicKey>,
+    pub previous_issuer: Option<ed25519::PublicKey>,
     /// Hash of the deterministic content of the block
-    inner_hash: Option<Hash>,
+    pub inner_hash: Option<Hash>,
     /// Amount of new dividend created at this block, None if no dividend is created at this block
-    dividend: Option<usize>,
+    pub dividend: Option<usize>,
     /// Identities
-    identities: Vec<IdentityDocument>,
+    pub identities: Vec<IdentityDocument>,
     /// joiners
-    joiners: Vec<MembershipDocument>,
+    pub joiners: Vec<MembershipDocument>,
     /// Actives (=renewals)
-    actives: Vec<MembershipDocument>,
+    pub actives: Vec<MembershipDocument>,
     /// Leavers
-    leavers: Vec<MembershipDocument>,
+    pub leavers: Vec<MembershipDocument>,
     /// Revokeds
-    revoked: Vec<RevocationDocument>,
+    pub revoked: Vec<RevocationDocument>,
     /// Excludeds
-    excluded: Vec<ed25519::PublicKey>,
+    pub excluded: Vec<ed25519::PublicKey>,
     /// Certifications
-    certifications: Vec<CertificationDocument>,
+    pub certifications: Vec<CertificationDocument>,
     /// Transactions
-    transactions: Vec<TransactionDocument>,
+    pub transactions: Vec<TransactionDocument>,
     /// Part to sign
-    inner_hash_and_nonce_str: String,
+    pub inner_hash_and_nonce_str: String,
 }
 
 impl BlockDocument {
-    /// Return blockstamp
-    pub fn blockstamp(&self) -> Blockstamp {
-        Blockstamp {
-            id: self.number,
-            hash: self.hash.unwrap(),
-        }
-    }
     /// Compute inner hash
     pub fn compute_inner_hash(&mut self) {
         let mut sha256 = Sha256::new();
-        sha256.input_str(&self.generate_compact_inner_text());
+        let inner_text = self.generate_compact_inner_text();
+        /*if self.number.0 == 46473 {
+            println!("#46473 raw_format=\"{}\"", inner_text);
+        }*/
+        sha256.input_str(&inner_text);
         self.inner_hash = Some(Hash::from_hex(&sha256.result_str()).unwrap());
     }
     /// Change nonce
@@ -269,7 +266,7 @@ Transactions:{transactions}
             issuers_frame = self.issuers_frame,
             issuers_frame_var = self.issuers_frame_var,
             issuers_count = self.issuers_count,
-            previous_hash = self.previous_hash.unwrap(),
+            previous_hash = self.previous_hash,
             previous_issuer = self.previous_issuer.unwrap(),
             members_count = self.members_count,
             identities = identities_str,
@@ -296,6 +293,13 @@ impl Document for BlockDocument {
         &self.currency
     }
 
+    fn blockstamp(&self) -> Blockstamp {
+        Blockstamp {
+            id: self.number,
+            hash: self.hash.unwrap(),
+        }
+    }
+
     fn issuers(&self) -> &Vec<ed25519::PublicKey> {
         &self.issuers
     }
@@ -357,7 +361,7 @@ mod tests {
             signatures: vec![ed25519::Signature::from_base64("FsRxB+NOiL+8zTr2d3B2j2KBItDuCa0KjFMF6hXmdQzfqXAs9g3m7DlGgYLcqzqe6JXjx/Lyzqze1HBR4cS0Aw==").unwrap()],
             hash: None,
             parameters: None,
-            previous_hash: Some(Hash::from_hex("0000001F8AACF6764135F3E5D0D4E8358A3CBE537A4BF71152A00CC442EFD136").expect("fail to parse previous_hash")),
+            previous_hash: Hash::from_hex("0000001F8AACF6764135F3E5D0D4E8358A3CBE537A4BF71152A00CC442EFD136").expect("fail to parse previous_hash"),
             previous_issuer: Some(ed25519::PublicKey::from_base58("38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE").unwrap()),
             inner_hash: None,
             dividend: None,
@@ -492,7 +496,7 @@ a9PHPuSfw7jW8FRQHXFsGi/bnLjbtDnTYvEVgUC9u0WlR7GVofa+Xb+l5iy6NwuEXiwvueAkf08wPVY8
             signatures: vec![ed25519::Signature::from_base64("92id58VmkhgVNee4LDqBGSm8u/ooHzAD67JM6fhAE/CV8LCz7XrMF1DvRl+eRpmlaVkp6I+Iy8gmZ1WUM5C8BA==").unwrap()],
             hash: None,
             parameters: None,
-            previous_hash: Some(Hash::from_hex("000001144968D0C3516BE6225E4662F182E28956AF46DD7FB228E3D0F9413FEB").expect("fail to parse previous_hash")),
+            previous_hash: Hash::from_hex("000001144968D0C3516BE6225E4662F182E28956AF46DD7FB228E3D0F9413FEB").expect("fail to parse previous_hash"),
             previous_issuer: Some(ed25519::PublicKey::from_base58("D3krfq6J9AmfpKnS3gQVYoy7NzGCc61vokteTS8LJ4YH").unwrap()),
             inner_hash: None,
             dividend: None,
diff --git a/documents/blockchain/v10/documents/certification.rs b/documents/blockchain/v10/documents/certification.rs
index 10286adf7bb66a3d182d746eeba762a4f26ba1c3..b3e8857ccbe90c902b1e7d8bc307cb61e780aec3 100644
--- a/documents/blockchain/v10/documents/certification.rs
+++ b/documents/blockchain/v10/documents/certification.rs
@@ -15,11 +15,16 @@
 
 //! Wrappers around Certification documents.
 
+extern crate serde;
+
+use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::{ed25519, PublicKey, Signature};
 use regex::Regex;
 
-use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder,
-                                 V10Document, V10DocumentParsingError};
+use blockchain::v10::documents::{
+    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
+    V10DocumentParsingError,
+};
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -86,6 +91,10 @@ impl Document for CertificationDocument {
         &self.currency
     }
 
+    fn blockstamp(&self) -> Blockstamp {
+        self.blockstamp
+    }
+
     fn issuers(&self) -> &Vec<ed25519::PublicKey> {
         &self.issuers
     }
@@ -115,6 +124,15 @@ impl TextDocument for CertificationDocument {
     }
 }
 
+impl Serialize for CertificationDocument {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.serialize_str(&self.generate_compact_text())
+    }
+}
+
 impl IntoSpecializedDocument<BlockchainProtocol> for CertificationDocument {
     fn into_specialized(self) -> BlockchainProtocol {
         BlockchainProtocol::V10(Box::new(V10Document::Certification(Box::new(self))))
diff --git a/documents/blockchain/v10/documents/identity.rs b/documents/blockchain/v10/documents/identity.rs
index 9eb9417791b6253f6e899807e8ad05e509b57919..6e986565b04dc04222ff93ed31b3509b7fb4b7be 100644
--- a/documents/blockchain/v10/documents/identity.rs
+++ b/documents/blockchain/v10/documents/identity.rs
@@ -15,11 +15,16 @@
 
 //! Wrappers around Identity documents.
 
+extern crate serde;
+
+use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::{ed25519, PublicKey};
 use regex::Regex;
 
-use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder,
-                                 V10Document, V10DocumentParsingError};
+use blockchain::v10::documents::{
+    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
+    V10DocumentParsingError,
+};
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -71,6 +76,10 @@ impl Document for IdentityDocument {
         &self.currency
     }
 
+    fn blockstamp(&self) -> Blockstamp {
+        self.blockstamp
+    }
+
     fn issuers(&self) -> &Vec<ed25519::PublicKey> {
         &self.issuers
     }
@@ -100,6 +109,15 @@ impl TextDocument for IdentityDocument {
     }
 }
 
+impl Serialize for IdentityDocument {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.serialize_str(&self.generate_compact_text())
+    }
+}
+
 impl IntoSpecializedDocument<BlockchainProtocol> for IdentityDocument {
     fn into_specialized(self) -> BlockchainProtocol {
         BlockchainProtocol::V10(Box::new(V10Document::Identity(self)))
diff --git a/documents/blockchain/v10/documents/membership.rs b/documents/blockchain/v10/documents/membership.rs
index f56937b2055212295ebae95bcc0d03d66dce4089..0cc53d51b5521471a4aa2719963e94a18704dbdf 100644
--- a/documents/blockchain/v10/documents/membership.rs
+++ b/documents/blockchain/v10/documents/membership.rs
@@ -15,11 +15,16 @@
 
 //! Wrappers around Membership documents.
 
+extern crate serde;
+
+use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::{ed25519, PublicKey};
 use regex::Regex;
 
-use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder,
-                                 V10Document, V10DocumentParsingError};
+use blockchain::v10::documents::{
+    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
+    V10DocumentParsingError,
+};
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -92,6 +97,10 @@ impl Document for MembershipDocument {
         &self.currency
     }
 
+    fn blockstamp(&self) -> Blockstamp {
+        self.blockstamp
+    }
+
     fn issuers(&self) -> &Vec<ed25519::PublicKey> {
         &self.issuers
     }
@@ -122,6 +131,15 @@ impl TextDocument for MembershipDocument {
     }
 }
 
+impl Serialize for MembershipDocument {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.serialize_str(&self.generate_compact_text())
+    }
+}
+
 impl IntoSpecializedDocument<BlockchainProtocol> for MembershipDocument {
     fn into_specialized(self) -> BlockchainProtocol {
         BlockchainProtocol::V10(Box::new(V10Document::Membership(self)))
diff --git a/documents/blockchain/v10/documents/mod.rs b/documents/blockchain/v10/documents/mod.rs
index bf8658d5d4aa5475934833d96355af5891b9e919..3557543aabb1be765eb61f36933a895a55c5eba1 100644
--- a/documents/blockchain/v10/documents/mod.rs
+++ b/documents/blockchain/v10/documents/mod.rs
@@ -32,13 +32,15 @@ pub mod revocation;
 pub mod transaction;
 
 pub use blockchain::v10::documents::block::BlockDocument;
-pub use blockchain::v10::documents::certification::{CertificationDocument,
-                                                    CertificationDocumentParser};
+pub use blockchain::v10::documents::certification::{
+    CertificationDocument, CertificationDocumentParser,
+};
 pub use blockchain::v10::documents::identity::{IdentityDocument, IdentityDocumentBuilder};
 pub use blockchain::v10::documents::membership::{MembershipDocument, MembershipDocumentParser};
 pub use blockchain::v10::documents::revocation::{RevocationDocument, RevocationDocumentParser};
-pub use blockchain::v10::documents::transaction::{TransactionDocument, TransactionDocumentBuilder,
-                                                  TransactionDocumentParser};
+pub use blockchain::v10::documents::transaction::{
+    TransactionDocument, TransactionDocumentBuilder, TransactionDocumentParser,
+};
 
 // Use of lazy_static so the regex is only compiled at first use.
 lazy_static! {
diff --git a/documents/blockchain/v10/documents/revocation.rs b/documents/blockchain/v10/documents/revocation.rs
index 7568a35560420d73f0b8b6a9573274a3b2dd1ab9..b954ae13b2ead8be53710732e66daadf3ae3eb26 100644
--- a/documents/blockchain/v10/documents/revocation.rs
+++ b/documents/blockchain/v10/documents/revocation.rs
@@ -15,11 +15,16 @@
 
 //! Wrappers around Revocation documents.
 
+extern crate serde;
+
+use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::{ed25519, PublicKey, Signature};
 use regex::Regex;
 
-use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder,
-                                 V10Document, V10DocumentParsingError};
+use blockchain::v10::documents::{
+    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
+    V10DocumentParsingError,
+};
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -75,6 +80,10 @@ impl Document for RevocationDocument {
         &self.currency
     }
 
+    fn blockstamp(&self) -> Blockstamp {
+        unimplemented!()
+    }
+
     fn issuers(&self) -> &Vec<ed25519::PublicKey> {
         &self.issuers
     }
@@ -102,6 +111,15 @@ impl TextDocument for RevocationDocument {
     }
 }
 
+impl Serialize for RevocationDocument {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.serialize_str(&self.generate_compact_text())
+    }
+}
+
 impl IntoSpecializedDocument<BlockchainProtocol> for RevocationDocument {
     fn into_specialized(self) -> BlockchainProtocol {
         BlockchainProtocol::V10(Box::new(V10Document::Revocation(Box::new(self))))
diff --git a/documents/blockchain/v10/documents/transaction.rs b/documents/blockchain/v10/documents/transaction.rs
index 5e0a117b638a68ff43772a87ebb38540d3995763..efcf04a7e1252862277bde9898b73b450bf415ee 100644
--- a/documents/blockchain/v10/documents/transaction.rs
+++ b/documents/blockchain/v10/documents/transaction.rs
@@ -15,14 +15,20 @@
 
 //! Wrappers around Transaction documents.
 
+extern crate serde;
+
 use std::ops::Deref;
 
 use duniter_crypto::keys::{ed25519, PublicKey};
 use regex::Regex;
 use regex::RegexBuilder;
 
-use blockchain::v10::documents::{StandardTextDocumentParser, TextDocument, TextDocumentBuilder,
-                                 V10Document, V10DocumentParsingError};
+use self::serde::ser::{Serialize, Serializer};
+
+use blockchain::v10::documents::{
+    StandardTextDocumentParser, TextDocument, TextDocumentBuilder, V10Document,
+    V10DocumentParsingError,
+};
 use blockchain::{BlockchainProtocol, Document, DocumentBuilder, IntoSpecializedDocument};
 use Blockstamp;
 
@@ -357,7 +363,7 @@ impl ToString for TransactionOutput {
 }
 
 impl TransactionOutput {
-    /// Parse Transaction Ouput from string.
+    /// Parse Transaction Output from string.
     pub fn parse_from_str(source: &str) -> Result<TransactionOutput, V10DocumentParsingError> {
         if let Some(caps) = OUTPUT_REGEX.captures(source) {
             let amount = caps["amount"].parse().expect("fail to parse output amount");
@@ -419,6 +425,10 @@ impl Document for TransactionDocument {
         &self.currency
     }
 
+    fn blockstamp(&self) -> Blockstamp {
+        self.blockstamp
+    }
+
     fn issuers(&self) -> &Vec<ed25519::PublicKey> {
         &self.issuers
     }
@@ -458,11 +468,17 @@ impl TextDocument for TransactionDocument {
             outputs_str.push_str("\n");
             outputs_str.push_str(&output.to_string());
         }
+        let mut comment_str = self.comment.clone();
+        if !comment_str.is_empty() {
+            comment_str.push_str("\n");
+        }
         let mut signatures_str = String::from("");
         for sig in self.signatures.clone() {
-            signatures_str.push_str("\n");
             signatures_str.push_str(&sig.to_string());
+            signatures_str.push_str("\n");
         }
+        // Remove end line step
+        signatures_str.pop();
         format!(
             "TX:10:{issuers_count}:{inputs_count}:{unlocks_count}:{outputs_count}:{has_comment}:{locktime}
 {blockstamp}{issuers}{inputs}{unlocks}{outputs}\n{comment}{signatures}",
@@ -477,12 +493,22 @@ impl TextDocument for TransactionDocument {
             inputs = inputs_str,
             unlocks = unlocks_str,
             outputs = outputs_str,
-            comment = self.comment,
+            comment = comment_str,
             signatures = signatures_str,
         )
     }
 }
 
+impl Serialize for TransactionDocument {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let compact_text = self.generate_compact_text();
+        serializer.serialize_str(&compact_text.replace("\n", "$"))
+    }
+}
+
 impl IntoSpecializedDocument<BlockchainProtocol> for TransactionDocument {
     fn into_specialized(self) -> BlockchainProtocol {
         BlockchainProtocol::V10(Box::new(V10Document::Transaction(Box::new(self))))
diff --git a/documents/lib.rs b/documents/lib.rs
index 7b360c1bc061797119d80bb00c1d51e1200ab302..f80ced520879f3dfb3e6e3a488513ae7fba74699 100644
--- a/documents/lib.rs
+++ b/documents/lib.rs
@@ -30,15 +30,18 @@ extern crate duniter_crypto;
 extern crate lazy_static;
 extern crate linked_hash_map;
 extern crate regex;
+extern crate serde;
 
+use std::cmp::Ordering;
 use std::fmt::{Debug, Display, Error, Formatter};
 
+use self::serde::ser::{Serialize, Serializer};
 use duniter_crypto::keys::BaseConvertionError;
 
 pub mod blockchain;
 
 /// A block Id.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Debug, Copy, Clone, Ord, PartialEq, PartialOrd, Eq, Hash)]
 pub struct BlockId(pub u32);
 
 impl Display for BlockId {
@@ -50,7 +53,7 @@ impl Display for BlockId {
 /// A hash wrapper.
 ///
 /// A hash is often provided as string composed of 64 hexadecimal character (0 to 9 then A to F).
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd, Hash)]
 pub struct Hash(pub [u8; 32]);
 
 impl Display for Hash {
@@ -119,8 +122,8 @@ impl Hash {
 }
 
 /// Wrapper of a block hash.
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct BlockHash(Hash);
+#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd, Hash)]
+pub struct BlockHash(pub Hash);
 
 impl Display for BlockHash {
     fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
@@ -186,6 +189,31 @@ impl Default for Blockstamp {
     }
 }
 
+impl Serialize for Blockstamp {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        serializer.serialize_str(&format!("{}-{}", self.id, self.hash))
+    }
+}
+
+impl PartialOrd for Blockstamp {
+    fn partial_cmp(&self, other: &Blockstamp) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Blockstamp {
+    fn cmp(&self, other: &Blockstamp) -> Ordering {
+        if self.id == other.id {
+            self.hash.cmp(&other.hash)
+        } else {
+            self.id.cmp(&other.id)
+        }
+    }
+}
+
 impl Blockstamp {
     /// Create a `BlockUId` from a text.
     pub fn from_string(src: &str) -> Result<Blockstamp, BlockUIdParseError> {