diff --git a/Cargo.lock b/Cargo.lock
index 41f5357d4c25955a87b3357d12bd74007a36a430..6b9b5569f13c6e9e3afd56cb3d83e9712ca13a46 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -273,6 +273,7 @@ dependencies = [
  "serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unwrap 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
diff --git a/lib/tools/documents/Cargo.toml b/lib/tools/documents/Cargo.toml
index 6637643b9bc87dbbdec4747f0e2f2674af48c0be..bd20e5263177a4c9c9307aa09a224f619555d984 100644
--- a/lib/tools/documents/Cargo.toml
+++ b/lib/tools/documents/Cargo.toml
@@ -24,6 +24,7 @@ serde = "1.0.*"
 serde_derive = "1.0.*"
 serde_json = "1.0.*"
 log = "0.4.*"
+unwrap = "1.2.1"
 
 [dev-dependencies]
 pretty_assertions = "0.5.1"
diff --git a/lib/tools/documents/src/documents/transaction.rs b/lib/tools/documents/src/documents/transaction.rs
index dc4a8694bae07a47e34a20c6d4812af4df1c59b3..f84de61145ce9a5d06d00dd350e94ed9ddfc2a78 100644
--- a/lib/tools/documents/src/documents/transaction.rs
+++ b/lib/tools/documents/src/documents/transaction.rs
@@ -22,6 +22,7 @@ use pest::iterators::Pairs;
 use pest::Parser;
 use std::ops::{Add, Deref, Sub};
 use std::str::FromStr;
+use unwrap::unwrap;
 
 use crate::blockstamp::Blockstamp;
 use crate::documents::*;
@@ -116,7 +117,7 @@ impl FromStr for TransactionInput {
                 pairs.next().unwrap().into_inner(),
             )),
             Err(_) => Err(TextDocumentParseError::InvalidInnerFormat(
-                "Invalid unlocks !",
+                "Invalid unlocks !".to_owned(),
             )),
         }
     }
@@ -239,7 +240,7 @@ impl FromStr for TransactionInputUnlocks {
                 pairs.next().unwrap().into_inner(),
             )),
             Err(_) => Err(TextDocumentParseError::InvalidInnerFormat(
-                "Invalid unlocks !",
+                "Invalid unlocks !".to_owned(),
             )),
         }
     }
@@ -466,13 +467,42 @@ impl FromStr for TransactionOutput {
     type Err = TextDocumentParseError;
 
     fn from_str(source: &str) -> Result<Self, Self::Err> {
-        match DocumentsParser::parse(Rule::tx_output, source) {
-            Ok(mut utxo_pairs) => Ok(TransactionOutput::from_pest_pair(
-                utxo_pairs.next().unwrap().into_inner(),
-            )),
-            Err(_) => Err(TextDocumentParseError::InvalidInnerFormat(
-                "Invalid output !",
-            )),
+        let output_parts: Vec<&str> = source.split(':').collect();
+        let amount = output_parts.get(0);
+        let base = output_parts.get(1);
+        let conditions_origin_str = output_parts.get(2);
+
+        let str_to_parse = if amount.is_some() && base.is_some() && conditions_origin_str.is_some()
+        {
+            format!(
+                "{}:{}:({})",
+                unwrap!(amount),
+                unwrap!(base),
+                unwrap!(conditions_origin_str)
+            )
+        } else {
+            source.to_owned()
+        };
+
+        match DocumentsParser::parse(Rule::tx_output, &str_to_parse) {
+            Ok(mut utxo_pairs) => {
+                let mut output =
+                    TransactionOutput::from_pest_pair(utxo_pairs.next().unwrap().into_inner());
+                output.conditions.origin_str = conditions_origin_str.map(ToString::to_string);
+                Ok(output)
+            }
+            Err(_) => match DocumentsParser::parse(Rule::tx_output, source) {
+                Ok(mut utxo_pairs) => {
+                    let mut output =
+                        TransactionOutput::from_pest_pair(utxo_pairs.next().unwrap().into_inner());
+                    output.conditions.origin_str = conditions_origin_str.map(ToString::to_string);
+                    Ok(output)
+                }
+                Err(e) => Err(TextDocumentParseError::InvalidInnerFormat(format!(
+                    "Invalid output : {}",
+                    e
+                ))),
+            },
         }
     }
 }
@@ -578,8 +608,10 @@ impl TransactionDocument {
         } else {
             fatal_error!("Try to compute_hash of tx with None text !")
         };
-        hashing_text.push_str(&self.signatures[0].to_string());
-        hashing_text.push_str("\n");
+        for sig in &self.signatures {
+            hashing_text.push_str(&sig.to_string());
+            hashing_text.push_str("\n");
+        }
         //println!("tx_text_hasing={}", hashing_text);
         self.hash = Some(Hash::compute_str(&hashing_text));
         self.hash.expect("Try to get hash of a reduce tx !")
diff --git a/lib/tools/documents/src/lib.rs b/lib/tools/documents/src/lib.rs
index 4b67e95d4832e227b9a913d08abdf6f9b4ecf440..940b8841370c011051b0048cd88954ac8433297d 100644
--- a/lib/tools/documents/src/lib.rs
+++ b/lib/tools/documents/src/lib.rs
@@ -76,8 +76,8 @@ pub trait TextDocumentParser<R: RuleType> {
 #[derive(Debug, Clone, Fail)]
 pub enum TextDocumentParseError {
     /// The given source don't have a valid specific document format (document type).
-    #[fail(display = "TextDocumentParseError: Invalid inner format.")]
-    InvalidInnerFormat(&'static str),
+    #[fail(display = "TextDocumentParseError: Invalid inner format: {}", _0)]
+    InvalidInnerFormat(String),
     /// Error with pest parser
     #[fail(display = "TextDocumentParseError: PestError.")]
     PestError(String),