diff --git a/documents/blockchain/v10/documents/block.rs b/documents/blockchain/v10/documents/block.rs
index da2cbe06ae695a3736324cf7c545d9538641032a..d547e0d12ef35c3cf914d2317dafff18c005d096 100644
--- a/documents/blockchain/v10/documents/block.rs
+++ b/documents/blockchain/v10/documents/block.rs
@@ -15,7 +15,9 @@
 
 //! Wrappers around Block document.
 
-use duniter_crypto::keys::ed25519;
+use crypto::digest::Digest;
+use crypto::sha2::Sha256;
+use duniter_crypto::keys::{PrivateKey, ed25519};
 
 use Hash;
 use blockchain::{BlockchainProtocol, Document, IntoSpecializedDocument};
@@ -116,7 +118,7 @@ pub struct BlockDocument {
     /// Issuer of the previous block
     previous_issuer: Option<ed25519::PublicKey>,
     /// Hash of the deterministic content of the block
-    inner_hash: Hash,
+    inner_hash: Option<Hash>,
     /// Amount of new dividend created at this block, None if no dividend is created at this block
     dividend: Option<usize>,
     /// Identities
@@ -135,45 +137,38 @@ pub struct BlockDocument {
     certifications: Vec<CertificationDocument>,
     /// Transactions
     transactions: Vec<TransactionDocument>,
-    /// Raw format
-    raw: Option<String>,
+    /// Part to sign
+    inner_hash_and_nonce_str: String,
 }
 
-impl Document for BlockDocument {
-    type PublicKey = ed25519::PublicKey;
-    type CurrencyType = str;
-
-    fn version(&self) -> u16 {
-        10
+impl BlockDocument {
+    fn _compute_inner_hash(&mut self) {
+        let mut sha256 = Sha256::new();
+        sha256.input_str(&self.generate_compact_inner_text());
+        self.inner_hash = Some(Hash::from_hex(&sha256.result_str()).unwrap());
     }
-
-    fn currency(&self) -> &str {
-        &self.currency
-    }
-
-    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
-        &self.issuers
-    }
-
-    fn signatures(&self) -> &Vec<ed25519::Signature> {
-        &self.signatures
+    fn _change_nonce(&mut self, new_nonce: u64) {
+        self.nonce = new_nonce;
+        self.inner_hash_and_nonce_str = format!(
+            "InnerHash: {}\nNonce: {}\n",
+            self.inner_hash.unwrap().to_hex(),
+            self.nonce
+        );
     }
-
-    fn as_bytes(&self) -> &[u8] {
-        if let Some(ref raw_block) = self.raw {
-            raw_block.as_bytes()
-        } else {
-            panic!("Fatal error: try to call block.as_bytes() before generate raw format !");
-        }
+    fn _sign(&mut self, privkey: ed25519::PrivateKey) {
+        self.signatures = vec![privkey.sign(self.inner_hash_and_nonce_str.as_bytes())];
     }
-}
-
-impl TextDocument for BlockDocument {
-    fn as_text(&self) -> &str {
-        panic!();
+    fn _compute_hash(&mut self) {
+        let mut sha256 = Sha256::new();
+        sha256.input_str(&format!(
+            "InnerHash: {}\nNonce: {}\n{}\n",
+            self.inner_hash.unwrap().to_hex(),
+            self.nonce,
+            self.signatures[0]
+        ));
+        self.hash = Some(Hash::from_hex(&sha256.result_str()).unwrap());
     }
-
-    fn generate_compact_text(&self) -> String {
+    fn generate_compact_inner_text(&self) -> String {
         let mut identities_str = String::from("");
         for identity in self.identities.clone() {
             identities_str.push_str("\n");
@@ -223,7 +218,7 @@ impl TextDocument for BlockDocument {
             "Version: 10
 Type: Block
 Currency: {currency}
-Number:  {block_number}
+Number: {block_number}
 PoWMin: {pow_min}
 Time: {time}
 MedianTime: {median_time}
@@ -243,8 +238,7 @@ Revoked:{revoked}
 Excluded:{excluded}
 Certifications:{certifications}
 Transactions:{transactions}
-InnerHash: {inner_hash}
-Nonce: ",
+",
             currency = self.currency,
             block_number = self.number,
             pow_min = self.pow_min,
@@ -266,7 +260,46 @@ Nonce: ",
             excluded = excludeds_str,
             certifications = certifications_str,
             transactions = transactions_str,
-            inner_hash = self.inner_hash,
+        )
+    }
+}
+
+impl Document for BlockDocument {
+    type PublicKey = ed25519::PublicKey;
+    type CurrencyType = str;
+
+    fn version(&self) -> u16 {
+        10
+    }
+
+    fn currency(&self) -> &str {
+        &self.currency
+    }
+
+    fn issuers(&self) -> &Vec<ed25519::PublicKey> {
+        &self.issuers
+    }
+
+    fn signatures(&self) -> &Vec<ed25519::Signature> {
+        &self.signatures
+    }
+
+    fn as_bytes(&self) -> &[u8] {
+        self.inner_hash_and_nonce_str.as_bytes()
+    }
+}
+
+impl TextDocument for BlockDocument {
+    fn as_text(&self) -> &str {
+        panic!();
+    }
+
+    fn generate_compact_text(&self) -> String {
+        let compact_inner_text = self.generate_compact_inner_text();
+        format!(
+            "{}InnerHash: {}\nNonce: ",
+            compact_inner_text,
+            self.inner_hash.unwrap().to_hex()
         )
     }
 }
@@ -280,7 +313,7 @@ impl IntoSpecializedDocument<BlockchainProtocol> for BlockDocument {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use duniter_crypto::keys::{PrivateKey, PublicKey, Signature};
+    use duniter_crypto::keys::{PublicKey, Signature};
     use blockchain::{Document, VerificationResult};
 
     #[test]
@@ -304,7 +337,7 @@ mod tests {
             parameters: None,
             previous_hash: Some(Hash::from_hex("0000001F8AACF6764135F3E5D0D4E8358A3CBE537A4BF71152A00CC442EFD136").expect("fail to parse previous_hash")),
             previous_issuer: Some(ed25519::PublicKey::from_base58("38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE").unwrap()),
-            inner_hash: Hash::from_hex("95948AC4D45E46DA07CE0713EDE1CE0295C227EE4CA5557F73F56B7DD46FE89C").expect("fail to parse inner_hash"),
+            inner_hash: Some(Hash::from_hex("95948AC4D45E46DA07CE0713EDE1CE0295C227EE4CA5557F73F56B7DD46FE89C").expect("fail to parse inner_hash")),
             dividend: None,
             identities: Vec::new(),
             joiners: Vec::new(),
@@ -314,12 +347,17 @@ mod tests {
             excluded: Vec::new(),
             certifications: Vec::new(),
             transactions: Vec::new(),
-            raw: None,
+            inner_hash_and_nonce_str: String::new(),
         };
-        let mut raw_block = block.generate_compact_text();
-        println!("{}", raw_block);
+        // test inner_hash computation
+        block._compute_inner_hash();
         assert_eq!(
-            raw_block,
+            block.inner_hash.unwrap().to_hex(),
+            "95948AC4D45E46DA07CE0713EDE1CE0295C227EE4CA5557F73F56B7DD46FE89C"
+        );
+        // test generate_compact_text()
+        assert_eq!(
+            block.generate_compact_text(),
             "Version: 10
 Type: Block
 Currency: g1
@@ -346,8 +384,14 @@ Transactions:
 InnerHash: 95948AC4D45E46DA07CE0713EDE1CE0295C227EE4CA5557F73F56B7DD46FE89C
 Nonce: "
         );
-        raw_block.push_str("10500000089933");
-        block.raw = Some(raw_block.clone());
+        // Test signature validity
+        block._change_nonce(10500000089933);
         assert_eq!(block.verify_signatures(), VerificationResult::Valid());
+        // Test hash computation
+        block._compute_hash();
+        assert_eq!(
+            block.hash.unwrap().to_hex(),
+            "000002D3296A2D257D01F6FEE8AEC5C3E5779D04EA43F08901F41998FA97D9A1"
+        );
     }
 }
diff --git a/documents/blockchain/v10/documents/mod.rs b/documents/blockchain/v10/documents/mod.rs
index 8a02f2ee0cdfb65debe2d972ebc944e57f75da06..90d8fd78a49ffec58a119bc1a01cc45daa7c35d2 100644
--- a/documents/blockchain/v10/documents/mod.rs
+++ b/documents/blockchain/v10/documents/mod.rs
@@ -29,6 +29,7 @@ pub mod membership;
 pub mod certification;
 pub mod revocation;
 pub mod transaction;
+pub mod block;
 
 pub use blockchain::v10::documents::identity::{IdentityDocument, IdentityDocumentBuilder};
 pub use blockchain::v10::documents::membership::{MembershipDocument, MembershipDocumentParser};
@@ -37,6 +38,7 @@ pub use blockchain::v10::documents::certification::{CertificationDocument,
 pub use blockchain::v10::documents::revocation::{RevocationDocument, RevocationDocumentParser};
 pub use blockchain::v10::documents::transaction::{TransactionDocument, TransactionDocumentBuilder,
                                                   TransactionDocumentParser};
+pub use blockchain::v10::documents::block::BlockDocument;
 
 // Use of lazy_static so the regex is only compiled at first use.
 lazy_static! {
@@ -56,7 +58,7 @@ lazy_static! {
 #[derive(Debug, Clone)]
 pub enum V10Document {
     /// Block document.
-    Block(),
+    Block(Box<BlockDocument>),
 
     /// Transaction document.
     Transaction(Box<TransactionDocument>),
@@ -95,6 +97,13 @@ pub trait TextDocument: Document<PublicKey = ed25519::PublicKey, CurrencyType =
 
         text
     }
+
+    /// Generate document compact text.
+    /// the compact format is the one used in the blocks.
+    ///
+    /// - Don't contains leading signatures
+    /// - Contains line breaks on all line.
+    fn generate_compact_text(&self) -> String;
 }
 
 /// Trait for a V10 document builder.
@@ -105,13 +114,6 @@ pub trait TextDocumentBuilder: DocumentBuilder {
     /// - Contains line breaks on all line.
     fn generate_text(&self) -> String;
 
-    /// Generate document compact text.
-    /// the compact format is the one used in the blocks.
-    ///
-    /// - Don't contains leading signatures
-    /// - Contains line breaks on all line.
-    fn generate_compact_text(&self, signatures: Vec<ed25519::Signature>) -> String;
-
     /// Generate final document with signatures, and also return them in an array.
     ///
     /// Returns :