diff --git a/Cargo.lock b/Cargo.lock
index 73d671bfc9e556e3726f32884b3d78b403cdc2c9..99c9b4adab1844cd673c8641d2a1bf0133a75da5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -166,6 +166,11 @@ dependencies = [
  "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "difference"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "dirs"
 version = "1.0.2"
@@ -281,6 +286,7 @@ version = "0.8.0-a0.1"
 dependencies = [
  "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "duniter-crypto 0.2.0-a0.1",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -324,6 +330,7 @@ dependencies = [
  "duniter-documents 0.8.0-a0.1",
  "duniter-module 0.1.0-a0.1",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.1 (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.66 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -662,6 +669,15 @@ name = "pkg-config"
 version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "pretty_assertions"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "proc-macro2"
 version = "0.4.6"
@@ -1147,6 +1163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "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"
+"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
 "checksum dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37a76dd8b997af7107d0bb69d43903cf37153a18266f8b3fdb9911f28efb5444"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
@@ -1184,6 +1201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum pbr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "deb73390ab68d81992bd994d145f697451bb0b54fd39738e72eef32458ad6907"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
+"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
 "checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
diff --git a/crypto/keys/ed25519.rs b/crypto/keys/ed25519.rs
index ef762c258616e224de2b7fcce3d6d85f5fa59dad..edc0f5f20900847830a604775f7b30500ad4202e 100644
--- a/crypto/keys/ed25519.rs
+++ b/crypto/keys/ed25519.rs
@@ -134,6 +134,10 @@ impl super::Signature for Signature {
         }
     }
 
+    fn to_bytes_vector(&self) -> Vec<u8> {
+        self.0.to_vec()
+    }
+
     fn to_base64(&self) -> String {
         base64::encode(&self.0[..]) // need to take a slice for required trait `AsRef<[u8]>`
     }
@@ -215,6 +219,10 @@ impl super::PublicKey for PublicKey {
         }
     }
 
+    fn to_bytes_vector(&self) -> Vec<u8> {
+        self.0.to_vec()
+    }
+
     fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
         crypto::ed25519::verify(message, &self.0, &signature.0)
     }
diff --git a/crypto/keys/mod.rs b/crypto/keys/mod.rs
index 1bd615e17ff431f1fb7ab0fd6963f7ea5459a0d8..632781eab3144afc08617a3d415f0cd99c7d151e 100644
--- a/crypto/keys/mod.rs
+++ b/crypto/keys/mod.rs
@@ -103,6 +103,9 @@ pub trait Signature: Clone + Display + Debug + PartialEq + Eq + Hash {
     /// [`BaseConvertionError`]: enum.BaseConvertionError.html
     fn from_base64(base64_string: &str) -> Result<Self, BaseConvertionError>;
 
+    /// Convert Signature into butes vector
+    fn to_bytes_vector(&self) -> Vec<u8>;
+
     /// Encode the signature into Base64 string format.
     fn to_base64(&self) -> String;
 }
