diff --git a/Cargo.lock b/Cargo.lock
index 57ecf4604f7e365b05db6b611245454874183268..9648b789bb4d65f41aacf4c31367e66662587faa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -94,7 +94,7 @@ dependencies = [
 
 [[package]]
 name = "duniter-documents"
-version = "0.4.1"
+version = "0.5.0"
 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)",
diff --git a/crypto/keys/ed25519.rs b/crypto/keys/ed25519.rs
index 1d3e50a046d647391b6b47980802eef5fd8daaf3..2ed603663b048770633b8277ba1749993c151705 100644
--- a/crypto/keys/ed25519.rs
+++ b/crypto/keys/ed25519.rs
@@ -19,10 +19,12 @@
 //!
 //! [`KeyPairGenerator`]: struct.KeyPairGenerator.html
 
+use std::collections::hash_map::DefaultHasher;
 use std::fmt::Display;
 use std::fmt::Error;
 use std::fmt::Formatter;
 use std::fmt::Debug;
+use std::hash::{Hash, Hasher};
 
 use base58::{FromBase58, FromBase58Error, ToBase58};
 use base64;
@@ -35,6 +37,13 @@ use super::{BaseConvertionError, PrivateKey as PrivateKeyMethods, PublicKey as P
 #[derive(Clone, Copy)]
 pub struct Signature(pub [u8; 64]);
 
+impl Hash for Signature {
+    fn hash<H: Hasher>(&self, _state: &mut H) {
+        let mut hasher = DefaultHasher::new();
+        Hash::hash_slice(&self.0, &mut hasher);
+    }
+}
+
 impl super::Signature for Signature {
     fn from_base64(base64_data: &str) -> Result<Signature, BaseConvertionError> {
         match base64::decode(base64_data) {
diff --git a/documents/Cargo.toml b/documents/Cargo.toml
index c43678b6062a4fb78d84bb7b415fa5e3417b0276..2a42d7fd9d4e01bde39d80f0f12c663078a1707c 100644
--- a/documents/Cargo.toml
+++ b/documents/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "duniter-documents"
-version = "0.4.1"
+version = "0.5.0"
 authors = ["nanocryk <nanocryk@duniter.org>", "elois <elois@ifee.fr>"]
 description = "Handles Duniter documents"
 repository = "https://git.duniter.org/nodes/rust/duniter-rs"
diff --git a/documents/blockchain/mod.rs b/documents/blockchain/mod.rs
index 5f997b0c9fd18f8dfc1443f8ca304c22a9c1d42f..97e35dd8508f605dc7c3ae697acdfc26e652e42b 100644
--- a/documents/blockchain/mod.rs
+++ b/documents/blockchain/mod.rs
@@ -25,7 +25,7 @@ pub mod v10;
 #[derive(Debug)]
 pub enum BlockchainProtocol {
     /// Version 10.
-    V10(v10::documents::V10Document),
+    V10(Box<v10::documents::V10Document>),
     /// Version 11. (not done yet, but defined for tests)
     V11(),
 }
diff --git a/documents/blockchain/v10/documents/identity.rs b/documents/blockchain/v10/documents/identity.rs
index 05762ee565f2683e3c4e2a1cd091d4a1bc46b63d..ac7622ec78cb27ce47dfb36c28668dd7f2980b35 100644
--- a/documents/blockchain/v10/documents/identity.rs
+++ b/documents/blockchain/v10/documents/identity.rs
@@ -32,7 +32,7 @@ lazy_static! {
 /// Wrap an Identity document.
 ///
 /// Must be created by parsing a text document or using a builder.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Hash)]
 pub struct IdentityDocument {
     /// Document as text.
     ///
@@ -92,7 +92,7 @@ impl TextDocument for IdentityDocument {
 
 impl IntoSpecializedDocument<BlockchainProtocol> for IdentityDocument {
     fn into_specialized(self) -> BlockchainProtocol {
-        BlockchainProtocol::V10(V10Document::Identity(self))
+        BlockchainProtocol::V10(Box::new(V10Document::Identity(self)))
     }
 }
 
diff --git a/documents/blockchain/v10/documents/membership.rs b/documents/blockchain/v10/documents/membership.rs
index fb1d2d12baeea41c74f4da7ee029f99a7399a1f7..0fab5443d53f047616407afbc153dc491c60289d 100644
--- a/documents/blockchain/v10/documents/membership.rs
+++ b/documents/blockchain/v10/documents/membership.rs
@@ -34,7 +34,7 @@ lazy_static! {
 }
 
 /// Type of a Membership.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Hash)]
 pub enum MembershipType {
     /// The member wishes to opt-in.
     In(),
@@ -45,7 +45,7 @@ pub enum MembershipType {
 /// Wrap an Membership document.
 ///
 /// Must be created by parsing a text document or using a builder.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Hash)]
 pub struct MembershipDocument {
     /// Document as text.
     ///
@@ -113,7 +113,7 @@ impl TextDocument for MembershipDocument {
 
 impl IntoSpecializedDocument<BlockchainProtocol> for MembershipDocument {
     fn into_specialized(self) -> BlockchainProtocol {
-        BlockchainProtocol::V10(V10Document::Membership(self))
+        BlockchainProtocol::V10(Box::new(V10Document::Membership(self)))
     }
 }
 
diff --git a/documents/lib.rs b/documents/lib.rs
index e3d8b38171011e2329eb1d41623b99ffae96bbcc..d445c12f94a8f699c25d279c25c11b8896cf7a30 100644
--- a/documents/lib.rs
+++ b/documents/lib.rs
@@ -36,7 +36,7 @@ use duniter_crypto::keys::BaseConvertionError;
 pub mod blockchain;
 
 /// A block Id.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct BlockId(pub u32);
 
 impl Display for BlockId {
@@ -48,7 +48,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)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Hash(pub [u8; 32]);
 
 impl Display for Hash {
@@ -110,7 +110,7 @@ impl Hash {
 }
 
 /// Wrapper of a block hash.
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct BlockHash(Hash);
 
 impl Display for BlockHash {
@@ -148,7 +148,7 @@ pub enum BlockUIdParseError {
 ///
 /// [`BlockId`]: struct.BlockId.html
 /// [`BlockHash`]: struct.BlockHash.html
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Blockstamp {
     /// Block Id.
     pub id: BlockId,