diff --git a/_ucoinpy_test/documents/test_status.py b/_ucoinpy_test/documents/test_status.py
deleted file mode 100644
index a995b01cfee2984396939c5b4cd291abbfcdaf53..0000000000000000000000000000000000000000
--- a/_ucoinpy_test/documents/test_status.py
+++ /dev/null
@@ -1,38 +0,0 @@
-'''
-Created on 13 déc. 2014
-
-@author: inso
-'''
-import unittest
-from ucoinpy.documents.status import Status
-
-raw_status = """Version: 1
-Type: Status
-Currency: beta_brousouf
-Status: UP
-Block: 8-1922C324ABC4AF7EF7656734A31F5197888DDD52
-From: HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY
-To: 8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU
-dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==
-"""
-
-
-class Test_Status(unittest.TestCase):
-    def test_fromraw(self):
-        status = Status.from_signed_raw(raw_status)
-        self.assertEqual(status.status, 'UP')
-        self.assertEqual(status.blockid, "8-1922C324ABC4AF7EF7656734A31F5197888DDD52")
-        self.assertEqual(status.sender, "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY")
-        self.assertEqual(status.recipient, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
-        self.assertEqual(status.signatures[0], "dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==")
-
-    def test_fromraw_toraw(self):
-        status = Status.from_signed_raw(raw_status)
-        rendered_status = status.signed_raw()
-        from_rendered_status = Status.from_signed_raw(rendered_status)
-        self.assertEqual(from_rendered_status.status, 'UP')
-        self.assertEqual(from_rendered_status.blockid, "8-1922C324ABC4AF7EF7656734A31F5197888DDD52")
-        self.assertEqual(from_rendered_status.sender, "HsLShAtzXTVxeUtQd7yi5Z5Zh4zNvbu8sTEZ53nfKcqY")
-        self.assertEqual(from_rendered_status.recipient, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU")
-        self.assertEqual(from_rendered_status.signatures[0], "dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu84rraDg==")
-
diff --git a/ucoinpy/__init__.py b/ucoinpy/__init__.py
index c0e54afbce24808a7f8f86b4dbd40484f9f1a7a0..1efe04b77f4f7ad617ddaafafedc9f3f4cd190f8 100644
--- a/ucoinpy/__init__.py
+++ b/ucoinpy/__init__.py
@@ -21,7 +21,7 @@ PROTOCOL_VERSION="1"
 MANAGED_API=["BASIC_MERKLED_API"]
 
 __author__      = 'Caner Candan & inso'
-__version__     = '0.14.2'
+__version__     = '0.14.3'
 __nonsense__    = 'uCoin'
 
 from . import api, documents, key
\ No newline at end of file
diff --git a/ucoinpy/documents/__init__.py b/ucoinpy/documents/__init__.py
index 2291e35a028452620bc12c2101ee2fd5a4bb8220..e229fd5fca387d0a527a901afe81c1f55d45a40f 100644
--- a/ucoinpy/documents/__init__.py
+++ b/ucoinpy/documents/__init__.py
@@ -2,6 +2,5 @@ from .block import Block, BlockId
 from .certification import SelfCertification, Certification
 from .membership import Membership
 from .peer import Endpoint, BMAEndpoint, UnknownEndpoint, Peer
-from .status import Status
 from .transaction import SimpleTransaction, Transaction
-from .document import Document
\ No newline at end of file
+from .document import Document, MalformedDocumentError
\ No newline at end of file
diff --git a/ucoinpy/documents/block.py b/ucoinpy/documents/block.py
index a7c4e35a1c434f1b878f1b0ff9ef8b91587b3a6d..6341118620e25d2180af3cddfc5bdb13acce9fd7 100644
--- a/ucoinpy/documents/block.py
+++ b/ucoinpy/documents/block.py
@@ -1,4 +1,4 @@
-from .document import Document
+from .document import Document, MalformedDocumentError
 from .certification import SelfCertification, Certification
 from .membership import Membership
 from .transaction import Transaction
@@ -28,6 +28,8 @@ class BlockId:
         :param str blockid: The block id
         """
         data = blockid.split("-")
+        if len(data) != 2:
+            raise MalformedDocumentError('BlockId')
         number = int(data[0])
         sha_hash = data[1]
         return cls(number, sha_hash)
@@ -107,6 +109,28 @@ The class Block handles Block documents.
     re_certifications = re.compile("Certifications:\n")
     re_transactions = re.compile("Transactions:\n")
 
+    fields_parsers = {**Document.fields_parsers, **{
+                'Type': re_type,
+                'Noonce': re_noonce,
+                'Number': re_number,
+                'PoWMin': re_powmin,
+                'Time': re_time,
+                'MedianTime': re_mediantime,
+                'UD': re_universaldividend,
+                'Issuer': re_issuer,
+                'PreviousIssuer': re_previousissuer,
+                'PreviousHash': re_previoushash,
+                'Parameters': re_parameters,
+                'MembersCount': re_memberscount,
+                'Identities': re_identities,
+                'Joiners': re_joiners,
+                'Actives': re_actives,
+                'Leavers': re_leavers,
+                'Certifications': re_certifications,
+                'Transactions': re_transactions
+            }
+      }
+
     Empty_Hash = "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"
 
     def __init__(self, version, currency, noonce, number, powmin, time,
@@ -167,54 +191,54 @@ The class Block handles Block documents.
         lines = raw.splitlines(True)
         n = 0
 
-        version = int(Block.re_version.match(lines[n]).group(1))
-        n = n + 1
+        version = int(Block.parse_field("Version", lines[n]))
+        n += 1
 
-        Block.re_type.match(lines[n]).group(1)
-        n = n + 1
+        Block.parse_field("Type", lines[n])
+        n += 1
 
-        currency = Block.re_currency.match(lines[n]).group(1)
-        n = n + 1
+        currency = Block.parse_field("Currency", lines[n])
+        n += 1
 
-        noonce = int(Block.re_noonce.match(lines[n]).group(1))
-        n = n + 1
+        noonce = int(Block.parse_field("Noonce", lines[n]))
+        n += 1
 
-        number = int(Block.re_number.match(lines[n]).group(1))
-        n = n + 1
+        number = int(Block.parse_field("Number", lines[n]))
+        n += 1
 
-        powmin = int(Block.re_powmin.match(lines[n]).group(1))
-        n = n + 1
+        powmin = int(Block.parse_field("PoWMin", lines[n]))
+        n += 1
 
-        time = int(Block.re_time.match(lines[n]).group(1))
-        n = n + 1
+        time = int(Block.parse_field("Time", lines[n]))
+        n += 1
 
-        mediantime = int(Block.re_mediantime.match(lines[n]).group(1))
-        n = n + 1
+        mediantime = int(Block.parse_field("MedianTime", lines[n]))
+        n += 1
 
         ud = Block.re_universaldividend.match(lines[n])
         if ud is not None:
             ud = int(ud.group(1))
-            n = n + 1
+            n += 1
 
-        issuer = Block.re_issuer.match(lines[n]).group(1)
-        n = n + 1
+        issuer = Block.parse_field("Issuer", lines[n])
+        n += 1
 
         prev_hash = None
         prev_issuer = None
         if number > 0:
-            prev_hash = Block.re_previoushash.match(lines[n]).group(1)
-            n = n + 1
+            prev_hash = Block.parse_field("PreviousHash", lines[n])
+            n += 1
 
-            prev_issuer = Block.re_previousissuer.match(lines[n]).group(1)
-            n = n + 1
+            prev_issuer = Block.parse_field("PreviousIssuer", lines[n])
+            n += 1
 
         parameters = None
         if number == 0:
             parameters = Block.re_parameters.match(lines[n]).groups()
-            n = n + 1
+            n += 1
 
-        members_count = int(Block.re_memberscount.match(lines[n]).group(1))
-        n = n + 1
+        members_count = int(Block.parse_field("MembersCount", lines[n]))
+        n += 1
 
         identities = []
         joiners = []
@@ -225,50 +249,50 @@ The class Block handles Block documents.
         transactions = []
 
         if Block.re_identities.match(lines[n]) is not None:
-            n = n + 1
+            n += 1
             while Block.re_joiners.match(lines[n]) is None:
                 selfcert = SelfCertification.from_inline(version, currency, lines[n])
                 identities.append(selfcert)
-                n = n + 1
+                n += 1
 
         if Block.re_joiners.match(lines[n]):
-            n = n + 1
+            n += 1
             while Block.re_actives.match(lines[n]) is None:
                 membership = Membership.from_inline(version, currency, "IN", lines[n])
                 joiners.append(membership)
-                n = n + 1
+                n += 1
 
         if Block.re_actives.match(lines[n]):
-            n = n + 1
+            n += 1
             while Block.re_leavers.match(lines[n]) is None:
                 membership = Membership.from_inline(version, currency, "IN", lines[n])
                 actives.append(membership)
-                n = n + 1
+                n += 1
 
         if Block.re_leavers.match(lines[n]):
-            n = n + 1
+            n += 1
             while Block.re_excluded.match(lines[n]) is None:
                 membership = Membership.from_inline(version, currency, "OUT", lines[n])
                 leavers.append(membership)
-                n = n + 1
+                n += 1
 
         if Block.re_excluded.match(lines[n]):
-            n = n + 1
+            n += 1
             while Block.re_certifications.match(lines[n]) is None:
                 membership = Block.re_exclusion.match(lines[n]).group(1)
                 excluded.append(membership)
-                n = n + 1
+                n += 1
 
         if Block.re_certifications.match(lines[n]):
-            n = n + 1
+            n += 1
             while Block.re_transactions.match(lines[n]) is None:
                 certification = Certification.from_inline(version, currency,
                                                           prev_hash, lines[n])
                 certifications.append(certification)
-                n = n + 1
+                n += 1
 
         if Block.re_transactions.match(lines[n]):
-            n = n + 1
+            n += 1
             while not Block.re_signature.match(lines[n]):
                 tx_lines = ""
                 header_data = Transaction.re_header.match(lines[n])
@@ -277,14 +301,14 @@ The class Block handles Block documents.
                 inputs_num = int(header_data.group(3))
                 outputs_num = int(header_data.group(4))
                 has_comment = int(header_data.group(5))
-                tx_max = n+issuers_num*2+inputs_num+outputs_num+has_comment+1
+                tx_max = n + issuers_num * 2 + inputs_num + outputs_num + has_comment + 1
                 for i in range(n, tx_max):
                     tx_lines += lines[n]
-                    n = n + 1
+                    n += 1
                 transaction = Transaction.from_compact(currency, tx_lines)
                 transactions.append(transaction)
 
-        signature = Block.re_signature.match(lines[n]).group(1)
+        signature = Block.parse_field("Signature", lines[n])
 
         return cls(version, currency, noonce, number, powmin, time,
                    mediantime, ud, issuer, prev_hash, prev_issuer,
diff --git a/ucoinpy/documents/certification.py b/ucoinpy/documents/certification.py
index 96a4a81f9bbf8fcd1f4e13881048be45dfa811de..33349b4b232c66513fb5d9b7d9ee438ab0d64508 100644
--- a/ucoinpy/documents/certification.py
+++ b/ucoinpy/documents/certification.py
@@ -2,7 +2,7 @@ import re
 import base64
 import logging
 
-from .document import Document
+from .document import Document, MalformedDocumentError
 
 
 class SelfCertification(Document):
@@ -26,6 +26,8 @@ class SelfCertification(Document):
     @classmethod
     def from_inline(cls, version, currency, inline):
         selfcert_data = SelfCertification.re_inline.match(inline)
+        if selfcert_data is None:
+            raise MalformedDocumentError("Inline self certification")
         pubkey = selfcert_data.group(1)
         signature = selfcert_data.group(2)
         ts = int(selfcert_data.group(3))
@@ -63,6 +65,8 @@ class Certification(Document):
     @classmethod
     def from_inline(cls, version, currency, blockhash, inline):
         cert_data = Certification.re_inline.match(inline)
+        if cert_data is None:
+            raise MalformedDocumentError("Certification")
         pubkey_from = cert_data.group(1)
         pubkey_to = cert_data.group(2)
         blocknumber = int(cert_data.group(3))
diff --git a/ucoinpy/documents/document.py b/ucoinpy/documents/document.py
index 8298d181f550be7071a1c9407099f1816b998097..c390bdee5aa3ba66864d9af834b6a05612a77b9d 100644
--- a/ucoinpy/documents/document.py
+++ b/ucoinpy/documents/document.py
@@ -1,15 +1,42 @@
-import base58
 import base64
 import re
 import logging
 import hashlib
 
 
+class MalformedDocumentError(Exception):
+    """
+    Malformed document exception
+    """
+    def __init__(self, field_name):
+        super().__init__("Could not parse field {0}".format(field_name))
+
+
 class Document:
     re_version = re.compile("Version: ([0-9]+)\n")
     re_currency = re.compile("Currency: ([^\n]+)\n")
     re_signature = re.compile("([A-Za-z0-9+/]+(?:=|==)?)\n")
 
+    fields_parsers = {
+        "Version": re_version,
+        "Currency": re_currency,
+        "Signature": re_signature
+    }
+
+    @classmethod
+    def parse_field(cls, field_name, line):
+        """
+
+        :param field_name:
+        :param line:
+        :return:
+        """
+        try:
+            value = cls.fields_parsers[field_name].match(line).group(1)
+        except AttributeError:
+            raise MalformedDocumentError(field_name)
+        return value
+
     def __init__(self, version, currency, signatures):
         self.version = version
         self.currency = currency
diff --git a/ucoinpy/documents/membership.py b/ucoinpy/documents/membership.py
index ca9b89978c7ca07aeedc19af1ad6794bed626e42..7cc787576e1bb580e1329f431ab3e728b8100ae9 100644
--- a/ucoinpy/documents/membership.py
+++ b/ucoinpy/documents/membership.py
@@ -3,7 +3,7 @@ Created on 2 déc. 2014
 
 @author: inso
 """
-from .document import Document
+from .document import Document, MalformedDocumentError
 
 import re
 
@@ -28,11 +28,20 @@ class Membership(Document):
 ([0-9]+):([0-9a-fA-F]{5,40}):([0-9]+):([^\n]+)\n")
     re_type = re.compile("Type: (Membership)")
     re_issuer = re.compile("Issuer: ([1-9A-Za-z][^OIl]{42,45})\n")
-    re_block = re.compile("Block: ([0-9]+)-([0-9a-fA-F]{5,40})\n")
+    re_block = re.compile("Block: ([0-9]+-[0-9a-fA-F]{5,40})\n")
     re_membership_type = re.compile("Membership: (IN|OUT)")
     re_userid = re.compile("UserID: ([^\n]+)\n")
     re_certts = re.compile("CertTS: ([0-9]+)\n")
 
+    fields_parsers = {**Document.fields_parsers, **{
+        "Type": re_type,
+        "Issuer": re_issuer,
+        "Block": re_block,
+        "Membership": re_membership_type,
+        "UserID": re_userid,
+        "CertTS": re_certts
+    }}
+
     def __init__(self, version, currency, issuer, blockid,
                  membership_type, uid, cert_ts, signature):
         """
@@ -48,6 +57,8 @@ class Membership(Document):
     @classmethod
     def from_inline(cls, version, currency, membership_type, inline):
         data = Membership.re_inline.match(inline)
+        if data is None:
+            raise MalformedDocumentError("Inline membership")
         issuer = data.group(1)
         signature = data.group(2)
         block_number = int(data.group(3))
@@ -59,40 +70,38 @@ class Membership(Document):
 
     @classmethod
     def from_signed_raw(cls, raw, signature=None):
+        from .block import BlockId
         lines = raw.splitlines(True)
         n = 0
 
-        version = int(Membership.re_version.match(lines[n]).group(1))
-        n = n + 1
+        version = int(Membership.parse_field("Version", lines[n]))
+        n += 1
 
-        Membership.re_type.match(lines[n]).group(1)
-        n = n + 1
+        Membership.parse_field("Type", lines[n])
+        n += 1
 
-        currency = Membership.re_currency.match(lines[n]).group(1)
-        n = n + 1
+        currency = Membership.parse_field("Currency", lines[n])
+        n += 1
 
-        issuer = Membership.re_issuer.match(lines[n]).group(1)
-        n = n + 1
+        issuer = Membership.parse_field("Issuer", lines[n])
+        n += 1
 
-        blockid = Membership.re_block.match(lines[n])
-        blocknumber = int(blockid.group(1))
-        blockhash = blockid.group(2)
-        n = n + 1
+        blockid = BlockId.from_str(Membership.parse_field("Block", lines[n]))
+        n += 1
 
-        membership_type = Membership.re_membership_type.match(lines[n]).group(1)
-        n = n + 1
+        membership_type = Membership.parse_field("Membership", lines[n])
+        n += 1
 
-        uid = Membership.re_userid.match(lines[n]).group(1)
-        n = n + 1
+        uid = Membership.parse_field("UserID", lines[n])
+        n += 1
 
-        cert_ts = int(Membership.re_certts.match(lines[n]).group(1))
-        n = n + 1
+        cert_ts = int(Membership.parse_field("CertTS", lines[n]))
+        n += 1
 
-        signature = Membership.re_signature.match(lines[n]).group(1)
-        n = n + 1
+        signature = Membership.parse_field("Signature", lines[n])
+        n += 1
 
-        from .block import BlockId
-        return cls(version, currency, issuer, BlockId(blocknumber, blockhash),
+        return cls(version, currency, issuer, blockid,
                    membership_type, uid, cert_ts, signature)
 
     def raw(self):
diff --git a/ucoinpy/documents/peer.py b/ucoinpy/documents/peer.py
index 838c55b3e476673650f3c45950eaea88dea5e05b..5a2cf0ae3ac80ee20b056917f56a2d8aaa00fcec 100644
--- a/ucoinpy/documents/peer.py
+++ b/ucoinpy/documents/peer.py
@@ -1,7 +1,7 @@
 import re
 
 from ..api.bma import ConnectionHandler
-from .document import Document
+from .document import Document, MalformedDocumentError
 from . import BlockId
 from .. import PROTOCOL_VERSION, MANAGED_API
 
@@ -26,7 +26,14 @@ class Peer(Document):
     re_type = re.compile("Type: (Peer)")
     re_pubkey = re.compile("PublicKey: ([1-9A-Za-z][^OIl]{42,45})\n")
     re_block = re.compile("Block: ([0-9]+-[0-9a-fA-F]{5,40})\n")
-    re_endpoints = re.compile("Endpoints:\n")
+    re_endpoints = re.compile("(Endpoints:)\n")
+
+    fields_parsers = {**Document.fields_parsers, **{
+        "Type": re_type,
+        "Pubkey": re_pubkey,
+        "Block": re_block,
+        "Endpoints": re_endpoints
+    }}
 
     def __init__(self, version, currency, pubkey, blockid,
                  endpoints, signature):
@@ -41,29 +48,29 @@ class Peer(Document):
         lines = raw.splitlines(True)
         n = 0
 
-        version = int(Peer.re_version.match(lines[n]).group(1))
-        n = n + 1
+        version = int(Peer.parse_field("Version", lines[n]))
+        n += 1
 
-        Peer.re_type.match(lines[n]).group(1)
-        n = n + 1
+        Peer.parse_field("Type", lines[n])
+        n += 1
 
-        currency = Peer.re_currency.match(lines[n]).group(1)
-        n = n + 1
+        currency = Peer.parse_field("Currency", lines[n])
+        n += 1
 
-        pubkey = Peer.re_pubkey.match(lines[n]).group(1)
-        n = n + 1
+        pubkey = Peer.parse_field("Pubkey", lines[n])
+        n += 1
 
-        blockid = BlockId.from_str(Peer.re_block.match(lines[n]).group(1))
-        n = n + 1
+        blockid = BlockId.from_str(Peer.parse_field("Block", lines[n]))
+        n += 1
 
-        Peer.re_endpoints.match(lines[n])
-        n = n + 1
+        Peer.parse_field("Endpoints", lines[n])
+        n += 1
 
         endpoints = []
         while not Peer.re_signature.match(lines[n]):
             endpoint = Endpoint.from_inline(lines[n])
             endpoints.append(endpoint)
-            n = n + 1
+            n += 1
 
         signature = Peer.re_signature.match(lines[n]).group(1)
 
@@ -123,6 +130,8 @@ class BMAEndpoint(Endpoint):
     @classmethod
     def from_inline(cls, inline):
         m = BMAEndpoint.re_inline.match(inline)
+        if m is None:
+            raise MalformedDocumentError("BMAEndpoint")
         server = m.group(1)
         ipv4 = m.group(2)
         ipv6 = m.group(3)
diff --git a/ucoinpy/documents/status.py b/ucoinpy/documents/status.py
deleted file mode 100644
index 547683a58fa811b76c415694f6f7d10d473e2093..0000000000000000000000000000000000000000
--- a/ucoinpy/documents/status.py
+++ /dev/null
@@ -1,78 +0,0 @@
-import re
-from .document import Document
-
-
-class Status(Document):
-    """
-.. note:: A status document is specified by the following format :
-
-    | Version: VERSION
-    | Type: Status
-    | Currency: CURRENCY_NAME
-    | Status: STATUS
-    | Block: BLOCK
-    | From: SENDER
-    | To: RECIPIENT
-
-    """
-
-    re_type = re.compile("Type: (Status)")
-    re_status = re.compile("Status: (NEW|NEW_BACK|UP|UP_BACK|DOWN)")
-    re_block = re.compile("Block: ([0-9]+-[0-9a-fA-F]{5,40})\n")
-    re_from = re.compile("From: ([1-9A-Za-z][^OIl]{42,45})\n")
-    re_to = re.compile("To: ([1-9A-Za-z][^OIl]{42,45})\n")
-
-    def __init__(self, version, currency, status, blockid, sender,
-                 recipient, signature):
-        """
-        Constructor
-        """
-        super().__init__(version, currency, [signature])
-
-        self.status = status
-        self.blockid = blockid
-        self.sender = sender
-        self.recipient = recipient
-
-    @classmethod
-    def from_signed_raw(cls, raw):
-        lines = raw.splitlines(True)
-        n = 0
-
-        version = int(Status.re_version.match(lines[n]).group(1))
-        n = n + 1
-
-        Status.re_type.match(lines[n]).group(1)
-        n = n + 1
-
-        currency = Status.re_currency.match(lines[n]).group(1)
-        n = n + 1
-
-        status = Status.re_status.match(lines[n]).group(1)
-        n = n + 1
-
-        blockid = Status.re_block.match(lines[n]).group(1)
-        n = n + 1
-
-        sender = Status.re_from.match(lines[n]).group(1)
-        n = n + 1
-
-        recipient = Status.re_to.match(lines[n]).group(1)
-        n = n + 1
-
-        signature = Status.re_signature.match(lines[n]).group(1)
-        n = n + 1
-
-        return cls(version, currency, status, blockid,
-                   sender, recipient, signature)
-
-    def raw(self):
-        return """Version: {0}
-Type: Status
-Currency: {1}
-Status: {2}
-Block: {3}
-From: {4}
-To: {5}
-""".format(self.version, self.currency, self.status,
-           self.blockid, self.sender, self.recipient)
diff --git a/ucoinpy/documents/transaction.py b/ucoinpy/documents/transaction.py
index d9b532d22d7615e17514c808ca1e143684797b3c..0bca5d368f3f34e7425b9a02a1fe27491c7d355a 100644
--- a/ucoinpy/documents/transaction.py
+++ b/ucoinpy/documents/transaction.py
@@ -1,6 +1,5 @@
-from .document import Document
+from .document import Document, MalformedDocumentError
 import re
-import logging
 
 
 class Transaction(Document):
@@ -47,6 +46,18 @@ class Transaction(Document):
     re_comment = re.compile("Comment: ([^\n]*)\n")
     re_pubkey = re.compile("([1-9A-Za-z][^OIl]{42,45})\n")
 
+    fields_parsers = {**Document.fields_parsers, **{
+            "Type": re_type,
+            "TX": re_header,
+            "Issuers": re_issuers,
+            "Inputs": re_inputs,
+            "Outputs": re_outputs,
+            "Comment": re_comment,
+            "Compact comment": re_compact_comment,
+            "Pubkey": re_pubkey
+        }
+    }
+
     def __init__(self, version, currency, issuers, inputs, outputs,
                  comment, signatures):
         """
@@ -65,40 +76,42 @@ class Transaction(Document):
         n = 0
 
         header_data = Transaction.re_header.match(lines[n])
+        if header_data is None:
+            raise MalformedDocumentError("Compact TX header")
         version = int(header_data.group(1))
         issuers_num = int(header_data.group(2))
         inputs_num = int(header_data.group(3))
         outputs_num = int(header_data.group(4))
         has_comment = int(header_data.group(5))
-        n = n + 1
+        n += 1
 
         issuers = []
         inputs = []
         outputs = []
         signatures = []
         for i in range(0, issuers_num):
-            issuer = Transaction.re_pubkey.match(lines[n]).group(1)
+            issuer = Transaction.parse_field("Pubkey", lines[n])
             issuers.append(issuer)
-            n = n + 1
+            n += 1
 
         for i in range(0, inputs_num):
             input_source = InputSource.from_inline(lines[n])
             inputs.append(input_source)
-            n = n + 1
+            n += 1
 
         for i in range(0, outputs_num):
             output_source = OutputSource.from_inline(lines[n])
             outputs.append(output_source)
-            n = n + 1
+            n += 1
 
         comment = ""
         if has_comment == 1:
             comment = Transaction.re_compact_comment.match(lines[n]).group(1)
-            n = n + 1
+            n += 1
 
         while n < len(lines):
             signatures.append(Transaction.re_signature.match(lines[n]).group(1))
-            n = n + 1
+            n += 1
 
         return cls(version, currency, issuers, inputs, outputs, comment, signatures)
 
@@ -107,14 +120,14 @@ class Transaction(Document):
         lines = raw.splitlines(True)
         n = 0
 
-        version = int(Transaction.re_version.match(lines[n]).group(1))
-        n = n + 1
+        version = int(Transaction.parse_field("Version", lines[n]))
+        n += 1
 
-        Transaction.re_type.match(lines[n]).group(1)
-        n = n + 1
+        Transaction.parse_field("Type", lines[n])
+        n += 1
 
-        currency = Transaction.re_currency.match(lines[n]).group(1)
-        n = n + 1
+        currency = Transaction.parse_field("Currency", lines[n])
+        n += 1
 
         issuers = []
         inputs = []
@@ -122,34 +135,34 @@ class Transaction(Document):
         signatures = []
 
         if Transaction.re_issuers.match(lines[n]):
-            n = n + 1
+            n += 1
             while Transaction.re_inputs.match(lines[n]) is None:
-                issuer = Transaction.re_pubkey.match(lines[n]).group(1)
+                issuer = Transaction.parse_field("Pubkey", lines[n])
                 issuers.append(issuer)
-                n = n + 1
+                n += 1
 
         if Transaction.re_inputs.match(lines[n]):
-            n = n + 1
+            n += 1
             while Transaction.re_outputs.match(lines[n]) is None:
                 input_source = InputSource.from_inline(lines[n])
                 inputs.append(input_source)
-                n = n + 1
+                n += 1
 
         if Transaction.re_outputs.match(lines[n]) is not None:
-            n = n + 1
+            n += 1
             while not Transaction.re_comment.match(lines[n]):
                 output = OutputSource.from_inline(lines[n])
                 outputs.append(output)
-                n = n + 1
+                n += 1
 
-        comment = Transaction.re_comment.match(lines[n]).group(1)
-        n = n + 1
+        comment = Transaction.parse_field("Comment", lines[n])
+        n += 1
 
         if Transaction.re_signature.match(lines[n]) is not None:
             while n < len(lines):
-                sign = Transaction.re_signature.match(lines[n]).group(1)
+                sign = Transaction.parse_field("Signature", lines[n])
                 signatures.append(sign)
-                n = n + 1
+                n += 1
 
         return cls(version, currency, issuers, inputs, outputs,
                    comment, signatures)
@@ -245,6 +258,8 @@ class InputSource:
     @classmethod
     def from_inline(cls, inline):
         data = InputSource.re_inline.match(inline)
+        if data is None:
+            raise MalformedDocumentError("Inline input")
         index = int(data.group(1))
         source = data.group(2)
         number = int(data.group(3))
@@ -282,6 +297,8 @@ class OutputSource():
     @classmethod
     def from_inline(cls, inline):
         data = OutputSource.re_inline.match(inline)
+        if data is None:
+            raise MalformedDocumentError("Inline output")
         pubkey = data.group(1)
         amount = int(data.group(2))
         return cls(pubkey, amount)