@@ -135,6 +138,12 @@ impl Signature for Sig {
     fn from_base64(_base64_string: &str) -> Result<Self, BaseConvertionError> {
         unimplemented!()
     }
+    fn to_bytes_vector(&self) -> Vec<u8> {
+        match *self {
+            Sig::Ed25519(ed25519_sig) => ed25519_sig.to_bytes_vector(),
+            Sig::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
     fn to_base64(&self) -> String {
         match *self {
             Sig::Ed25519(ed25519_sig) => ed25519_sig.to_base64(),
@@ -165,6 +174,9 @@ pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + Hash + ToBase58
     /// [`BaseConvertionError`]: enum.BaseConvertionError.html
     fn from_base58(base58_string: &str) -> Result<Self, BaseConvertionError>;
 
+    /// Convert into bytes vector
+    fn to_bytes_vector(&self) -> Vec<u8>;
+
     /// Verify a signature with this public key.
     fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
 }
@@ -208,6 +220,12 @@ impl PublicKey for PubKey {
     fn from_base58(_base58_string: &str) -> Result<Self, BaseConvertionError> {
         unimplemented!()
     }
+    fn to_bytes_vector(&self) -> Vec<u8> {
+        match *self {
+            PubKey::Ed25519(ed25519_pubkey) => ed25519_pubkey.to_bytes_vector(),
+            PubKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
+        }
+    }
     fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
         match *self {
             PubKey::Ed25519(ed25519_pubkey) => if let Sig::Ed25519(ed25519_sig) = signature {
diff --git a/documents/Cargo.toml b/documents/Cargo.toml
index 4c541dcb0bbaacf5f805952a63a81cd377e02389..0f6fd6ff01c1ff0d37fab7097e9a8d19ec22358e 100644
--- a/documents/Cargo.toml
+++ b/documents/Cargo.toml
@@ -14,6 +14,7 @@ path = "lib.rs"
 [dependencies]
 base58 = "0.1.*"
 base64 = "0.9.*"
+byteorder = "1.2.3"
 duniter-crypto = { path = "../crypto" }
 lazy_static = "1.0.*"
 linked-hash-map = "0.5.*"
diff --git a/documents/lib.rs b/documents/lib.rs
index 1ea9914223164135b15c3b245f0ad71d2135ff89..aaf595cb3847a1436826e1cf1cb3cbe6e921d156 100644
--- a/documents/lib.rs
+++ b/documents/lib.rs
@@ -30,15 +30,19 @@ extern crate serde_derive;
 
 extern crate base58;
 extern crate base64;
+extern crate byteorder;
 extern crate crypto;
 extern crate duniter_crypto;
 extern crate linked_hash_map;
 extern crate regex;
 extern crate serde;
 
+use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
 use duniter_crypto::keys::BaseConvertionError;
 use std::cmp::Ordering;
 use std::fmt::{Debug, Display, Error, Formatter};
+use std::io::Cursor;
+use std::mem;
 
 pub mod blockchain;
 
@@ -78,6 +82,11 @@ impl Default for Hash {
 }
 
 impl Hash {
+    /// Convert Hash into bytes vector
+    pub fn to_bytes_vector(&self) -> Vec<u8> {
+        self.0.to_vec()
+    }
+
     /// Convert a `Hash` to an hex string.
     pub fn to_hex(&self) -> String {
         let strings: Vec<String> = self.0.iter().map(|b| format!("{:02X}", b)).collect();
@@ -210,7 +219,57 @@ impl Ord for Blockstamp {
     }
 }
 
+#[derive(Debug)]
+/// Error when converting a byte vector to Blockstamp
+pub enum ReadBytesBlockstampError {
+    /// Bytes vector is too short
+    TooShort(),
+    /// Bytes vector is too long
+    TooLong(),
+    /// IoError
+    IoError(::std::io::Error),
+}
+
+impl From<::std::io::Error> for ReadBytesBlockstampError {
+    fn from(e: ::std::io::Error) -> Self {
+        ReadBytesBlockstampError::IoError(e)
+    }
+}
+
 impl Blockstamp {
+    /// Convert Blockstamp into bytes vector
+    pub fn to_bytes_vector(&self) -> Vec<u8> {
+        let mut bytes = Vec::with_capacity(36);
+        // BlockId
+        let mut buffer = [0u8; mem::size_of::<u32>()];
+        buffer
+            .as_mut()
+            .write_u32::<BigEndian>(self.id.0)
+            .expect("Unable to write");
+        bytes.extend_from_slice(&buffer);
+        // BlockHash
+        bytes.extend(self.hash.0.to_bytes_vector());
+        bytes
+    }
+    /// Create Blockstamp from bytes slice
+    pub fn from_bytes_slice(bytes: &[u8]) -> Result<Blockstamp, ReadBytesBlockstampError> {
+        if bytes.len() > 36 {
+            Err(ReadBytesBlockstampError::TooLong())
+        } else if bytes.len() < 36 {
+            Err(ReadBytesBlockstampError::TooShort())
+        } else {
+            // read id
+            let mut id_bytes = Cursor::new(bytes[0..4].to_vec());
+            let id = BlockId(id_bytes.read_u32::<BigEndian>()?);
+            // read hash
+            let mut hash_datas: [u8; 32] = [0u8; 32];
+            hash_datas.copy_from_slice(&bytes[4..36]);
+            let hash = BlockHash(Hash(hash_datas));
+            // return Blockstamp
+            Ok(Blockstamp { id, hash })
+        }
+    }
+
     /// Create a `BlockUId` from a text.
     pub fn from_string(src: &str) -> Result<Blockstamp, BlockUIdParseError> {
         let mut split = src.split('-');
diff --git a/network/Cargo.toml b/network/Cargo.toml
index f9e6c5df9d36b1a7cf1fcfef00fa9d8e2bd0a484..6313e20e8d5c8f85dfea8053fd01cc8b0ff93512 100644
--- a/network/Cargo.toml
+++ b/network/Cargo.toml
@@ -20,6 +20,9 @@ serde = "1.0.*"
 serde_derive = "1.0.*"
 serde_json = "1.0.*"
 
+[dev-dependencies]
+pretty_assertions = "0.5.1"
+
 [features]
 # Treat warnings as a build error.
 strict = []
\ No newline at end of file
diff --git a/network/lib.rs b/network/lib.rs
index 4df1a8168d0ca02df5611f09e6f2b95cdc57e9c6..c6d1db69c60592121c9eecae58d3d14363f1b813 100644
--- a/network/lib.rs
+++ b/network/lib.rs
@@ -24,6 +24,9 @@
 
 #[macro_use]
 extern crate lazy_static;
+//#[cfg(test)]
+//#[macro_use]
+//extern crate pretty_assertions;
 #[macro_use]
 extern crate serde_derive;
 
@@ -50,7 +53,7 @@ use duniter_documents::blockchain::Document;
 use duniter_documents::{BlockHash, BlockId, Blockstamp, Hash};
 use duniter_module::*;
 use network_head::NetworkHead;
-use network_peer::NetworkPeer;
+use network_peer::PeerCard;
 use std::fmt::{Debug, Display, Error, Formatter};
 use std::ops::Deref;
 use std::sync::mpsc;
@@ -82,34 +85,34 @@ pub struct SyncEndpoint {
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
 /// Random identifier with which several Duniter nodes with the same network keypair can be differentiated
-pub struct NodeUUID(pub u32);
+pub struct NodeId(pub u32);
 
-impl Default for NodeUUID {
-    fn default() -> NodeUUID {
-        NodeUUID(0)
+impl Default for NodeId {
+    fn default() -> NodeId {
+        NodeId(0)
     }
 }
 
-impl Display for NodeUUID {
+impl Display for NodeId {
     fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
         write!(f, "{:x}", self.0)
     }
 }
 
-impl<'a> From<&'a str> for NodeUUID {
-    fn from(source: &'a str) -> NodeUUID {
-        NodeUUID(u32::from_str_radix(source, 16).expect("Fail to parse NodeUUID"))
+impl<'a> From<&'a str> for NodeId {
+    fn from(source: &'a str) -> NodeId {
+        NodeId(u32::from_str_radix(source, 16).expect("Fail to parse NodeId"))
     }
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 /// Complete identifier of a duniter node.
-pub struct NodeFullId(pub NodeUUID, pub PubKey);
+pub struct NodeFullId(pub NodeId, pub PubKey);
 
 impl Default for NodeFullId {
     fn default() -> NodeFullId {
         NodeFullId(
-            NodeUUID::default(),
+            NodeId::default(),
             PubKey::Ed25519(
                 ed25519::PublicKey::from_base58("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
                     .unwrap(),
@@ -318,7 +321,7 @@ pub enum NetworkEvent {
     /// Receiving Pending Documents
     ReceiveDocuments(Vec<NetworkDocument>),
     /// Receipt of peer cards
-    ReceivePeers(Vec<NetworkPeer>),
+    ReceivePeers(Vec<PeerCard>),
     /// Receiving heads
     ReceiveHeads(Vec<NetworkHead>),
 }
@@ -335,7 +338,7 @@ mod tests {
             ed25519::PublicKey::from_base58("D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx")
                 .unwrap(),
         );
-        let node_id = NodeUUID(u32::from_str_radix("c1c39a0a", 16).unwrap());
+        let node_id = NodeId(u32::from_str_radix("c1c39a0a", 16).unwrap());
         let full_id = NodeFullId(node_id, issuer);
         assert_eq!(
             NetworkEndpoint::parse_from_raw("WS2P c1c39a0a i3.ifee.fr 80 /ws2p", issuer, 0, 0, 1),
@@ -361,7 +364,7 @@ mod tests {
             ed25519::PublicKey::from_base58("5gJYnQp8v7bWwk7EWRoL8vCLof1r3y9c6VDdnGSM1GLv")
                 .unwrap(),
         );
-        let node_id = NodeUUID(u32::from_str_radix("cb06a19b", 16).unwrap());
+        let node_id = NodeId(u32::from_str_radix("cb06a19b", 16).unwrap());
         let full_id = NodeFullId(node_id, issuer);
         assert_eq!(
             NetworkEndpoint::parse_from_raw("WS2P cb06a19b g1.imirhil.fr 53012 /", issuer, 0, 0, 1),
diff --git a/network/network_endpoint.rs b/network/network_endpoint.rs
index 85180159f25b470db77da34585602b6298e14331..b584d5f7ffa5bae3867390143fdfdc570c18594e 100644
--- a/network/network_endpoint.rs
+++ b/network/network_endpoint.rs
@@ -23,7 +23,7 @@ extern crate regex;
 extern crate serde;
 
 use self::regex::Regex;
-use super::{NodeFullId, NodeUUID};
+use super::{NodeFullId, NodeId};
 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
 use duniter_crypto::keys::PubKey;
 use duniter_documents::Hash;
@@ -128,7 +128,7 @@ pub struct NetworkEndpointV10 {
     /// API Name
     pub api: NetworkEndpointApi,
     /// Node unique identifier
-    pub node_id: Option<NodeUUID>,
+    pub node_id: Option<NodeId>,
     /// Public key of the node declaring this endpoint
     pub issuer: PubKey,
     /// NodeFullID hash
@@ -230,7 +230,7 @@ impl EndpointV11Api {
         }
     }
     /// Convert api name into bytes vector
-    pub fn into_bytes(&self) -> Vec<u8> {
+    pub fn to_bytes_vector(&self) -> Vec<u8> {
         match *self {
             EndpointV11Api::Bin(api_bin_name) => vec![api_bin_name.into_u8()],
             EndpointV11Api::Str(ref api_name) => api_name.as_bytes().to_vec(),
@@ -291,7 +291,7 @@ impl EndpointV11NetworkFeatures {
         self.0.len() as u8
     }
     /// Convert Self into bytes
-    pub fn into_bytes(&self) -> &[u8] {
+    pub fn to_bytes_slice(&self) -> &[u8] {
         &self.0
     }
     /// network feature ip_v4 is enable ?
@@ -434,13 +434,13 @@ impl EndpointV11 {
         }
     }
     /// Convert endpoint into bytes vector
-    pub fn into_bytes(self) -> Vec<u8> {
+    pub fn into_bytes_vector(self) -> Vec<u8> {
         let endpoint_size = self.compute_endpoint_size();
         let mut binary_endpoint = Vec::with_capacity(endpoint_size.total_size());
         binary_endpoint.push(endpoint_size.api_size);
         binary_endpoint.push(endpoint_size.host_size);
         binary_endpoint.push(endpoint_size.path_size);
-        binary_endpoint.append(&mut self.api.into_bytes());
+        binary_endpoint.append(&mut self.api.to_bytes_vector());
         // api_version
         let mut buffer = [0u8; mem::size_of::<u16>()];
         buffer
@@ -451,7 +451,7 @@ impl EndpointV11 {
         // nf_size
         binary_endpoint.push(endpoint_size.nf_size);
         // network_features
-        binary_endpoint.extend_from_slice(&self.network_features.into_bytes());
+        binary_endpoint.extend_from_slice(&self.network_features.to_bytes_slice());
         binary_endpoint.push(endpoint_size.af_size);
         binary_endpoint.append(&mut self.api_features.clone());
         if let Some(ip_v4) = self.ip_v4 {
@@ -624,10 +624,14 @@ impl EndpointV11 {
                             "All api features must be declared !",
                         )));
                     }
-                    for i in (4 + network_features_count)
-                        ..(4 + network_features_count + api_features_count)
+                    /*for i in (4 + network_features_count)
+                        ..(4 + network_features_count + api_features_count)*/
+                    for str_feature in raw_ep_elements
+                        .iter()
+                        .take(4 + network_features_count + api_features_count)
+                        .skip(4 + network_features_count)
                     {
-                        if let Ok(feature) = raw_ep_elements[i].parse::<usize>() {
+                        if let Ok(feature) = str_feature.parse::<usize>() {
                             if feature > *MAX_API_FEATURES_COUNT {
                                 return Err(ParseEndpointError::TooHighApiFeature());
                             }
@@ -636,24 +640,24 @@ impl EndpointV11 {
                             api_features[byte_index] += feature.pow(2);
                         } else if let EndpointV11Api::Bin(know_api) = api {
                             if let ApiKnownByDuniter::WS2P() = know_api {
-                                match raw_ep_elements[i] {
+                                match *str_feature {
                                     "DEF" => api_features[0] += 1u8,
                                     "LOW" => api_features[0] += 2u8,
                                     "ABF" => api_features[0] += 4u8,
                                     _ => {
                                         return Err(ParseEndpointError::UnknowApiFeature(
-                                            String::from(raw_ep_elements[i]),
+                                            String::from(*str_feature),
                                         ))
                                     }
                                 }
                             } else {
                                 return Err(ParseEndpointError::UnknowApiFeature(String::from(
-                                    raw_ep_elements[i],
+                                    *str_feature,
                                 )));
                             }
                         } else {
                             return Err(ParseEndpointError::UnknowApiFeature(String::from(
-                                raw_ep_elements[i],
+                                *str_feature,
                             )));
                         }
                     }
@@ -758,7 +762,7 @@ impl NetworkEndpoint {
         }
     }
     /// Accessors providing node unique identifier
-    pub fn node_uuid(&self) -> Option<NodeUUID> {
+    pub fn node_uuid(&self) -> Option<NodeId> {
         match *self {
             NetworkEndpoint::V10(ref ep) => ep.node_id,
             _ => panic!("Endpoint version is not supported !"),
@@ -855,7 +859,7 @@ impl NetworkEndpoint {
                     let node_id = match caps.name("uuid") {
                         Some(caps_node_id) => {
                             match u32::from_str_radix(caps_node_id.as_str(), 16) {
-                                Ok(node_id) => Some(NodeUUID(node_id)),
+                                Ok(node_id) => Some(NodeId(node_id)),
                                 Err(_) => None,
                             }
                         }
@@ -914,7 +918,7 @@ mod tests {
             EndpointV11::parse_from_raw(str_endpoint, 0, 0),
             Ok(NetworkEndpoint::V11(endpoint.clone())),
         );
-        let binary_endpoint = endpoint.clone().into_bytes();
+        let binary_endpoint = endpoint.clone().into_bytes_vector();
         assert_eq!(
             EndpointV11::from_bytes(&binary_endpoint)
                 .expect("Fail to convert byte vector into endpoint !"),
@@ -938,7 +942,7 @@ mod tests {
             last_check: 0,
         };
         assert_eq!(
-            endpoint_v11.into_bytes(),
+            endpoint_v11.into_bytes_vector(),
             vec![
                 0, 15, 4, 1, 0, 2, 1, 4, 1, 7, 103, 49, 46, 100, 117, 114, 115, 46, 105, 102, 101,
                 101, 46, 102, 114, 1, 187, 119, 115, 50, 112,
@@ -966,7 +970,7 @@ mod tests {
             EndpointV11::parse_from_raw(str_endpoint, 0, 0),
             Ok(NetworkEndpoint::V11(endpoint.clone())),
         );
-        let binary_endpoint = endpoint.clone().into_bytes();
+        let binary_endpoint = endpoint.clone().into_bytes_vector();
         assert_eq!(
             EndpointV11::from_bytes(&binary_endpoint)
                 .expect("Fail to convert byte vector into endpoint !"),
@@ -994,7 +998,7 @@ mod tests {
             EndpointV11::parse_from_raw(str_endpoint, 0, 0),
             Ok(NetworkEndpoint::V11(endpoint.clone())),
         );
-        let binary_endpoint = endpoint.clone().into_bytes();
+        let binary_endpoint = endpoint.clone().into_bytes_vector();
         assert_eq!(
             EndpointV11::from_bytes(&binary_endpoint)
                 .expect("Fail to convert byte vector into endpoint !"),
@@ -1023,7 +1027,7 @@ mod tests {
             EndpointV11::parse_from_raw(str_endpoint, 0, 0),
             Ok(NetworkEndpoint::V11(endpoint.clone())),
         );
-        let binary_endpoint = endpoint.clone().into_bytes();
+        let binary_endpoint = endpoint.clone().into_bytes_vector();
         assert_eq!(
             EndpointV11::from_bytes(&binary_endpoint)
                 .expect("Fail to convert byte vector into endpoint !"),
diff --git a/network/network_head.rs b/network/network_head.rs
index 91bf2843e11cbcffa64cd1232f6b00c40576271a..cd32676d83ff7a9849eb62f8e811e581425f9a0f 100644
--- a/network/network_head.rs
+++ b/network/network_head.rs
@@ -19,7 +19,7 @@ extern crate duniter_crypto;
 extern crate duniter_documents;
 extern crate serde_json;
 
-use super::{NodeFullId, NodeUUID};
+use super::{NodeFullId, NodeId};
 use duniter_crypto::keys::*;
 use duniter_documents::Blockstamp;
 use std::cmp::Ordering;
@@ -38,7 +38,7 @@ pub struct NetworkHeadMessageV2 {
     /// Head blockstamp
     pub blockstamp: Blockstamp,
     /// Head node id
-    pub node_uuid: NodeUUID,
+    pub node_uuid: NodeId,
     /// Issuer node software
     pub software: String,
     /// Issuer node soft version
@@ -157,7 +157,7 @@ impl NetworkHeadMessage {
                 version: source_array[2].parse().unwrap(),
                 pubkey: PubKey::Ed25519(pubkey),
                 blockstamp: Blockstamp::from_string(source_array[4]).unwrap(),
-                node_uuid: NodeUUID(u32::from_str_radix(source_array[5], 16).unwrap()),
+                node_uuid: NodeId(u32::from_str_radix(source_array[5], 16).unwrap()),
                 software: source_array[6].to_string(),
                 soft_version: source_array[7].to_string(),
                 prefix: source_array[8].parse().unwrap(),
@@ -184,7 +184,7 @@ impl NetworkHeadMessage {
         }
     }
     /// Get head node id
-    fn node_uuid(&self) -> NodeUUID {
+    fn node_uuid(&self) -> NodeId {
         match *self {
             NetworkHeadMessage::V2(ref head_message_v2) => head_message_v2.node_uuid,
             _ => panic!("This HEAD version is not supported !"),
@@ -371,7 +371,7 @@ impl NetworkHead {
         }
     }
     /// Returns issuer node id
-    pub fn node_uuid(&self) -> NodeUUID {
+    pub fn node_uuid(&self) -> NodeId {
         match *self {
             NetworkHead::V2(ref head_v2) => head_v2.message_v2.node_uuid(),
             _ => panic!("This HEAD version is not supported !"),
diff --git a/network/network_peer.rs b/network/network_peer.rs
index b539af01dcaaff77a0b3f9e4557f0065aa7b5649..eae07036d9d8fee8ae748f6fc76cf95ef5e1aac9 100644
--- a/network/network_peer.rs
+++ b/network/network_peer.rs
@@ -21,13 +21,59 @@ extern crate duniter_documents;
 extern crate duniter_module;
 extern crate serde;
 
-use super::network_endpoint::NetworkEndpoint;
+use super::network_endpoint::*;
+use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
 use duniter_crypto::keys::*;
-use duniter_documents::Blockstamp;
+use duniter_documents::{Blockstamp, ReadBytesBlockstampError};
+use std::io::Cursor;
+use std::mem;
+use NodeId;
+
+/// Total size of all fixed size fields of an PeerCardV11
+pub static PEER_CARDV11_FIXED_SIZE: &'static usize = &140;
+
+#[derive(Debug)]
+/// Error when converting a byte vector to peerCard
+pub enum PeerCardReadBytesError {
+    /// Bytes vector is too short
+    TooShort(String),
+    /// Bytes vector is too long
+    TooLong(),
+    /// IoError
+    IoError(::std::io::Error),
+    /// FromUtf8Error
+    FromUtf8Error(::std::string::FromUtf8Error),
+    /// ReadBytesBlockstampError
+    ReadBytesBlockstampError(ReadBytesBlockstampError),
+    /// EndpointReadBytesError
+    EndpointReadBytesError(EndpointReadBytesError),
+    /// too early version (don't support binary format)
+    TooEarlyVersion(),
+    /// Version not yet supported
+    VersionNotYetSupported(),
+}
+
+impl From<::std::io::Error> for PeerCardReadBytesError {
+    fn from(e: ::std::io::Error) -> Self {
+        PeerCardReadBytesError::IoError(e)
+    }
+}
+
+impl From<ReadBytesBlockstampError> for PeerCardReadBytesError {
+    fn from(e: ReadBytesBlockstampError) -> Self {
+        PeerCardReadBytesError::ReadBytesBlockstampError(e)
+    }
+}
+
+impl From<EndpointReadBytesError> for PeerCardReadBytesError {
+    fn from(e: EndpointReadBytesError) -> Self {
+        PeerCardReadBytesError::EndpointReadBytesError(e)
+    }
+}
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 /// Peer card V10
-pub struct NetworkPeerV10 {
+pub struct PeerCardV10 {
     /// Peer card Blockstamp
     pub blockstamp: Blockstamp,
     /// Peer card issuer
@@ -36,34 +82,196 @@ pub struct NetworkPeerV10 {
     pub endpoints: Vec<NetworkEndpoint>,
 }
 
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+/// Peer card V11
+pub struct PeerCardV11 {
+    /// Currency code
+    pub currency_code: u16,
+    /// Peer card issuer
+    pub issuer: PubKey,
+    /// Issuer node id
+    pub node_id: NodeId,
+    /// Peer card Blockstamp
+    pub blockstamp: Blockstamp,
+    /// Peer card endpoints list
+    pub endpoints: Vec<EndpointV11>,
+    /// Signature
+    pub sig: Option<Sig>,
+}
+
+impl PeerCardV11 {
+    /// Convert peer card into bytes vector
+    pub fn into_bytes_vector(self) -> Vec<u8> {
+        let endpoints_count = self.endpoints.len() as u8;
+        let mut binary_endpoints = vec![];
+        for ep in self.endpoints {
+            binary_endpoints.push(ep.into_bytes_vector());
+        }
+        let endpoints_size: usize = binary_endpoints.iter().map(|bin_ep| bin_ep.len() + 2).sum();
+        let peer_card_size = *PEER_CARDV11_FIXED_SIZE + endpoints_size;
+        let mut binary_peer_card = Vec::with_capacity(peer_card_size + 2);
+        // peer_card_size
+        let mut buffer = [0u8; mem::size_of::<u16>()];
+        buffer
+            .as_mut()
+            .write_u16::<BigEndian>(peer_card_size as u16)
+            .expect("Unable to write");
+        binary_peer_card.extend_from_slice(&buffer);
+        // version
+        binary_peer_card.push(11u8);
+        // endpoints_count
+        binary_peer_card.push(endpoints_count);
+        // currency_code
+        let mut buffer = [0u8; mem::size_of::<u16>()];
+        buffer
+            .as_mut()
+            .write_u16::<BigEndian>(self.currency_code)
+            .expect("Unable to write");
+        binary_peer_card.extend_from_slice(&buffer);
+        // node_id
+        let mut buffer = [0u8; mem::size_of::<u32>()];
+        buffer
+            .as_mut()
+            .write_u32::<BigEndian>(self.node_id.0)
+            .expect("Unable to write");
+        binary_peer_card.extend_from_slice(&buffer);
+        // issuer_public_key
+        binary_peer_card.extend(self.issuer.to_bytes_vector());
+        // blockstamp
+        binary_peer_card.extend(self.blockstamp.to_bytes_vector());
+        // endpoints_datas
+        for bin_ep in binary_endpoints {
+            let mut buffer = [0u8; mem::size_of::<u16>()];
+            buffer
+                .as_mut()
+                .write_u16::<BigEndian>(bin_ep.len() as u16)
+                .expect("Unable to write");
+            binary_peer_card.extend_from_slice(&buffer);
+            binary_peer_card.extend(bin_ep);
+        }
+        // sig
+        if let Some(sig) = self.sig {
+            binary_peer_card.extend(sig.to_bytes_vector());
+        }
+        binary_peer_card
+    }
+    /// Create peer card from bytes vector (without peer_card_size field)
+    pub fn from_bytes(binary_peer_card: &[u8]) -> Result<PeerCardV11, PeerCardReadBytesError> {
+        let mut index = 0;
+        // read version
+        let version = binary_peer_card[index];
+        index += 1;
+        // read endpoints_count
+        let endpoints_count = binary_peer_card[index];
+        index += 1;
+        // read currency_code
+        let mut currency_code_bytes = Cursor::new(binary_peer_card[index..index + 2].to_vec());
+        index += 2;
+        let currency_code = currency_code_bytes.read_u16::<BigEndian>()?;
+        // read node_id
+        let mut node_id_bytes = Cursor::new(binary_peer_card[index..index + 4].to_vec());
+        index += 4;
+        let node_id = NodeId(node_id_bytes.read_u32::<BigEndian>()?);
+        // read issuer_public_key
+        let issuer = if binary_peer_card.len() > index + 32 {
+            index += 32;
+            let mut issuer_datas: [u8; 32] = [0u8; 32];
+            issuer_datas.copy_from_slice(&binary_peer_card[index - 32..index]);
+            PubKey::Ed25519(ed25519::PublicKey(issuer_datas))
+        } else {
+            return Err(PeerCardReadBytesError::TooShort(String::from("issuer")));
+        };
+        // read blockstamp
+        let blockstamp = if binary_peer_card.len() > index + 36 {
+            index += 36;
+            Blockstamp::from_bytes_slice(&binary_peer_card[index - 36..index])?
+        } else {
+            return Err(PeerCardReadBytesError::TooShort(String::from("blockstamp")));
+        };
+        // read endpoints_datas
+        let mut endpoints = Vec::with_capacity(endpoints_count as usize);
+        for _ in 0..endpoints_count {
+            // read endpoint_size
+            if binary_peer_card.len() < index + 2 {
+                return Err(PeerCardReadBytesError::TooShort(String::from(
+                    "endpoint_size",
+                )));
+            }
+
+            let mut endpoint_size_bytes = Cursor::new(binary_peer_card[index..index + 2].to_vec());
+            index += 2;
+            let endpoint_size = endpoint_size_bytes.read_u16::<BigEndian>()?;
+            // read endpoint_datas
+            if binary_peer_card.len() < index + endpoint_size as usize {
+                return Err(PeerCardReadBytesError::TooShort(format!(
+                    "endpoint_datas (expected >= {} found {})",
+                    index + endpoint_size as usize,
+                    binary_peer_card.len()
+                )));
+            }
+            endpoints.push(EndpointV11::from_bytes(
+                &binary_peer_card[index..index + endpoint_size as usize],
+            )?);
+            index += endpoint_size as usize;
+        }
+        // read signature
+        let sig = if binary_peer_card.len() > index + 64 {
+            return Err(PeerCardReadBytesError::TooLong());
+        } else if binary_peer_card.len() == index + 64 {
+            let mut sig_datas: [u8; 64] = [0u8; 64];
+            sig_datas.copy_from_slice(&binary_peer_card[index..index + 64]);
+            Some(Sig::Ed25519(ed25519::Signature(sig_datas)))
+        } else if binary_peer_card.len() > index {
+            return Err(PeerCardReadBytesError::TooLong());
+        } else if binary_peer_card.len() == index {
+            None
+        } else {
+            return Err(PeerCardReadBytesError::TooShort(String::from("end")));
+        };
+
+        match version {
+            tmp if tmp > 11 => Err(PeerCardReadBytesError::VersionNotYetSupported()),
+            11 => Ok(PeerCardV11 {
+                currency_code,
+                issuer,
+                node_id,
+                blockstamp,
+                endpoints,
+                sig,
+            }),
+            _ => Err(PeerCardReadBytesError::TooEarlyVersion()),
+        }
+    }
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 /// Peer card
-pub enum NetworkPeer {
+pub enum PeerCard {
     /// Peer card V10
-    V10(NetworkPeerV10),
+    V10(PeerCardV10),
     /// Peer card V11
-    V11(),
+    V11(PeerCardV11),
 }
 
-impl NetworkPeer {
+impl PeerCard {
     /// Get peer card version
     pub fn version(&self) -> u32 {
         match *self {
-            NetworkPeer::V10(ref _peer_v10) => 10,
-            _ => panic!("Peer version is not supported !"),
+            PeerCard::V10(ref _peer_v10) => 10,
+            PeerCard::V11(ref _peer_v11) => 11,
         }
     }
     /// Get peer card blockstamp
     pub fn blockstamp(&self) -> Blockstamp {
         match *self {
-            NetworkPeer::V10(ref peer_v10) => peer_v10.blockstamp,
+            PeerCard::V10(ref peer_v10) => peer_v10.blockstamp,
             _ => panic!("Peer version is not supported !"),
         }
     }
     /// Get peer card issuer
     pub fn issuer(&self) -> PubKey {
         match *self {
-            NetworkPeer::V10(ref peer_v10) => peer_v10.issuer,
+            PeerCard::V10(ref peer_v10) => peer_v10.issuer,
             _ => panic!("Peer version is not supported !"),
         }
     }
@@ -76,3 +284,76 @@ impl NetworkPeer {
         Vec::with_capacity(0)
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::net::Ipv4Addr;
+    use std::str::FromStr;
+
+    fn create_endpoint_v11() -> EndpointV11 {
+        EndpointV11 {
+            api: EndpointV11Api::Bin(ApiKnownByDuniter::WS2P()),
+            api_version: 2,
+            network_features: EndpointV11NetworkFeatures(vec![4u8]),
+            api_features: vec![7u8],
+            ip_v4: None,
+            ip_v6: None,
+            host: Some(String::from("g1.durs.ifee.fr")),
+            port: 443u16,
+            path: Some(String::from("ws2p")),
+            status: 0,
+            last_check: 0,
+        }
+    }
+    fn create_second_endpoint_v11() -> EndpointV11 {
+        EndpointV11 {
+            api: EndpointV11Api::Bin(ApiKnownByDuniter::WS2P()),
+            api_version: 2,
+            network_features: EndpointV11NetworkFeatures(vec![5u8]),
+            api_features: vec![7u8],
+            ip_v4: Some(Ipv4Addr::from_str("84.16.72.210").unwrap()),
+            ip_v6: None,
+            host: None,
+            port: 443u16,
+            path: Some(String::from("ws2p")),
+            status: 0,
+            last_check: 0,
+        }
+    }
+
+    #[test]
+    fn test_convert_peer_card_v11_into_bytes_vector() {
+        let peer_card_v11 = PeerCardV11 {
+            currency_code: 1u16,
+            issuer: PubKey::Ed25519(
+                ed25519::PublicKey::from_base58("D9D2zaJoWYWveii1JRYLVK3J4Z7ZH3QczoKrnQeiM6mx")
+                    .unwrap(),
+            ),
+            node_id: NodeId(0),
+            blockstamp: Blockstamp::from_string(
+                "50-000005B1CEB4EC5245EF7E33101A330A1C9A358EC45A25FC13F78BB58C9E7370",
+            ).unwrap(),
+            endpoints: vec![create_endpoint_v11(), create_second_endpoint_v11()],
+            sig: None,
+        };
+        let peer_card_v11_bytes = peer_card_v11.clone().into_bytes_vector();
+        assert_eq!(
+            peer_card_v11_bytes,
+            vec![
+                0, 195, 11, 2, 0, 1, 0, 0, 0, 0, 180, 102, 127, 51, 114, 94, 79, 133, 126, 196,
+                144, 254, 52, 196, 225, 10, 252, 31, 249, 217, 220, 10, 64, 221, 246, 95, 190, 249,
+                34, 159, 139, 243, 0, 0, 0, 50, 0, 0, 5, 177, 206, 180, 236, 82, 69, 239, 126, 51,
+                16, 26, 51, 10, 28, 154, 53, 142, 196, 90, 37, 252, 19, 247, 139, 181, 140, 158,
+                115, 112, 0, 31, 0, 15, 4, 1, 0, 2, 1, 4, 1, 7, 103, 49, 46, 100, 117, 114, 115,
+                46, 105, 102, 101, 101, 46, 102, 114, 1, 187, 119, 115, 50, 112, 0, 20, 0, 0, 4, 1,
+                0, 2, 1, 5, 1, 7, 84, 16, 72, 210, 1, 187, 119, 115, 50, 112,
+            ]
+        );
+        assert_eq!(
+            peer_card_v11,
+            PeerCardV11::from_bytes(&peer_card_v11_bytes[2..])
+                .expect("Fail to parse peer card bytes vector"),
+        )
+    }
+}
diff --git a/ws2p/datas.rs b/ws2p/datas.rs
index 0177cf120786960addd972c5046ac558de09ce39..1a81444e0b245d128393563936d3a5c0ae704991 100644
--- a/ws2p/datas.rs
+++ b/ws2p/datas.rs
@@ -31,7 +31,7 @@ pub struct WS2PModuleDatas {
     pub currency: Option<String>,
     pub key_pair: Option<KeyPairEnum>,
     pub conf: WS2PConf,
-    pub node_id: NodeUUID,
+    pub node_id: NodeId,
     pub main_thread_channel: (
         mpsc::Sender<WS2PThreadSignal>,
         mpsc::Receiver<WS2PThreadSignal>,
diff --git a/ws2p/heads.rs b/ws2p/heads.rs
index 5528e630d4b596cd2eb6f003cc0c853fb49db2bd..26d1fd72d4d97880903e126154d48f5cb1638c8b 100644
--- a/ws2p/heads.rs
+++ b/ws2p/heads.rs
@@ -19,7 +19,7 @@ use *;
 
 pub fn generate_my_head(
     network_keypair: &KeyPairEnum,
-    node_id: NodeUUID,
+    node_id: NodeId,
     soft_name: &str,
     soft_version: &str,
     my_current_blockstamp: &Blockstamp,
diff --git a/ws2p/lib.rs b/ws2p/lib.rs
index ec3fe6bd6d3a22776a5685a53ba0840880da13f6..d5d7758f0bae788246e04c2ba1c155a918210f26 100644
--- a/ws2p/lib.rs
+++ b/ws2p/lib.rs
@@ -219,7 +219,7 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
             key_pair: None,
             currency: None,
             conf,
-            node_id: NodeUUID(soft_meta_datas.conf.my_node_id()),
+            node_id: NodeId(soft_meta_datas.conf.my_node_id()),
             main_thread_channel: mpsc::channel(),
             ws2p_endpoints: HashMap::new(),
             websockets: HashMap::new(),
@@ -349,7 +349,7 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
                                         if ws2p_module.my_head.is_none() {
                                             ws2p_module.my_head = Some(heads::generate_my_head(
                                                 &key_pair,
-                                                NodeUUID(soft_meta_datas.conf.my_node_id()),
+                                                NodeId(soft_meta_datas.conf.my_node_id()),
                                                 soft_meta_datas.soft_name,
                                                 soft_meta_datas.soft_version,
                                                 &current_blockstamp,
@@ -435,7 +435,7 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
                                     );
                                     ws2p_module.my_head = Some(heads::generate_my_head(
                                         &key_pair,
-                                        NodeUUID(soft_meta_datas.conf.my_node_id()),
+                                        NodeId(soft_meta_datas.conf.my_node_id()),
                                         soft_meta_datas.soft_name,
                                         soft_meta_datas.soft_version,
                                         &current_blockstamp,
@@ -488,7 +488,7 @@ impl DuniterModule<DuRsConf, DuniterMessage> for WS2PModule {
                                                 ws2p_module.my_head =
                                                     Some(heads::generate_my_head(
                                                         &key_pair,
-                                                        NodeUUID(soft_meta_datas.conf.my_node_id()),
+                                                        NodeId(soft_meta_datas.conf.my_node_id()),
                                                         soft_meta_datas.soft_name,
                                                         soft_meta_datas.soft_version,
                                                         &current_blockstamp,
diff --git a/ws2p/ws2p_connection.rs b/ws2p/ws2p_connection.rs
index d4a50aa45f860900f6624aa0be667084ca0acebb..09ea0134763157e5819b4a31651b324cb4c6db94 100644
--- a/ws2p/ws2p_connection.rs
+++ b/ws2p/ws2p_connection.rs
@@ -2,7 +2,7 @@ use constants::*;
 use duniter_crypto::keys::*;
 use duniter_module::ModuleReqId;
 use duniter_network::network_endpoint::{NetworkEndpoint, NetworkEndpointApi};
-use duniter_network::{NetworkDocument, NodeUUID};
+use duniter_network::{NetworkDocument, NodeId};
 use parsers::blocks::parse_json_block;
 use rand::Rng;
 use std::sync::mpsc;
@@ -292,7 +292,7 @@ pub enum WS2PCloseConnectionReason {
 #[derive(Debug, Clone)]
 pub struct WS2PConnectionMetaDatas {
     pub state: WS2PConnectionState,
-    pub remote_uuid: Option<NodeUUID>,
+    pub remote_uuid: Option<NodeId>,
     pub remote_pubkey: Option<PubKey>,
     pub challenge: String,
     pub remote_challenge: String,
diff --git a/ws2p/ws2p_db.rs b/ws2p/ws2p_db.rs
index 740ef46af0b32fa1820a1c7f176f17949e141d0e..2dbc60b14e8dbef7fbf415bc6b615474d24263cc 100644
--- a/ws2p/ws2p_db.rs
+++ b/ws2p/ws2p_db.rs
@@ -79,7 +79,10 @@ pub fn get_endpoints_for_api(
             1u16,
         ) {
             Ok(ep) => ep,
-            Err(_) => panic!(format!("Fail to parse endpoint : {}", raw_ep)),
+            Err(e) => panic!(format!(
+                "Fail to parse endpoint : {} (Error: {:?})",
+                raw_ep, e
+            )),
         };
         ep.set_status(row[1].as_integer().unwrap() as u32);
         ep.set_last_check(row[7].as_integer().unwrap() as u64);