text: import inspect
  from binascii import hexlify, unhexlify
  from importlib import import_module
  
  from binary.hex.writer import write_high, write_low
  from binary.unsigned_integer.writer import write_bit32, write_bit64, write_bit8
  
  from crypto.configuration.network import get_network
  from crypto.constants import TRANSACTION_TYPES
  from crypto.exceptions import ArkSerializerException
  from crypto.transactions.serializers.base import BaseSerializer
  
  
  class Serializer(object):
  
      transaction = None
  
      def __init__(self, transaction):
          if not transaction:
              raise ArkSerializerException('No transaction data provided')
          self.transaction = transaction
  
      def serialize(self):
          """Perform AIP11 compliant serialization
  
          Returns:
              bytes: bytes string
          """
          network_config = get_network()
          bytes_data = bytes()
          bytes_data += write_bit8(0xff)
          bytes_data += write_low(self.transaction.get('version') or 0x01)
          bytes_data += write_bit8(self.transaction.get('network') or network_config['version'])
          bytes_data += write_low(self.transaction['type'])
          bytes_data += write_bit32(self.transaction['timestamp'])
          bytes_data += write_high(self.transaction['senderPublicKey'])
          bytes_data += write_bit64(self.transaction['fee'])
  
          if self.transaction.get('vendorField'):
              vendorFieldLength = len(self.transaction['vendorField'])
              bytes_data += write_bit8(vendorFieldLength)
              bytes_data += self.transaction['vendorField']
          elif self.transaction.get('vendorFieldHex'):
              vendorField_hex_length = len(self.transaction['vendorFieldHex'])
              bytes_data += write_bit8(vendorField_hex_length / 2)
              bytes_data += self.transaction['vendorFieldHex']
          else:
              bytes_data += write_bit8(0x00)
  
          bytes_data = self._handle_transaction_type(bytes_data)
          bytes_data = self._handle_signature(bytes_data)
  
          return hexlify(bytes_data).decode()
  
      def _handle_transaction_type(self, bytes_data):
          """Serialize transaction specific data (eg. delegate registration)
  
          Args:
              bytes_data (bytes): already serialized data about a transaction (eg. version, network)
  
          Returns:
              bytes: bytes string
          """
          serializer_name = TRANSACTION_TYPES[self.transaction['type']]
  
          module = import_module('crypto.transactions.serializers.{}'.format(serializer_name))
          for attr in dir(module):
              # If attr name is `BaseSerializer`, skip it as it's a class and also has a
              # subclass of BaseSerializer
              if attr == 'BaseSerializer':
                  continue
  
              attribute = getattr(module, attr)
              if inspect.isclass(attribute) and issubclass(attribute, BaseSerializer):
                  # this attribute is actually a specific serializer that we want to use
                  serializer = attribute
                  break
          return serializer(self.transaction, bytes_data).serialize()
  
      def _handle_signature(self, bytes_data):
          """Serialize signature data of the transaction
  
          Args:
              bytes_data (bytes): already serialized data
  
          Returns:
              bytes: bytes string
          """
          if self.transaction.get('signature'):
              bytes_data += unhexlify(self.transaction['signature'])
  
          if self.transaction.get('secondSignature'):
              bytes_data += unhexlify(self.transaction['secondSignature'])
          elif self.transaction.get('signSignature'):
              bytes_data += unhexlify(self.transaction['signSignature'])
  
          if self.transaction.get('signatures'):
              bytes_data += write_bit8(0xff)
              bytes_data += unhexlify(''.join(self.transaction['signatures']))
  
          return bytes_data
  