#!/usr/bin/python
#
# Code generated by catbuffer python generator; DO NOT EDIT.

from __future__ import annotations

from binascii import hexlify
from enum import Enum, Flag
from typing import ByteString, List, TypeVar

from ..core.ArrayHelpers import ArrayHelpers
from ..core.BaseValue import BaseValue
from ..core.ByteArray import ByteArray


# string or bytes
StrBytes = TypeVar('StrBytes', str, bytes)

class Amount(BaseValue):
    SIZE = 8

    def __init__(self, amount: int = 0):
        super().__init__(self.SIZE, amount, Amount)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> Amount:
        buffer_ = memoryview(payload)
        return Amount(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class BlockDuration(BaseValue):
    SIZE = 8

    def __init__(self, block_duration: int = 0):
        super().__init__(self.SIZE, block_duration, BlockDuration)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> BlockDuration:
        buffer_ = memoryview(payload)
        return BlockDuration(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class BlockFeeMultiplier(BaseValue):
    SIZE = 4

    def __init__(self, block_fee_multiplier: int = 0):
        super().__init__(self.SIZE, block_fee_multiplier, BlockFeeMultiplier)

    def size(self) -> int:
        return 4

    @classmethod
    def deserialize(self, payload: ByteString) -> BlockFeeMultiplier:
        buffer_ = memoryview(payload)
        return BlockFeeMultiplier(int.from_bytes(buffer_[:4], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(4, byteorder="little", signed=False)


class Difficulty(BaseValue):
    SIZE = 8

    def __init__(self, difficulty: int = 0):
        super().__init__(self.SIZE, difficulty, Difficulty)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> Difficulty:
        buffer_ = memoryview(payload)
        return Difficulty(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class FinalizationEpoch(BaseValue):
    SIZE = 4

    def __init__(self, finalization_epoch: int = 0):
        super().__init__(self.SIZE, finalization_epoch, FinalizationEpoch)

    def size(self) -> int:
        return 4

    @classmethod
    def deserialize(self, payload: ByteString) -> FinalizationEpoch:
        buffer_ = memoryview(payload)
        return FinalizationEpoch(int.from_bytes(buffer_[:4], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(4, byteorder="little", signed=False)


class FinalizationPoint(BaseValue):
    SIZE = 4

    def __init__(self, finalization_point: int = 0):
        super().__init__(self.SIZE, finalization_point, FinalizationPoint)

    def size(self) -> int:
        return 4

    @classmethod
    def deserialize(self, payload: ByteString) -> FinalizationPoint:
        buffer_ = memoryview(payload)
        return FinalizationPoint(int.from_bytes(buffer_[:4], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(4, byteorder="little", signed=False)


class Height(BaseValue):
    SIZE = 8

    def __init__(self, height: int = 0):
        super().__init__(self.SIZE, height, Height)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> Height:
        buffer_ = memoryview(payload)
        return Height(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class Importance(BaseValue):
    SIZE = 8

    def __init__(self, importance: int = 0):
        super().__init__(self.SIZE, importance, Importance)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> Importance:
        buffer_ = memoryview(payload)
        return Importance(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class ImportanceHeight(BaseValue):
    SIZE = 8

    def __init__(self, importance_height: int = 0):
        super().__init__(self.SIZE, importance_height, ImportanceHeight)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> ImportanceHeight:
        buffer_ = memoryview(payload)
        return ImportanceHeight(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class UnresolvedMosaicId(BaseValue):
    SIZE = 8

    def __init__(self, unresolved_mosaic_id: int = 0):
        super().__init__(self.SIZE, unresolved_mosaic_id, UnresolvedMosaicId)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> UnresolvedMosaicId:
        buffer_ = memoryview(payload)
        return UnresolvedMosaicId(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class MosaicId(BaseValue):
    SIZE = 8

    def __init__(self, mosaic_id: int = 0):
        super().__init__(self.SIZE, mosaic_id, MosaicId)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicId:
        buffer_ = memoryview(payload)
        return MosaicId(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class Timestamp(BaseValue):
    SIZE = 8

    def __init__(self, timestamp: int = 0):
        super().__init__(self.SIZE, timestamp, Timestamp)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> Timestamp:
        buffer_ = memoryview(payload)
        return Timestamp(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class UnresolvedAddress(ByteArray):
    SIZE = 24

    def __init__(self, unresolved_address: StrBytes = bytes(24)):
        super().__init__(self.SIZE, unresolved_address, UnresolvedAddress)

    def size(self) -> int:
        return 24

    @classmethod
    def deserialize(self, payload: ByteString) -> UnresolvedAddress:
        buffer_ = memoryview(payload)
        return UnresolvedAddress(ArrayHelpers.get_bytes(buffer_, 24))

    def serialize(self) -> bytes:
        return self.bytes


class Address(ByteArray):
    SIZE = 24

    def __init__(self, address: StrBytes = bytes(24)):
        super().__init__(self.SIZE, address, Address)

    def size(self) -> int:
        return 24

    @classmethod
    def deserialize(self, payload: ByteString) -> Address:
        buffer_ = memoryview(payload)
        return Address(ArrayHelpers.get_bytes(buffer_, 24))

    def serialize(self) -> bytes:
        return self.bytes


class Hash256(ByteArray):
    SIZE = 32

    def __init__(self, hash256: StrBytes = bytes(32)):
        super().__init__(self.SIZE, hash256, Hash256)

    def size(self) -> int:
        return 32

    @classmethod
    def deserialize(self, payload: ByteString) -> Hash256:
        buffer_ = memoryview(payload)
        return Hash256(ArrayHelpers.get_bytes(buffer_, 32))

    def serialize(self) -> bytes:
        return self.bytes


class Hash512(ByteArray):
    SIZE = 64

    def __init__(self, hash512: StrBytes = bytes(64)):
        super().__init__(self.SIZE, hash512, Hash512)

    def size(self) -> int:
        return 64

    @classmethod
    def deserialize(self, payload: ByteString) -> Hash512:
        buffer_ = memoryview(payload)
        return Hash512(ArrayHelpers.get_bytes(buffer_, 64))

    def serialize(self) -> bytes:
        return self.bytes


class PublicKey(ByteArray):
    SIZE = 32

    def __init__(self, public_key: StrBytes = bytes(32)):
        super().__init__(self.SIZE, public_key, PublicKey)

    def size(self) -> int:
        return 32

    @classmethod
    def deserialize(self, payload: ByteString) -> PublicKey:
        buffer_ = memoryview(payload)
        return PublicKey(ArrayHelpers.get_bytes(buffer_, 32))

    def serialize(self) -> bytes:
        return self.bytes


class VotingPublicKey(ByteArray):
    SIZE = 32

    def __init__(self, voting_public_key: StrBytes = bytes(32)):
        super().__init__(self.SIZE, voting_public_key, VotingPublicKey)

    def size(self) -> int:
        return 32

    @classmethod
    def deserialize(self, payload: ByteString) -> VotingPublicKey:
        buffer_ = memoryview(payload)
        return VotingPublicKey(ArrayHelpers.get_bytes(buffer_, 32))

    def serialize(self) -> bytes:
        return self.bytes


class Signature(ByteArray):
    SIZE = 64

    def __init__(self, signature: StrBytes = bytes(64)):
        super().__init__(self.SIZE, signature, Signature)

    def size(self) -> int:
        return 64

    @classmethod
    def deserialize(self, payload: ByteString) -> Signature:
        buffer_ = memoryview(payload)
        return Signature(ArrayHelpers.get_bytes(buffer_, 64))

    def serialize(self) -> bytes:
        return self.bytes


class Mosaic:
    TYPE_HINTS = {
        "mosaic_id": "pod:MosaicId",
        "amount": "pod:Amount"
    }

    def __init__(self):
        self._mosaic_id = MosaicId()
        self._amount = Amount()

    @property
    def mosaic_id(self) -> MosaicId:
        return self._mosaic_id

    @property
    def amount(self) -> Amount:
        return self._amount

    @mosaic_id.setter
    def mosaic_id(self, value: MosaicId):
        self._mosaic_id = value

    @amount.setter
    def amount(self, value: Amount):
        self._amount = value

    def size(self) -> int:
        size = 0
        size += self.mosaic_id.size()
        size += self.amount.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> Mosaic:
        buffer_ = memoryview(payload)
        mosaic_id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        amount = Amount.deserialize(buffer_)
        buffer_ = buffer_[amount.size():]

        instance = Mosaic()
        instance._mosaic_id = mosaic_id
        instance._amount = amount
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._amount.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "amount: {}, ".format(self._amount.__str__())
        result += ")"
        return result


class UnresolvedMosaic:
    TYPE_HINTS = {
        "mosaic_id": "pod:UnresolvedMosaicId",
        "amount": "pod:Amount"
    }

    def __init__(self):
        self._mosaic_id = UnresolvedMosaicId()
        self._amount = Amount()

    @property
    def mosaic_id(self) -> UnresolvedMosaicId:
        return self._mosaic_id

    @property
    def amount(self) -> Amount:
        return self._amount

    @mosaic_id.setter
    def mosaic_id(self, value: UnresolvedMosaicId):
        self._mosaic_id = value

    @amount.setter
    def amount(self, value: Amount):
        self._amount = value

    def size(self) -> int:
        size = 0
        size += self.mosaic_id.size()
        size += self.amount.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> UnresolvedMosaic:
        buffer_ = memoryview(payload)
        mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        amount = Amount.deserialize(buffer_)
        buffer_ = buffer_[amount.size():]

        instance = UnresolvedMosaic()
        instance._mosaic_id = mosaic_id
        instance._amount = amount
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._amount.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "amount: {}, ".format(self._amount.__str__())
        result += ")"
        return result


class LinkAction(Enum):
    UNLINK = 0
    LINK = 1

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> LinkAction:
        buffer_ = memoryview(payload)
        return LinkAction(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class NetworkType(Enum):
    MAINNET = 104
    TESTNET = 152

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> NetworkType:
        buffer_ = memoryview(payload)
        return NetworkType(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class TransactionType(Enum):
    ACCOUNT_KEY_LINK = 16716
    NODE_KEY_LINK = 16972
    AGGREGATE_COMPLETE = 16705
    AGGREGATE_BONDED = 16961
    VOTING_KEY_LINK = 16707
    VRF_KEY_LINK = 16963
    HASH_LOCK = 16712
    SECRET_LOCK = 16722
    SECRET_PROOF = 16978
    ACCOUNT_METADATA = 16708
    MOSAIC_METADATA = 16964
    NAMESPACE_METADATA = 17220
    MOSAIC_DEFINITION = 16717
    MOSAIC_SUPPLY_CHANGE = 16973
    MOSAIC_SUPPLY_REVOCATION = 17229
    MULTISIG_ACCOUNT_MODIFICATION = 16725
    ADDRESS_ALIAS = 16974
    MOSAIC_ALIAS = 17230
    NAMESPACE_REGISTRATION = 16718
    ACCOUNT_ADDRESS_RESTRICTION = 16720
    ACCOUNT_MOSAIC_RESTRICTION = 16976
    ACCOUNT_OPERATION_RESTRICTION = 17232
    MOSAIC_ADDRESS_RESTRICTION = 16977
    MOSAIC_GLOBAL_RESTRICTION = 16721
    TRANSFER = 16724

    def size(self) -> int:
        return 2

    @classmethod
    def deserialize(self, payload: ByteString) -> TransactionType:
        buffer_ = memoryview(payload)
        return TransactionType(int.from_bytes(buffer_[:2], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(2, byteorder="little", signed=False)
        return buffer_


class Transaction:
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = 0
        self._network = NetworkType.MAINNET
        self._type_ = TransactionType.ACCOUNT_KEY_LINK
        self._fee = Amount()
        self._deadline = Timestamp()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> Transaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]

        instance = Transaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += ")"
        return result


class EmbeddedTransaction:
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = 0
        self._network = NetworkType.MAINNET
        self._type_ = TransactionType.ACCOUNT_KEY_LINK
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]

        instance = EmbeddedTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += ")"
        return result


class ProofGamma(ByteArray):
    SIZE = 32

    def __init__(self, proof_gamma: StrBytes = bytes(32)):
        super().__init__(self.SIZE, proof_gamma, ProofGamma)

    def size(self) -> int:
        return 32

    @classmethod
    def deserialize(self, payload: ByteString) -> ProofGamma:
        buffer_ = memoryview(payload)
        return ProofGamma(ArrayHelpers.get_bytes(buffer_, 32))

    def serialize(self) -> bytes:
        return self.bytes


class ProofVerificationHash(ByteArray):
    SIZE = 16

    def __init__(self, proof_verification_hash: StrBytes = bytes(16)):
        super().__init__(self.SIZE, proof_verification_hash, ProofVerificationHash)

    def size(self) -> int:
        return 16

    @classmethod
    def deserialize(self, payload: ByteString) -> ProofVerificationHash:
        buffer_ = memoryview(payload)
        return ProofVerificationHash(ArrayHelpers.get_bytes(buffer_, 16))

    def serialize(self) -> bytes:
        return self.bytes


class ProofScalar(ByteArray):
    SIZE = 32

    def __init__(self, proof_scalar: StrBytes = bytes(32)):
        super().__init__(self.SIZE, proof_scalar, ProofScalar)

    def size(self) -> int:
        return 32

    @classmethod
    def deserialize(self, payload: ByteString) -> ProofScalar:
        buffer_ = memoryview(payload)
        return ProofScalar(ArrayHelpers.get_bytes(buffer_, 32))

    def serialize(self) -> bytes:
        return self.bytes


class BlockType(Enum):
    NEMESIS = 32835
    NORMAL = 33091
    IMPORTANCE = 33347

    def size(self) -> int:
        return 2

    @classmethod
    def deserialize(self, payload: ByteString) -> BlockType:
        buffer_ = memoryview(payload)
        return BlockType(int.from_bytes(buffer_[:2], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(2, byteorder="little", signed=False)
        return buffer_


class VrfProof:
    TYPE_HINTS = {
        "gamma": "pod:ProofGamma",
        "verification_hash": "pod:ProofVerificationHash",
        "scalar": "pod:ProofScalar"
    }

    def __init__(self):
        self._gamma = ProofGamma()
        self._verification_hash = ProofVerificationHash()
        self._scalar = ProofScalar()

    @property
    def gamma(self) -> ProofGamma:
        return self._gamma

    @property
    def verification_hash(self) -> ProofVerificationHash:
        return self._verification_hash

    @property
    def scalar(self) -> ProofScalar:
        return self._scalar

    @gamma.setter
    def gamma(self, value: ProofGamma):
        self._gamma = value

    @verification_hash.setter
    def verification_hash(self, value: ProofVerificationHash):
        self._verification_hash = value

    @scalar.setter
    def scalar(self, value: ProofScalar):
        self._scalar = value

    def size(self) -> int:
        size = 0
        size += self.gamma.size()
        size += self.verification_hash.size()
        size += self.scalar.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> VrfProof:
        buffer_ = memoryview(payload)
        gamma = ProofGamma.deserialize(buffer_)
        buffer_ = buffer_[gamma.size():]
        verification_hash = ProofVerificationHash.deserialize(buffer_)
        buffer_ = buffer_[verification_hash.size():]
        scalar = ProofScalar.deserialize(buffer_)
        buffer_ = buffer_[scalar.size():]

        instance = VrfProof()
        instance._gamma = gamma
        instance._verification_hash = verification_hash
        instance._scalar = scalar
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._gamma.serialize()
        buffer_ += self._verification_hash.serialize()
        buffer_ += self._scalar.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "gamma: {}, ".format(self._gamma.__str__())
        result += "verification_hash: {}, ".format(self._verification_hash.__str__())
        result += "scalar: {}, ".format(self._scalar.__str__())
        result += ")"
        return result


class Block:
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:BlockType",
        "height": "pod:Height",
        "timestamp": "pod:Timestamp",
        "difficulty": "pod:Difficulty",
        "generation_hash_proof": "struct:VrfProof",
        "previous_block_hash": "pod:Hash256",
        "transactions_hash": "pod:Hash256",
        "receipts_hash": "pod:Hash256",
        "state_hash": "pod:Hash256",
        "beneficiary_address": "pod:Address",
        "fee_multiplier": "pod:BlockFeeMultiplier"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = 0
        self._network = NetworkType.MAINNET
        self._type_ = BlockType.NEMESIS
        self._height = Height()
        self._timestamp = Timestamp()
        self._difficulty = Difficulty()
        self._generation_hash_proof = VrfProof()
        self._previous_block_hash = Hash256()
        self._transactions_hash = Hash256()
        self._receipts_hash = Hash256()
        self._state_hash = Hash256()
        self._beneficiary_address = Address()
        self._fee_multiplier = BlockFeeMultiplier()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> BlockType:
        return self._type_

    @property
    def height(self) -> Height:
        return self._height

    @property
    def timestamp(self) -> Timestamp:
        return self._timestamp

    @property
    def difficulty(self) -> Difficulty:
        return self._difficulty

    @property
    def generation_hash_proof(self) -> VrfProof:
        return self._generation_hash_proof

    @property
    def previous_block_hash(self) -> Hash256:
        return self._previous_block_hash

    @property
    def transactions_hash(self) -> Hash256:
        return self._transactions_hash

    @property
    def receipts_hash(self) -> Hash256:
        return self._receipts_hash

    @property
    def state_hash(self) -> Hash256:
        return self._state_hash

    @property
    def beneficiary_address(self) -> Address:
        return self._beneficiary_address

    @property
    def fee_multiplier(self) -> BlockFeeMultiplier:
        return self._fee_multiplier

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: BlockType):
        self._type_ = value

    @height.setter
    def height(self, value: Height):
        self._height = value

    @timestamp.setter
    def timestamp(self, value: Timestamp):
        self._timestamp = value

    @difficulty.setter
    def difficulty(self, value: Difficulty):
        self._difficulty = value

    @generation_hash_proof.setter
    def generation_hash_proof(self, value: VrfProof):
        self._generation_hash_proof = value

    @previous_block_hash.setter
    def previous_block_hash(self, value: Hash256):
        self._previous_block_hash = value

    @transactions_hash.setter
    def transactions_hash(self, value: Hash256):
        self._transactions_hash = value

    @receipts_hash.setter
    def receipts_hash(self, value: Hash256):
        self._receipts_hash = value

    @state_hash.setter
    def state_hash(self, value: Hash256):
        self._state_hash = value

    @beneficiary_address.setter
    def beneficiary_address(self, value: Address):
        self._beneficiary_address = value

    @fee_multiplier.setter
    def fee_multiplier(self, value: BlockFeeMultiplier):
        self._fee_multiplier = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.height.size()
        size += self.timestamp.size()
        size += self.difficulty.size()
        size += self.generation_hash_proof.size()
        size += self.previous_block_hash.size()
        size += self.transactions_hash.size()
        size += self.receipts_hash.size()
        size += self.state_hash.size()
        size += self.beneficiary_address.size()
        size += self.fee_multiplier.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> Block:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = BlockType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        height = Height.deserialize(buffer_)
        buffer_ = buffer_[height.size():]
        timestamp = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[timestamp.size():]
        difficulty = Difficulty.deserialize(buffer_)
        buffer_ = buffer_[difficulty.size():]
        generation_hash_proof = VrfProof.deserialize(buffer_)
        buffer_ = buffer_[generation_hash_proof.size():]
        previous_block_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[previous_block_hash.size():]
        transactions_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[transactions_hash.size():]
        receipts_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[receipts_hash.size():]
        state_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[state_hash.size():]
        beneficiary_address = Address.deserialize(buffer_)
        buffer_ = buffer_[beneficiary_address.size():]
        fee_multiplier = BlockFeeMultiplier.deserialize(buffer_)
        buffer_ = buffer_[fee_multiplier.size():]

        instance = Block()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._height = height
        instance._timestamp = timestamp
        instance._difficulty = difficulty
        instance._generation_hash_proof = generation_hash_proof
        instance._previous_block_hash = previous_block_hash
        instance._transactions_hash = transactions_hash
        instance._receipts_hash = receipts_hash
        instance._state_hash = state_hash
        instance._beneficiary_address = beneficiary_address
        instance._fee_multiplier = fee_multiplier
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._height.serialize()
        buffer_ += self._timestamp.serialize()
        buffer_ += self._difficulty.serialize()
        buffer_ += self._generation_hash_proof.serialize()
        buffer_ += self._previous_block_hash.serialize()
        buffer_ += self._transactions_hash.serialize()
        buffer_ += self._receipts_hash.serialize()
        buffer_ += self._state_hash.serialize()
        buffer_ += self._beneficiary_address.serialize()
        buffer_ += self._fee_multiplier.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "height: {}, ".format(self._height.__str__())
        result += "timestamp: {}, ".format(self._timestamp.__str__())
        result += "difficulty: {}, ".format(self._difficulty.__str__())
        result += "generation_hash_proof: {}, ".format(self._generation_hash_proof.__str__())
        result += "previous_block_hash: {}, ".format(self._previous_block_hash.__str__())
        result += "transactions_hash: {}, ".format(self._transactions_hash.__str__())
        result += "receipts_hash: {}, ".format(self._receipts_hash.__str__())
        result += "state_hash: {}, ".format(self._state_hash.__str__())
        result += "beneficiary_address: {}, ".format(self._beneficiary_address.__str__())
        result += "fee_multiplier: {}, ".format(self._fee_multiplier.__str__())
        result += ")"
        return result


class NemesisBlock:
    BLOCK_VERSION: int = 1
    BLOCK_TYPE: BlockType = BlockType.NEMESIS
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:BlockType",
        "height": "pod:Height",
        "timestamp": "pod:Timestamp",
        "difficulty": "pod:Difficulty",
        "generation_hash_proof": "struct:VrfProof",
        "previous_block_hash": "pod:Hash256",
        "transactions_hash": "pod:Hash256",
        "receipts_hash": "pod:Hash256",
        "state_hash": "pod:Hash256",
        "beneficiary_address": "pod:Address",
        "fee_multiplier": "pod:BlockFeeMultiplier",
        "total_voting_balance": "pod:Amount",
        "previous_importance_block_hash": "pod:Hash256",
        "transactions": "array[Transaction]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = NemesisBlock.BLOCK_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = NemesisBlock.BLOCK_TYPE
        self._height = Height()
        self._timestamp = Timestamp()
        self._difficulty = Difficulty()
        self._generation_hash_proof = VrfProof()
        self._previous_block_hash = Hash256()
        self._transactions_hash = Hash256()
        self._receipts_hash = Hash256()
        self._state_hash = Hash256()
        self._beneficiary_address = Address()
        self._fee_multiplier = BlockFeeMultiplier()
        self._voting_eligible_accounts_count = 0
        self._harvesting_eligible_accounts_count = 0
        self._total_voting_balance = Amount()
        self._previous_importance_block_hash = Hash256()
        self._transactions = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> BlockType:
        return self._type_

    @property
    def height(self) -> Height:
        return self._height

    @property
    def timestamp(self) -> Timestamp:
        return self._timestamp

    @property
    def difficulty(self) -> Difficulty:
        return self._difficulty

    @property
    def generation_hash_proof(self) -> VrfProof:
        return self._generation_hash_proof

    @property
    def previous_block_hash(self) -> Hash256:
        return self._previous_block_hash

    @property
    def transactions_hash(self) -> Hash256:
        return self._transactions_hash

    @property
    def receipts_hash(self) -> Hash256:
        return self._receipts_hash

    @property
    def state_hash(self) -> Hash256:
        return self._state_hash

    @property
    def beneficiary_address(self) -> Address:
        return self._beneficiary_address

    @property
    def fee_multiplier(self) -> BlockFeeMultiplier:
        return self._fee_multiplier

    @property
    def voting_eligible_accounts_count(self) -> int:
        return self._voting_eligible_accounts_count

    @property
    def harvesting_eligible_accounts_count(self) -> int:
        return self._harvesting_eligible_accounts_count

    @property
    def total_voting_balance(self) -> Amount:
        return self._total_voting_balance

    @property
    def previous_importance_block_hash(self) -> Hash256:
        return self._previous_importance_block_hash

    @property
    def transactions(self) -> List[Transaction]:
        return self._transactions

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: BlockType):
        self._type_ = value

    @height.setter
    def height(self, value: Height):
        self._height = value

    @timestamp.setter
    def timestamp(self, value: Timestamp):
        self._timestamp = value

    @difficulty.setter
    def difficulty(self, value: Difficulty):
        self._difficulty = value

    @generation_hash_proof.setter
    def generation_hash_proof(self, value: VrfProof):
        self._generation_hash_proof = value

    @previous_block_hash.setter
    def previous_block_hash(self, value: Hash256):
        self._previous_block_hash = value

    @transactions_hash.setter
    def transactions_hash(self, value: Hash256):
        self._transactions_hash = value

    @receipts_hash.setter
    def receipts_hash(self, value: Hash256):
        self._receipts_hash = value

    @state_hash.setter
    def state_hash(self, value: Hash256):
        self._state_hash = value

    @beneficiary_address.setter
    def beneficiary_address(self, value: Address):
        self._beneficiary_address = value

    @fee_multiplier.setter
    def fee_multiplier(self, value: BlockFeeMultiplier):
        self._fee_multiplier = value

    @voting_eligible_accounts_count.setter
    def voting_eligible_accounts_count(self, value: int):
        self._voting_eligible_accounts_count = value

    @harvesting_eligible_accounts_count.setter
    def harvesting_eligible_accounts_count(self, value: int):
        self._harvesting_eligible_accounts_count = value

    @total_voting_balance.setter
    def total_voting_balance(self, value: Amount):
        self._total_voting_balance = value

    @previous_importance_block_hash.setter
    def previous_importance_block_hash(self, value: Hash256):
        self._previous_importance_block_hash = value

    @transactions.setter
    def transactions(self, value: List[Transaction]):
        self._transactions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.height.size()
        size += self.timestamp.size()
        size += self.difficulty.size()
        size += self.generation_hash_proof.size()
        size += self.previous_block_hash.size()
        size += self.transactions_hash.size()
        size += self.receipts_hash.size()
        size += self.state_hash.size()
        size += self.beneficiary_address.size()
        size += self.fee_multiplier.size()
        size += 4
        size += 8
        size += self.total_voting_balance.size()
        size += self.previous_importance_block_hash.size()
        size += sum(map(lambda e: e.size(), self.transactions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NemesisBlock:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = BlockType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        height = Height.deserialize(buffer_)
        buffer_ = buffer_[height.size():]
        timestamp = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[timestamp.size():]
        difficulty = Difficulty.deserialize(buffer_)
        buffer_ = buffer_[difficulty.size():]
        generation_hash_proof = VrfProof.deserialize(buffer_)
        buffer_ = buffer_[generation_hash_proof.size():]
        previous_block_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[previous_block_hash.size():]
        transactions_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[transactions_hash.size():]
        receipts_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[receipts_hash.size():]
        state_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[state_hash.size():]
        beneficiary_address = Address.deserialize(buffer_)
        buffer_ = buffer_[beneficiary_address.size():]
        fee_multiplier = BlockFeeMultiplier.deserialize(buffer_)
        buffer_ = buffer_[fee_multiplier.size():]
        voting_eligible_accounts_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        harvesting_eligible_accounts_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        total_voting_balance = Amount.deserialize(buffer_)
        buffer_ = buffer_[total_voting_balance.size():]
        previous_importance_block_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[previous_importance_block_hash.size():]
        transactions = ArrayHelpers.read_array(buffer_, Transaction)
        buffer_ = buffer_[sum(map(lambda e: e.size(), transactions)):]

        instance = NemesisBlock()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._height = height
        instance._timestamp = timestamp
        instance._difficulty = difficulty
        instance._generation_hash_proof = generation_hash_proof
        instance._previous_block_hash = previous_block_hash
        instance._transactions_hash = transactions_hash
        instance._receipts_hash = receipts_hash
        instance._state_hash = state_hash
        instance._beneficiary_address = beneficiary_address
        instance._fee_multiplier = fee_multiplier
        instance._voting_eligible_accounts_count = voting_eligible_accounts_count
        instance._harvesting_eligible_accounts_count = harvesting_eligible_accounts_count
        instance._total_voting_balance = total_voting_balance
        instance._previous_importance_block_hash = previous_importance_block_hash
        instance._transactions = transactions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._height.serialize()
        buffer_ += self._timestamp.serialize()
        buffer_ += self._difficulty.serialize()
        buffer_ += self._generation_hash_proof.serialize()
        buffer_ += self._previous_block_hash.serialize()
        buffer_ += self._transactions_hash.serialize()
        buffer_ += self._receipts_hash.serialize()
        buffer_ += self._state_hash.serialize()
        buffer_ += self._beneficiary_address.serialize()
        buffer_ += self._fee_multiplier.serialize()
        buffer_ += self._voting_eligible_accounts_count.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._harvesting_eligible_accounts_count.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._total_voting_balance.serialize()
        buffer_ += self._previous_importance_block_hash.serialize()
        buffer_ += ArrayHelpers.write_array(self._transactions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "height: {}, ".format(self._height.__str__())
        result += "timestamp: {}, ".format(self._timestamp.__str__())
        result += "difficulty: {}, ".format(self._difficulty.__str__())
        result += "generation_hash_proof: {}, ".format(self._generation_hash_proof.__str__())
        result += "previous_block_hash: {}, ".format(self._previous_block_hash.__str__())
        result += "transactions_hash: {}, ".format(self._transactions_hash.__str__())
        result += "receipts_hash: {}, ".format(self._receipts_hash.__str__())
        result += "state_hash: {}, ".format(self._state_hash.__str__())
        result += "beneficiary_address: {}, ".format(self._beneficiary_address.__str__())
        result += "fee_multiplier: {}, ".format(self._fee_multiplier.__str__())
        result += "voting_eligible_accounts_count: {}, ".format("0x{:X}".format(self._voting_eligible_accounts_count))
        result += "harvesting_eligible_accounts_count: {}, ".format("0x{:X}".format(self._harvesting_eligible_accounts_count))
        result += "total_voting_balance: {}, ".format(self._total_voting_balance.__str__())
        result += "previous_importance_block_hash: {}, ".format(self._previous_importance_block_hash.__str__())
        result += "transactions: {}, ".format(list(map(str, self._transactions)))
        result += ")"
        return result


class NormalBlock:
    BLOCK_VERSION: int = 1
    BLOCK_TYPE: BlockType = BlockType.NORMAL
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:BlockType",
        "height": "pod:Height",
        "timestamp": "pod:Timestamp",
        "difficulty": "pod:Difficulty",
        "generation_hash_proof": "struct:VrfProof",
        "previous_block_hash": "pod:Hash256",
        "transactions_hash": "pod:Hash256",
        "receipts_hash": "pod:Hash256",
        "state_hash": "pod:Hash256",
        "beneficiary_address": "pod:Address",
        "fee_multiplier": "pod:BlockFeeMultiplier",
        "transactions": "array[Transaction]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = NormalBlock.BLOCK_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = NormalBlock.BLOCK_TYPE
        self._height = Height()
        self._timestamp = Timestamp()
        self._difficulty = Difficulty()
        self._generation_hash_proof = VrfProof()
        self._previous_block_hash = Hash256()
        self._transactions_hash = Hash256()
        self._receipts_hash = Hash256()
        self._state_hash = Hash256()
        self._beneficiary_address = Address()
        self._fee_multiplier = BlockFeeMultiplier()
        self._transactions = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._block_header_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> BlockType:
        return self._type_

    @property
    def height(self) -> Height:
        return self._height

    @property
    def timestamp(self) -> Timestamp:
        return self._timestamp

    @property
    def difficulty(self) -> Difficulty:
        return self._difficulty

    @property
    def generation_hash_proof(self) -> VrfProof:
        return self._generation_hash_proof

    @property
    def previous_block_hash(self) -> Hash256:
        return self._previous_block_hash

    @property
    def transactions_hash(self) -> Hash256:
        return self._transactions_hash

    @property
    def receipts_hash(self) -> Hash256:
        return self._receipts_hash

    @property
    def state_hash(self) -> Hash256:
        return self._state_hash

    @property
    def beneficiary_address(self) -> Address:
        return self._beneficiary_address

    @property
    def fee_multiplier(self) -> BlockFeeMultiplier:
        return self._fee_multiplier

    @property
    def transactions(self) -> List[Transaction]:
        return self._transactions

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: BlockType):
        self._type_ = value

    @height.setter
    def height(self, value: Height):
        self._height = value

    @timestamp.setter
    def timestamp(self, value: Timestamp):
        self._timestamp = value

    @difficulty.setter
    def difficulty(self, value: Difficulty):
        self._difficulty = value

    @generation_hash_proof.setter
    def generation_hash_proof(self, value: VrfProof):
        self._generation_hash_proof = value

    @previous_block_hash.setter
    def previous_block_hash(self, value: Hash256):
        self._previous_block_hash = value

    @transactions_hash.setter
    def transactions_hash(self, value: Hash256):
        self._transactions_hash = value

    @receipts_hash.setter
    def receipts_hash(self, value: Hash256):
        self._receipts_hash = value

    @state_hash.setter
    def state_hash(self, value: Hash256):
        self._state_hash = value

    @beneficiary_address.setter
    def beneficiary_address(self, value: Address):
        self._beneficiary_address = value

    @fee_multiplier.setter
    def fee_multiplier(self, value: BlockFeeMultiplier):
        self._fee_multiplier = value

    @transactions.setter
    def transactions(self, value: List[Transaction]):
        self._transactions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.height.size()
        size += self.timestamp.size()
        size += self.difficulty.size()
        size += self.generation_hash_proof.size()
        size += self.previous_block_hash.size()
        size += self.transactions_hash.size()
        size += self.receipts_hash.size()
        size += self.state_hash.size()
        size += self.beneficiary_address.size()
        size += self.fee_multiplier.size()
        size += 4
        size += sum(map(lambda e: e.size(), self.transactions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NormalBlock:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = BlockType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        height = Height.deserialize(buffer_)
        buffer_ = buffer_[height.size():]
        timestamp = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[timestamp.size():]
        difficulty = Difficulty.deserialize(buffer_)
        buffer_ = buffer_[difficulty.size():]
        generation_hash_proof = VrfProof.deserialize(buffer_)
        buffer_ = buffer_[generation_hash_proof.size():]
        previous_block_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[previous_block_hash.size():]
        transactions_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[transactions_hash.size():]
        receipts_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[receipts_hash.size():]
        state_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[state_hash.size():]
        beneficiary_address = Address.deserialize(buffer_)
        buffer_ = buffer_[beneficiary_address.size():]
        fee_multiplier = BlockFeeMultiplier.deserialize(buffer_)
        buffer_ = buffer_[fee_multiplier.size():]
        block_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert block_header_reserved_1 == 0, f"Invalid value of reserved field ({block_header_reserved_1})"
        transactions = ArrayHelpers.read_array(buffer_, Transaction)
        buffer_ = buffer_[sum(map(lambda e: e.size(), transactions)):]

        instance = NormalBlock()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._height = height
        instance._timestamp = timestamp
        instance._difficulty = difficulty
        instance._generation_hash_proof = generation_hash_proof
        instance._previous_block_hash = previous_block_hash
        instance._transactions_hash = transactions_hash
        instance._receipts_hash = receipts_hash
        instance._state_hash = state_hash
        instance._beneficiary_address = beneficiary_address
        instance._fee_multiplier = fee_multiplier
        instance._transactions = transactions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._height.serialize()
        buffer_ += self._timestamp.serialize()
        buffer_ += self._difficulty.serialize()
        buffer_ += self._generation_hash_proof.serialize()
        buffer_ += self._previous_block_hash.serialize()
        buffer_ += self._transactions_hash.serialize()
        buffer_ += self._receipts_hash.serialize()
        buffer_ += self._state_hash.serialize()
        buffer_ += self._beneficiary_address.serialize()
        buffer_ += self._fee_multiplier.serialize()
        buffer_ += self._block_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._transactions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "height: {}, ".format(self._height.__str__())
        result += "timestamp: {}, ".format(self._timestamp.__str__())
        result += "difficulty: {}, ".format(self._difficulty.__str__())
        result += "generation_hash_proof: {}, ".format(self._generation_hash_proof.__str__())
        result += "previous_block_hash: {}, ".format(self._previous_block_hash.__str__())
        result += "transactions_hash: {}, ".format(self._transactions_hash.__str__())
        result += "receipts_hash: {}, ".format(self._receipts_hash.__str__())
        result += "state_hash: {}, ".format(self._state_hash.__str__())
        result += "beneficiary_address: {}, ".format(self._beneficiary_address.__str__())
        result += "fee_multiplier: {}, ".format(self._fee_multiplier.__str__())
        result += "transactions: {}, ".format(list(map(str, self._transactions)))
        result += ")"
        return result


class ImportanceBlock:
    BLOCK_VERSION: int = 1
    BLOCK_TYPE: BlockType = BlockType.IMPORTANCE
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:BlockType",
        "height": "pod:Height",
        "timestamp": "pod:Timestamp",
        "difficulty": "pod:Difficulty",
        "generation_hash_proof": "struct:VrfProof",
        "previous_block_hash": "pod:Hash256",
        "transactions_hash": "pod:Hash256",
        "receipts_hash": "pod:Hash256",
        "state_hash": "pod:Hash256",
        "beneficiary_address": "pod:Address",
        "fee_multiplier": "pod:BlockFeeMultiplier",
        "total_voting_balance": "pod:Amount",
        "previous_importance_block_hash": "pod:Hash256",
        "transactions": "array[Transaction]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = ImportanceBlock.BLOCK_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = ImportanceBlock.BLOCK_TYPE
        self._height = Height()
        self._timestamp = Timestamp()
        self._difficulty = Difficulty()
        self._generation_hash_proof = VrfProof()
        self._previous_block_hash = Hash256()
        self._transactions_hash = Hash256()
        self._receipts_hash = Hash256()
        self._state_hash = Hash256()
        self._beneficiary_address = Address()
        self._fee_multiplier = BlockFeeMultiplier()
        self._voting_eligible_accounts_count = 0
        self._harvesting_eligible_accounts_count = 0
        self._total_voting_balance = Amount()
        self._previous_importance_block_hash = Hash256()
        self._transactions = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> BlockType:
        return self._type_

    @property
    def height(self) -> Height:
        return self._height

    @property
    def timestamp(self) -> Timestamp:
        return self._timestamp

    @property
    def difficulty(self) -> Difficulty:
        return self._difficulty

    @property
    def generation_hash_proof(self) -> VrfProof:
        return self._generation_hash_proof

    @property
    def previous_block_hash(self) -> Hash256:
        return self._previous_block_hash

    @property
    def transactions_hash(self) -> Hash256:
        return self._transactions_hash

    @property
    def receipts_hash(self) -> Hash256:
        return self._receipts_hash

    @property
    def state_hash(self) -> Hash256:
        return self._state_hash

    @property
    def beneficiary_address(self) -> Address:
        return self._beneficiary_address

    @property
    def fee_multiplier(self) -> BlockFeeMultiplier:
        return self._fee_multiplier

    @property
    def voting_eligible_accounts_count(self) -> int:
        return self._voting_eligible_accounts_count

    @property
    def harvesting_eligible_accounts_count(self) -> int:
        return self._harvesting_eligible_accounts_count

    @property
    def total_voting_balance(self) -> Amount:
        return self._total_voting_balance

    @property
    def previous_importance_block_hash(self) -> Hash256:
        return self._previous_importance_block_hash

    @property
    def transactions(self) -> List[Transaction]:
        return self._transactions

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: BlockType):
        self._type_ = value

    @height.setter
    def height(self, value: Height):
        self._height = value

    @timestamp.setter
    def timestamp(self, value: Timestamp):
        self._timestamp = value

    @difficulty.setter
    def difficulty(self, value: Difficulty):
        self._difficulty = value

    @generation_hash_proof.setter
    def generation_hash_proof(self, value: VrfProof):
        self._generation_hash_proof = value

    @previous_block_hash.setter
    def previous_block_hash(self, value: Hash256):
        self._previous_block_hash = value

    @transactions_hash.setter
    def transactions_hash(self, value: Hash256):
        self._transactions_hash = value

    @receipts_hash.setter
    def receipts_hash(self, value: Hash256):
        self._receipts_hash = value

    @state_hash.setter
    def state_hash(self, value: Hash256):
        self._state_hash = value

    @beneficiary_address.setter
    def beneficiary_address(self, value: Address):
        self._beneficiary_address = value

    @fee_multiplier.setter
    def fee_multiplier(self, value: BlockFeeMultiplier):
        self._fee_multiplier = value

    @voting_eligible_accounts_count.setter
    def voting_eligible_accounts_count(self, value: int):
        self._voting_eligible_accounts_count = value

    @harvesting_eligible_accounts_count.setter
    def harvesting_eligible_accounts_count(self, value: int):
        self._harvesting_eligible_accounts_count = value

    @total_voting_balance.setter
    def total_voting_balance(self, value: Amount):
        self._total_voting_balance = value

    @previous_importance_block_hash.setter
    def previous_importance_block_hash(self, value: Hash256):
        self._previous_importance_block_hash = value

    @transactions.setter
    def transactions(self, value: List[Transaction]):
        self._transactions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.height.size()
        size += self.timestamp.size()
        size += self.difficulty.size()
        size += self.generation_hash_proof.size()
        size += self.previous_block_hash.size()
        size += self.transactions_hash.size()
        size += self.receipts_hash.size()
        size += self.state_hash.size()
        size += self.beneficiary_address.size()
        size += self.fee_multiplier.size()
        size += 4
        size += 8
        size += self.total_voting_balance.size()
        size += self.previous_importance_block_hash.size()
        size += sum(map(lambda e: e.size(), self.transactions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> ImportanceBlock:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = BlockType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        height = Height.deserialize(buffer_)
        buffer_ = buffer_[height.size():]
        timestamp = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[timestamp.size():]
        difficulty = Difficulty.deserialize(buffer_)
        buffer_ = buffer_[difficulty.size():]
        generation_hash_proof = VrfProof.deserialize(buffer_)
        buffer_ = buffer_[generation_hash_proof.size():]
        previous_block_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[previous_block_hash.size():]
        transactions_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[transactions_hash.size():]
        receipts_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[receipts_hash.size():]
        state_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[state_hash.size():]
        beneficiary_address = Address.deserialize(buffer_)
        buffer_ = buffer_[beneficiary_address.size():]
        fee_multiplier = BlockFeeMultiplier.deserialize(buffer_)
        buffer_ = buffer_[fee_multiplier.size():]
        voting_eligible_accounts_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        harvesting_eligible_accounts_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        total_voting_balance = Amount.deserialize(buffer_)
        buffer_ = buffer_[total_voting_balance.size():]
        previous_importance_block_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[previous_importance_block_hash.size():]
        transactions = ArrayHelpers.read_array(buffer_, Transaction)
        buffer_ = buffer_[sum(map(lambda e: e.size(), transactions)):]

        instance = ImportanceBlock()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._height = height
        instance._timestamp = timestamp
        instance._difficulty = difficulty
        instance._generation_hash_proof = generation_hash_proof
        instance._previous_block_hash = previous_block_hash
        instance._transactions_hash = transactions_hash
        instance._receipts_hash = receipts_hash
        instance._state_hash = state_hash
        instance._beneficiary_address = beneficiary_address
        instance._fee_multiplier = fee_multiplier
        instance._voting_eligible_accounts_count = voting_eligible_accounts_count
        instance._harvesting_eligible_accounts_count = harvesting_eligible_accounts_count
        instance._total_voting_balance = total_voting_balance
        instance._previous_importance_block_hash = previous_importance_block_hash
        instance._transactions = transactions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._height.serialize()
        buffer_ += self._timestamp.serialize()
        buffer_ += self._difficulty.serialize()
        buffer_ += self._generation_hash_proof.serialize()
        buffer_ += self._previous_block_hash.serialize()
        buffer_ += self._transactions_hash.serialize()
        buffer_ += self._receipts_hash.serialize()
        buffer_ += self._state_hash.serialize()
        buffer_ += self._beneficiary_address.serialize()
        buffer_ += self._fee_multiplier.serialize()
        buffer_ += self._voting_eligible_accounts_count.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._harvesting_eligible_accounts_count.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._total_voting_balance.serialize()
        buffer_ += self._previous_importance_block_hash.serialize()
        buffer_ += ArrayHelpers.write_array(self._transactions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "height: {}, ".format(self._height.__str__())
        result += "timestamp: {}, ".format(self._timestamp.__str__())
        result += "difficulty: {}, ".format(self._difficulty.__str__())
        result += "generation_hash_proof: {}, ".format(self._generation_hash_proof.__str__())
        result += "previous_block_hash: {}, ".format(self._previous_block_hash.__str__())
        result += "transactions_hash: {}, ".format(self._transactions_hash.__str__())
        result += "receipts_hash: {}, ".format(self._receipts_hash.__str__())
        result += "state_hash: {}, ".format(self._state_hash.__str__())
        result += "beneficiary_address: {}, ".format(self._beneficiary_address.__str__())
        result += "fee_multiplier: {}, ".format(self._fee_multiplier.__str__())
        result += "voting_eligible_accounts_count: {}, ".format("0x{:X}".format(self._voting_eligible_accounts_count))
        result += "harvesting_eligible_accounts_count: {}, ".format("0x{:X}".format(self._harvesting_eligible_accounts_count))
        result += "total_voting_balance: {}, ".format(self._total_voting_balance.__str__())
        result += "previous_importance_block_hash: {}, ".format(self._previous_importance_block_hash.__str__())
        result += "transactions: {}, ".format(list(map(str, self._transactions)))
        result += ")"
        return result


class FinalizationRound:
    TYPE_HINTS = {
        "epoch": "pod:FinalizationEpoch",
        "point": "pod:FinalizationPoint"
    }

    def __init__(self):
        self._epoch = FinalizationEpoch()
        self._point = FinalizationPoint()

    @property
    def epoch(self) -> FinalizationEpoch:
        return self._epoch

    @property
    def point(self) -> FinalizationPoint:
        return self._point

    @epoch.setter
    def epoch(self, value: FinalizationEpoch):
        self._epoch = value

    @point.setter
    def point(self, value: FinalizationPoint):
        self._point = value

    def size(self) -> int:
        size = 0
        size += self.epoch.size()
        size += self.point.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> FinalizationRound:
        buffer_ = memoryview(payload)
        epoch = FinalizationEpoch.deserialize(buffer_)
        buffer_ = buffer_[epoch.size():]
        point = FinalizationPoint.deserialize(buffer_)
        buffer_ = buffer_[point.size():]

        instance = FinalizationRound()
        instance._epoch = epoch
        instance._point = point
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._epoch.serialize()
        buffer_ += self._point.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "epoch: {}, ".format(self._epoch.__str__())
        result += "point: {}, ".format(self._point.__str__())
        result += ")"
        return result


class FinalizedBlockHeader:
    TYPE_HINTS = {
        "round": "struct:FinalizationRound",
        "height": "pod:Height",
        "hash": "pod:Hash256"
    }

    def __init__(self):
        self._round = FinalizationRound()
        self._height = Height()
        self._hash = Hash256()

    @property
    def round(self) -> FinalizationRound:
        return self._round

    @property
    def height(self) -> Height:
        return self._height

    @property
    def hash(self) -> Hash256:
        return self._hash

    @round.setter
    def round(self, value: FinalizationRound):
        self._round = value

    @height.setter
    def height(self, value: Height):
        self._height = value

    @hash.setter
    def hash(self, value: Hash256):
        self._hash = value

    def size(self) -> int:
        size = 0
        size += self.round.size()
        size += self.height.size()
        size += self.hash.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> FinalizedBlockHeader:
        buffer_ = memoryview(payload)
        round = FinalizationRound.deserialize(buffer_)
        buffer_ = buffer_[round.size():]
        height = Height.deserialize(buffer_)
        buffer_ = buffer_[height.size():]
        hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[hash.size():]

        instance = FinalizedBlockHeader()
        instance._round = round
        instance._height = height
        instance._hash = hash
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._round.serialize()
        buffer_ += self._height.serialize()
        buffer_ += self._hash.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "round: {}, ".format(self._round.__str__())
        result += "height: {}, ".format(self._height.__str__())
        result += "hash: {}, ".format(self._hash.__str__())
        result += ")"
        return result


class ReceiptType(Enum):
    MOSAIC_RENTAL_FEE = 4685
    NAMESPACE_RENTAL_FEE = 4942
    HARVEST_FEE = 8515
    LOCK_HASH_COMPLETED = 8776
    LOCK_HASH_EXPIRED = 9032
    LOCK_SECRET_COMPLETED = 8786
    LOCK_SECRET_EXPIRED = 9042
    LOCK_HASH_CREATED = 12616
    LOCK_SECRET_CREATED = 12626
    MOSAIC_EXPIRED = 16717
    NAMESPACE_EXPIRED = 16718
    NAMESPACE_DELETED = 16974
    INFLATION = 20803
    TRANSACTION_GROUP = 57667
    ADDRESS_ALIAS_RESOLUTION = 61763
    MOSAIC_ALIAS_RESOLUTION = 62019

    def size(self) -> int:
        return 2

    @classmethod
    def deserialize(self, payload: ByteString) -> ReceiptType:
        buffer_ = memoryview(payload)
        return ReceiptType(int.from_bytes(buffer_[:2], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(2, byteorder="little", signed=False)
        return buffer_


class Receipt:
    TYPE_HINTS = {
        "type_": "enum:ReceiptType"
    }

    def __init__(self):
        self._version = 0
        self._type_ = ReceiptType.MOSAIC_RENTAL_FEE

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> Receipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]

        instance = Receipt()
        instance._version = version
        instance._type_ = type_
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += ")"
        return result


class HarvestFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.HARVEST_FEE
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "target_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = HarvestFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._target_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def target_address(self) -> Address:
        return self._target_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @target_address.setter
    def target_address(self, value: Address):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> HarvestFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        target_address = Address.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = HarvestFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class InflationReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.INFLATION
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic"
    }

    def __init__(self):
        self._version = 0
        self._type_ = InflationReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> InflationReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]

        instance = InflationReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += ")"
        return result


class LockHashCreatedFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.LOCK_HASH_CREATED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "target_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = LockHashCreatedFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._target_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def target_address(self) -> Address:
        return self._target_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @target_address.setter
    def target_address(self, value: Address):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> LockHashCreatedFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        target_address = Address.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = LockHashCreatedFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class LockHashCompletedFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.LOCK_HASH_COMPLETED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "target_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = LockHashCompletedFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._target_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def target_address(self) -> Address:
        return self._target_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @target_address.setter
    def target_address(self, value: Address):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> LockHashCompletedFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        target_address = Address.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = LockHashCompletedFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class LockHashExpiredFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.LOCK_HASH_EXPIRED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "target_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = LockHashExpiredFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._target_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def target_address(self) -> Address:
        return self._target_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @target_address.setter
    def target_address(self, value: Address):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> LockHashExpiredFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        target_address = Address.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = LockHashExpiredFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class LockSecretCreatedFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.LOCK_SECRET_CREATED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "target_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = LockSecretCreatedFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._target_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def target_address(self) -> Address:
        return self._target_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @target_address.setter
    def target_address(self, value: Address):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> LockSecretCreatedFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        target_address = Address.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = LockSecretCreatedFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class LockSecretCompletedFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.LOCK_SECRET_COMPLETED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "target_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = LockSecretCompletedFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._target_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def target_address(self) -> Address:
        return self._target_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @target_address.setter
    def target_address(self, value: Address):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> LockSecretCompletedFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        target_address = Address.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = LockSecretCompletedFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class LockSecretExpiredFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.LOCK_SECRET_EXPIRED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "target_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = LockSecretExpiredFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._target_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def target_address(self) -> Address:
        return self._target_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @target_address.setter
    def target_address(self, value: Address):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> LockSecretExpiredFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        target_address = Address.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = LockSecretExpiredFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class MosaicExpiredReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.MOSAIC_EXPIRED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "artifact_id": "pod:MosaicId"
    }

    def __init__(self):
        self._version = 0
        self._type_ = MosaicExpiredReceipt.RECEIPT_TYPE
        self._artifact_id = MosaicId()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def artifact_id(self) -> MosaicId:
        return self._artifact_id

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @artifact_id.setter
    def artifact_id(self, value: MosaicId):
        self._artifact_id = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.artifact_id.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicExpiredReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        artifact_id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[artifact_id.size():]

        instance = MosaicExpiredReceipt()
        instance._version = version
        instance._type_ = type_
        instance._artifact_id = artifact_id
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._artifact_id.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "artifact_id: {}, ".format(self._artifact_id.__str__())
        result += ")"
        return result


class MosaicRentalFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.MOSAIC_RENTAL_FEE
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "sender_address": "pod:Address",
        "recipient_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = MosaicRentalFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._sender_address = Address()
        self._recipient_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def sender_address(self) -> Address:
        return self._sender_address

    @property
    def recipient_address(self) -> Address:
        return self._recipient_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @sender_address.setter
    def sender_address(self, value: Address):
        self._sender_address = value

    @recipient_address.setter
    def recipient_address(self, value: Address):
        self._recipient_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.sender_address.size()
        size += self.recipient_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicRentalFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        sender_address = Address.deserialize(buffer_)
        buffer_ = buffer_[sender_address.size():]
        recipient_address = Address.deserialize(buffer_)
        buffer_ = buffer_[recipient_address.size():]

        instance = MosaicRentalFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._sender_address = sender_address
        instance._recipient_address = recipient_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._sender_address.serialize()
        buffer_ += self._recipient_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "sender_address: {}, ".format(self._sender_address.__str__())
        result += "recipient_address: {}, ".format(self._recipient_address.__str__())
        result += ")"
        return result


class NamespaceId(BaseValue):
    SIZE = 8

    def __init__(self, namespace_id: int = 0):
        super().__init__(self.SIZE, namespace_id, NamespaceId)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceId:
        buffer_ = memoryview(payload)
        return NamespaceId(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class NamespaceRegistrationType(Enum):
    ROOT = 0
    CHILD = 1

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceRegistrationType:
        buffer_ = memoryview(payload)
        return NamespaceRegistrationType(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class AliasAction(Enum):
    UNLINK = 0
    LINK = 1

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> AliasAction:
        buffer_ = memoryview(payload)
        return AliasAction(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class NamespaceExpiredReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.NAMESPACE_EXPIRED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "artifact_id": "pod:NamespaceId"
    }

    def __init__(self):
        self._version = 0
        self._type_ = NamespaceExpiredReceipt.RECEIPT_TYPE
        self._artifact_id = NamespaceId()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def artifact_id(self) -> NamespaceId:
        return self._artifact_id

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @artifact_id.setter
    def artifact_id(self, value: NamespaceId):
        self._artifact_id = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.artifact_id.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceExpiredReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        artifact_id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[artifact_id.size():]

        instance = NamespaceExpiredReceipt()
        instance._version = version
        instance._type_ = type_
        instance._artifact_id = artifact_id
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._artifact_id.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "artifact_id: {}, ".format(self._artifact_id.__str__())
        result += ")"
        return result


class NamespaceDeletedReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.NAMESPACE_DELETED
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "artifact_id": "pod:NamespaceId"
    }

    def __init__(self):
        self._version = 0
        self._type_ = NamespaceDeletedReceipt.RECEIPT_TYPE
        self._artifact_id = NamespaceId()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def artifact_id(self) -> NamespaceId:
        return self._artifact_id

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @artifact_id.setter
    def artifact_id(self, value: NamespaceId):
        self._artifact_id = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.artifact_id.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceDeletedReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        artifact_id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[artifact_id.size():]

        instance = NamespaceDeletedReceipt()
        instance._version = version
        instance._type_ = type_
        instance._artifact_id = artifact_id
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._artifact_id.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "artifact_id: {}, ".format(self._artifact_id.__str__())
        result += ")"
        return result


class NamespaceRentalFeeReceipt:
    RECEIPT_TYPE: ReceiptType = ReceiptType.NAMESPACE_RENTAL_FEE
    TYPE_HINTS = {
        "type_": "enum:ReceiptType",
        "mosaic": "struct:Mosaic",
        "sender_address": "pod:Address",
        "recipient_address": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._type_ = NamespaceRentalFeeReceipt.RECEIPT_TYPE
        self._mosaic = Mosaic()
        self._sender_address = Address()
        self._recipient_address = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def type_(self) -> ReceiptType:
        return self._type_

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def sender_address(self) -> Address:
        return self._sender_address

    @property
    def recipient_address(self) -> Address:
        return self._recipient_address

    @version.setter
    def version(self, value: int):
        self._version = value

    @type_.setter
    def type_(self, value: ReceiptType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @sender_address.setter
    def sender_address(self, value: Address):
        self._sender_address = value

    @recipient_address.setter
    def recipient_address(self, value: Address):
        self._recipient_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 2
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.sender_address.size()
        size += self.recipient_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceRentalFeeReceipt:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        type_ = ReceiptType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        sender_address = Address.deserialize(buffer_)
        buffer_ = buffer_[sender_address.size():]
        recipient_address = Address.deserialize(buffer_)
        buffer_ = buffer_[recipient_address.size():]

        instance = NamespaceRentalFeeReceipt()
        instance._version = version
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._sender_address = sender_address
        instance._recipient_address = recipient_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._sender_address.serialize()
        buffer_ += self._recipient_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "sender_address: {}, ".format(self._sender_address.__str__())
        result += "recipient_address: {}, ".format(self._recipient_address.__str__())
        result += ")"
        return result


class ReceiptSource:
    TYPE_HINTS = {
    }

    def __init__(self):
        self._primary_id = 0
        self._secondary_id = 0

    @property
    def primary_id(self) -> int:
        return self._primary_id

    @property
    def secondary_id(self) -> int:
        return self._secondary_id

    @primary_id.setter
    def primary_id(self, value: int):
        self._primary_id = value

    @secondary_id.setter
    def secondary_id(self, value: int):
        self._secondary_id = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> ReceiptSource:
        buffer_ = memoryview(payload)
        primary_id = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        secondary_id = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]

        instance = ReceiptSource()
        instance._primary_id = primary_id
        instance._secondary_id = secondary_id
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._primary_id.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._secondary_id.to_bytes(4, byteorder="little", signed=False)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "primary_id: {}, ".format("0x{:X}".format(self._primary_id))
        result += "secondary_id: {}, ".format("0x{:X}".format(self._secondary_id))
        result += ")"
        return result


class AddressResolutionEntry:
    TYPE_HINTS = {
        "source": "struct:ReceiptSource",
        "resolved_value": "pod:Address"
    }

    def __init__(self):
        self._source = ReceiptSource()
        self._resolved_value = Address()

    @property
    def source(self) -> ReceiptSource:
        return self._source

    @property
    def resolved_value(self) -> Address:
        return self._resolved_value

    @source.setter
    def source(self, value: ReceiptSource):
        self._source = value

    @resolved_value.setter
    def resolved_value(self, value: Address):
        self._resolved_value = value

    def size(self) -> int:
        size = 0
        size += self.source.size()
        size += self.resolved_value.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AddressResolutionEntry:
        buffer_ = memoryview(payload)
        source = ReceiptSource.deserialize(buffer_)
        buffer_ = buffer_[source.size():]
        resolved_value = Address.deserialize(buffer_)
        buffer_ = buffer_[resolved_value.size():]

        instance = AddressResolutionEntry()
        instance._source = source
        instance._resolved_value = resolved_value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._source.serialize()
        buffer_ += self._resolved_value.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "source: {}, ".format(self._source.__str__())
        result += "resolved_value: {}, ".format(self._resolved_value.__str__())
        result += ")"
        return result


class AddressResolutionStatement:
    TYPE_HINTS = {
        "unresolved": "pod:UnresolvedAddress",
        "resolution_entries": "array[AddressResolutionEntry]"
    }

    def __init__(self):
        self._unresolved = UnresolvedAddress()
        self._resolution_entries = []

    @property
    def unresolved(self) -> UnresolvedAddress:
        return self._unresolved

    @property
    def resolution_entries(self) -> List[AddressResolutionEntry]:
        return self._resolution_entries

    @unresolved.setter
    def unresolved(self, value: UnresolvedAddress):
        self._unresolved = value

    @resolution_entries.setter
    def resolution_entries(self, value: List[AddressResolutionEntry]):
        self._resolution_entries = value

    def size(self) -> int:
        size = 0
        size += self.unresolved.size()
        size += 4
        size += sum(map(lambda e: e.size(), self.resolution_entries))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AddressResolutionStatement:
        buffer_ = memoryview(payload)
        unresolved = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[unresolved.size():]
        resolution_entries_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        resolution_entries = ArrayHelpers.read_array_count(buffer_, AddressResolutionEntry, resolution_entries_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), resolution_entries)):]

        instance = AddressResolutionStatement()
        instance._unresolved = unresolved
        instance._resolution_entries = resolution_entries
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._unresolved.serialize()
        buffer_ += len(self._resolution_entries).to_bytes(4, byteorder="little", signed=False)  # resolution_entries_count
        buffer_ += ArrayHelpers.write_array(self._resolution_entries)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "unresolved: {}, ".format(self._unresolved.__str__())
        result += "resolution_entries: {}, ".format(list(map(str, self._resolution_entries)))
        result += ")"
        return result


class MosaicResolutionEntry:
    TYPE_HINTS = {
        "source": "struct:ReceiptSource",
        "resolved_value": "pod:MosaicId"
    }

    def __init__(self):
        self._source = ReceiptSource()
        self._resolved_value = MosaicId()

    @property
    def source(self) -> ReceiptSource:
        return self._source

    @property
    def resolved_value(self) -> MosaicId:
        return self._resolved_value

    @source.setter
    def source(self, value: ReceiptSource):
        self._source = value

    @resolved_value.setter
    def resolved_value(self, value: MosaicId):
        self._resolved_value = value

    def size(self) -> int:
        size = 0
        size += self.source.size()
        size += self.resolved_value.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicResolutionEntry:
        buffer_ = memoryview(payload)
        source = ReceiptSource.deserialize(buffer_)
        buffer_ = buffer_[source.size():]
        resolved_value = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[resolved_value.size():]

        instance = MosaicResolutionEntry()
        instance._source = source
        instance._resolved_value = resolved_value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._source.serialize()
        buffer_ += self._resolved_value.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "source: {}, ".format(self._source.__str__())
        result += "resolved_value: {}, ".format(self._resolved_value.__str__())
        result += ")"
        return result


class MosaicResolutionStatement:
    TYPE_HINTS = {
        "unresolved": "pod:UnresolvedMosaicId",
        "resolution_entries": "array[MosaicResolutionEntry]"
    }

    def __init__(self):
        self._unresolved = UnresolvedMosaicId()
        self._resolution_entries = []

    @property
    def unresolved(self) -> UnresolvedMosaicId:
        return self._unresolved

    @property
    def resolution_entries(self) -> List[MosaicResolutionEntry]:
        return self._resolution_entries

    @unresolved.setter
    def unresolved(self, value: UnresolvedMosaicId):
        self._unresolved = value

    @resolution_entries.setter
    def resolution_entries(self, value: List[MosaicResolutionEntry]):
        self._resolution_entries = value

    def size(self) -> int:
        size = 0
        size += self.unresolved.size()
        size += 4
        size += sum(map(lambda e: e.size(), self.resolution_entries))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicResolutionStatement:
        buffer_ = memoryview(payload)
        unresolved = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[unresolved.size():]
        resolution_entries_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        resolution_entries = ArrayHelpers.read_array_count(buffer_, MosaicResolutionEntry, resolution_entries_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), resolution_entries)):]

        instance = MosaicResolutionStatement()
        instance._unresolved = unresolved
        instance._resolution_entries = resolution_entries
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._unresolved.serialize()
        buffer_ += len(self._resolution_entries).to_bytes(4, byteorder="little", signed=False)  # resolution_entries_count
        buffer_ += ArrayHelpers.write_array(self._resolution_entries)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "unresolved: {}, ".format(self._unresolved.__str__())
        result += "resolution_entries: {}, ".format(list(map(str, self._resolution_entries)))
        result += ")"
        return result


class TransactionStatement:
    TYPE_HINTS = {
        "receipts": "array[Receipt]"
    }

    def __init__(self):
        self._primary_id = 0
        self._secondary_id = 0
        self._receipts = []

    @property
    def primary_id(self) -> int:
        return self._primary_id

    @property
    def secondary_id(self) -> int:
        return self._secondary_id

    @property
    def receipts(self) -> List[Receipt]:
        return self._receipts

    @primary_id.setter
    def primary_id(self, value: int):
        self._primary_id = value

    @secondary_id.setter
    def secondary_id(self, value: int):
        self._secondary_id = value

    @receipts.setter
    def receipts(self, value: List[Receipt]):
        self._receipts = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += 4
        size += sum(map(lambda e: e.size(), self.receipts))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> TransactionStatement:
        buffer_ = memoryview(payload)
        primary_id = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        secondary_id = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        receipt_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        receipts = ArrayHelpers.read_array_count(buffer_, Receipt, receipt_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), receipts)):]

        instance = TransactionStatement()
        instance._primary_id = primary_id
        instance._secondary_id = secondary_id
        instance._receipts = receipts
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._primary_id.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._secondary_id.to_bytes(4, byteorder="little", signed=False)
        buffer_ += len(self._receipts).to_bytes(4, byteorder="little", signed=False)  # receipt_count
        buffer_ += ArrayHelpers.write_array(self._receipts)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "primary_id: {}, ".format("0x{:X}".format(self._primary_id))
        result += "secondary_id: {}, ".format("0x{:X}".format(self._secondary_id))
        result += "receipts: {}, ".format(list(map(str, self._receipts)))
        result += ")"
        return result


class BlockStatement:
    TYPE_HINTS = {
        "transaction_statements": "array[TransactionStatement]",
        "address_resolution_statements": "array[AddressResolutionStatement]",
        "mosaic_resolution_statements": "array[MosaicResolutionStatement]"
    }

    def __init__(self):
        self._transaction_statements = []
        self._address_resolution_statements = []
        self._mosaic_resolution_statements = []

    @property
    def transaction_statements(self) -> List[TransactionStatement]:
        return self._transaction_statements

    @property
    def address_resolution_statements(self) -> List[AddressResolutionStatement]:
        return self._address_resolution_statements

    @property
    def mosaic_resolution_statements(self) -> List[MosaicResolutionStatement]:
        return self._mosaic_resolution_statements

    @transaction_statements.setter
    def transaction_statements(self, value: List[TransactionStatement]):
        self._transaction_statements = value

    @address_resolution_statements.setter
    def address_resolution_statements(self, value: List[AddressResolutionStatement]):
        self._address_resolution_statements = value

    @mosaic_resolution_statements.setter
    def mosaic_resolution_statements(self, value: List[MosaicResolutionStatement]):
        self._mosaic_resolution_statements = value

    def size(self) -> int:
        size = 0
        size += 4
        size += sum(map(lambda e: e.size(), self.transaction_statements))
        size += 4
        size += sum(map(lambda e: e.size(), self.address_resolution_statements))
        size += 4
        size += sum(map(lambda e: e.size(), self.mosaic_resolution_statements))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> BlockStatement:
        buffer_ = memoryview(payload)
        transaction_statement_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        transaction_statements = ArrayHelpers.read_array_count(buffer_, TransactionStatement, transaction_statement_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), transaction_statements)):]
        address_resolution_statement_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        address_resolution_statements = ArrayHelpers.read_array_count(buffer_, AddressResolutionStatement, address_resolution_statement_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), address_resolution_statements)):]
        mosaic_resolution_statement_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        mosaic_resolution_statements = ArrayHelpers.read_array_count(buffer_, MosaicResolutionStatement, mosaic_resolution_statement_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), mosaic_resolution_statements)):]

        instance = BlockStatement()
        instance._transaction_statements = transaction_statements
        instance._address_resolution_statements = address_resolution_statements
        instance._mosaic_resolution_statements = mosaic_resolution_statements
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += len(self._transaction_statements).to_bytes(4, byteorder="little", signed=False)  # transaction_statement_count
        buffer_ += ArrayHelpers.write_array(self._transaction_statements)
        buffer_ += len(self._address_resolution_statements).to_bytes(4, byteorder="little", signed=False)  # address_resolution_statement_count
        buffer_ += ArrayHelpers.write_array(self._address_resolution_statements)
        buffer_ += len(self._mosaic_resolution_statements).to_bytes(4, byteorder="little", signed=False)  # mosaic_resolution_statement_count
        buffer_ += ArrayHelpers.write_array(self._mosaic_resolution_statements)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "transaction_statements: {}, ".format(list(map(str, self._transaction_statements)))
        result += "address_resolution_statements: {}, ".format(list(map(str, self._address_resolution_statements)))
        result += "mosaic_resolution_statements: {}, ".format(list(map(str, self._mosaic_resolution_statements)))
        result += ")"
        return result


class AccountType(Enum):
    UNLINKED = 0
    MAIN = 1
    REMOTE = 2
    REMOTE_UNLINKED = 3

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountType:
        buffer_ = memoryview(payload)
        return AccountType(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class AccountKeyTypeFlags(Flag):
    UNSET = 0
    LINKED = 1
    NODE = 2
    VRF = 4

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountKeyTypeFlags:
        buffer_ = memoryview(payload)
        return AccountKeyTypeFlags(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class AccountStateFormat(Enum):
    REGULAR = 0
    HIGH_VALUE = 1

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountStateFormat:
        buffer_ = memoryview(payload)
        return AccountStateFormat(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class PinnedVotingKey:
    TYPE_HINTS = {
        "voting_key": "pod:VotingPublicKey",
        "start_epoch": "pod:FinalizationEpoch",
        "end_epoch": "pod:FinalizationEpoch"
    }

    def __init__(self):
        self._voting_key = VotingPublicKey()
        self._start_epoch = FinalizationEpoch()
        self._end_epoch = FinalizationEpoch()

    @property
    def voting_key(self) -> VotingPublicKey:
        return self._voting_key

    @property
    def start_epoch(self) -> FinalizationEpoch:
        return self._start_epoch

    @property
    def end_epoch(self) -> FinalizationEpoch:
        return self._end_epoch

    @voting_key.setter
    def voting_key(self, value: VotingPublicKey):
        self._voting_key = value

    @start_epoch.setter
    def start_epoch(self, value: FinalizationEpoch):
        self._start_epoch = value

    @end_epoch.setter
    def end_epoch(self, value: FinalizationEpoch):
        self._end_epoch = value

    def size(self) -> int:
        size = 0
        size += self.voting_key.size()
        size += self.start_epoch.size()
        size += self.end_epoch.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> PinnedVotingKey:
        buffer_ = memoryview(payload)
        voting_key = VotingPublicKey.deserialize(buffer_)
        buffer_ = buffer_[voting_key.size():]
        start_epoch = FinalizationEpoch.deserialize(buffer_)
        buffer_ = buffer_[start_epoch.size():]
        end_epoch = FinalizationEpoch.deserialize(buffer_)
        buffer_ = buffer_[end_epoch.size():]

        instance = PinnedVotingKey()
        instance._voting_key = voting_key
        instance._start_epoch = start_epoch
        instance._end_epoch = end_epoch
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._voting_key.serialize()
        buffer_ += self._start_epoch.serialize()
        buffer_ += self._end_epoch.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "voting_key: {}, ".format(self._voting_key.__str__())
        result += "start_epoch: {}, ".format(self._start_epoch.__str__())
        result += "end_epoch: {}, ".format(self._end_epoch.__str__())
        result += ")"
        return result


class ImportanceSnapshot:
    TYPE_HINTS = {
        "importance": "pod:Importance",
        "height": "pod:ImportanceHeight"
    }

    def __init__(self):
        self._importance = Importance()
        self._height = ImportanceHeight()

    @property
    def importance(self) -> Importance:
        return self._importance

    @property
    def height(self) -> ImportanceHeight:
        return self._height

    @importance.setter
    def importance(self, value: Importance):
        self._importance = value

    @height.setter
    def height(self, value: ImportanceHeight):
        self._height = value

    def size(self) -> int:
        size = 0
        size += self.importance.size()
        size += self.height.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> ImportanceSnapshot:
        buffer_ = memoryview(payload)
        importance = Importance.deserialize(buffer_)
        buffer_ = buffer_[importance.size():]
        height = ImportanceHeight.deserialize(buffer_)
        buffer_ = buffer_[height.size():]

        instance = ImportanceSnapshot()
        instance._importance = importance
        instance._height = height
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._importance.serialize()
        buffer_ += self._height.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "importance: {}, ".format(self._importance.__str__())
        result += "height: {}, ".format(self._height.__str__())
        result += ")"
        return result


class HeightActivityBucket:
    TYPE_HINTS = {
        "start_height": "pod:ImportanceHeight",
        "total_fees_paid": "pod:Amount"
    }

    def __init__(self):
        self._start_height = ImportanceHeight()
        self._total_fees_paid = Amount()
        self._beneficiary_count = 0
        self._raw_score = 0

    @property
    def start_height(self) -> ImportanceHeight:
        return self._start_height

    @property
    def total_fees_paid(self) -> Amount:
        return self._total_fees_paid

    @property
    def beneficiary_count(self) -> int:
        return self._beneficiary_count

    @property
    def raw_score(self) -> int:
        return self._raw_score

    @start_height.setter
    def start_height(self, value: ImportanceHeight):
        self._start_height = value

    @total_fees_paid.setter
    def total_fees_paid(self, value: Amount):
        self._total_fees_paid = value

    @beneficiary_count.setter
    def beneficiary_count(self, value: int):
        self._beneficiary_count = value

    @raw_score.setter
    def raw_score(self, value: int):
        self._raw_score = value

    def size(self) -> int:
        size = 0
        size += self.start_height.size()
        size += self.total_fees_paid.size()
        size += 4
        size += 8
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> HeightActivityBucket:
        buffer_ = memoryview(payload)
        start_height = ImportanceHeight.deserialize(buffer_)
        buffer_ = buffer_[start_height.size():]
        total_fees_paid = Amount.deserialize(buffer_)
        buffer_ = buffer_[total_fees_paid.size():]
        beneficiary_count = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        raw_score = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]

        instance = HeightActivityBucket()
        instance._start_height = start_height
        instance._total_fees_paid = total_fees_paid
        instance._beneficiary_count = beneficiary_count
        instance._raw_score = raw_score
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._start_height.serialize()
        buffer_ += self._total_fees_paid.serialize()
        buffer_ += self._beneficiary_count.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._raw_score.to_bytes(8, byteorder="little", signed=False)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "start_height: {}, ".format(self._start_height.__str__())
        result += "total_fees_paid: {}, ".format(self._total_fees_paid.__str__())
        result += "beneficiary_count: {}, ".format("0x{:X}".format(self._beneficiary_count))
        result += "raw_score: {}, ".format("0x{:X}".format(self._raw_score))
        result += ")"
        return result


class HeightActivityBuckets:
    TYPE_HINTS = {
        "buckets": "array[HeightActivityBucket]"
    }

    def __init__(self):
        self._buckets = []

    @property
    def buckets(self) -> List[HeightActivityBucket]:
        return self._buckets

    @buckets.setter
    def buckets(self, value: List[HeightActivityBucket]):
        self._buckets = value

    def size(self) -> int:
        size = 0
        size += sum(map(lambda e: e.size(), self.buckets))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> HeightActivityBuckets:
        buffer_ = memoryview(payload)
        buckets = ArrayHelpers.read_array_count(buffer_, HeightActivityBucket, 5)
        buffer_ = buffer_[sum(map(lambda e: e.size(), buckets)):]

        instance = HeightActivityBuckets()
        instance._buckets = buckets
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += ArrayHelpers.write_array_count(self._buckets, 5)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "buckets: {}, ".format(list(map(str, self._buckets)))
        result += ")"
        return result


class AccountState:
    TYPE_HINTS = {
        "address": "pod:Address",
        "address_height": "pod:Height",
        "public_key": "pod:PublicKey",
        "public_key_height": "pod:Height",
        "account_type": "enum:AccountType",
        "format": "enum:AccountStateFormat",
        "supplemental_public_keys_mask": "enum:AccountKeyTypeFlags",
        "linked_public_key": "pod:PublicKey",
        "node_public_key": "pod:PublicKey",
        "vrf_public_key": "pod:PublicKey",
        "voting_public_keys": "array[PinnedVotingKey]",
        "importance_snapshots": "struct:ImportanceSnapshot",
        "activity_buckets": "struct:HeightActivityBuckets",
        "balances": "array[Mosaic]"
    }

    def __init__(self):
        self._version = 0
        self._address = Address()
        self._address_height = Height()
        self._public_key = PublicKey()
        self._public_key_height = Height()
        self._account_type = AccountType.UNLINKED
        self._format = AccountStateFormat.REGULAR
        self._supplemental_public_keys_mask = AccountKeyTypeFlags.UNSET
        self._linked_public_key = PublicKey()
        self._node_public_key = PublicKey()
        self._vrf_public_key = PublicKey()
        self._voting_public_keys = []
        self._importance_snapshots = ImportanceSnapshot()
        self._activity_buckets = HeightActivityBuckets()
        self._balances = []

    @property
    def version(self) -> int:
        return self._version

    @property
    def address(self) -> Address:
        return self._address

    @property
    def address_height(self) -> Height:
        return self._address_height

    @property
    def public_key(self) -> PublicKey:
        return self._public_key

    @property
    def public_key_height(self) -> Height:
        return self._public_key_height

    @property
    def account_type(self) -> AccountType:
        return self._account_type

    @property
    def format(self) -> AccountStateFormat:
        return self._format

    @property
    def supplemental_public_keys_mask(self) -> AccountKeyTypeFlags:
        return self._supplemental_public_keys_mask

    @property
    def linked_public_key(self) -> PublicKey:
        return self._linked_public_key

    @property
    def node_public_key(self) -> PublicKey:
        return self._node_public_key

    @property
    def vrf_public_key(self) -> PublicKey:
        return self._vrf_public_key

    @property
    def voting_public_keys(self) -> List[PinnedVotingKey]:
        return self._voting_public_keys

    @property
    def importance_snapshots(self) -> ImportanceSnapshot:
        return self._importance_snapshots

    @property
    def activity_buckets(self) -> HeightActivityBuckets:
        return self._activity_buckets

    @property
    def balances(self) -> List[Mosaic]:
        return self._balances

    @version.setter
    def version(self, value: int):
        self._version = value

    @address.setter
    def address(self, value: Address):
        self._address = value

    @address_height.setter
    def address_height(self, value: Height):
        self._address_height = value

    @public_key.setter
    def public_key(self, value: PublicKey):
        self._public_key = value

    @public_key_height.setter
    def public_key_height(self, value: Height):
        self._public_key_height = value

    @account_type.setter
    def account_type(self, value: AccountType):
        self._account_type = value

    @format.setter
    def format(self, value: AccountStateFormat):
        self._format = value

    @supplemental_public_keys_mask.setter
    def supplemental_public_keys_mask(self, value: AccountKeyTypeFlags):
        self._supplemental_public_keys_mask = value

    @linked_public_key.setter
    def linked_public_key(self, value: PublicKey):
        self._linked_public_key = value

    @node_public_key.setter
    def node_public_key(self, value: PublicKey):
        self._node_public_key = value

    @vrf_public_key.setter
    def vrf_public_key(self, value: PublicKey):
        self._vrf_public_key = value

    @voting_public_keys.setter
    def voting_public_keys(self, value: List[PinnedVotingKey]):
        self._voting_public_keys = value

    @importance_snapshots.setter
    def importance_snapshots(self, value: ImportanceSnapshot):
        self._importance_snapshots = value

    @activity_buckets.setter
    def activity_buckets(self, value: HeightActivityBuckets):
        self._activity_buckets = value

    @balances.setter
    def balances(self, value: List[Mosaic]):
        self._balances = value

    def size(self) -> int:
        size = 0
        size += 2
        size += self.address.size()
        size += self.address_height.size()
        size += self.public_key.size()
        size += self.public_key_height.size()
        size += self.account_type.size()
        size += self.format.size()
        size += self.supplemental_public_keys_mask.size()
        size += 1
        if AccountKeyTypeFlags.LINKED in self.supplemental_public_keys_mask:
            size += self.linked_public_key.size()
        if AccountKeyTypeFlags.NODE in self.supplemental_public_keys_mask:
            size += self.node_public_key.size()
        if AccountKeyTypeFlags.VRF in self.supplemental_public_keys_mask:
            size += self.vrf_public_key.size()
        size += sum(map(lambda e: e.size(), self.voting_public_keys))
        if AccountStateFormat.HIGH_VALUE == self.format:
            size += self.importance_snapshots.size()
        if AccountStateFormat.HIGH_VALUE == self.format:
            size += self.activity_buckets.size()
        size += 2
        size += sum(map(lambda e: e.size(), self.balances))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountState:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        address = Address.deserialize(buffer_)
        buffer_ = buffer_[address.size():]
        address_height = Height.deserialize(buffer_)
        buffer_ = buffer_[address_height.size():]
        public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[public_key.size():]
        public_key_height = Height.deserialize(buffer_)
        buffer_ = buffer_[public_key_height.size():]
        account_type = AccountType.deserialize(buffer_)
        buffer_ = buffer_[account_type.size():]
        format = AccountStateFormat.deserialize(buffer_)
        buffer_ = buffer_[format.size():]
        supplemental_public_keys_mask = AccountKeyTypeFlags.deserialize(buffer_)
        buffer_ = buffer_[supplemental_public_keys_mask.size():]
        voting_public_keys_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        linked_public_key = None
        if AccountKeyTypeFlags.LINKED in supplemental_public_keys_mask:
            linked_public_key = PublicKey.deserialize(buffer_)
            buffer_ = buffer_[linked_public_key.size():]
        node_public_key = None
        if AccountKeyTypeFlags.NODE in supplemental_public_keys_mask:
            node_public_key = PublicKey.deserialize(buffer_)
            buffer_ = buffer_[node_public_key.size():]
        vrf_public_key = None
        if AccountKeyTypeFlags.VRF in supplemental_public_keys_mask:
            vrf_public_key = PublicKey.deserialize(buffer_)
            buffer_ = buffer_[vrf_public_key.size():]
        voting_public_keys = ArrayHelpers.read_array_count(buffer_, PinnedVotingKey, voting_public_keys_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), voting_public_keys)):]
        importance_snapshots = None
        if AccountStateFormat.HIGH_VALUE == format:
            importance_snapshots = ImportanceSnapshot.deserialize(buffer_)
            buffer_ = buffer_[importance_snapshots.size():]
        activity_buckets = None
        if AccountStateFormat.HIGH_VALUE == format:
            activity_buckets = HeightActivityBuckets.deserialize(buffer_)
            buffer_ = buffer_[activity_buckets.size():]
        balances_count = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        balances = ArrayHelpers.read_array_count(buffer_, Mosaic, balances_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), balances)):]

        instance = AccountState()
        instance._version = version
        instance._address = address
        instance._address_height = address_height
        instance._public_key = public_key
        instance._public_key_height = public_key_height
        instance._account_type = account_type
        instance._format = format
        instance._supplemental_public_keys_mask = supplemental_public_keys_mask
        instance._linked_public_key = linked_public_key
        instance._node_public_key = node_public_key
        instance._vrf_public_key = vrf_public_key
        instance._voting_public_keys = voting_public_keys
        instance._importance_snapshots = importance_snapshots
        instance._activity_buckets = activity_buckets
        instance._balances = balances
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._address.serialize()
        buffer_ += self._address_height.serialize()
        buffer_ += self._public_key.serialize()
        buffer_ += self._public_key_height.serialize()
        buffer_ += self._account_type.serialize()
        buffer_ += self._format.serialize()
        buffer_ += self._supplemental_public_keys_mask.serialize()
        buffer_ += len(self._voting_public_keys).to_bytes(1, byteorder="little", signed=False)  # voting_public_keys_count
        if AccountKeyTypeFlags.LINKED in self.supplemental_public_keys_mask:
            buffer_ += self._linked_public_key.serialize()
        if AccountKeyTypeFlags.NODE in self.supplemental_public_keys_mask:
            buffer_ += self._node_public_key.serialize()
        if AccountKeyTypeFlags.VRF in self.supplemental_public_keys_mask:
            buffer_ += self._vrf_public_key.serialize()
        buffer_ += ArrayHelpers.write_array(self._voting_public_keys)
        if AccountStateFormat.HIGH_VALUE == self.format:
            buffer_ += self._importance_snapshots.serialize()
        if AccountStateFormat.HIGH_VALUE == self.format:
            buffer_ += self._activity_buckets.serialize()
        buffer_ += len(self._balances).to_bytes(2, byteorder="little", signed=False)  # balances_count
        buffer_ += ArrayHelpers.write_array(self._balances)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "address: {}, ".format(self._address.__str__())
        result += "address_height: {}, ".format(self._address_height.__str__())
        result += "public_key: {}, ".format(self._public_key.__str__())
        result += "public_key_height: {}, ".format(self._public_key_height.__str__())
        result += "account_type: {}, ".format(self._account_type.__str__())
        result += "format: {}, ".format(self._format.__str__())
        result += "supplemental_public_keys_mask: {}, ".format(self._supplemental_public_keys_mask.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "node_public_key: {}, ".format(self._node_public_key.__str__())
        result += "vrf_public_key: {}, ".format(self._vrf_public_key.__str__())
        result += "voting_public_keys: {}, ".format(list(map(str, self._voting_public_keys)))
        result += "importance_snapshots: {}, ".format(self._importance_snapshots.__str__())
        result += "activity_buckets: {}, ".format(self._activity_buckets.__str__())
        result += "balances: {}, ".format(list(map(str, self._balances)))
        result += ")"
        return result


class LockStatus(Enum):
    UNUSED = 0
    USED = 1

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> LockStatus:
        buffer_ = memoryview(payload)
        return LockStatus(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class HashLockInfo:
    TYPE_HINTS = {
        "owner_address": "pod:Address",
        "mosaic": "struct:Mosaic",
        "end_height": "pod:Height",
        "status": "enum:LockStatus",
        "hash": "pod:Hash256"
    }

    def __init__(self):
        self._version = 0
        self._owner_address = Address()
        self._mosaic = Mosaic()
        self._end_height = Height()
        self._status = LockStatus.UNUSED
        self._hash = Hash256()

    @property
    def version(self) -> int:
        return self._version

    @property
    def owner_address(self) -> Address:
        return self._owner_address

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def end_height(self) -> Height:
        return self._end_height

    @property
    def status(self) -> LockStatus:
        return self._status

    @property
    def hash(self) -> Hash256:
        return self._hash

    @version.setter
    def version(self, value: int):
        self._version = value

    @owner_address.setter
    def owner_address(self, value: Address):
        self._owner_address = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @end_height.setter
    def end_height(self, value: Height):
        self._end_height = value

    @status.setter
    def status(self, value: LockStatus):
        self._status = value

    @hash.setter
    def hash(self, value: Hash256):
        self._hash = value

    def size(self) -> int:
        size = 0
        size += 2
        size += self.owner_address.size()
        size += self.mosaic.size()
        size += self.end_height.size()
        size += self.status.size()
        size += self.hash.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> HashLockInfo:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        owner_address = Address.deserialize(buffer_)
        buffer_ = buffer_[owner_address.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        end_height = Height.deserialize(buffer_)
        buffer_ = buffer_[end_height.size():]
        status = LockStatus.deserialize(buffer_)
        buffer_ = buffer_[status.size():]
        hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[hash.size():]

        instance = HashLockInfo()
        instance._version = version
        instance._owner_address = owner_address
        instance._mosaic = mosaic
        instance._end_height = end_height
        instance._status = status
        instance._hash = hash
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._owner_address.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._end_height.serialize()
        buffer_ += self._status.serialize()
        buffer_ += self._hash.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "owner_address: {}, ".format(self._owner_address.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "end_height: {}, ".format(self._end_height.__str__())
        result += "status: {}, ".format(self._status.__str__())
        result += "hash: {}, ".format(self._hash.__str__())
        result += ")"
        return result


class ScopedMetadataKey(BaseValue):
    SIZE = 8

    def __init__(self, scoped_metadata_key: int = 0):
        super().__init__(self.SIZE, scoped_metadata_key, ScopedMetadataKey)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> ScopedMetadataKey:
        buffer_ = memoryview(payload)
        return ScopedMetadataKey(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class MetadataType(Enum):
    ACCOUNT = 0
    MOSAIC = 1
    NAMESPACE = 2

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> MetadataType:
        buffer_ = memoryview(payload)
        return MetadataType(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class MetadataValue:
    TYPE_HINTS = {
        "data": "bytes_array"
    }

    def __init__(self):
        self._data = bytes()

    @property
    def data(self) -> bytes:
        return self._data

    @data.setter
    def data(self, value: bytes):
        self._data = value

    def size(self) -> int:
        size = 0
        size += 2
        size += len(self._data)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MetadataValue:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        data = ArrayHelpers.get_bytes(buffer_, size_)
        buffer_ = buffer_[size_:]

        instance = MetadataValue()
        instance._data = data
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += len(self._data).to_bytes(2, byteorder="little", signed=False)  # size
        buffer_ += self._data
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "data: {}, ".format(hexlify(self._data).decode("utf8"))
        result += ")"
        return result


class MetadataEntry:
    TYPE_HINTS = {
        "source_address": "pod:Address",
        "target_address": "pod:Address",
        "scoped_metadata_key": "pod:ScopedMetadataKey",
        "metadata_type": "enum:MetadataType",
        "value": "struct:MetadataValue"
    }

    def __init__(self):
        self._version = 0
        self._source_address = Address()
        self._target_address = Address()
        self._scoped_metadata_key = ScopedMetadataKey()
        self._target_id = 0
        self._metadata_type = MetadataType.ACCOUNT
        self._value = MetadataValue()

    @property
    def version(self) -> int:
        return self._version

    @property
    def source_address(self) -> Address:
        return self._source_address

    @property
    def target_address(self) -> Address:
        return self._target_address

    @property
    def scoped_metadata_key(self) -> ScopedMetadataKey:
        return self._scoped_metadata_key

    @property
    def target_id(self) -> int:
        return self._target_id

    @property
    def metadata_type(self) -> MetadataType:
        return self._metadata_type

    @property
    def value(self) -> MetadataValue:
        return self._value

    @version.setter
    def version(self, value: int):
        self._version = value

    @source_address.setter
    def source_address(self, value: Address):
        self._source_address = value

    @target_address.setter
    def target_address(self, value: Address):
        self._target_address = value

    @scoped_metadata_key.setter
    def scoped_metadata_key(self, value: ScopedMetadataKey):
        self._scoped_metadata_key = value

    @target_id.setter
    def target_id(self, value: int):
        self._target_id = value

    @metadata_type.setter
    def metadata_type(self, value: MetadataType):
        self._metadata_type = value

    @value.setter
    def value(self, value: MetadataValue):
        self._value = value

    def size(self) -> int:
        size = 0
        size += 2
        size += self.source_address.size()
        size += self.target_address.size()
        size += self.scoped_metadata_key.size()
        size += 8
        size += self.metadata_type.size()
        size += self.value.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MetadataEntry:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        source_address = Address.deserialize(buffer_)
        buffer_ = buffer_[source_address.size():]
        target_address = Address.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]
        scoped_metadata_key = ScopedMetadataKey.deserialize(buffer_)
        buffer_ = buffer_[scoped_metadata_key.size():]
        target_id = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        metadata_type = MetadataType.deserialize(buffer_)
        buffer_ = buffer_[metadata_type.size():]
        value = MetadataValue.deserialize(buffer_)
        buffer_ = buffer_[value.size():]

        instance = MetadataEntry()
        instance._version = version
        instance._source_address = source_address
        instance._target_address = target_address
        instance._scoped_metadata_key = scoped_metadata_key
        instance._target_id = target_id
        instance._metadata_type = metadata_type
        instance._value = value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._source_address.serialize()
        buffer_ += self._target_address.serialize()
        buffer_ += self._scoped_metadata_key.serialize()
        buffer_ += self._target_id.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._metadata_type.serialize()
        buffer_ += self._value.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "source_address: {}, ".format(self._source_address.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += "scoped_metadata_key: {}, ".format(self._scoped_metadata_key.__str__())
        result += "target_id: {}, ".format("0x{:X}".format(self._target_id))
        result += "metadata_type: {}, ".format(self._metadata_type.__str__())
        result += "value: {}, ".format(self._value.__str__())
        result += ")"
        return result


class MosaicNonce(BaseValue):
    SIZE = 4

    def __init__(self, mosaic_nonce: int = 0):
        super().__init__(self.SIZE, mosaic_nonce, MosaicNonce)

    def size(self) -> int:
        return 4

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicNonce:
        buffer_ = memoryview(payload)
        return MosaicNonce(int.from_bytes(buffer_[:4], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(4, byteorder="little", signed=False)


class MosaicFlags(Flag):
    NONE = 0
    SUPPLY_MUTABLE = 1
    TRANSFERABLE = 2
    RESTRICTABLE = 4
    REVOKABLE = 8

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicFlags:
        buffer_ = memoryview(payload)
        return MosaicFlags(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class MosaicSupplyChangeAction(Enum):
    DECREASE = 0
    INCREASE = 1

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicSupplyChangeAction:
        buffer_ = memoryview(payload)
        return MosaicSupplyChangeAction(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class MosaicProperties:
    TYPE_HINTS = {
        "flags": "enum:MosaicFlags",
        "duration": "pod:BlockDuration"
    }

    def __init__(self):
        self._flags = MosaicFlags.NONE
        self._divisibility = 0
        self._duration = BlockDuration()

    @property
    def flags(self) -> MosaicFlags:
        return self._flags

    @property
    def divisibility(self) -> int:
        return self._divisibility

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @flags.setter
    def flags(self, value: MosaicFlags):
        self._flags = value

    @divisibility.setter
    def divisibility(self, value: int):
        self._divisibility = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    def size(self) -> int:
        size = 0
        size += self.flags.size()
        size += 1
        size += self.duration.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicProperties:
        buffer_ = memoryview(payload)
        flags = MosaicFlags.deserialize(buffer_)
        buffer_ = buffer_[flags.size():]
        divisibility = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        duration = BlockDuration.deserialize(buffer_)
        buffer_ = buffer_[duration.size():]

        instance = MosaicProperties()
        instance._flags = flags
        instance._divisibility = divisibility
        instance._duration = duration
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._flags.serialize()
        buffer_ += self._divisibility.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._duration.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "flags: {}, ".format(self._flags.__str__())
        result += "divisibility: {}, ".format("0x{:X}".format(self._divisibility))
        result += "duration: {}, ".format(self._duration.__str__())
        result += ")"
        return result


class MosaicDefinition:
    TYPE_HINTS = {
        "start_height": "pod:Height",
        "owner_address": "pod:Address",
        "properties": "struct:MosaicProperties"
    }

    def __init__(self):
        self._start_height = Height()
        self._owner_address = Address()
        self._revision = 0
        self._properties = MosaicProperties()

    @property
    def start_height(self) -> Height:
        return self._start_height

    @property
    def owner_address(self) -> Address:
        return self._owner_address

    @property
    def revision(self) -> int:
        return self._revision

    @property
    def properties(self) -> MosaicProperties:
        return self._properties

    @start_height.setter
    def start_height(self, value: Height):
        self._start_height = value

    @owner_address.setter
    def owner_address(self, value: Address):
        self._owner_address = value

    @revision.setter
    def revision(self, value: int):
        self._revision = value

    @properties.setter
    def properties(self, value: MosaicProperties):
        self._properties = value

    def size(self) -> int:
        size = 0
        size += self.start_height.size()
        size += self.owner_address.size()
        size += 4
        size += self.properties.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicDefinition:
        buffer_ = memoryview(payload)
        start_height = Height.deserialize(buffer_)
        buffer_ = buffer_[start_height.size():]
        owner_address = Address.deserialize(buffer_)
        buffer_ = buffer_[owner_address.size():]
        revision = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        properties = MosaicProperties.deserialize(buffer_)
        buffer_ = buffer_[properties.size():]

        instance = MosaicDefinition()
        instance._start_height = start_height
        instance._owner_address = owner_address
        instance._revision = revision
        instance._properties = properties
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._start_height.serialize()
        buffer_ += self._owner_address.serialize()
        buffer_ += self._revision.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._properties.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "start_height: {}, ".format(self._start_height.__str__())
        result += "owner_address: {}, ".format(self._owner_address.__str__())
        result += "revision: {}, ".format("0x{:X}".format(self._revision))
        result += "properties: {}, ".format(self._properties.__str__())
        result += ")"
        return result


class MosaicEntry:
    TYPE_HINTS = {
        "mosaic_id": "pod:MosaicId",
        "supply": "pod:Amount",
        "definition": "struct:MosaicDefinition"
    }

    def __init__(self):
        self._version = 0
        self._mosaic_id = MosaicId()
        self._supply = Amount()
        self._definition = MosaicDefinition()

    @property
    def version(self) -> int:
        return self._version

    @property
    def mosaic_id(self) -> MosaicId:
        return self._mosaic_id

    @property
    def supply(self) -> Amount:
        return self._supply

    @property
    def definition(self) -> MosaicDefinition:
        return self._definition

    @version.setter
    def version(self, value: int):
        self._version = value

    @mosaic_id.setter
    def mosaic_id(self, value: MosaicId):
        self._mosaic_id = value

    @supply.setter
    def supply(self, value: Amount):
        self._supply = value

    @definition.setter
    def definition(self, value: MosaicDefinition):
        self._definition = value

    def size(self) -> int:
        size = 0
        size += 2
        size += self.mosaic_id.size()
        size += self.supply.size()
        size += self.definition.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicEntry:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        mosaic_id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        supply = Amount.deserialize(buffer_)
        buffer_ = buffer_[supply.size():]
        definition = MosaicDefinition.deserialize(buffer_)
        buffer_ = buffer_[definition.size():]

        instance = MosaicEntry()
        instance._version = version
        instance._mosaic_id = mosaic_id
        instance._supply = supply
        instance._definition = definition
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._supply.serialize()
        buffer_ += self._definition.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "supply: {}, ".format(self._supply.__str__())
        result += "definition: {}, ".format(self._definition.__str__())
        result += ")"
        return result


class MultisigEntry:
    TYPE_HINTS = {
        "account_address": "pod:Address",
        "cosignatory_addresses": "array[Address]",
        "multisig_addresses": "array[Address]"
    }

    def __init__(self):
        self._version = 0
        self._min_approval = 0
        self._min_removal = 0
        self._account_address = Address()
        self._cosignatory_addresses = []
        self._multisig_addresses = []

    @property
    def version(self) -> int:
        return self._version

    @property
    def min_approval(self) -> int:
        return self._min_approval

    @property
    def min_removal(self) -> int:
        return self._min_removal

    @property
    def account_address(self) -> Address:
        return self._account_address

    @property
    def cosignatory_addresses(self) -> List[Address]:
        return self._cosignatory_addresses

    @property
    def multisig_addresses(self) -> List[Address]:
        return self._multisig_addresses

    @version.setter
    def version(self, value: int):
        self._version = value

    @min_approval.setter
    def min_approval(self, value: int):
        self._min_approval = value

    @min_removal.setter
    def min_removal(self, value: int):
        self._min_removal = value

    @account_address.setter
    def account_address(self, value: Address):
        self._account_address = value

    @cosignatory_addresses.setter
    def cosignatory_addresses(self, value: List[Address]):
        self._cosignatory_addresses = value

    @multisig_addresses.setter
    def multisig_addresses(self, value: List[Address]):
        self._multisig_addresses = value

    def size(self) -> int:
        size = 0
        size += 2
        size += 4
        size += 4
        size += self.account_address.size()
        size += 8
        size += sum(map(lambda e: e.size(), self.cosignatory_addresses))
        size += 8
        size += sum(map(lambda e: e.size(), self.multisig_addresses))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MultisigEntry:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        min_approval = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        min_removal = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        account_address = Address.deserialize(buffer_)
        buffer_ = buffer_[account_address.size():]
        cosignatory_addresses_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        cosignatory_addresses = ArrayHelpers.read_array_count(buffer_, Address, cosignatory_addresses_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), cosignatory_addresses)):]
        multisig_addresses_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        multisig_addresses = ArrayHelpers.read_array_count(buffer_, Address, multisig_addresses_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), multisig_addresses)):]

        instance = MultisigEntry()
        instance._version = version
        instance._min_approval = min_approval
        instance._min_removal = min_removal
        instance._account_address = account_address
        instance._cosignatory_addresses = cosignatory_addresses
        instance._multisig_addresses = multisig_addresses
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._min_approval.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._min_removal.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._account_address.serialize()
        buffer_ += len(self._cosignatory_addresses).to_bytes(8, byteorder="little", signed=False)  # cosignatory_addresses_count
        buffer_ += ArrayHelpers.write_array(self._cosignatory_addresses)
        buffer_ += len(self._multisig_addresses).to_bytes(8, byteorder="little", signed=False)  # multisig_addresses_count
        buffer_ += ArrayHelpers.write_array(self._multisig_addresses)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "min_approval: {}, ".format("0x{:X}".format(self._min_approval))
        result += "min_removal: {}, ".format("0x{:X}".format(self._min_removal))
        result += "account_address: {}, ".format(self._account_address.__str__())
        result += "cosignatory_addresses: {}, ".format(list(map(str, self._cosignatory_addresses)))
        result += "multisig_addresses: {}, ".format(list(map(str, self._multisig_addresses)))
        result += ")"
        return result


class NamespaceLifetime:
    TYPE_HINTS = {
        "lifetime_start": "pod:Height",
        "lifetime_end": "pod:Height"
    }

    def __init__(self):
        self._lifetime_start = Height()
        self._lifetime_end = Height()

    @property
    def lifetime_start(self) -> Height:
        return self._lifetime_start

    @property
    def lifetime_end(self) -> Height:
        return self._lifetime_end

    @lifetime_start.setter
    def lifetime_start(self, value: Height):
        self._lifetime_start = value

    @lifetime_end.setter
    def lifetime_end(self, value: Height):
        self._lifetime_end = value

    def size(self) -> int:
        size = 0
        size += self.lifetime_start.size()
        size += self.lifetime_end.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceLifetime:
        buffer_ = memoryview(payload)
        lifetime_start = Height.deserialize(buffer_)
        buffer_ = buffer_[lifetime_start.size():]
        lifetime_end = Height.deserialize(buffer_)
        buffer_ = buffer_[lifetime_end.size():]

        instance = NamespaceLifetime()
        instance._lifetime_start = lifetime_start
        instance._lifetime_end = lifetime_end
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._lifetime_start.serialize()
        buffer_ += self._lifetime_end.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "lifetime_start: {}, ".format(self._lifetime_start.__str__())
        result += "lifetime_end: {}, ".format(self._lifetime_end.__str__())
        result += ")"
        return result


class NamespaceAliasType(Enum):
    NONE = 0
    MOSAIC_ID = 1
    ADDRESS = 2

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceAliasType:
        buffer_ = memoryview(payload)
        return NamespaceAliasType(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class NamespaceAlias:
    TYPE_HINTS = {
        "namespace_alias_type": "enum:NamespaceAliasType",
        "mosaic_alias": "pod:MosaicId",
        "address_alias": "pod:Address"
    }

    def __init__(self):
        self._namespace_alias_type = NamespaceAliasType.NONE
        self._mosaic_alias = MosaicId()
        self._address_alias = Address()

    @property
    def namespace_alias_type(self) -> NamespaceAliasType:
        return self._namespace_alias_type

    @property
    def mosaic_alias(self) -> MosaicId:
        return self._mosaic_alias

    @property
    def address_alias(self) -> Address:
        return self._address_alias

    @namespace_alias_type.setter
    def namespace_alias_type(self, value: NamespaceAliasType):
        self._namespace_alias_type = value

    @mosaic_alias.setter
    def mosaic_alias(self, value: MosaicId):
        self._mosaic_alias = value

    @address_alias.setter
    def address_alias(self, value: Address):
        self._address_alias = value

    def size(self) -> int:
        size = 0
        size += self.namespace_alias_type.size()
        if NamespaceAliasType.MOSAIC_ID == self.namespace_alias_type:
            size += self.mosaic_alias.size()
        if NamespaceAliasType.ADDRESS == self.namespace_alias_type:
            size += self.address_alias.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceAlias:
        buffer_ = memoryview(payload)
        namespace_alias_type = NamespaceAliasType.deserialize(buffer_)
        buffer_ = buffer_[namespace_alias_type.size():]
        mosaic_alias = None
        if NamespaceAliasType.MOSAIC_ID == namespace_alias_type:
            mosaic_alias = MosaicId.deserialize(buffer_)
            buffer_ = buffer_[mosaic_alias.size():]
        address_alias = None
        if NamespaceAliasType.ADDRESS == namespace_alias_type:
            address_alias = Address.deserialize(buffer_)
            buffer_ = buffer_[address_alias.size():]

        instance = NamespaceAlias()
        instance._namespace_alias_type = namespace_alias_type
        instance._mosaic_alias = mosaic_alias
        instance._address_alias = address_alias
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._namespace_alias_type.serialize()
        if NamespaceAliasType.MOSAIC_ID == self.namespace_alias_type:
            buffer_ += self._mosaic_alias.serialize()
        if NamespaceAliasType.ADDRESS == self.namespace_alias_type:
            buffer_ += self._address_alias.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "namespace_alias_type: {}, ".format(self._namespace_alias_type.__str__())
        result += "mosaic_alias: {}, ".format(self._mosaic_alias.__str__())
        result += "address_alias: {}, ".format(self._address_alias.__str__())
        result += ")"
        return result


class NamespacePath:
    TYPE_HINTS = {
        "path": "array[NamespaceId]",
        "alias": "struct:NamespaceAlias"
    }

    def __init__(self):
        self._path = []
        self._alias = NamespaceAlias()

    @property
    def path(self) -> List[NamespaceId]:
        return self._path

    @property
    def alias(self) -> NamespaceAlias:
        return self._alias

    @path.setter
    def path(self, value: List[NamespaceId]):
        self._path = value

    @alias.setter
    def alias(self, value: NamespaceAlias):
        self._alias = value

    def size(self) -> int:
        size = 0
        size += 1
        size += sum(map(lambda e: e.size(), self.path))
        size += self.alias.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespacePath:
        buffer_ = memoryview(payload)
        path_size = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        path = ArrayHelpers.read_array_count(buffer_, NamespaceId, path_size)
        buffer_ = buffer_[sum(map(lambda e: e.size(), path)):]
        alias = NamespaceAlias.deserialize(buffer_)
        buffer_ = buffer_[alias.size():]

        instance = NamespacePath()
        instance._path = path
        instance._alias = alias
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += len(self._path).to_bytes(1, byteorder="little", signed=False)  # path_size
        buffer_ += ArrayHelpers.write_array(self._path)
        buffer_ += self._alias.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "path: {}, ".format(list(map(str, self._path)))
        result += "alias: {}, ".format(self._alias.__str__())
        result += ")"
        return result


class RootNamespaceHistory:
    TYPE_HINTS = {
        "id": "pod:NamespaceId",
        "owner_address": "pod:Address",
        "lifetime": "struct:NamespaceLifetime",
        "root_alias": "struct:NamespaceAlias",
        "paths": "array[NamespacePath]"
    }

    def __init__(self):
        self._version = 0
        self._id = NamespaceId()
        self._owner_address = Address()
        self._lifetime = NamespaceLifetime()
        self._root_alias = NamespaceAlias()
        self._paths = []

    @property
    def version(self) -> int:
        return self._version

    @property
    def id(self) -> NamespaceId:
        return self._id

    @property
    def owner_address(self) -> Address:
        return self._owner_address

    @property
    def lifetime(self) -> NamespaceLifetime:
        return self._lifetime

    @property
    def root_alias(self) -> NamespaceAlias:
        return self._root_alias

    @property
    def paths(self) -> List[NamespacePath]:
        return self._paths

    @version.setter
    def version(self, value: int):
        self._version = value

    @id.setter
    def id(self, value: NamespaceId):
        self._id = value

    @owner_address.setter
    def owner_address(self, value: Address):
        self._owner_address = value

    @lifetime.setter
    def lifetime(self, value: NamespaceLifetime):
        self._lifetime = value

    @root_alias.setter
    def root_alias(self, value: NamespaceAlias):
        self._root_alias = value

    @paths.setter
    def paths(self, value: List[NamespacePath]):
        self._paths = value

    def size(self) -> int:
        size = 0
        size += 2
        size += self.id.size()
        size += self.owner_address.size()
        size += self.lifetime.size()
        size += self.root_alias.size()
        size += 8
        size += sum(map(lambda e: e.size(), self.paths))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> RootNamespaceHistory:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[id.size():]
        owner_address = Address.deserialize(buffer_)
        buffer_ = buffer_[owner_address.size():]
        lifetime = NamespaceLifetime.deserialize(buffer_)
        buffer_ = buffer_[lifetime.size():]
        root_alias = NamespaceAlias.deserialize(buffer_)
        buffer_ = buffer_[root_alias.size():]
        children_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        paths = ArrayHelpers.read_array_count(buffer_, NamespacePath, children_count, lambda e: e.path)
        buffer_ = buffer_[sum(map(lambda e: e.size(), paths)):]

        instance = RootNamespaceHistory()
        instance._version = version
        instance._id = id
        instance._owner_address = owner_address
        instance._lifetime = lifetime
        instance._root_alias = root_alias
        instance._paths = paths
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._id.serialize()
        buffer_ += self._owner_address.serialize()
        buffer_ += self._lifetime.serialize()
        buffer_ += self._root_alias.serialize()
        buffer_ += len(self._paths).to_bytes(8, byteorder="little", signed=False)  # children_count
        buffer_ += ArrayHelpers.write_array(self._paths, lambda e: e.path)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "id: {}, ".format(self._id.__str__())
        result += "owner_address: {}, ".format(self._owner_address.__str__())
        result += "lifetime: {}, ".format(self._lifetime.__str__())
        result += "root_alias: {}, ".format(self._root_alias.__str__())
        result += "paths: {}, ".format(list(map(str, self._paths)))
        result += ")"
        return result


class AccountRestrictionFlags(Flag):
    ADDRESS = 1
    MOSAIC_ID = 2
    TRANSACTION_TYPE = 4
    OUTGOING = 16384
    BLOCK = 32768

    def size(self) -> int:
        return 2

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountRestrictionFlags:
        buffer_ = memoryview(payload)
        return AccountRestrictionFlags(int.from_bytes(buffer_[:2], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(2, byteorder="little", signed=False)
        return buffer_


class AccountRestrictionAddressValue:
    TYPE_HINTS = {
        "restriction_values": "array[Address]"
    }

    def __init__(self):
        self._restriction_values = []

    @property
    def restriction_values(self) -> List[Address]:
        return self._restriction_values

    @restriction_values.setter
    def restriction_values(self, value: List[Address]):
        self._restriction_values = value

    def size(self) -> int:
        size = 0
        size += 8
        size += sum(map(lambda e: e.size(), self.restriction_values))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountRestrictionAddressValue:
        buffer_ = memoryview(payload)
        restriction_values_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        restriction_values = ArrayHelpers.read_array_count(buffer_, Address, restriction_values_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_values)):]

        instance = AccountRestrictionAddressValue()
        instance._restriction_values = restriction_values
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += len(self._restriction_values).to_bytes(8, byteorder="little", signed=False)  # restriction_values_count
        buffer_ += ArrayHelpers.write_array(self._restriction_values)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "restriction_values: {}, ".format(list(map(str, self._restriction_values)))
        result += ")"
        return result


class AccountRestrictionMosaicValue:
    TYPE_HINTS = {
        "restriction_values": "array[MosaicId]"
    }

    def __init__(self):
        self._restriction_values = []

    @property
    def restriction_values(self) -> List[MosaicId]:
        return self._restriction_values

    @restriction_values.setter
    def restriction_values(self, value: List[MosaicId]):
        self._restriction_values = value

    def size(self) -> int:
        size = 0
        size += 8
        size += sum(map(lambda e: e.size(), self.restriction_values))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountRestrictionMosaicValue:
        buffer_ = memoryview(payload)
        restriction_values_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        restriction_values = ArrayHelpers.read_array_count(buffer_, MosaicId, restriction_values_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_values)):]

        instance = AccountRestrictionMosaicValue()
        instance._restriction_values = restriction_values
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += len(self._restriction_values).to_bytes(8, byteorder="little", signed=False)  # restriction_values_count
        buffer_ += ArrayHelpers.write_array(self._restriction_values)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "restriction_values: {}, ".format(list(map(str, self._restriction_values)))
        result += ")"
        return result


class AccountRestrictionTransactionTypeValue:
    TYPE_HINTS = {
        "restriction_values": "array[TransactionType]"
    }

    def __init__(self):
        self._restriction_values = []

    @property
    def restriction_values(self) -> List[TransactionType]:
        return self._restriction_values

    @restriction_values.setter
    def restriction_values(self, value: List[TransactionType]):
        self._restriction_values = value

    def size(self) -> int:
        size = 0
        size += 8
        size += sum(map(lambda e: e.size(), self.restriction_values))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountRestrictionTransactionTypeValue:
        buffer_ = memoryview(payload)
        restriction_values_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        restriction_values = ArrayHelpers.read_array_count(buffer_, TransactionType, restriction_values_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_values)):]

        instance = AccountRestrictionTransactionTypeValue()
        instance._restriction_values = restriction_values
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += len(self._restriction_values).to_bytes(8, byteorder="little", signed=False)  # restriction_values_count
        buffer_ += ArrayHelpers.write_array(self._restriction_values)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "restriction_values: {}, ".format(list(map(str, self._restriction_values)))
        result += ")"
        return result


class AccountRestrictionsInfo:
    TYPE_HINTS = {
        "restriction_flags": "enum:AccountRestrictionFlags",
        "address_restrictions": "struct:AccountRestrictionAddressValue",
        "mosaic_id_restrictions": "struct:AccountRestrictionMosaicValue",
        "transaction_type_restrictions": "struct:AccountRestrictionTransactionTypeValue"
    }

    def __init__(self):
        self._restriction_flags = AccountRestrictionFlags.ADDRESS
        self._address_restrictions = AccountRestrictionAddressValue()
        self._mosaic_id_restrictions = AccountRestrictionMosaicValue()
        self._transaction_type_restrictions = AccountRestrictionTransactionTypeValue()

    @property
    def restriction_flags(self) -> AccountRestrictionFlags:
        return self._restriction_flags

    @property
    def address_restrictions(self) -> AccountRestrictionAddressValue:
        return self._address_restrictions

    @property
    def mosaic_id_restrictions(self) -> AccountRestrictionMosaicValue:
        return self._mosaic_id_restrictions

    @property
    def transaction_type_restrictions(self) -> AccountRestrictionTransactionTypeValue:
        return self._transaction_type_restrictions

    @restriction_flags.setter
    def restriction_flags(self, value: AccountRestrictionFlags):
        self._restriction_flags = value

    @address_restrictions.setter
    def address_restrictions(self, value: AccountRestrictionAddressValue):
        self._address_restrictions = value

    @mosaic_id_restrictions.setter
    def mosaic_id_restrictions(self, value: AccountRestrictionMosaicValue):
        self._mosaic_id_restrictions = value

    @transaction_type_restrictions.setter
    def transaction_type_restrictions(self, value: AccountRestrictionTransactionTypeValue):
        self._transaction_type_restrictions = value

    def size(self) -> int:
        size = 0
        size += self.restriction_flags.size()
        if AccountRestrictionFlags.ADDRESS in self.restriction_flags:
            size += self.address_restrictions.size()
        if AccountRestrictionFlags.MOSAIC_ID in self.restriction_flags:
            size += self.mosaic_id_restrictions.size()
        if AccountRestrictionFlags.TRANSACTION_TYPE in self.restriction_flags:
            size += self.transaction_type_restrictions.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountRestrictionsInfo:
        buffer_ = memoryview(payload)
        restriction_flags = AccountRestrictionFlags.deserialize(buffer_)
        buffer_ = buffer_[restriction_flags.size():]
        address_restrictions = None
        if AccountRestrictionFlags.ADDRESS in restriction_flags:
            address_restrictions = AccountRestrictionAddressValue.deserialize(buffer_)
            buffer_ = buffer_[address_restrictions.size():]
        mosaic_id_restrictions = None
        if AccountRestrictionFlags.MOSAIC_ID in restriction_flags:
            mosaic_id_restrictions = AccountRestrictionMosaicValue.deserialize(buffer_)
            buffer_ = buffer_[mosaic_id_restrictions.size():]
        transaction_type_restrictions = None
        if AccountRestrictionFlags.TRANSACTION_TYPE in restriction_flags:
            transaction_type_restrictions = AccountRestrictionTransactionTypeValue.deserialize(buffer_)
            buffer_ = buffer_[transaction_type_restrictions.size():]

        instance = AccountRestrictionsInfo()
        instance._restriction_flags = restriction_flags
        instance._address_restrictions = address_restrictions
        instance._mosaic_id_restrictions = mosaic_id_restrictions
        instance._transaction_type_restrictions = transaction_type_restrictions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._restriction_flags.serialize()
        if AccountRestrictionFlags.ADDRESS in self.restriction_flags:
            buffer_ += self._address_restrictions.serialize()
        if AccountRestrictionFlags.MOSAIC_ID in self.restriction_flags:
            buffer_ += self._mosaic_id_restrictions.serialize()
        if AccountRestrictionFlags.TRANSACTION_TYPE in self.restriction_flags:
            buffer_ += self._transaction_type_restrictions.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "restriction_flags: {}, ".format(self._restriction_flags.__str__())
        result += "address_restrictions: {}, ".format(self._address_restrictions.__str__())
        result += "mosaic_id_restrictions: {}, ".format(self._mosaic_id_restrictions.__str__())
        result += "transaction_type_restrictions: {}, ".format(self._transaction_type_restrictions.__str__())
        result += ")"
        return result


class AccountRestrictions:
    TYPE_HINTS = {
        "address": "pod:Address",
        "restrictions": "array[AccountRestrictionsInfo]"
    }

    def __init__(self):
        self._version = 0
        self._address = Address()
        self._restrictions = []

    @property
    def version(self) -> int:
        return self._version

    @property
    def address(self) -> Address:
        return self._address

    @property
    def restrictions(self) -> List[AccountRestrictionsInfo]:
        return self._restrictions

    @version.setter
    def version(self, value: int):
        self._version = value

    @address.setter
    def address(self, value: Address):
        self._address = value

    @restrictions.setter
    def restrictions(self, value: List[AccountRestrictionsInfo]):
        self._restrictions = value

    def size(self) -> int:
        size = 0
        size += 2
        size += self.address.size()
        size += 8
        size += sum(map(lambda e: e.size(), self.restrictions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountRestrictions:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        address = Address.deserialize(buffer_)
        buffer_ = buffer_[address.size():]
        restrictions_count = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        restrictions = ArrayHelpers.read_array_count(buffer_, AccountRestrictionsInfo, restrictions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restrictions)):]

        instance = AccountRestrictions()
        instance._version = version
        instance._address = address
        instance._restrictions = restrictions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._address.serialize()
        buffer_ += len(self._restrictions).to_bytes(8, byteorder="little", signed=False)  # restrictions_count
        buffer_ += ArrayHelpers.write_array(self._restrictions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "address: {}, ".format(self._address.__str__())
        result += "restrictions: {}, ".format(list(map(str, self._restrictions)))
        result += ")"
        return result


class MosaicRestrictionKey(BaseValue):
    SIZE = 8

    def __init__(self, mosaic_restriction_key: int = 0):
        super().__init__(self.SIZE, mosaic_restriction_key, MosaicRestrictionKey)

    def size(self) -> int:
        return 8

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicRestrictionKey:
        buffer_ = memoryview(payload)
        return MosaicRestrictionKey(int.from_bytes(buffer_[:8], byteorder="little"))

    def serialize(self) -> bytes:
        return self.value.to_bytes(8, byteorder="little", signed=False)


class MosaicRestrictionType(Enum):
    NONE = 0
    EQ = 1
    NE = 2
    LT = 3
    LE = 4
    GT = 5
    GE = 6

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicRestrictionType:
        buffer_ = memoryview(payload)
        return MosaicRestrictionType(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class MosaicRestrictionEntryType(Enum):
    ADDRESS = 0
    GLOBAL = 1

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicRestrictionEntryType:
        buffer_ = memoryview(payload)
        return MosaicRestrictionEntryType(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class AddressKeyValue:
    TYPE_HINTS = {
        "key": "pod:MosaicRestrictionKey"
    }

    def __init__(self):
        self._key = MosaicRestrictionKey()
        self._value = 0

    @property
    def key(self) -> MosaicRestrictionKey:
        return self._key

    @property
    def value(self) -> int:
        return self._value

    @key.setter
    def key(self, value: MosaicRestrictionKey):
        self._key = value

    @value.setter
    def value(self, value: int):
        self._value = value

    def size(self) -> int:
        size = 0
        size += self.key.size()
        size += 8
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AddressKeyValue:
        buffer_ = memoryview(payload)
        key = MosaicRestrictionKey.deserialize(buffer_)
        buffer_ = buffer_[key.size():]
        value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]

        instance = AddressKeyValue()
        instance._key = key
        instance._value = value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._key.serialize()
        buffer_ += self._value.to_bytes(8, byteorder="little", signed=False)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "key: {}, ".format(self._key.__str__())
        result += "value: {}, ".format("0x{:X}".format(self._value))
        result += ")"
        return result


class AddressKeyValueSet:
    TYPE_HINTS = {
        "keys": "array[AddressKeyValue]"
    }

    def __init__(self):
        self._keys = []

    @property
    def keys(self) -> List[AddressKeyValue]:
        return self._keys

    @keys.setter
    def keys(self, value: List[AddressKeyValue]):
        self._keys = value

    def size(self) -> int:
        size = 0
        size += 1
        size += sum(map(lambda e: e.size(), self.keys))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AddressKeyValueSet:
        buffer_ = memoryview(payload)
        key_value_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        keys = ArrayHelpers.read_array_count(buffer_, AddressKeyValue, key_value_count, lambda e: e.key)
        buffer_ = buffer_[sum(map(lambda e: e.size(), keys)):]

        instance = AddressKeyValueSet()
        instance._keys = keys
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += len(self._keys).to_bytes(1, byteorder="little", signed=False)  # key_value_count
        buffer_ += ArrayHelpers.write_array(self._keys, lambda e: e.key)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "keys: {}, ".format(list(map(str, self._keys)))
        result += ")"
        return result


class RestrictionRule:
    TYPE_HINTS = {
        "reference_mosaic_id": "pod:MosaicId",
        "restriction_type": "enum:MosaicRestrictionType"
    }

    def __init__(self):
        self._reference_mosaic_id = MosaicId()
        self._restriction_value = 0
        self._restriction_type = MosaicRestrictionType.NONE

    @property
    def reference_mosaic_id(self) -> MosaicId:
        return self._reference_mosaic_id

    @property
    def restriction_value(self) -> int:
        return self._restriction_value

    @property
    def restriction_type(self) -> MosaicRestrictionType:
        return self._restriction_type

    @reference_mosaic_id.setter
    def reference_mosaic_id(self, value: MosaicId):
        self._reference_mosaic_id = value

    @restriction_value.setter
    def restriction_value(self, value: int):
        self._restriction_value = value

    @restriction_type.setter
    def restriction_type(self, value: MosaicRestrictionType):
        self._restriction_type = value

    def size(self) -> int:
        size = 0
        size += self.reference_mosaic_id.size()
        size += 8
        size += self.restriction_type.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> RestrictionRule:
        buffer_ = memoryview(payload)
        reference_mosaic_id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[reference_mosaic_id.size():]
        restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        restriction_type = MosaicRestrictionType.deserialize(buffer_)
        buffer_ = buffer_[restriction_type.size():]

        instance = RestrictionRule()
        instance._reference_mosaic_id = reference_mosaic_id
        instance._restriction_value = restriction_value
        instance._restriction_type = restriction_type
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._reference_mosaic_id.serialize()
        buffer_ += self._restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._restriction_type.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "reference_mosaic_id: {}, ".format(self._reference_mosaic_id.__str__())
        result += "restriction_value: {}, ".format("0x{:X}".format(self._restriction_value))
        result += "restriction_type: {}, ".format(self._restriction_type.__str__())
        result += ")"
        return result


class GlobalKeyValue:
    TYPE_HINTS = {
        "key": "pod:MosaicRestrictionKey",
        "restriction_rule": "struct:RestrictionRule"
    }

    def __init__(self):
        self._key = MosaicRestrictionKey()
        self._restriction_rule = RestrictionRule()

    @property
    def key(self) -> MosaicRestrictionKey:
        return self._key

    @property
    def restriction_rule(self) -> RestrictionRule:
        return self._restriction_rule

    @key.setter
    def key(self, value: MosaicRestrictionKey):
        self._key = value

    @restriction_rule.setter
    def restriction_rule(self, value: RestrictionRule):
        self._restriction_rule = value

    def size(self) -> int:
        size = 0
        size += self.key.size()
        size += self.restriction_rule.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> GlobalKeyValue:
        buffer_ = memoryview(payload)
        key = MosaicRestrictionKey.deserialize(buffer_)
        buffer_ = buffer_[key.size():]
        restriction_rule = RestrictionRule.deserialize(buffer_)
        buffer_ = buffer_[restriction_rule.size():]

        instance = GlobalKeyValue()
        instance._key = key
        instance._restriction_rule = restriction_rule
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._key.serialize()
        buffer_ += self._restriction_rule.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "key: {}, ".format(self._key.__str__())
        result += "restriction_rule: {}, ".format(self._restriction_rule.__str__())
        result += ")"
        return result


class GlobalKeyValueSet:
    TYPE_HINTS = {
        "keys": "array[GlobalKeyValue]"
    }

    def __init__(self):
        self._keys = []

    @property
    def keys(self) -> List[GlobalKeyValue]:
        return self._keys

    @keys.setter
    def keys(self, value: List[GlobalKeyValue]):
        self._keys = value

    def size(self) -> int:
        size = 0
        size += 1
        size += sum(map(lambda e: e.size(), self.keys))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> GlobalKeyValueSet:
        buffer_ = memoryview(payload)
        key_value_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        keys = ArrayHelpers.read_array_count(buffer_, GlobalKeyValue, key_value_count, lambda e: e.key)
        buffer_ = buffer_[sum(map(lambda e: e.size(), keys)):]

        instance = GlobalKeyValueSet()
        instance._keys = keys
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += len(self._keys).to_bytes(1, byteorder="little", signed=False)  # key_value_count
        buffer_ += ArrayHelpers.write_array(self._keys, lambda e: e.key)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "keys: {}, ".format(list(map(str, self._keys)))
        result += ")"
        return result


class MosaicAddressRestrictionEntry:
    TYPE_HINTS = {
        "mosaic_id": "pod:MosaicId",
        "address": "pod:Address",
        "key_pairs": "struct:AddressKeyValueSet"
    }

    def __init__(self):
        self._mosaic_id = MosaicId()
        self._address = Address()
        self._key_pairs = AddressKeyValueSet()

    @property
    def mosaic_id(self) -> MosaicId:
        return self._mosaic_id

    @property
    def address(self) -> Address:
        return self._address

    @property
    def key_pairs(self) -> AddressKeyValueSet:
        return self._key_pairs

    @mosaic_id.setter
    def mosaic_id(self, value: MosaicId):
        self._mosaic_id = value

    @address.setter
    def address(self, value: Address):
        self._address = value

    @key_pairs.setter
    def key_pairs(self, value: AddressKeyValueSet):
        self._key_pairs = value

    def size(self) -> int:
        size = 0
        size += self.mosaic_id.size()
        size += self.address.size()
        size += self.key_pairs.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicAddressRestrictionEntry:
        buffer_ = memoryview(payload)
        mosaic_id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        address = Address.deserialize(buffer_)
        buffer_ = buffer_[address.size():]
        key_pairs = AddressKeyValueSet.deserialize(buffer_)
        buffer_ = buffer_[key_pairs.size():]

        instance = MosaicAddressRestrictionEntry()
        instance._mosaic_id = mosaic_id
        instance._address = address
        instance._key_pairs = key_pairs
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._address.serialize()
        buffer_ += self._key_pairs.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "address: {}, ".format(self._address.__str__())
        result += "key_pairs: {}, ".format(self._key_pairs.__str__())
        result += ")"
        return result


class MosaicGlobalRestrictionEntry:
    TYPE_HINTS = {
        "mosaic_id": "pod:MosaicId",
        "key_pairs": "struct:GlobalKeyValueSet"
    }

    def __init__(self):
        self._mosaic_id = MosaicId()
        self._key_pairs = GlobalKeyValueSet()

    @property
    def mosaic_id(self) -> MosaicId:
        return self._mosaic_id

    @property
    def key_pairs(self) -> GlobalKeyValueSet:
        return self._key_pairs

    @mosaic_id.setter
    def mosaic_id(self, value: MosaicId):
        self._mosaic_id = value

    @key_pairs.setter
    def key_pairs(self, value: GlobalKeyValueSet):
        self._key_pairs = value

    def size(self) -> int:
        size = 0
        size += self.mosaic_id.size()
        size += self.key_pairs.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicGlobalRestrictionEntry:
        buffer_ = memoryview(payload)
        mosaic_id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        key_pairs = GlobalKeyValueSet.deserialize(buffer_)
        buffer_ = buffer_[key_pairs.size():]

        instance = MosaicGlobalRestrictionEntry()
        instance._mosaic_id = mosaic_id
        instance._key_pairs = key_pairs
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._key_pairs.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "key_pairs: {}, ".format(self._key_pairs.__str__())
        result += ")"
        return result


class MosaicRestrictionEntry:
    TYPE_HINTS = {
        "entry_type": "enum:MosaicRestrictionEntryType",
        "address_entry": "struct:MosaicAddressRestrictionEntry",
        "global_entry": "struct:MosaicGlobalRestrictionEntry"
    }

    def __init__(self):
        self._version = 0
        self._entry_type = MosaicRestrictionEntryType.ADDRESS
        self._address_entry = MosaicAddressRestrictionEntry()
        self._global_entry = MosaicGlobalRestrictionEntry()

    @property
    def version(self) -> int:
        return self._version

    @property
    def entry_type(self) -> MosaicRestrictionEntryType:
        return self._entry_type

    @property
    def address_entry(self) -> MosaicAddressRestrictionEntry:
        return self._address_entry

    @property
    def global_entry(self) -> MosaicGlobalRestrictionEntry:
        return self._global_entry

    @version.setter
    def version(self, value: int):
        self._version = value

    @entry_type.setter
    def entry_type(self, value: MosaicRestrictionEntryType):
        self._entry_type = value

    @address_entry.setter
    def address_entry(self, value: MosaicAddressRestrictionEntry):
        self._address_entry = value

    @global_entry.setter
    def global_entry(self, value: MosaicGlobalRestrictionEntry):
        self._global_entry = value

    def size(self) -> int:
        size = 0
        size += 2
        size += self.entry_type.size()
        if MosaicRestrictionEntryType.ADDRESS == self.entry_type:
            size += self.address_entry.size()
        if MosaicRestrictionEntryType.GLOBAL == self.entry_type:
            size += self.global_entry.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicRestrictionEntry:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        entry_type = MosaicRestrictionEntryType.deserialize(buffer_)
        buffer_ = buffer_[entry_type.size():]
        address_entry = None
        if MosaicRestrictionEntryType.ADDRESS == entry_type:
            address_entry = MosaicAddressRestrictionEntry.deserialize(buffer_)
            buffer_ = buffer_[address_entry.size():]
        global_entry = None
        if MosaicRestrictionEntryType.GLOBAL == entry_type:
            global_entry = MosaicGlobalRestrictionEntry.deserialize(buffer_)
            buffer_ = buffer_[global_entry.size():]

        instance = MosaicRestrictionEntry()
        instance._version = version
        instance._entry_type = entry_type
        instance._address_entry = address_entry
        instance._global_entry = global_entry
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._entry_type.serialize()
        if MosaicRestrictionEntryType.ADDRESS == self.entry_type:
            buffer_ += self._address_entry.serialize()
        if MosaicRestrictionEntryType.GLOBAL == self.entry_type:
            buffer_ += self._global_entry.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "entry_type: {}, ".format(self._entry_type.__str__())
        result += "address_entry: {}, ".format(self._address_entry.__str__())
        result += "global_entry: {}, ".format(self._global_entry.__str__())
        result += ")"
        return result


class LockHashAlgorithm(Enum):
    SHA3_256 = 0
    HASH_160 = 1
    HASH_256 = 2

    def size(self) -> int:
        return 1

    @classmethod
    def deserialize(self, payload: ByteString) -> LockHashAlgorithm:
        buffer_ = memoryview(payload)
        return LockHashAlgorithm(int.from_bytes(buffer_[:1], byteorder="little"))

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.value.to_bytes(1, byteorder="little", signed=False)
        return buffer_


class SecretLockInfo:
    TYPE_HINTS = {
        "owner_address": "pod:Address",
        "mosaic": "struct:Mosaic",
        "end_height": "pod:Height",
        "status": "enum:LockStatus",
        "hash_algorithm": "enum:LockHashAlgorithm",
        "secret": "pod:Hash256",
        "recipient": "pod:Address"
    }

    def __init__(self):
        self._version = 0
        self._owner_address = Address()
        self._mosaic = Mosaic()
        self._end_height = Height()
        self._status = LockStatus.UNUSED
        self._hash_algorithm = LockHashAlgorithm.SHA3_256
        self._secret = Hash256()
        self._recipient = Address()

    @property
    def version(self) -> int:
        return self._version

    @property
    def owner_address(self) -> Address:
        return self._owner_address

    @property
    def mosaic(self) -> Mosaic:
        return self._mosaic

    @property
    def end_height(self) -> Height:
        return self._end_height

    @property
    def status(self) -> LockStatus:
        return self._status

    @property
    def hash_algorithm(self) -> LockHashAlgorithm:
        return self._hash_algorithm

    @property
    def secret(self) -> Hash256:
        return self._secret

    @property
    def recipient(self) -> Address:
        return self._recipient

    @version.setter
    def version(self, value: int):
        self._version = value

    @owner_address.setter
    def owner_address(self, value: Address):
        self._owner_address = value

    @mosaic.setter
    def mosaic(self, value: Mosaic):
        self._mosaic = value

    @end_height.setter
    def end_height(self, value: Height):
        self._end_height = value

    @status.setter
    def status(self, value: LockStatus):
        self._status = value

    @hash_algorithm.setter
    def hash_algorithm(self, value: LockHashAlgorithm):
        self._hash_algorithm = value

    @secret.setter
    def secret(self, value: Hash256):
        self._secret = value

    @recipient.setter
    def recipient(self, value: Address):
        self._recipient = value

    def size(self) -> int:
        size = 0
        size += 2
        size += self.owner_address.size()
        size += self.mosaic.size()
        size += self.end_height.size()
        size += self.status.size()
        size += self.hash_algorithm.size()
        size += self.secret.size()
        size += self.recipient.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> SecretLockInfo:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        owner_address = Address.deserialize(buffer_)
        buffer_ = buffer_[owner_address.size():]
        mosaic = Mosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        end_height = Height.deserialize(buffer_)
        buffer_ = buffer_[end_height.size():]
        status = LockStatus.deserialize(buffer_)
        buffer_ = buffer_[status.size():]
        hash_algorithm = LockHashAlgorithm.deserialize(buffer_)
        buffer_ = buffer_[hash_algorithm.size():]
        secret = Hash256.deserialize(buffer_)
        buffer_ = buffer_[secret.size():]
        recipient = Address.deserialize(buffer_)
        buffer_ = buffer_[recipient.size():]

        instance = SecretLockInfo()
        instance._version = version
        instance._owner_address = owner_address
        instance._mosaic = mosaic
        instance._end_height = end_height
        instance._status = status
        instance._hash_algorithm = hash_algorithm
        instance._secret = secret
        instance._recipient = recipient
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(2, byteorder="little", signed=False)
        buffer_ += self._owner_address.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._end_height.serialize()
        buffer_ += self._status.serialize()
        buffer_ += self._hash_algorithm.serialize()
        buffer_ += self._secret.serialize()
        buffer_ += self._recipient.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "owner_address: {}, ".format(self._owner_address.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "end_height: {}, ".format(self._end_height.__str__())
        result += "status: {}, ".format(self._status.__str__())
        result += "hash_algorithm: {}, ".format(self._hash_algorithm.__str__())
        result += "secret: {}, ".format(self._secret.__str__())
        result += "recipient: {}, ".format(self._recipient.__str__())
        result += ")"
        return result


class AccountKeyLinkTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_KEY_LINK
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "linked_public_key": "pod:PublicKey",
        "link_action": "enum:LinkAction"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = AccountKeyLinkTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = AccountKeyLinkTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._linked_public_key = PublicKey()
        self._link_action = LinkAction.UNLINK
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def linked_public_key(self) -> PublicKey:
        return self._linked_public_key

    @property
    def link_action(self) -> LinkAction:
        return self._link_action

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @linked_public_key.setter
    def linked_public_key(self, value: PublicKey):
        self._linked_public_key = value

    @link_action.setter
    def link_action(self, value: LinkAction):
        self._link_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.linked_public_key.size()
        size += self.link_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountKeyLinkTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        linked_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[linked_public_key.size():]
        link_action = LinkAction.deserialize(buffer_)
        buffer_ = buffer_[link_action.size():]

        instance = AccountKeyLinkTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._linked_public_key = linked_public_key
        instance._link_action = link_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._linked_public_key.serialize()
        buffer_ += self._link_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "link_action: {}, ".format(self._link_action.__str__())
        result += ")"
        return result


class EmbeddedAccountKeyLinkTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_KEY_LINK
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "linked_public_key": "pod:PublicKey",
        "link_action": "enum:LinkAction"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedAccountKeyLinkTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedAccountKeyLinkTransaction.TRANSACTION_TYPE
        self._linked_public_key = PublicKey()
        self._link_action = LinkAction.UNLINK
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def linked_public_key(self) -> PublicKey:
        return self._linked_public_key

    @property
    def link_action(self) -> LinkAction:
        return self._link_action

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @linked_public_key.setter
    def linked_public_key(self, value: PublicKey):
        self._linked_public_key = value

    @link_action.setter
    def link_action(self, value: LinkAction):
        self._link_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.linked_public_key.size()
        size += self.link_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedAccountKeyLinkTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        linked_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[linked_public_key.size():]
        link_action = LinkAction.deserialize(buffer_)
        buffer_ = buffer_[link_action.size():]

        instance = EmbeddedAccountKeyLinkTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._linked_public_key = linked_public_key
        instance._link_action = link_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._linked_public_key.serialize()
        buffer_ += self._link_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "link_action: {}, ".format(self._link_action.__str__())
        result += ")"
        return result


class NodeKeyLinkTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.NODE_KEY_LINK
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "linked_public_key": "pod:PublicKey",
        "link_action": "enum:LinkAction"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = NodeKeyLinkTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = NodeKeyLinkTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._linked_public_key = PublicKey()
        self._link_action = LinkAction.UNLINK
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def linked_public_key(self) -> PublicKey:
        return self._linked_public_key

    @property
    def link_action(self) -> LinkAction:
        return self._link_action

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @linked_public_key.setter
    def linked_public_key(self, value: PublicKey):
        self._linked_public_key = value

    @link_action.setter
    def link_action(self, value: LinkAction):
        self._link_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.linked_public_key.size()
        size += self.link_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NodeKeyLinkTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        linked_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[linked_public_key.size():]
        link_action = LinkAction.deserialize(buffer_)
        buffer_ = buffer_[link_action.size():]

        instance = NodeKeyLinkTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._linked_public_key = linked_public_key
        instance._link_action = link_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._linked_public_key.serialize()
        buffer_ += self._link_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "link_action: {}, ".format(self._link_action.__str__())
        result += ")"
        return result


class EmbeddedNodeKeyLinkTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.NODE_KEY_LINK
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "linked_public_key": "pod:PublicKey",
        "link_action": "enum:LinkAction"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedNodeKeyLinkTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedNodeKeyLinkTransaction.TRANSACTION_TYPE
        self._linked_public_key = PublicKey()
        self._link_action = LinkAction.UNLINK
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def linked_public_key(self) -> PublicKey:
        return self._linked_public_key

    @property
    def link_action(self) -> LinkAction:
        return self._link_action

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @linked_public_key.setter
    def linked_public_key(self, value: PublicKey):
        self._linked_public_key = value

    @link_action.setter
    def link_action(self, value: LinkAction):
        self._link_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.linked_public_key.size()
        size += self.link_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedNodeKeyLinkTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        linked_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[linked_public_key.size():]
        link_action = LinkAction.deserialize(buffer_)
        buffer_ = buffer_[link_action.size():]

        instance = EmbeddedNodeKeyLinkTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._linked_public_key = linked_public_key
        instance._link_action = link_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._linked_public_key.serialize()
        buffer_ += self._link_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "link_action: {}, ".format(self._link_action.__str__())
        result += ")"
        return result


class Cosignature:
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "signature": "pod:Signature"
    }

    def __init__(self):
        self._version = 0
        self._signer_public_key = PublicKey()
        self._signature = Signature()

    @property
    def version(self) -> int:
        return self._version

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def signature(self) -> Signature:
        return self._signature

    @version.setter
    def version(self, value: int):
        self._version = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    def size(self) -> int:
        size = 0
        size += 8
        size += self.signer_public_key.size()
        size += self.signature.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> Cosignature:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]

        instance = Cosignature()
        instance._version = version
        instance._signer_public_key = signer_public_key
        instance._signature = signature
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._signature.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "signature: {}, ".format(self._signature.__str__())
        result += ")"
        return result


class DetachedCosignature:
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "signature": "pod:Signature",
        "parent_hash": "pod:Hash256"
    }

    def __init__(self):
        self._version = 0
        self._signer_public_key = PublicKey()
        self._signature = Signature()
        self._parent_hash = Hash256()

    @property
    def version(self) -> int:
        return self._version

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def parent_hash(self) -> Hash256:
        return self._parent_hash

    @version.setter
    def version(self, value: int):
        self._version = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @parent_hash.setter
    def parent_hash(self, value: Hash256):
        self._parent_hash = value

    def size(self) -> int:
        size = 0
        size += 8
        size += self.signer_public_key.size()
        size += self.signature.size()
        size += self.parent_hash.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> DetachedCosignature:
        buffer_ = memoryview(payload)
        version = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        parent_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[parent_hash.size():]

        instance = DetachedCosignature()
        instance._version = version
        instance._signer_public_key = signer_public_key
        instance._signature = signature
        instance._parent_hash = parent_hash
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self._version.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._signature.serialize()
        buffer_ += self._parent_hash.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "signature: {}, ".format(self._signature.__str__())
        result += "parent_hash: {}, ".format(self._parent_hash.__str__())
        result += ")"
        return result


class AggregateCompleteTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.AGGREGATE_COMPLETE
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "transactions_hash": "pod:Hash256",
        "transactions": "array[EmbeddedTransaction]",
        "cosignatures": "array[Cosignature]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = AggregateCompleteTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = AggregateCompleteTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._transactions_hash = Hash256()
        self._transactions = []
        self._cosignatures = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._aggregate_transaction_header_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def transactions_hash(self) -> Hash256:
        return self._transactions_hash

    @property
    def transactions(self) -> List[EmbeddedTransaction]:
        return self._transactions

    @property
    def cosignatures(self) -> List[Cosignature]:
        return self._cosignatures

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @transactions_hash.setter
    def transactions_hash(self, value: Hash256):
        self._transactions_hash = value

    @transactions.setter
    def transactions(self, value: List[EmbeddedTransaction]):
        self._transactions = value

    @cosignatures.setter
    def cosignatures(self, value: List[Cosignature]):
        self._cosignatures = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.transactions_hash.size()
        size += 4
        size += 4
        size += sum(map(lambda e: ArrayHelpers.align_up(e.size(), 8), self.transactions))
        size += sum(map(lambda e: e.size(), self.cosignatures))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AggregateCompleteTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        transactions_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[transactions_hash.size():]
        payload_size = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        aggregate_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert aggregate_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({aggregate_transaction_header_reserved_1})"
        transactions = ArrayHelpers.read_variable_size_elements(buffer_[:payload_size], EmbeddedTransactionFactory, 8)
        buffer_ = buffer_[payload_size:]
        cosignatures = ArrayHelpers.read_array(buffer_, Cosignature)
        buffer_ = buffer_[sum(map(lambda e: e.size(), cosignatures)):]

        instance = AggregateCompleteTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._transactions_hash = transactions_hash
        instance._transactions = transactions
        instance._cosignatures = cosignatures
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._transactions_hash.serialize()
        buffer_ += sum(map(lambda e: ArrayHelpers.align_up(e.size(), 8), self.transactions)).to_bytes(4, byteorder="little", signed=False)  # payload_size
        buffer_ += self._aggregate_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_variable_size_elements(self._transactions, 8)
        buffer_ += ArrayHelpers.write_array(self._cosignatures)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "transactions_hash: {}, ".format(self._transactions_hash.__str__())
        result += "transactions: {}, ".format(list(map(str, self._transactions)))
        result += "cosignatures: {}, ".format(list(map(str, self._cosignatures)))
        result += ")"
        return result


class AggregateBondedTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.AGGREGATE_BONDED
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "transactions_hash": "pod:Hash256",
        "transactions": "array[EmbeddedTransaction]",
        "cosignatures": "array[Cosignature]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = AggregateBondedTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = AggregateBondedTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._transactions_hash = Hash256()
        self._transactions = []
        self._cosignatures = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._aggregate_transaction_header_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def transactions_hash(self) -> Hash256:
        return self._transactions_hash

    @property
    def transactions(self) -> List[EmbeddedTransaction]:
        return self._transactions

    @property
    def cosignatures(self) -> List[Cosignature]:
        return self._cosignatures

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @transactions_hash.setter
    def transactions_hash(self, value: Hash256):
        self._transactions_hash = value

    @transactions.setter
    def transactions(self, value: List[EmbeddedTransaction]):
        self._transactions = value

    @cosignatures.setter
    def cosignatures(self, value: List[Cosignature]):
        self._cosignatures = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.transactions_hash.size()
        size += 4
        size += 4
        size += sum(map(lambda e: ArrayHelpers.align_up(e.size(), 8), self.transactions))
        size += sum(map(lambda e: e.size(), self.cosignatures))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AggregateBondedTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        transactions_hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[transactions_hash.size():]
        payload_size = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        aggregate_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert aggregate_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({aggregate_transaction_header_reserved_1})"
        transactions = ArrayHelpers.read_variable_size_elements(buffer_[:payload_size], EmbeddedTransactionFactory, 8)
        buffer_ = buffer_[payload_size:]
        cosignatures = ArrayHelpers.read_array(buffer_, Cosignature)
        buffer_ = buffer_[sum(map(lambda e: e.size(), cosignatures)):]

        instance = AggregateBondedTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._transactions_hash = transactions_hash
        instance._transactions = transactions
        instance._cosignatures = cosignatures
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._transactions_hash.serialize()
        buffer_ += sum(map(lambda e: ArrayHelpers.align_up(e.size(), 8), self.transactions)).to_bytes(4, byteorder="little", signed=False)  # payload_size
        buffer_ += self._aggregate_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_variable_size_elements(self._transactions, 8)
        buffer_ += ArrayHelpers.write_array(self._cosignatures)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "transactions_hash: {}, ".format(self._transactions_hash.__str__())
        result += "transactions: {}, ".format(list(map(str, self._transactions)))
        result += "cosignatures: {}, ".format(list(map(str, self._cosignatures)))
        result += ")"
        return result


class VotingKeyLinkTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.VOTING_KEY_LINK
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "linked_public_key": "pod:VotingPublicKey",
        "start_epoch": "pod:FinalizationEpoch",
        "end_epoch": "pod:FinalizationEpoch",
        "link_action": "enum:LinkAction"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = VotingKeyLinkTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = VotingKeyLinkTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._linked_public_key = VotingPublicKey()
        self._start_epoch = FinalizationEpoch()
        self._end_epoch = FinalizationEpoch()
        self._link_action = LinkAction.UNLINK
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def linked_public_key(self) -> VotingPublicKey:
        return self._linked_public_key

    @property
    def start_epoch(self) -> FinalizationEpoch:
        return self._start_epoch

    @property
    def end_epoch(self) -> FinalizationEpoch:
        return self._end_epoch

    @property
    def link_action(self) -> LinkAction:
        return self._link_action

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @linked_public_key.setter
    def linked_public_key(self, value: VotingPublicKey):
        self._linked_public_key = value

    @start_epoch.setter
    def start_epoch(self, value: FinalizationEpoch):
        self._start_epoch = value

    @end_epoch.setter
    def end_epoch(self, value: FinalizationEpoch):
        self._end_epoch = value

    @link_action.setter
    def link_action(self, value: LinkAction):
        self._link_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.linked_public_key.size()
        size += self.start_epoch.size()
        size += self.end_epoch.size()
        size += self.link_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> VotingKeyLinkTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        linked_public_key = VotingPublicKey.deserialize(buffer_)
        buffer_ = buffer_[linked_public_key.size():]
        start_epoch = FinalizationEpoch.deserialize(buffer_)
        buffer_ = buffer_[start_epoch.size():]
        end_epoch = FinalizationEpoch.deserialize(buffer_)
        buffer_ = buffer_[end_epoch.size():]
        link_action = LinkAction.deserialize(buffer_)
        buffer_ = buffer_[link_action.size():]

        instance = VotingKeyLinkTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._linked_public_key = linked_public_key
        instance._start_epoch = start_epoch
        instance._end_epoch = end_epoch
        instance._link_action = link_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._linked_public_key.serialize()
        buffer_ += self._start_epoch.serialize()
        buffer_ += self._end_epoch.serialize()
        buffer_ += self._link_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "start_epoch: {}, ".format(self._start_epoch.__str__())
        result += "end_epoch: {}, ".format(self._end_epoch.__str__())
        result += "link_action: {}, ".format(self._link_action.__str__())
        result += ")"
        return result


class EmbeddedVotingKeyLinkTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.VOTING_KEY_LINK
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "linked_public_key": "pod:VotingPublicKey",
        "start_epoch": "pod:FinalizationEpoch",
        "end_epoch": "pod:FinalizationEpoch",
        "link_action": "enum:LinkAction"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedVotingKeyLinkTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedVotingKeyLinkTransaction.TRANSACTION_TYPE
        self._linked_public_key = VotingPublicKey()
        self._start_epoch = FinalizationEpoch()
        self._end_epoch = FinalizationEpoch()
        self._link_action = LinkAction.UNLINK
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def linked_public_key(self) -> VotingPublicKey:
        return self._linked_public_key

    @property
    def start_epoch(self) -> FinalizationEpoch:
        return self._start_epoch

    @property
    def end_epoch(self) -> FinalizationEpoch:
        return self._end_epoch

    @property
    def link_action(self) -> LinkAction:
        return self._link_action

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @linked_public_key.setter
    def linked_public_key(self, value: VotingPublicKey):
        self._linked_public_key = value

    @start_epoch.setter
    def start_epoch(self, value: FinalizationEpoch):
        self._start_epoch = value

    @end_epoch.setter
    def end_epoch(self, value: FinalizationEpoch):
        self._end_epoch = value

    @link_action.setter
    def link_action(self, value: LinkAction):
        self._link_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.linked_public_key.size()
        size += self.start_epoch.size()
        size += self.end_epoch.size()
        size += self.link_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedVotingKeyLinkTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        linked_public_key = VotingPublicKey.deserialize(buffer_)
        buffer_ = buffer_[linked_public_key.size():]
        start_epoch = FinalizationEpoch.deserialize(buffer_)
        buffer_ = buffer_[start_epoch.size():]
        end_epoch = FinalizationEpoch.deserialize(buffer_)
        buffer_ = buffer_[end_epoch.size():]
        link_action = LinkAction.deserialize(buffer_)
        buffer_ = buffer_[link_action.size():]

        instance = EmbeddedVotingKeyLinkTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._linked_public_key = linked_public_key
        instance._start_epoch = start_epoch
        instance._end_epoch = end_epoch
        instance._link_action = link_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._linked_public_key.serialize()
        buffer_ += self._start_epoch.serialize()
        buffer_ += self._end_epoch.serialize()
        buffer_ += self._link_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "start_epoch: {}, ".format(self._start_epoch.__str__())
        result += "end_epoch: {}, ".format(self._end_epoch.__str__())
        result += "link_action: {}, ".format(self._link_action.__str__())
        result += ")"
        return result


class VrfKeyLinkTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.VRF_KEY_LINK
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "linked_public_key": "pod:PublicKey",
        "link_action": "enum:LinkAction"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = VrfKeyLinkTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = VrfKeyLinkTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._linked_public_key = PublicKey()
        self._link_action = LinkAction.UNLINK
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def linked_public_key(self) -> PublicKey:
        return self._linked_public_key

    @property
    def link_action(self) -> LinkAction:
        return self._link_action

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @linked_public_key.setter
    def linked_public_key(self, value: PublicKey):
        self._linked_public_key = value

    @link_action.setter
    def link_action(self, value: LinkAction):
        self._link_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.linked_public_key.size()
        size += self.link_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> VrfKeyLinkTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        linked_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[linked_public_key.size():]
        link_action = LinkAction.deserialize(buffer_)
        buffer_ = buffer_[link_action.size():]

        instance = VrfKeyLinkTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._linked_public_key = linked_public_key
        instance._link_action = link_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._linked_public_key.serialize()
        buffer_ += self._link_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "link_action: {}, ".format(self._link_action.__str__())
        result += ")"
        return result


class EmbeddedVrfKeyLinkTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.VRF_KEY_LINK
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "linked_public_key": "pod:PublicKey",
        "link_action": "enum:LinkAction"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedVrfKeyLinkTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedVrfKeyLinkTransaction.TRANSACTION_TYPE
        self._linked_public_key = PublicKey()
        self._link_action = LinkAction.UNLINK
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def linked_public_key(self) -> PublicKey:
        return self._linked_public_key

    @property
    def link_action(self) -> LinkAction:
        return self._link_action

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @linked_public_key.setter
    def linked_public_key(self, value: PublicKey):
        self._linked_public_key = value

    @link_action.setter
    def link_action(self, value: LinkAction):
        self._link_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.linked_public_key.size()
        size += self.link_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedVrfKeyLinkTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        linked_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[linked_public_key.size():]
        link_action = LinkAction.deserialize(buffer_)
        buffer_ = buffer_[link_action.size():]

        instance = EmbeddedVrfKeyLinkTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._linked_public_key = linked_public_key
        instance._link_action = link_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._linked_public_key.serialize()
        buffer_ += self._link_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "linked_public_key: {}, ".format(self._linked_public_key.__str__())
        result += "link_action: {}, ".format(self._link_action.__str__())
        result += ")"
        return result


class HashLockTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.HASH_LOCK
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "mosaic": "struct:UnresolvedMosaic",
        "duration": "pod:BlockDuration",
        "hash": "pod:Hash256"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = HashLockTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = HashLockTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._mosaic = UnresolvedMosaic()
        self._duration = BlockDuration()
        self._hash = Hash256()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def mosaic(self) -> UnresolvedMosaic:
        return self._mosaic

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @property
    def hash(self) -> Hash256:
        return self._hash

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @mosaic.setter
    def mosaic(self, value: UnresolvedMosaic):
        self._mosaic = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    @hash.setter
    def hash(self, value: Hash256):
        self._hash = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.mosaic.size()
        size += self.duration.size()
        size += self.hash.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> HashLockTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        mosaic = UnresolvedMosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        duration = BlockDuration.deserialize(buffer_)
        buffer_ = buffer_[duration.size():]
        hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[hash.size():]

        instance = HashLockTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._mosaic = mosaic
        instance._duration = duration
        instance._hash = hash
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._duration.serialize()
        buffer_ += self._hash.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "duration: {}, ".format(self._duration.__str__())
        result += "hash: {}, ".format(self._hash.__str__())
        result += ")"
        return result


class EmbeddedHashLockTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.HASH_LOCK
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "mosaic": "struct:UnresolvedMosaic",
        "duration": "pod:BlockDuration",
        "hash": "pod:Hash256"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedHashLockTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedHashLockTransaction.TRANSACTION_TYPE
        self._mosaic = UnresolvedMosaic()
        self._duration = BlockDuration()
        self._hash = Hash256()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def mosaic(self) -> UnresolvedMosaic:
        return self._mosaic

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @property
    def hash(self) -> Hash256:
        return self._hash

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @mosaic.setter
    def mosaic(self, value: UnresolvedMosaic):
        self._mosaic = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    @hash.setter
    def hash(self, value: Hash256):
        self._hash = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.mosaic.size()
        size += self.duration.size()
        size += self.hash.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedHashLockTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic = UnresolvedMosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        duration = BlockDuration.deserialize(buffer_)
        buffer_ = buffer_[duration.size():]
        hash = Hash256.deserialize(buffer_)
        buffer_ = buffer_[hash.size():]

        instance = EmbeddedHashLockTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._mosaic = mosaic
        instance._duration = duration
        instance._hash = hash
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._duration.serialize()
        buffer_ += self._hash.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "duration: {}, ".format(self._duration.__str__())
        result += "hash: {}, ".format(self._hash.__str__())
        result += ")"
        return result


class SecretLockTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.SECRET_LOCK
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "recipient_address": "pod:UnresolvedAddress",
        "secret": "pod:Hash256",
        "mosaic": "struct:UnresolvedMosaic",
        "duration": "pod:BlockDuration",
        "hash_algorithm": "enum:LockHashAlgorithm"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = SecretLockTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = SecretLockTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._recipient_address = UnresolvedAddress()
        self._secret = Hash256()
        self._mosaic = UnresolvedMosaic()
        self._duration = BlockDuration()
        self._hash_algorithm = LockHashAlgorithm.SHA3_256
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def recipient_address(self) -> UnresolvedAddress:
        return self._recipient_address

    @property
    def secret(self) -> Hash256:
        return self._secret

    @property
    def mosaic(self) -> UnresolvedMosaic:
        return self._mosaic

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @property
    def hash_algorithm(self) -> LockHashAlgorithm:
        return self._hash_algorithm

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @recipient_address.setter
    def recipient_address(self, value: UnresolvedAddress):
        self._recipient_address = value

    @secret.setter
    def secret(self, value: Hash256):
        self._secret = value

    @mosaic.setter
    def mosaic(self, value: UnresolvedMosaic):
        self._mosaic = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    @hash_algorithm.setter
    def hash_algorithm(self, value: LockHashAlgorithm):
        self._hash_algorithm = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.recipient_address.size()
        size += self.secret.size()
        size += self.mosaic.size()
        size += self.duration.size()
        size += self.hash_algorithm.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> SecretLockTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        recipient_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[recipient_address.size():]
        secret = Hash256.deserialize(buffer_)
        buffer_ = buffer_[secret.size():]
        mosaic = UnresolvedMosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        duration = BlockDuration.deserialize(buffer_)
        buffer_ = buffer_[duration.size():]
        hash_algorithm = LockHashAlgorithm.deserialize(buffer_)
        buffer_ = buffer_[hash_algorithm.size():]

        instance = SecretLockTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._recipient_address = recipient_address
        instance._secret = secret
        instance._mosaic = mosaic
        instance._duration = duration
        instance._hash_algorithm = hash_algorithm
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._recipient_address.serialize()
        buffer_ += self._secret.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._duration.serialize()
        buffer_ += self._hash_algorithm.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "recipient_address: {}, ".format(self._recipient_address.__str__())
        result += "secret: {}, ".format(self._secret.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "duration: {}, ".format(self._duration.__str__())
        result += "hash_algorithm: {}, ".format(self._hash_algorithm.__str__())
        result += ")"
        return result


class EmbeddedSecretLockTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.SECRET_LOCK
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "recipient_address": "pod:UnresolvedAddress",
        "secret": "pod:Hash256",
        "mosaic": "struct:UnresolvedMosaic",
        "duration": "pod:BlockDuration",
        "hash_algorithm": "enum:LockHashAlgorithm"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedSecretLockTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedSecretLockTransaction.TRANSACTION_TYPE
        self._recipient_address = UnresolvedAddress()
        self._secret = Hash256()
        self._mosaic = UnresolvedMosaic()
        self._duration = BlockDuration()
        self._hash_algorithm = LockHashAlgorithm.SHA3_256
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def recipient_address(self) -> UnresolvedAddress:
        return self._recipient_address

    @property
    def secret(self) -> Hash256:
        return self._secret

    @property
    def mosaic(self) -> UnresolvedMosaic:
        return self._mosaic

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @property
    def hash_algorithm(self) -> LockHashAlgorithm:
        return self._hash_algorithm

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @recipient_address.setter
    def recipient_address(self, value: UnresolvedAddress):
        self._recipient_address = value

    @secret.setter
    def secret(self, value: Hash256):
        self._secret = value

    @mosaic.setter
    def mosaic(self, value: UnresolvedMosaic):
        self._mosaic = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    @hash_algorithm.setter
    def hash_algorithm(self, value: LockHashAlgorithm):
        self._hash_algorithm = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.recipient_address.size()
        size += self.secret.size()
        size += self.mosaic.size()
        size += self.duration.size()
        size += self.hash_algorithm.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedSecretLockTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        recipient_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[recipient_address.size():]
        secret = Hash256.deserialize(buffer_)
        buffer_ = buffer_[secret.size():]
        mosaic = UnresolvedMosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]
        duration = BlockDuration.deserialize(buffer_)
        buffer_ = buffer_[duration.size():]
        hash_algorithm = LockHashAlgorithm.deserialize(buffer_)
        buffer_ = buffer_[hash_algorithm.size():]

        instance = EmbeddedSecretLockTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._recipient_address = recipient_address
        instance._secret = secret
        instance._mosaic = mosaic
        instance._duration = duration
        instance._hash_algorithm = hash_algorithm
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._recipient_address.serialize()
        buffer_ += self._secret.serialize()
        buffer_ += self._mosaic.serialize()
        buffer_ += self._duration.serialize()
        buffer_ += self._hash_algorithm.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "recipient_address: {}, ".format(self._recipient_address.__str__())
        result += "secret: {}, ".format(self._secret.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += "duration: {}, ".format(self._duration.__str__())
        result += "hash_algorithm: {}, ".format(self._hash_algorithm.__str__())
        result += ")"
        return result


class SecretProofTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.SECRET_PROOF
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "recipient_address": "pod:UnresolvedAddress",
        "secret": "pod:Hash256",
        "hash_algorithm": "enum:LockHashAlgorithm",
        "proof": "bytes_array"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = SecretProofTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = SecretProofTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._recipient_address = UnresolvedAddress()
        self._secret = Hash256()
        self._hash_algorithm = LockHashAlgorithm.SHA3_256
        self._proof = bytes()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def recipient_address(self) -> UnresolvedAddress:
        return self._recipient_address

    @property
    def secret(self) -> Hash256:
        return self._secret

    @property
    def hash_algorithm(self) -> LockHashAlgorithm:
        return self._hash_algorithm

    @property
    def proof(self) -> bytes:
        return self._proof

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @recipient_address.setter
    def recipient_address(self, value: UnresolvedAddress):
        self._recipient_address = value

    @secret.setter
    def secret(self, value: Hash256):
        self._secret = value

    @hash_algorithm.setter
    def hash_algorithm(self, value: LockHashAlgorithm):
        self._hash_algorithm = value

    @proof.setter
    def proof(self, value: bytes):
        self._proof = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.recipient_address.size()
        size += self.secret.size()
        size += 2
        size += self.hash_algorithm.size()
        size += len(self._proof)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> SecretProofTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        recipient_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[recipient_address.size():]
        secret = Hash256.deserialize(buffer_)
        buffer_ = buffer_[secret.size():]
        proof_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        hash_algorithm = LockHashAlgorithm.deserialize(buffer_)
        buffer_ = buffer_[hash_algorithm.size():]
        proof = ArrayHelpers.get_bytes(buffer_, proof_size)
        buffer_ = buffer_[proof_size:]

        instance = SecretProofTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._recipient_address = recipient_address
        instance._secret = secret
        instance._hash_algorithm = hash_algorithm
        instance._proof = proof
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._recipient_address.serialize()
        buffer_ += self._secret.serialize()
        buffer_ += len(self._proof).to_bytes(2, byteorder="little", signed=False)  # proof_size
        buffer_ += self._hash_algorithm.serialize()
        buffer_ += self._proof
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "recipient_address: {}, ".format(self._recipient_address.__str__())
        result += "secret: {}, ".format(self._secret.__str__())
        result += "hash_algorithm: {}, ".format(self._hash_algorithm.__str__())
        result += "proof: {}, ".format(hexlify(self._proof).decode("utf8"))
        result += ")"
        return result


class EmbeddedSecretProofTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.SECRET_PROOF
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "recipient_address": "pod:UnresolvedAddress",
        "secret": "pod:Hash256",
        "hash_algorithm": "enum:LockHashAlgorithm",
        "proof": "bytes_array"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedSecretProofTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedSecretProofTransaction.TRANSACTION_TYPE
        self._recipient_address = UnresolvedAddress()
        self._secret = Hash256()
        self._hash_algorithm = LockHashAlgorithm.SHA3_256
        self._proof = bytes()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def recipient_address(self) -> UnresolvedAddress:
        return self._recipient_address

    @property
    def secret(self) -> Hash256:
        return self._secret

    @property
    def hash_algorithm(self) -> LockHashAlgorithm:
        return self._hash_algorithm

    @property
    def proof(self) -> bytes:
        return self._proof

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @recipient_address.setter
    def recipient_address(self, value: UnresolvedAddress):
        self._recipient_address = value

    @secret.setter
    def secret(self, value: Hash256):
        self._secret = value

    @hash_algorithm.setter
    def hash_algorithm(self, value: LockHashAlgorithm):
        self._hash_algorithm = value

    @proof.setter
    def proof(self, value: bytes):
        self._proof = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.recipient_address.size()
        size += self.secret.size()
        size += 2
        size += self.hash_algorithm.size()
        size += len(self._proof)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedSecretProofTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        recipient_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[recipient_address.size():]
        secret = Hash256.deserialize(buffer_)
        buffer_ = buffer_[secret.size():]
        proof_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        hash_algorithm = LockHashAlgorithm.deserialize(buffer_)
        buffer_ = buffer_[hash_algorithm.size():]
        proof = ArrayHelpers.get_bytes(buffer_, proof_size)
        buffer_ = buffer_[proof_size:]

        instance = EmbeddedSecretProofTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._recipient_address = recipient_address
        instance._secret = secret
        instance._hash_algorithm = hash_algorithm
        instance._proof = proof
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._recipient_address.serialize()
        buffer_ += self._secret.serialize()
        buffer_ += len(self._proof).to_bytes(2, byteorder="little", signed=False)  # proof_size
        buffer_ += self._hash_algorithm.serialize()
        buffer_ += self._proof
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "recipient_address: {}, ".format(self._recipient_address.__str__())
        result += "secret: {}, ".format(self._secret.__str__())
        result += "hash_algorithm: {}, ".format(self._hash_algorithm.__str__())
        result += "proof: {}, ".format(hexlify(self._proof).decode("utf8"))
        result += ")"
        return result


class AccountMetadataTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_METADATA
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "target_address": "pod:UnresolvedAddress",
        "value": "bytes_array"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = AccountMetadataTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = AccountMetadataTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._target_address = UnresolvedAddress()
        self._scoped_metadata_key = 0
        self._value_size_delta = 0
        self._value = bytes()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def target_address(self) -> UnresolvedAddress:
        return self._target_address

    @property
    def scoped_metadata_key(self) -> int:
        return self._scoped_metadata_key

    @property
    def value_size_delta(self) -> int:
        return self._value_size_delta

    @property
    def value(self) -> bytes:
        return self._value

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @target_address.setter
    def target_address(self, value: UnresolvedAddress):
        self._target_address = value

    @scoped_metadata_key.setter
    def scoped_metadata_key(self, value: int):
        self._scoped_metadata_key = value

    @value_size_delta.setter
    def value_size_delta(self, value: int):
        self._value_size_delta = value

    @value.setter
    def value(self, value: bytes):
        self._value = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.target_address.size()
        size += 8
        size += 2
        size += 2
        size += len(self._value)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountMetadataTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        target_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]
        scoped_metadata_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        value_size_delta = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value = ArrayHelpers.get_bytes(buffer_, value_size)
        buffer_ = buffer_[value_size:]

        instance = AccountMetadataTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._target_address = target_address
        instance._scoped_metadata_key = scoped_metadata_key
        instance._value_size_delta = value_size_delta
        instance._value = value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._target_address.serialize()
        buffer_ += self._scoped_metadata_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._value_size_delta.to_bytes(2, byteorder="little", signed=False)
        buffer_ += len(self._value).to_bytes(2, byteorder="little", signed=False)  # value_size
        buffer_ += self._value
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += "scoped_metadata_key: {}, ".format("0x{:X}".format(self._scoped_metadata_key))
        result += "value_size_delta: {}, ".format("0x{:X}".format(self._value_size_delta))
        result += "value: {}, ".format(hexlify(self._value).decode("utf8"))
        result += ")"
        return result


class EmbeddedAccountMetadataTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_METADATA
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "target_address": "pod:UnresolvedAddress",
        "value": "bytes_array"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedAccountMetadataTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedAccountMetadataTransaction.TRANSACTION_TYPE
        self._target_address = UnresolvedAddress()
        self._scoped_metadata_key = 0
        self._value_size_delta = 0
        self._value = bytes()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def target_address(self) -> UnresolvedAddress:
        return self._target_address

    @property
    def scoped_metadata_key(self) -> int:
        return self._scoped_metadata_key

    @property
    def value_size_delta(self) -> int:
        return self._value_size_delta

    @property
    def value(self) -> bytes:
        return self._value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @target_address.setter
    def target_address(self, value: UnresolvedAddress):
        self._target_address = value

    @scoped_metadata_key.setter
    def scoped_metadata_key(self, value: int):
        self._scoped_metadata_key = value

    @value_size_delta.setter
    def value_size_delta(self, value: int):
        self._value_size_delta = value

    @value.setter
    def value(self, value: bytes):
        self._value = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.target_address.size()
        size += 8
        size += 2
        size += 2
        size += len(self._value)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedAccountMetadataTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        target_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]
        scoped_metadata_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        value_size_delta = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value = ArrayHelpers.get_bytes(buffer_, value_size)
        buffer_ = buffer_[value_size:]

        instance = EmbeddedAccountMetadataTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._target_address = target_address
        instance._scoped_metadata_key = scoped_metadata_key
        instance._value_size_delta = value_size_delta
        instance._value = value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._target_address.serialize()
        buffer_ += self._scoped_metadata_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._value_size_delta.to_bytes(2, byteorder="little", signed=False)
        buffer_ += len(self._value).to_bytes(2, byteorder="little", signed=False)  # value_size
        buffer_ += self._value
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += "scoped_metadata_key: {}, ".format("0x{:X}".format(self._scoped_metadata_key))
        result += "value_size_delta: {}, ".format("0x{:X}".format(self._value_size_delta))
        result += "value: {}, ".format(hexlify(self._value).decode("utf8"))
        result += ")"
        return result


class MosaicMetadataTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_METADATA
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "target_address": "pod:UnresolvedAddress",
        "target_mosaic_id": "pod:UnresolvedMosaicId",
        "value": "bytes_array"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = MosaicMetadataTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = MosaicMetadataTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._target_address = UnresolvedAddress()
        self._scoped_metadata_key = 0
        self._target_mosaic_id = UnresolvedMosaicId()
        self._value_size_delta = 0
        self._value = bytes()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def target_address(self) -> UnresolvedAddress:
        return self._target_address

    @property
    def scoped_metadata_key(self) -> int:
        return self._scoped_metadata_key

    @property
    def target_mosaic_id(self) -> UnresolvedMosaicId:
        return self._target_mosaic_id

    @property
    def value_size_delta(self) -> int:
        return self._value_size_delta

    @property
    def value(self) -> bytes:
        return self._value

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @target_address.setter
    def target_address(self, value: UnresolvedAddress):
        self._target_address = value

    @scoped_metadata_key.setter
    def scoped_metadata_key(self, value: int):
        self._scoped_metadata_key = value

    @target_mosaic_id.setter
    def target_mosaic_id(self, value: UnresolvedMosaicId):
        self._target_mosaic_id = value

    @value_size_delta.setter
    def value_size_delta(self, value: int):
        self._value_size_delta = value

    @value.setter
    def value(self, value: bytes):
        self._value = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.target_address.size()
        size += 8
        size += self.target_mosaic_id.size()
        size += 2
        size += 2
        size += len(self._value)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicMetadataTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        target_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]
        scoped_metadata_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        target_mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[target_mosaic_id.size():]
        value_size_delta = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value = ArrayHelpers.get_bytes(buffer_, value_size)
        buffer_ = buffer_[value_size:]

        instance = MosaicMetadataTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._target_address = target_address
        instance._scoped_metadata_key = scoped_metadata_key
        instance._target_mosaic_id = target_mosaic_id
        instance._value_size_delta = value_size_delta
        instance._value = value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._target_address.serialize()
        buffer_ += self._scoped_metadata_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._target_mosaic_id.serialize()
        buffer_ += self._value_size_delta.to_bytes(2, byteorder="little", signed=False)
        buffer_ += len(self._value).to_bytes(2, byteorder="little", signed=False)  # value_size
        buffer_ += self._value
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += "scoped_metadata_key: {}, ".format("0x{:X}".format(self._scoped_metadata_key))
        result += "target_mosaic_id: {}, ".format(self._target_mosaic_id.__str__())
        result += "value_size_delta: {}, ".format("0x{:X}".format(self._value_size_delta))
        result += "value: {}, ".format(hexlify(self._value).decode("utf8"))
        result += ")"
        return result


class EmbeddedMosaicMetadataTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_METADATA
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "target_address": "pod:UnresolvedAddress",
        "target_mosaic_id": "pod:UnresolvedMosaicId",
        "value": "bytes_array"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedMosaicMetadataTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedMosaicMetadataTransaction.TRANSACTION_TYPE
        self._target_address = UnresolvedAddress()
        self._scoped_metadata_key = 0
        self._target_mosaic_id = UnresolvedMosaicId()
        self._value_size_delta = 0
        self._value = bytes()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def target_address(self) -> UnresolvedAddress:
        return self._target_address

    @property
    def scoped_metadata_key(self) -> int:
        return self._scoped_metadata_key

    @property
    def target_mosaic_id(self) -> UnresolvedMosaicId:
        return self._target_mosaic_id

    @property
    def value_size_delta(self) -> int:
        return self._value_size_delta

    @property
    def value(self) -> bytes:
        return self._value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @target_address.setter
    def target_address(self, value: UnresolvedAddress):
        self._target_address = value

    @scoped_metadata_key.setter
    def scoped_metadata_key(self, value: int):
        self._scoped_metadata_key = value

    @target_mosaic_id.setter
    def target_mosaic_id(self, value: UnresolvedMosaicId):
        self._target_mosaic_id = value

    @value_size_delta.setter
    def value_size_delta(self, value: int):
        self._value_size_delta = value

    @value.setter
    def value(self, value: bytes):
        self._value = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.target_address.size()
        size += 8
        size += self.target_mosaic_id.size()
        size += 2
        size += 2
        size += len(self._value)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedMosaicMetadataTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        target_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]
        scoped_metadata_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        target_mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[target_mosaic_id.size():]
        value_size_delta = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value = ArrayHelpers.get_bytes(buffer_, value_size)
        buffer_ = buffer_[value_size:]

        instance = EmbeddedMosaicMetadataTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._target_address = target_address
        instance._scoped_metadata_key = scoped_metadata_key
        instance._target_mosaic_id = target_mosaic_id
        instance._value_size_delta = value_size_delta
        instance._value = value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._target_address.serialize()
        buffer_ += self._scoped_metadata_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._target_mosaic_id.serialize()
        buffer_ += self._value_size_delta.to_bytes(2, byteorder="little", signed=False)
        buffer_ += len(self._value).to_bytes(2, byteorder="little", signed=False)  # value_size
        buffer_ += self._value
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += "scoped_metadata_key: {}, ".format("0x{:X}".format(self._scoped_metadata_key))
        result += "target_mosaic_id: {}, ".format(self._target_mosaic_id.__str__())
        result += "value_size_delta: {}, ".format("0x{:X}".format(self._value_size_delta))
        result += "value: {}, ".format(hexlify(self._value).decode("utf8"))
        result += ")"
        return result


class NamespaceMetadataTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.NAMESPACE_METADATA
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "target_address": "pod:UnresolvedAddress",
        "target_namespace_id": "pod:NamespaceId",
        "value": "bytes_array"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = NamespaceMetadataTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = NamespaceMetadataTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._target_address = UnresolvedAddress()
        self._scoped_metadata_key = 0
        self._target_namespace_id = NamespaceId()
        self._value_size_delta = 0
        self._value = bytes()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def target_address(self) -> UnresolvedAddress:
        return self._target_address

    @property
    def scoped_metadata_key(self) -> int:
        return self._scoped_metadata_key

    @property
    def target_namespace_id(self) -> NamespaceId:
        return self._target_namespace_id

    @property
    def value_size_delta(self) -> int:
        return self._value_size_delta

    @property
    def value(self) -> bytes:
        return self._value

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @target_address.setter
    def target_address(self, value: UnresolvedAddress):
        self._target_address = value

    @scoped_metadata_key.setter
    def scoped_metadata_key(self, value: int):
        self._scoped_metadata_key = value

    @target_namespace_id.setter
    def target_namespace_id(self, value: NamespaceId):
        self._target_namespace_id = value

    @value_size_delta.setter
    def value_size_delta(self, value: int):
        self._value_size_delta = value

    @value.setter
    def value(self, value: bytes):
        self._value = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.target_address.size()
        size += 8
        size += self.target_namespace_id.size()
        size += 2
        size += 2
        size += len(self._value)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceMetadataTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        target_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]
        scoped_metadata_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        target_namespace_id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[target_namespace_id.size():]
        value_size_delta = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value = ArrayHelpers.get_bytes(buffer_, value_size)
        buffer_ = buffer_[value_size:]

        instance = NamespaceMetadataTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._target_address = target_address
        instance._scoped_metadata_key = scoped_metadata_key
        instance._target_namespace_id = target_namespace_id
        instance._value_size_delta = value_size_delta
        instance._value = value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._target_address.serialize()
        buffer_ += self._scoped_metadata_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._target_namespace_id.serialize()
        buffer_ += self._value_size_delta.to_bytes(2, byteorder="little", signed=False)
        buffer_ += len(self._value).to_bytes(2, byteorder="little", signed=False)  # value_size
        buffer_ += self._value
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += "scoped_metadata_key: {}, ".format("0x{:X}".format(self._scoped_metadata_key))
        result += "target_namespace_id: {}, ".format(self._target_namespace_id.__str__())
        result += "value_size_delta: {}, ".format("0x{:X}".format(self._value_size_delta))
        result += "value: {}, ".format(hexlify(self._value).decode("utf8"))
        result += ")"
        return result


class EmbeddedNamespaceMetadataTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.NAMESPACE_METADATA
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "target_address": "pod:UnresolvedAddress",
        "target_namespace_id": "pod:NamespaceId",
        "value": "bytes_array"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedNamespaceMetadataTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedNamespaceMetadataTransaction.TRANSACTION_TYPE
        self._target_address = UnresolvedAddress()
        self._scoped_metadata_key = 0
        self._target_namespace_id = NamespaceId()
        self._value_size_delta = 0
        self._value = bytes()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def target_address(self) -> UnresolvedAddress:
        return self._target_address

    @property
    def scoped_metadata_key(self) -> int:
        return self._scoped_metadata_key

    @property
    def target_namespace_id(self) -> NamespaceId:
        return self._target_namespace_id

    @property
    def value_size_delta(self) -> int:
        return self._value_size_delta

    @property
    def value(self) -> bytes:
        return self._value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @target_address.setter
    def target_address(self, value: UnresolvedAddress):
        self._target_address = value

    @scoped_metadata_key.setter
    def scoped_metadata_key(self, value: int):
        self._scoped_metadata_key = value

    @target_namespace_id.setter
    def target_namespace_id(self, value: NamespaceId):
        self._target_namespace_id = value

    @value_size_delta.setter
    def value_size_delta(self, value: int):
        self._value_size_delta = value

    @value.setter
    def value(self, value: bytes):
        self._value = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.target_address.size()
        size += 8
        size += self.target_namespace_id.size()
        size += 2
        size += 2
        size += len(self._value)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedNamespaceMetadataTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        target_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]
        scoped_metadata_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        target_namespace_id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[target_namespace_id.size():]
        value_size_delta = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        value = ArrayHelpers.get_bytes(buffer_, value_size)
        buffer_ = buffer_[value_size:]

        instance = EmbeddedNamespaceMetadataTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._target_address = target_address
        instance._scoped_metadata_key = scoped_metadata_key
        instance._target_namespace_id = target_namespace_id
        instance._value_size_delta = value_size_delta
        instance._value = value
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._target_address.serialize()
        buffer_ += self._scoped_metadata_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._target_namespace_id.serialize()
        buffer_ += self._value_size_delta.to_bytes(2, byteorder="little", signed=False)
        buffer_ += len(self._value).to_bytes(2, byteorder="little", signed=False)  # value_size
        buffer_ += self._value
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += "scoped_metadata_key: {}, ".format("0x{:X}".format(self._scoped_metadata_key))
        result += "target_namespace_id: {}, ".format(self._target_namespace_id.__str__())
        result += "value_size_delta: {}, ".format("0x{:X}".format(self._value_size_delta))
        result += "value: {}, ".format(hexlify(self._value).decode("utf8"))
        result += ")"
        return result


class MosaicDefinitionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_DEFINITION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "id": "pod:MosaicId",
        "duration": "pod:BlockDuration",
        "nonce": "pod:MosaicNonce",
        "flags": "enum:MosaicFlags"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = MosaicDefinitionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = MosaicDefinitionTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._id = MosaicId()
        self._duration = BlockDuration()
        self._nonce = MosaicNonce()
        self._flags = MosaicFlags.NONE
        self._divisibility = 0
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def id(self) -> MosaicId:
        return self._id

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @property
    def nonce(self) -> MosaicNonce:
        return self._nonce

    @property
    def flags(self) -> MosaicFlags:
        return self._flags

    @property
    def divisibility(self) -> int:
        return self._divisibility

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @id.setter
    def id(self, value: MosaicId):
        self._id = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    @nonce.setter
    def nonce(self, value: MosaicNonce):
        self._nonce = value

    @flags.setter
    def flags(self, value: MosaicFlags):
        self._flags = value

    @divisibility.setter
    def divisibility(self, value: int):
        self._divisibility = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.id.size()
        size += self.duration.size()
        size += self.nonce.size()
        size += self.flags.size()
        size += 1
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicDefinitionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[id.size():]
        duration = BlockDuration.deserialize(buffer_)
        buffer_ = buffer_[duration.size():]
        nonce = MosaicNonce.deserialize(buffer_)
        buffer_ = buffer_[nonce.size():]
        flags = MosaicFlags.deserialize(buffer_)
        buffer_ = buffer_[flags.size():]
        divisibility = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]

        instance = MosaicDefinitionTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._id = id
        instance._duration = duration
        instance._nonce = nonce
        instance._flags = flags
        instance._divisibility = divisibility
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._id.serialize()
        buffer_ += self._duration.serialize()
        buffer_ += self._nonce.serialize()
        buffer_ += self._flags.serialize()
        buffer_ += self._divisibility.to_bytes(1, byteorder="little", signed=False)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "id: {}, ".format(self._id.__str__())
        result += "duration: {}, ".format(self._duration.__str__())
        result += "nonce: {}, ".format(self._nonce.__str__())
        result += "flags: {}, ".format(self._flags.__str__())
        result += "divisibility: {}, ".format("0x{:X}".format(self._divisibility))
        result += ")"
        return result


class EmbeddedMosaicDefinitionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_DEFINITION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "id": "pod:MosaicId",
        "duration": "pod:BlockDuration",
        "nonce": "pod:MosaicNonce",
        "flags": "enum:MosaicFlags"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedMosaicDefinitionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedMosaicDefinitionTransaction.TRANSACTION_TYPE
        self._id = MosaicId()
        self._duration = BlockDuration()
        self._nonce = MosaicNonce()
        self._flags = MosaicFlags.NONE
        self._divisibility = 0
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def id(self) -> MosaicId:
        return self._id

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @property
    def nonce(self) -> MosaicNonce:
        return self._nonce

    @property
    def flags(self) -> MosaicFlags:
        return self._flags

    @property
    def divisibility(self) -> int:
        return self._divisibility

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @id.setter
    def id(self, value: MosaicId):
        self._id = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    @nonce.setter
    def nonce(self, value: MosaicNonce):
        self._nonce = value

    @flags.setter
    def flags(self, value: MosaicFlags):
        self._flags = value

    @divisibility.setter
    def divisibility(self, value: int):
        self._divisibility = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.id.size()
        size += self.duration.size()
        size += self.nonce.size()
        size += self.flags.size()
        size += 1
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedMosaicDefinitionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[id.size():]
        duration = BlockDuration.deserialize(buffer_)
        buffer_ = buffer_[duration.size():]
        nonce = MosaicNonce.deserialize(buffer_)
        buffer_ = buffer_[nonce.size():]
        flags = MosaicFlags.deserialize(buffer_)
        buffer_ = buffer_[flags.size():]
        divisibility = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]

        instance = EmbeddedMosaicDefinitionTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._id = id
        instance._duration = duration
        instance._nonce = nonce
        instance._flags = flags
        instance._divisibility = divisibility
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._id.serialize()
        buffer_ += self._duration.serialize()
        buffer_ += self._nonce.serialize()
        buffer_ += self._flags.serialize()
        buffer_ += self._divisibility.to_bytes(1, byteorder="little", signed=False)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "id: {}, ".format(self._id.__str__())
        result += "duration: {}, ".format(self._duration.__str__())
        result += "nonce: {}, ".format(self._nonce.__str__())
        result += "flags: {}, ".format(self._flags.__str__())
        result += "divisibility: {}, ".format("0x{:X}".format(self._divisibility))
        result += ")"
        return result


class MosaicSupplyChangeTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_SUPPLY_CHANGE
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "mosaic_id": "pod:UnresolvedMosaicId",
        "delta": "pod:Amount",
        "action": "enum:MosaicSupplyChangeAction"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = MosaicSupplyChangeTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = MosaicSupplyChangeTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._mosaic_id = UnresolvedMosaicId()
        self._delta = Amount()
        self._action = MosaicSupplyChangeAction.DECREASE
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def mosaic_id(self) -> UnresolvedMosaicId:
        return self._mosaic_id

    @property
    def delta(self) -> Amount:
        return self._delta

    @property
    def action(self) -> MosaicSupplyChangeAction:
        return self._action

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @mosaic_id.setter
    def mosaic_id(self, value: UnresolvedMosaicId):
        self._mosaic_id = value

    @delta.setter
    def delta(self, value: Amount):
        self._delta = value

    @action.setter
    def action(self, value: MosaicSupplyChangeAction):
        self._action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.mosaic_id.size()
        size += self.delta.size()
        size += self.action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicSupplyChangeTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        delta = Amount.deserialize(buffer_)
        buffer_ = buffer_[delta.size():]
        action = MosaicSupplyChangeAction.deserialize(buffer_)
        buffer_ = buffer_[action.size():]

        instance = MosaicSupplyChangeTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._mosaic_id = mosaic_id
        instance._delta = delta
        instance._action = action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._delta.serialize()
        buffer_ += self._action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "delta: {}, ".format(self._delta.__str__())
        result += "action: {}, ".format(self._action.__str__())
        result += ")"
        return result


class EmbeddedMosaicSupplyChangeTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_SUPPLY_CHANGE
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "mosaic_id": "pod:UnresolvedMosaicId",
        "delta": "pod:Amount",
        "action": "enum:MosaicSupplyChangeAction"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedMosaicSupplyChangeTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedMosaicSupplyChangeTransaction.TRANSACTION_TYPE
        self._mosaic_id = UnresolvedMosaicId()
        self._delta = Amount()
        self._action = MosaicSupplyChangeAction.DECREASE
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def mosaic_id(self) -> UnresolvedMosaicId:
        return self._mosaic_id

    @property
    def delta(self) -> Amount:
        return self._delta

    @property
    def action(self) -> MosaicSupplyChangeAction:
        return self._action

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @mosaic_id.setter
    def mosaic_id(self, value: UnresolvedMosaicId):
        self._mosaic_id = value

    @delta.setter
    def delta(self, value: Amount):
        self._delta = value

    @action.setter
    def action(self, value: MosaicSupplyChangeAction):
        self._action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.mosaic_id.size()
        size += self.delta.size()
        size += self.action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedMosaicSupplyChangeTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        delta = Amount.deserialize(buffer_)
        buffer_ = buffer_[delta.size():]
        action = MosaicSupplyChangeAction.deserialize(buffer_)
        buffer_ = buffer_[action.size():]

        instance = EmbeddedMosaicSupplyChangeTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._mosaic_id = mosaic_id
        instance._delta = delta
        instance._action = action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._delta.serialize()
        buffer_ += self._action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "delta: {}, ".format(self._delta.__str__())
        result += "action: {}, ".format(self._action.__str__())
        result += ")"
        return result


class MosaicSupplyRevocationTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_SUPPLY_REVOCATION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "source_address": "pod:UnresolvedAddress",
        "mosaic": "struct:UnresolvedMosaic"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = MosaicSupplyRevocationTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = MosaicSupplyRevocationTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._source_address = UnresolvedAddress()
        self._mosaic = UnresolvedMosaic()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def source_address(self) -> UnresolvedAddress:
        return self._source_address

    @property
    def mosaic(self) -> UnresolvedMosaic:
        return self._mosaic

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @source_address.setter
    def source_address(self, value: UnresolvedAddress):
        self._source_address = value

    @mosaic.setter
    def mosaic(self, value: UnresolvedMosaic):
        self._mosaic = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.source_address.size()
        size += self.mosaic.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicSupplyRevocationTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        source_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[source_address.size():]
        mosaic = UnresolvedMosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]

        instance = MosaicSupplyRevocationTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._source_address = source_address
        instance._mosaic = mosaic
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._source_address.serialize()
        buffer_ += self._mosaic.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "source_address: {}, ".format(self._source_address.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += ")"
        return result


class EmbeddedMosaicSupplyRevocationTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_SUPPLY_REVOCATION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "source_address": "pod:UnresolvedAddress",
        "mosaic": "struct:UnresolvedMosaic"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedMosaicSupplyRevocationTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedMosaicSupplyRevocationTransaction.TRANSACTION_TYPE
        self._source_address = UnresolvedAddress()
        self._mosaic = UnresolvedMosaic()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def source_address(self) -> UnresolvedAddress:
        return self._source_address

    @property
    def mosaic(self) -> UnresolvedMosaic:
        return self._mosaic

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @source_address.setter
    def source_address(self, value: UnresolvedAddress):
        self._source_address = value

    @mosaic.setter
    def mosaic(self, value: UnresolvedMosaic):
        self._mosaic = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.source_address.size()
        size += self.mosaic.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedMosaicSupplyRevocationTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        source_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[source_address.size():]
        mosaic = UnresolvedMosaic.deserialize(buffer_)
        buffer_ = buffer_[mosaic.size():]

        instance = EmbeddedMosaicSupplyRevocationTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._source_address = source_address
        instance._mosaic = mosaic
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._source_address.serialize()
        buffer_ += self._mosaic.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "source_address: {}, ".format(self._source_address.__str__())
        result += "mosaic: {}, ".format(self._mosaic.__str__())
        result += ")"
        return result


class MultisigAccountModificationTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MULTISIG_ACCOUNT_MODIFICATION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "address_additions": "array[UnresolvedAddress]",
        "address_deletions": "array[UnresolvedAddress]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = MultisigAccountModificationTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = MultisigAccountModificationTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._min_removal_delta = 0
        self._min_approval_delta = 0
        self._address_additions = []
        self._address_deletions = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._multisig_account_modification_transaction_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def min_removal_delta(self) -> int:
        return self._min_removal_delta

    @property
    def min_approval_delta(self) -> int:
        return self._min_approval_delta

    @property
    def address_additions(self) -> List[UnresolvedAddress]:
        return self._address_additions

    @property
    def address_deletions(self) -> List[UnresolvedAddress]:
        return self._address_deletions

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @min_removal_delta.setter
    def min_removal_delta(self, value: int):
        self._min_removal_delta = value

    @min_approval_delta.setter
    def min_approval_delta(self, value: int):
        self._min_approval_delta = value

    @address_additions.setter
    def address_additions(self, value: List[UnresolvedAddress]):
        self._address_additions = value

    @address_deletions.setter
    def address_deletions(self, value: List[UnresolvedAddress]):
        self._address_deletions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += 1
        size += 1
        size += 1
        size += 1
        size += 4
        size += sum(map(lambda e: e.size(), self.address_additions))
        size += sum(map(lambda e: e.size(), self.address_deletions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MultisigAccountModificationTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        min_removal_delta = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        min_approval_delta = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        address_additions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        address_deletions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        multisig_account_modification_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert multisig_account_modification_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({multisig_account_modification_transaction_body_reserved_1})"
        address_additions = ArrayHelpers.read_array_count(buffer_, UnresolvedAddress, address_additions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), address_additions)):]
        address_deletions = ArrayHelpers.read_array_count(buffer_, UnresolvedAddress, address_deletions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), address_deletions)):]

        instance = MultisigAccountModificationTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._min_removal_delta = min_removal_delta
        instance._min_approval_delta = min_approval_delta
        instance._address_additions = address_additions
        instance._address_deletions = address_deletions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._min_removal_delta.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._min_approval_delta.to_bytes(1, byteorder="little", signed=False)
        buffer_ += len(self._address_additions).to_bytes(1, byteorder="little", signed=False)  # address_additions_count
        buffer_ += len(self._address_deletions).to_bytes(1, byteorder="little", signed=False)  # address_deletions_count
        buffer_ += self._multisig_account_modification_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._address_additions)
        buffer_ += ArrayHelpers.write_array(self._address_deletions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "min_removal_delta: {}, ".format("0x{:X}".format(self._min_removal_delta))
        result += "min_approval_delta: {}, ".format("0x{:X}".format(self._min_approval_delta))
        result += "address_additions: {}, ".format(list(map(str, self._address_additions)))
        result += "address_deletions: {}, ".format(list(map(str, self._address_deletions)))
        result += ")"
        return result


class EmbeddedMultisigAccountModificationTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MULTISIG_ACCOUNT_MODIFICATION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "address_additions": "array[UnresolvedAddress]",
        "address_deletions": "array[UnresolvedAddress]"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedMultisigAccountModificationTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedMultisigAccountModificationTransaction.TRANSACTION_TYPE
        self._min_removal_delta = 0
        self._min_approval_delta = 0
        self._address_additions = []
        self._address_deletions = []
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._multisig_account_modification_transaction_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def min_removal_delta(self) -> int:
        return self._min_removal_delta

    @property
    def min_approval_delta(self) -> int:
        return self._min_approval_delta

    @property
    def address_additions(self) -> List[UnresolvedAddress]:
        return self._address_additions

    @property
    def address_deletions(self) -> List[UnresolvedAddress]:
        return self._address_deletions

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @min_removal_delta.setter
    def min_removal_delta(self, value: int):
        self._min_removal_delta = value

    @min_approval_delta.setter
    def min_approval_delta(self, value: int):
        self._min_approval_delta = value

    @address_additions.setter
    def address_additions(self, value: List[UnresolvedAddress]):
        self._address_additions = value

    @address_deletions.setter
    def address_deletions(self, value: List[UnresolvedAddress]):
        self._address_deletions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += 1
        size += 1
        size += 1
        size += 1
        size += 4
        size += sum(map(lambda e: e.size(), self.address_additions))
        size += sum(map(lambda e: e.size(), self.address_deletions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedMultisigAccountModificationTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        min_removal_delta = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        min_approval_delta = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        address_additions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        address_deletions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        multisig_account_modification_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert multisig_account_modification_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({multisig_account_modification_transaction_body_reserved_1})"
        address_additions = ArrayHelpers.read_array_count(buffer_, UnresolvedAddress, address_additions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), address_additions)):]
        address_deletions = ArrayHelpers.read_array_count(buffer_, UnresolvedAddress, address_deletions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), address_deletions)):]

        instance = EmbeddedMultisigAccountModificationTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._min_removal_delta = min_removal_delta
        instance._min_approval_delta = min_approval_delta
        instance._address_additions = address_additions
        instance._address_deletions = address_deletions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._min_removal_delta.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._min_approval_delta.to_bytes(1, byteorder="little", signed=False)
        buffer_ += len(self._address_additions).to_bytes(1, byteorder="little", signed=False)  # address_additions_count
        buffer_ += len(self._address_deletions).to_bytes(1, byteorder="little", signed=False)  # address_deletions_count
        buffer_ += self._multisig_account_modification_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._address_additions)
        buffer_ += ArrayHelpers.write_array(self._address_deletions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "min_removal_delta: {}, ".format("0x{:X}".format(self._min_removal_delta))
        result += "min_approval_delta: {}, ".format("0x{:X}".format(self._min_approval_delta))
        result += "address_additions: {}, ".format(list(map(str, self._address_additions)))
        result += "address_deletions: {}, ".format(list(map(str, self._address_deletions)))
        result += ")"
        return result


class AddressAliasTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ADDRESS_ALIAS
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "namespace_id": "pod:NamespaceId",
        "address": "pod:Address",
        "alias_action": "enum:AliasAction"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = AddressAliasTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = AddressAliasTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._namespace_id = NamespaceId()
        self._address = Address()
        self._alias_action = AliasAction.UNLINK
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def namespace_id(self) -> NamespaceId:
        return self._namespace_id

    @property
    def address(self) -> Address:
        return self._address

    @property
    def alias_action(self) -> AliasAction:
        return self._alias_action

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @namespace_id.setter
    def namespace_id(self, value: NamespaceId):
        self._namespace_id = value

    @address.setter
    def address(self, value: Address):
        self._address = value

    @alias_action.setter
    def alias_action(self, value: AliasAction):
        self._alias_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.namespace_id.size()
        size += self.address.size()
        size += self.alias_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AddressAliasTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        namespace_id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[namespace_id.size():]
        address = Address.deserialize(buffer_)
        buffer_ = buffer_[address.size():]
        alias_action = AliasAction.deserialize(buffer_)
        buffer_ = buffer_[alias_action.size():]

        instance = AddressAliasTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._namespace_id = namespace_id
        instance._address = address
        instance._alias_action = alias_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._namespace_id.serialize()
        buffer_ += self._address.serialize()
        buffer_ += self._alias_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "namespace_id: {}, ".format(self._namespace_id.__str__())
        result += "address: {}, ".format(self._address.__str__())
        result += "alias_action: {}, ".format(self._alias_action.__str__())
        result += ")"
        return result


class EmbeddedAddressAliasTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ADDRESS_ALIAS
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "namespace_id": "pod:NamespaceId",
        "address": "pod:Address",
        "alias_action": "enum:AliasAction"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedAddressAliasTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedAddressAliasTransaction.TRANSACTION_TYPE
        self._namespace_id = NamespaceId()
        self._address = Address()
        self._alias_action = AliasAction.UNLINK
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def namespace_id(self) -> NamespaceId:
        return self._namespace_id

    @property
    def address(self) -> Address:
        return self._address

    @property
    def alias_action(self) -> AliasAction:
        return self._alias_action

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @namespace_id.setter
    def namespace_id(self, value: NamespaceId):
        self._namespace_id = value

    @address.setter
    def address(self, value: Address):
        self._address = value

    @alias_action.setter
    def alias_action(self, value: AliasAction):
        self._alias_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.namespace_id.size()
        size += self.address.size()
        size += self.alias_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedAddressAliasTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        namespace_id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[namespace_id.size():]
        address = Address.deserialize(buffer_)
        buffer_ = buffer_[address.size():]
        alias_action = AliasAction.deserialize(buffer_)
        buffer_ = buffer_[alias_action.size():]

        instance = EmbeddedAddressAliasTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._namespace_id = namespace_id
        instance._address = address
        instance._alias_action = alias_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._namespace_id.serialize()
        buffer_ += self._address.serialize()
        buffer_ += self._alias_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "namespace_id: {}, ".format(self._namespace_id.__str__())
        result += "address: {}, ".format(self._address.__str__())
        result += "alias_action: {}, ".format(self._alias_action.__str__())
        result += ")"
        return result


class MosaicAliasTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_ALIAS
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "namespace_id": "pod:NamespaceId",
        "mosaic_id": "pod:MosaicId",
        "alias_action": "enum:AliasAction"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = MosaicAliasTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = MosaicAliasTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._namespace_id = NamespaceId()
        self._mosaic_id = MosaicId()
        self._alias_action = AliasAction.UNLINK
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def namespace_id(self) -> NamespaceId:
        return self._namespace_id

    @property
    def mosaic_id(self) -> MosaicId:
        return self._mosaic_id

    @property
    def alias_action(self) -> AliasAction:
        return self._alias_action

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @namespace_id.setter
    def namespace_id(self, value: NamespaceId):
        self._namespace_id = value

    @mosaic_id.setter
    def mosaic_id(self, value: MosaicId):
        self._mosaic_id = value

    @alias_action.setter
    def alias_action(self, value: AliasAction):
        self._alias_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.namespace_id.size()
        size += self.mosaic_id.size()
        size += self.alias_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicAliasTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        namespace_id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[namespace_id.size():]
        mosaic_id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        alias_action = AliasAction.deserialize(buffer_)
        buffer_ = buffer_[alias_action.size():]

        instance = MosaicAliasTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._namespace_id = namespace_id
        instance._mosaic_id = mosaic_id
        instance._alias_action = alias_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._namespace_id.serialize()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._alias_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "namespace_id: {}, ".format(self._namespace_id.__str__())
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "alias_action: {}, ".format(self._alias_action.__str__())
        result += ")"
        return result


class EmbeddedMosaicAliasTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_ALIAS
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "namespace_id": "pod:NamespaceId",
        "mosaic_id": "pod:MosaicId",
        "alias_action": "enum:AliasAction"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedMosaicAliasTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedMosaicAliasTransaction.TRANSACTION_TYPE
        self._namespace_id = NamespaceId()
        self._mosaic_id = MosaicId()
        self._alias_action = AliasAction.UNLINK
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def namespace_id(self) -> NamespaceId:
        return self._namespace_id

    @property
    def mosaic_id(self) -> MosaicId:
        return self._mosaic_id

    @property
    def alias_action(self) -> AliasAction:
        return self._alias_action

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @namespace_id.setter
    def namespace_id(self, value: NamespaceId):
        self._namespace_id = value

    @mosaic_id.setter
    def mosaic_id(self, value: MosaicId):
        self._mosaic_id = value

    @alias_action.setter
    def alias_action(self, value: AliasAction):
        self._alias_action = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.namespace_id.size()
        size += self.mosaic_id.size()
        size += self.alias_action.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedMosaicAliasTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        namespace_id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[namespace_id.size():]
        mosaic_id = MosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        alias_action = AliasAction.deserialize(buffer_)
        buffer_ = buffer_[alias_action.size():]

        instance = EmbeddedMosaicAliasTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._namespace_id = namespace_id
        instance._mosaic_id = mosaic_id
        instance._alias_action = alias_action
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._namespace_id.serialize()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._alias_action.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "namespace_id: {}, ".format(self._namespace_id.__str__())
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "alias_action: {}, ".format(self._alias_action.__str__())
        result += ")"
        return result


class NamespaceRegistrationTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.NAMESPACE_REGISTRATION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "duration": "pod:BlockDuration",
        "parent_id": "pod:NamespaceId",
        "id": "pod:NamespaceId",
        "registration_type": "enum:NamespaceRegistrationType",
        "name": "bytes_array"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = NamespaceRegistrationTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = NamespaceRegistrationTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._duration = BlockDuration()
        self._parent_id = NamespaceId()
        self._id = NamespaceId()
        self._registration_type = NamespaceRegistrationType.ROOT
        self._name = bytes()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @property
    def parent_id(self) -> NamespaceId:
        return self._parent_id

    @property
    def id(self) -> NamespaceId:
        return self._id

    @property
    def registration_type(self) -> NamespaceRegistrationType:
        return self._registration_type

    @property
    def name(self) -> bytes:
        return self._name

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    @parent_id.setter
    def parent_id(self, value: NamespaceId):
        self._parent_id = value

    @id.setter
    def id(self, value: NamespaceId):
        self._id = value

    @registration_type.setter
    def registration_type(self, value: NamespaceRegistrationType):
        self._registration_type = value

    @name.setter
    def name(self, value: bytes):
        self._name = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        if NamespaceRegistrationType.ROOT == self.registration_type:
            size += self.duration.size()
        if NamespaceRegistrationType.CHILD == self.registration_type:
            size += self.parent_id.size()
        size += self.id.size()
        size += self.registration_type.size()
        size += 1
        size += len(self._name)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> NamespaceRegistrationTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        # deserialize to temporary buffer for further processing
        duration_temporary = BlockDuration.deserialize(buffer_)
        registration_type_condition = buffer_[:duration_temporary.size()]
        buffer_ = buffer_[duration_temporary.size():]

        id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[id.size():]
        registration_type = NamespaceRegistrationType.deserialize(buffer_)
        buffer_ = buffer_[registration_type.size():]
        duration = None
        if NamespaceRegistrationType.ROOT == registration_type:
            duration = BlockDuration.deserialize(registration_type_condition)
            registration_type_condition = registration_type_condition[duration.size():]
        parent_id = None
        if NamespaceRegistrationType.CHILD == registration_type:
            parent_id = NamespaceId.deserialize(registration_type_condition)
            registration_type_condition = registration_type_condition[parent_id.size():]
        name_size = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        name = ArrayHelpers.get_bytes(buffer_, name_size)
        buffer_ = buffer_[name_size:]

        instance = NamespaceRegistrationTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._duration = duration
        instance._parent_id = parent_id
        instance._id = id
        instance._registration_type = registration_type
        instance._name = name
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        if NamespaceRegistrationType.ROOT == self.registration_type:
            buffer_ += self._duration.serialize()
        if NamespaceRegistrationType.CHILD == self.registration_type:
            buffer_ += self._parent_id.serialize()
        buffer_ += self._id.serialize()
        buffer_ += self._registration_type.serialize()
        buffer_ += len(self._name).to_bytes(1, byteorder="little", signed=False)  # name_size
        buffer_ += self._name
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "duration: {}, ".format(self._duration.__str__())
        result += "parent_id: {}, ".format(self._parent_id.__str__())
        result += "id: {}, ".format(self._id.__str__())
        result += "registration_type: {}, ".format(self._registration_type.__str__())
        result += "name: {}, ".format(hexlify(self._name).decode("utf8"))
        result += ")"
        return result


class EmbeddedNamespaceRegistrationTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.NAMESPACE_REGISTRATION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "duration": "pod:BlockDuration",
        "parent_id": "pod:NamespaceId",
        "id": "pod:NamespaceId",
        "registration_type": "enum:NamespaceRegistrationType",
        "name": "bytes_array"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedNamespaceRegistrationTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedNamespaceRegistrationTransaction.TRANSACTION_TYPE
        self._duration = BlockDuration()
        self._parent_id = NamespaceId()
        self._id = NamespaceId()
        self._registration_type = NamespaceRegistrationType.ROOT
        self._name = bytes()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def duration(self) -> BlockDuration:
        return self._duration

    @property
    def parent_id(self) -> NamespaceId:
        return self._parent_id

    @property
    def id(self) -> NamespaceId:
        return self._id

    @property
    def registration_type(self) -> NamespaceRegistrationType:
        return self._registration_type

    @property
    def name(self) -> bytes:
        return self._name

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @duration.setter
    def duration(self, value: BlockDuration):
        self._duration = value

    @parent_id.setter
    def parent_id(self, value: NamespaceId):
        self._parent_id = value

    @id.setter
    def id(self, value: NamespaceId):
        self._id = value

    @registration_type.setter
    def registration_type(self, value: NamespaceRegistrationType):
        self._registration_type = value

    @name.setter
    def name(self, value: bytes):
        self._name = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        if NamespaceRegistrationType.ROOT == self.registration_type:
            size += self.duration.size()
        if NamespaceRegistrationType.CHILD == self.registration_type:
            size += self.parent_id.size()
        size += self.id.size()
        size += self.registration_type.size()
        size += 1
        size += len(self._name)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedNamespaceRegistrationTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        # deserialize to temporary buffer for further processing
        duration_temporary = BlockDuration.deserialize(buffer_)
        registration_type_condition = buffer_[:duration_temporary.size()]
        buffer_ = buffer_[duration_temporary.size():]

        id = NamespaceId.deserialize(buffer_)
        buffer_ = buffer_[id.size():]
        registration_type = NamespaceRegistrationType.deserialize(buffer_)
        buffer_ = buffer_[registration_type.size():]
        duration = None
        if NamespaceRegistrationType.ROOT == registration_type:
            duration = BlockDuration.deserialize(registration_type_condition)
            registration_type_condition = registration_type_condition[duration.size():]
        parent_id = None
        if NamespaceRegistrationType.CHILD == registration_type:
            parent_id = NamespaceId.deserialize(registration_type_condition)
            registration_type_condition = registration_type_condition[parent_id.size():]
        name_size = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        name = ArrayHelpers.get_bytes(buffer_, name_size)
        buffer_ = buffer_[name_size:]

        instance = EmbeddedNamespaceRegistrationTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._duration = duration
        instance._parent_id = parent_id
        instance._id = id
        instance._registration_type = registration_type
        instance._name = name
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        if NamespaceRegistrationType.ROOT == self.registration_type:
            buffer_ += self._duration.serialize()
        if NamespaceRegistrationType.CHILD == self.registration_type:
            buffer_ += self._parent_id.serialize()
        buffer_ += self._id.serialize()
        buffer_ += self._registration_type.serialize()
        buffer_ += len(self._name).to_bytes(1, byteorder="little", signed=False)  # name_size
        buffer_ += self._name
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "duration: {}, ".format(self._duration.__str__())
        result += "parent_id: {}, ".format(self._parent_id.__str__())
        result += "id: {}, ".format(self._id.__str__())
        result += "registration_type: {}, ".format(self._registration_type.__str__())
        result += "name: {}, ".format(hexlify(self._name).decode("utf8"))
        result += ")"
        return result


class AccountAddressRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_ADDRESS_RESTRICTION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "restriction_flags": "enum:AccountRestrictionFlags",
        "restriction_additions": "array[UnresolvedAddress]",
        "restriction_deletions": "array[UnresolvedAddress]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = AccountAddressRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = AccountAddressRestrictionTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._restriction_flags = AccountRestrictionFlags.ADDRESS
        self._restriction_additions = []
        self._restriction_deletions = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._account_restriction_transaction_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def restriction_flags(self) -> AccountRestrictionFlags:
        return self._restriction_flags

    @property
    def restriction_additions(self) -> List[UnresolvedAddress]:
        return self._restriction_additions

    @property
    def restriction_deletions(self) -> List[UnresolvedAddress]:
        return self._restriction_deletions

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @restriction_flags.setter
    def restriction_flags(self, value: AccountRestrictionFlags):
        self._restriction_flags = value

    @restriction_additions.setter
    def restriction_additions(self, value: List[UnresolvedAddress]):
        self._restriction_additions = value

    @restriction_deletions.setter
    def restriction_deletions(self, value: List[UnresolvedAddress]):
        self._restriction_deletions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.restriction_flags.size()
        size += 1
        size += 1
        size += 4
        size += sum(map(lambda e: e.size(), self.restriction_additions))
        size += sum(map(lambda e: e.size(), self.restriction_deletions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountAddressRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        restriction_flags = AccountRestrictionFlags.deserialize(buffer_)
        buffer_ = buffer_[restriction_flags.size():]
        restriction_additions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        restriction_deletions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        account_restriction_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert account_restriction_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({account_restriction_transaction_body_reserved_1})"
        restriction_additions = ArrayHelpers.read_array_count(buffer_, UnresolvedAddress, restriction_additions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_additions)):]
        restriction_deletions = ArrayHelpers.read_array_count(buffer_, UnresolvedAddress, restriction_deletions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_deletions)):]

        instance = AccountAddressRestrictionTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._restriction_flags = restriction_flags
        instance._restriction_additions = restriction_additions
        instance._restriction_deletions = restriction_deletions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._restriction_flags.serialize()
        buffer_ += len(self._restriction_additions).to_bytes(1, byteorder="little", signed=False)  # restriction_additions_count
        buffer_ += len(self._restriction_deletions).to_bytes(1, byteorder="little", signed=False)  # restriction_deletions_count
        buffer_ += self._account_restriction_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._restriction_additions)
        buffer_ += ArrayHelpers.write_array(self._restriction_deletions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "restriction_flags: {}, ".format(self._restriction_flags.__str__())
        result += "restriction_additions: {}, ".format(list(map(str, self._restriction_additions)))
        result += "restriction_deletions: {}, ".format(list(map(str, self._restriction_deletions)))
        result += ")"
        return result


class EmbeddedAccountAddressRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_ADDRESS_RESTRICTION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "restriction_flags": "enum:AccountRestrictionFlags",
        "restriction_additions": "array[UnresolvedAddress]",
        "restriction_deletions": "array[UnresolvedAddress]"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedAccountAddressRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedAccountAddressRestrictionTransaction.TRANSACTION_TYPE
        self._restriction_flags = AccountRestrictionFlags.ADDRESS
        self._restriction_additions = []
        self._restriction_deletions = []
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._account_restriction_transaction_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def restriction_flags(self) -> AccountRestrictionFlags:
        return self._restriction_flags

    @property
    def restriction_additions(self) -> List[UnresolvedAddress]:
        return self._restriction_additions

    @property
    def restriction_deletions(self) -> List[UnresolvedAddress]:
        return self._restriction_deletions

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @restriction_flags.setter
    def restriction_flags(self, value: AccountRestrictionFlags):
        self._restriction_flags = value

    @restriction_additions.setter
    def restriction_additions(self, value: List[UnresolvedAddress]):
        self._restriction_additions = value

    @restriction_deletions.setter
    def restriction_deletions(self, value: List[UnresolvedAddress]):
        self._restriction_deletions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.restriction_flags.size()
        size += 1
        size += 1
        size += 4
        size += sum(map(lambda e: e.size(), self.restriction_additions))
        size += sum(map(lambda e: e.size(), self.restriction_deletions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedAccountAddressRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        restriction_flags = AccountRestrictionFlags.deserialize(buffer_)
        buffer_ = buffer_[restriction_flags.size():]
        restriction_additions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        restriction_deletions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        account_restriction_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert account_restriction_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({account_restriction_transaction_body_reserved_1})"
        restriction_additions = ArrayHelpers.read_array_count(buffer_, UnresolvedAddress, restriction_additions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_additions)):]
        restriction_deletions = ArrayHelpers.read_array_count(buffer_, UnresolvedAddress, restriction_deletions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_deletions)):]

        instance = EmbeddedAccountAddressRestrictionTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._restriction_flags = restriction_flags
        instance._restriction_additions = restriction_additions
        instance._restriction_deletions = restriction_deletions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._restriction_flags.serialize()
        buffer_ += len(self._restriction_additions).to_bytes(1, byteorder="little", signed=False)  # restriction_additions_count
        buffer_ += len(self._restriction_deletions).to_bytes(1, byteorder="little", signed=False)  # restriction_deletions_count
        buffer_ += self._account_restriction_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._restriction_additions)
        buffer_ += ArrayHelpers.write_array(self._restriction_deletions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "restriction_flags: {}, ".format(self._restriction_flags.__str__())
        result += "restriction_additions: {}, ".format(list(map(str, self._restriction_additions)))
        result += "restriction_deletions: {}, ".format(list(map(str, self._restriction_deletions)))
        result += ")"
        return result


class AccountMosaicRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_MOSAIC_RESTRICTION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "restriction_flags": "enum:AccountRestrictionFlags",
        "restriction_additions": "array[UnresolvedMosaicId]",
        "restriction_deletions": "array[UnresolvedMosaicId]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = AccountMosaicRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = AccountMosaicRestrictionTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._restriction_flags = AccountRestrictionFlags.ADDRESS
        self._restriction_additions = []
        self._restriction_deletions = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._account_restriction_transaction_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def restriction_flags(self) -> AccountRestrictionFlags:
        return self._restriction_flags

    @property
    def restriction_additions(self) -> List[UnresolvedMosaicId]:
        return self._restriction_additions

    @property
    def restriction_deletions(self) -> List[UnresolvedMosaicId]:
        return self._restriction_deletions

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @restriction_flags.setter
    def restriction_flags(self, value: AccountRestrictionFlags):
        self._restriction_flags = value

    @restriction_additions.setter
    def restriction_additions(self, value: List[UnresolvedMosaicId]):
        self._restriction_additions = value

    @restriction_deletions.setter
    def restriction_deletions(self, value: List[UnresolvedMosaicId]):
        self._restriction_deletions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.restriction_flags.size()
        size += 1
        size += 1
        size += 4
        size += sum(map(lambda e: e.size(), self.restriction_additions))
        size += sum(map(lambda e: e.size(), self.restriction_deletions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountMosaicRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        restriction_flags = AccountRestrictionFlags.deserialize(buffer_)
        buffer_ = buffer_[restriction_flags.size():]
        restriction_additions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        restriction_deletions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        account_restriction_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert account_restriction_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({account_restriction_transaction_body_reserved_1})"
        restriction_additions = ArrayHelpers.read_array_count(buffer_, UnresolvedMosaicId, restriction_additions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_additions)):]
        restriction_deletions = ArrayHelpers.read_array_count(buffer_, UnresolvedMosaicId, restriction_deletions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_deletions)):]

        instance = AccountMosaicRestrictionTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._restriction_flags = restriction_flags
        instance._restriction_additions = restriction_additions
        instance._restriction_deletions = restriction_deletions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._restriction_flags.serialize()
        buffer_ += len(self._restriction_additions).to_bytes(1, byteorder="little", signed=False)  # restriction_additions_count
        buffer_ += len(self._restriction_deletions).to_bytes(1, byteorder="little", signed=False)  # restriction_deletions_count
        buffer_ += self._account_restriction_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._restriction_additions)
        buffer_ += ArrayHelpers.write_array(self._restriction_deletions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "restriction_flags: {}, ".format(self._restriction_flags.__str__())
        result += "restriction_additions: {}, ".format(list(map(str, self._restriction_additions)))
        result += "restriction_deletions: {}, ".format(list(map(str, self._restriction_deletions)))
        result += ")"
        return result


class EmbeddedAccountMosaicRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_MOSAIC_RESTRICTION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "restriction_flags": "enum:AccountRestrictionFlags",
        "restriction_additions": "array[UnresolvedMosaicId]",
        "restriction_deletions": "array[UnresolvedMosaicId]"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedAccountMosaicRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedAccountMosaicRestrictionTransaction.TRANSACTION_TYPE
        self._restriction_flags = AccountRestrictionFlags.ADDRESS
        self._restriction_additions = []
        self._restriction_deletions = []
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._account_restriction_transaction_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def restriction_flags(self) -> AccountRestrictionFlags:
        return self._restriction_flags

    @property
    def restriction_additions(self) -> List[UnresolvedMosaicId]:
        return self._restriction_additions

    @property
    def restriction_deletions(self) -> List[UnresolvedMosaicId]:
        return self._restriction_deletions

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @restriction_flags.setter
    def restriction_flags(self, value: AccountRestrictionFlags):
        self._restriction_flags = value

    @restriction_additions.setter
    def restriction_additions(self, value: List[UnresolvedMosaicId]):
        self._restriction_additions = value

    @restriction_deletions.setter
    def restriction_deletions(self, value: List[UnresolvedMosaicId]):
        self._restriction_deletions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.restriction_flags.size()
        size += 1
        size += 1
        size += 4
        size += sum(map(lambda e: e.size(), self.restriction_additions))
        size += sum(map(lambda e: e.size(), self.restriction_deletions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedAccountMosaicRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        restriction_flags = AccountRestrictionFlags.deserialize(buffer_)
        buffer_ = buffer_[restriction_flags.size():]
        restriction_additions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        restriction_deletions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        account_restriction_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert account_restriction_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({account_restriction_transaction_body_reserved_1})"
        restriction_additions = ArrayHelpers.read_array_count(buffer_, UnresolvedMosaicId, restriction_additions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_additions)):]
        restriction_deletions = ArrayHelpers.read_array_count(buffer_, UnresolvedMosaicId, restriction_deletions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_deletions)):]

        instance = EmbeddedAccountMosaicRestrictionTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._restriction_flags = restriction_flags
        instance._restriction_additions = restriction_additions
        instance._restriction_deletions = restriction_deletions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._restriction_flags.serialize()
        buffer_ += len(self._restriction_additions).to_bytes(1, byteorder="little", signed=False)  # restriction_additions_count
        buffer_ += len(self._restriction_deletions).to_bytes(1, byteorder="little", signed=False)  # restriction_deletions_count
        buffer_ += self._account_restriction_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._restriction_additions)
        buffer_ += ArrayHelpers.write_array(self._restriction_deletions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "restriction_flags: {}, ".format(self._restriction_flags.__str__())
        result += "restriction_additions: {}, ".format(list(map(str, self._restriction_additions)))
        result += "restriction_deletions: {}, ".format(list(map(str, self._restriction_deletions)))
        result += ")"
        return result


class AccountOperationRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_OPERATION_RESTRICTION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "restriction_flags": "enum:AccountRestrictionFlags",
        "restriction_additions": "array[TransactionType]",
        "restriction_deletions": "array[TransactionType]"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = AccountOperationRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = AccountOperationRestrictionTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._restriction_flags = AccountRestrictionFlags.ADDRESS
        self._restriction_additions = []
        self._restriction_deletions = []
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._account_restriction_transaction_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def restriction_flags(self) -> AccountRestrictionFlags:
        return self._restriction_flags

    @property
    def restriction_additions(self) -> List[TransactionType]:
        return self._restriction_additions

    @property
    def restriction_deletions(self) -> List[TransactionType]:
        return self._restriction_deletions

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @restriction_flags.setter
    def restriction_flags(self, value: AccountRestrictionFlags):
        self._restriction_flags = value

    @restriction_additions.setter
    def restriction_additions(self, value: List[TransactionType]):
        self._restriction_additions = value

    @restriction_deletions.setter
    def restriction_deletions(self, value: List[TransactionType]):
        self._restriction_deletions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.restriction_flags.size()
        size += 1
        size += 1
        size += 4
        size += sum(map(lambda e: e.size(), self.restriction_additions))
        size += sum(map(lambda e: e.size(), self.restriction_deletions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> AccountOperationRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        restriction_flags = AccountRestrictionFlags.deserialize(buffer_)
        buffer_ = buffer_[restriction_flags.size():]
        restriction_additions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        restriction_deletions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        account_restriction_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert account_restriction_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({account_restriction_transaction_body_reserved_1})"
        restriction_additions = ArrayHelpers.read_array_count(buffer_, TransactionType, restriction_additions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_additions)):]
        restriction_deletions = ArrayHelpers.read_array_count(buffer_, TransactionType, restriction_deletions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_deletions)):]

        instance = AccountOperationRestrictionTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._restriction_flags = restriction_flags
        instance._restriction_additions = restriction_additions
        instance._restriction_deletions = restriction_deletions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._restriction_flags.serialize()
        buffer_ += len(self._restriction_additions).to_bytes(1, byteorder="little", signed=False)  # restriction_additions_count
        buffer_ += len(self._restriction_deletions).to_bytes(1, byteorder="little", signed=False)  # restriction_deletions_count
        buffer_ += self._account_restriction_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._restriction_additions)
        buffer_ += ArrayHelpers.write_array(self._restriction_deletions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "restriction_flags: {}, ".format(self._restriction_flags.__str__())
        result += "restriction_additions: {}, ".format(list(map(str, self._restriction_additions)))
        result += "restriction_deletions: {}, ".format(list(map(str, self._restriction_deletions)))
        result += ")"
        return result


class EmbeddedAccountOperationRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.ACCOUNT_OPERATION_RESTRICTION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "restriction_flags": "enum:AccountRestrictionFlags",
        "restriction_additions": "array[TransactionType]",
        "restriction_deletions": "array[TransactionType]"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedAccountOperationRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedAccountOperationRestrictionTransaction.TRANSACTION_TYPE
        self._restriction_flags = AccountRestrictionFlags.ADDRESS
        self._restriction_additions = []
        self._restriction_deletions = []
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._account_restriction_transaction_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def restriction_flags(self) -> AccountRestrictionFlags:
        return self._restriction_flags

    @property
    def restriction_additions(self) -> List[TransactionType]:
        return self._restriction_additions

    @property
    def restriction_deletions(self) -> List[TransactionType]:
        return self._restriction_deletions

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @restriction_flags.setter
    def restriction_flags(self, value: AccountRestrictionFlags):
        self._restriction_flags = value

    @restriction_additions.setter
    def restriction_additions(self, value: List[TransactionType]):
        self._restriction_additions = value

    @restriction_deletions.setter
    def restriction_deletions(self, value: List[TransactionType]):
        self._restriction_deletions = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.restriction_flags.size()
        size += 1
        size += 1
        size += 4
        size += sum(map(lambda e: e.size(), self.restriction_additions))
        size += sum(map(lambda e: e.size(), self.restriction_deletions))
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedAccountOperationRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        restriction_flags = AccountRestrictionFlags.deserialize(buffer_)
        buffer_ = buffer_[restriction_flags.size():]
        restriction_additions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        restriction_deletions_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        account_restriction_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert account_restriction_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({account_restriction_transaction_body_reserved_1})"
        restriction_additions = ArrayHelpers.read_array_count(buffer_, TransactionType, restriction_additions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_additions)):]
        restriction_deletions = ArrayHelpers.read_array_count(buffer_, TransactionType, restriction_deletions_count)
        buffer_ = buffer_[sum(map(lambda e: e.size(), restriction_deletions)):]

        instance = EmbeddedAccountOperationRestrictionTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._restriction_flags = restriction_flags
        instance._restriction_additions = restriction_additions
        instance._restriction_deletions = restriction_deletions
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._restriction_flags.serialize()
        buffer_ += len(self._restriction_additions).to_bytes(1, byteorder="little", signed=False)  # restriction_additions_count
        buffer_ += len(self._restriction_deletions).to_bytes(1, byteorder="little", signed=False)  # restriction_deletions_count
        buffer_ += self._account_restriction_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._restriction_additions)
        buffer_ += ArrayHelpers.write_array(self._restriction_deletions)
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "restriction_flags: {}, ".format(self._restriction_flags.__str__())
        result += "restriction_additions: {}, ".format(list(map(str, self._restriction_additions)))
        result += "restriction_deletions: {}, ".format(list(map(str, self._restriction_deletions)))
        result += ")"
        return result


class MosaicAddressRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_ADDRESS_RESTRICTION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "mosaic_id": "pod:UnresolvedMosaicId",
        "target_address": "pod:UnresolvedAddress"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = MosaicAddressRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = MosaicAddressRestrictionTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._mosaic_id = UnresolvedMosaicId()
        self._restriction_key = 0
        self._previous_restriction_value = 0
        self._new_restriction_value = 0
        self._target_address = UnresolvedAddress()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def mosaic_id(self) -> UnresolvedMosaicId:
        return self._mosaic_id

    @property
    def restriction_key(self) -> int:
        return self._restriction_key

    @property
    def previous_restriction_value(self) -> int:
        return self._previous_restriction_value

    @property
    def new_restriction_value(self) -> int:
        return self._new_restriction_value

    @property
    def target_address(self) -> UnresolvedAddress:
        return self._target_address

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @mosaic_id.setter
    def mosaic_id(self, value: UnresolvedMosaicId):
        self._mosaic_id = value

    @restriction_key.setter
    def restriction_key(self, value: int):
        self._restriction_key = value

    @previous_restriction_value.setter
    def previous_restriction_value(self, value: int):
        self._previous_restriction_value = value

    @new_restriction_value.setter
    def new_restriction_value(self, value: int):
        self._new_restriction_value = value

    @target_address.setter
    def target_address(self, value: UnresolvedAddress):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.mosaic_id.size()
        size += 8
        size += 8
        size += 8
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicAddressRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        restriction_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        previous_restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        new_restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        target_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = MosaicAddressRestrictionTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._mosaic_id = mosaic_id
        instance._restriction_key = restriction_key
        instance._previous_restriction_value = previous_restriction_value
        instance._new_restriction_value = new_restriction_value
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._restriction_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._previous_restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._new_restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "restriction_key: {}, ".format("0x{:X}".format(self._restriction_key))
        result += "previous_restriction_value: {}, ".format("0x{:X}".format(self._previous_restriction_value))
        result += "new_restriction_value: {}, ".format("0x{:X}".format(self._new_restriction_value))
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class EmbeddedMosaicAddressRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_ADDRESS_RESTRICTION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "mosaic_id": "pod:UnresolvedMosaicId",
        "target_address": "pod:UnresolvedAddress"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedMosaicAddressRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedMosaicAddressRestrictionTransaction.TRANSACTION_TYPE
        self._mosaic_id = UnresolvedMosaicId()
        self._restriction_key = 0
        self._previous_restriction_value = 0
        self._new_restriction_value = 0
        self._target_address = UnresolvedAddress()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def mosaic_id(self) -> UnresolvedMosaicId:
        return self._mosaic_id

    @property
    def restriction_key(self) -> int:
        return self._restriction_key

    @property
    def previous_restriction_value(self) -> int:
        return self._previous_restriction_value

    @property
    def new_restriction_value(self) -> int:
        return self._new_restriction_value

    @property
    def target_address(self) -> UnresolvedAddress:
        return self._target_address

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @mosaic_id.setter
    def mosaic_id(self, value: UnresolvedMosaicId):
        self._mosaic_id = value

    @restriction_key.setter
    def restriction_key(self, value: int):
        self._restriction_key = value

    @previous_restriction_value.setter
    def previous_restriction_value(self, value: int):
        self._previous_restriction_value = value

    @new_restriction_value.setter
    def new_restriction_value(self, value: int):
        self._new_restriction_value = value

    @target_address.setter
    def target_address(self, value: UnresolvedAddress):
        self._target_address = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.mosaic_id.size()
        size += 8
        size += 8
        size += 8
        size += self.target_address.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedMosaicAddressRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        restriction_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        previous_restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        new_restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        target_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[target_address.size():]

        instance = EmbeddedMosaicAddressRestrictionTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._mosaic_id = mosaic_id
        instance._restriction_key = restriction_key
        instance._previous_restriction_value = previous_restriction_value
        instance._new_restriction_value = new_restriction_value
        instance._target_address = target_address
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._restriction_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._previous_restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._new_restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._target_address.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "restriction_key: {}, ".format("0x{:X}".format(self._restriction_key))
        result += "previous_restriction_value: {}, ".format("0x{:X}".format(self._previous_restriction_value))
        result += "new_restriction_value: {}, ".format("0x{:X}".format(self._new_restriction_value))
        result += "target_address: {}, ".format(self._target_address.__str__())
        result += ")"
        return result


class MosaicGlobalRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_GLOBAL_RESTRICTION
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "mosaic_id": "pod:UnresolvedMosaicId",
        "reference_mosaic_id": "pod:UnresolvedMosaicId",
        "previous_restriction_type": "enum:MosaicRestrictionType",
        "new_restriction_type": "enum:MosaicRestrictionType"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = MosaicGlobalRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = MosaicGlobalRestrictionTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._mosaic_id = UnresolvedMosaicId()
        self._reference_mosaic_id = UnresolvedMosaicId()
        self._restriction_key = 0
        self._previous_restriction_value = 0
        self._new_restriction_value = 0
        self._previous_restriction_type = MosaicRestrictionType.NONE
        self._new_restriction_type = MosaicRestrictionType.NONE
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def mosaic_id(self) -> UnresolvedMosaicId:
        return self._mosaic_id

    @property
    def reference_mosaic_id(self) -> UnresolvedMosaicId:
        return self._reference_mosaic_id

    @property
    def restriction_key(self) -> int:
        return self._restriction_key

    @property
    def previous_restriction_value(self) -> int:
        return self._previous_restriction_value

    @property
    def new_restriction_value(self) -> int:
        return self._new_restriction_value

    @property
    def previous_restriction_type(self) -> MosaicRestrictionType:
        return self._previous_restriction_type

    @property
    def new_restriction_type(self) -> MosaicRestrictionType:
        return self._new_restriction_type

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @mosaic_id.setter
    def mosaic_id(self, value: UnresolvedMosaicId):
        self._mosaic_id = value

    @reference_mosaic_id.setter
    def reference_mosaic_id(self, value: UnresolvedMosaicId):
        self._reference_mosaic_id = value

    @restriction_key.setter
    def restriction_key(self, value: int):
        self._restriction_key = value

    @previous_restriction_value.setter
    def previous_restriction_value(self, value: int):
        self._previous_restriction_value = value

    @new_restriction_value.setter
    def new_restriction_value(self, value: int):
        self._new_restriction_value = value

    @previous_restriction_type.setter
    def previous_restriction_type(self, value: MosaicRestrictionType):
        self._previous_restriction_type = value

    @new_restriction_type.setter
    def new_restriction_type(self, value: MosaicRestrictionType):
        self._new_restriction_type = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.mosaic_id.size()
        size += self.reference_mosaic_id.size()
        size += 8
        size += 8
        size += 8
        size += self.previous_restriction_type.size()
        size += self.new_restriction_type.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> MosaicGlobalRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        reference_mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[reference_mosaic_id.size():]
        restriction_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        previous_restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        new_restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        previous_restriction_type = MosaicRestrictionType.deserialize(buffer_)
        buffer_ = buffer_[previous_restriction_type.size():]
        new_restriction_type = MosaicRestrictionType.deserialize(buffer_)
        buffer_ = buffer_[new_restriction_type.size():]

        instance = MosaicGlobalRestrictionTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._mosaic_id = mosaic_id
        instance._reference_mosaic_id = reference_mosaic_id
        instance._restriction_key = restriction_key
        instance._previous_restriction_value = previous_restriction_value
        instance._new_restriction_value = new_restriction_value
        instance._previous_restriction_type = previous_restriction_type
        instance._new_restriction_type = new_restriction_type
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._reference_mosaic_id.serialize()
        buffer_ += self._restriction_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._previous_restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._new_restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._previous_restriction_type.serialize()
        buffer_ += self._new_restriction_type.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "reference_mosaic_id: {}, ".format(self._reference_mosaic_id.__str__())
        result += "restriction_key: {}, ".format("0x{:X}".format(self._restriction_key))
        result += "previous_restriction_value: {}, ".format("0x{:X}".format(self._previous_restriction_value))
        result += "new_restriction_value: {}, ".format("0x{:X}".format(self._new_restriction_value))
        result += "previous_restriction_type: {}, ".format(self._previous_restriction_type.__str__())
        result += "new_restriction_type: {}, ".format(self._new_restriction_type.__str__())
        result += ")"
        return result


class EmbeddedMosaicGlobalRestrictionTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.MOSAIC_GLOBAL_RESTRICTION
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "mosaic_id": "pod:UnresolvedMosaicId",
        "reference_mosaic_id": "pod:UnresolvedMosaicId",
        "previous_restriction_type": "enum:MosaicRestrictionType",
        "new_restriction_type": "enum:MosaicRestrictionType"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedMosaicGlobalRestrictionTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedMosaicGlobalRestrictionTransaction.TRANSACTION_TYPE
        self._mosaic_id = UnresolvedMosaicId()
        self._reference_mosaic_id = UnresolvedMosaicId()
        self._restriction_key = 0
        self._previous_restriction_value = 0
        self._new_restriction_value = 0
        self._previous_restriction_type = MosaicRestrictionType.NONE
        self._new_restriction_type = MosaicRestrictionType.NONE
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def mosaic_id(self) -> UnresolvedMosaicId:
        return self._mosaic_id

    @property
    def reference_mosaic_id(self) -> UnresolvedMosaicId:
        return self._reference_mosaic_id

    @property
    def restriction_key(self) -> int:
        return self._restriction_key

    @property
    def previous_restriction_value(self) -> int:
        return self._previous_restriction_value

    @property
    def new_restriction_value(self) -> int:
        return self._new_restriction_value

    @property
    def previous_restriction_type(self) -> MosaicRestrictionType:
        return self._previous_restriction_type

    @property
    def new_restriction_type(self) -> MosaicRestrictionType:
        return self._new_restriction_type

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @mosaic_id.setter
    def mosaic_id(self, value: UnresolvedMosaicId):
        self._mosaic_id = value

    @reference_mosaic_id.setter
    def reference_mosaic_id(self, value: UnresolvedMosaicId):
        self._reference_mosaic_id = value

    @restriction_key.setter
    def restriction_key(self, value: int):
        self._restriction_key = value

    @previous_restriction_value.setter
    def previous_restriction_value(self, value: int):
        self._previous_restriction_value = value

    @new_restriction_value.setter
    def new_restriction_value(self, value: int):
        self._new_restriction_value = value

    @previous_restriction_type.setter
    def previous_restriction_type(self, value: MosaicRestrictionType):
        self._previous_restriction_type = value

    @new_restriction_type.setter
    def new_restriction_type(self, value: MosaicRestrictionType):
        self._new_restriction_type = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.mosaic_id.size()
        size += self.reference_mosaic_id.size()
        size += 8
        size += 8
        size += 8
        size += self.previous_restriction_type.size()
        size += self.new_restriction_type.size()
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedMosaicGlobalRestrictionTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[mosaic_id.size():]
        reference_mosaic_id = UnresolvedMosaicId.deserialize(buffer_)
        buffer_ = buffer_[reference_mosaic_id.size():]
        restriction_key = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        previous_restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        new_restriction_value = int.from_bytes(buffer_[:8], byteorder="little")
        buffer_ = buffer_[8:]
        previous_restriction_type = MosaicRestrictionType.deserialize(buffer_)
        buffer_ = buffer_[previous_restriction_type.size():]
        new_restriction_type = MosaicRestrictionType.deserialize(buffer_)
        buffer_ = buffer_[new_restriction_type.size():]

        instance = EmbeddedMosaicGlobalRestrictionTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._mosaic_id = mosaic_id
        instance._reference_mosaic_id = reference_mosaic_id
        instance._restriction_key = restriction_key
        instance._previous_restriction_value = previous_restriction_value
        instance._new_restriction_value = new_restriction_value
        instance._previous_restriction_type = previous_restriction_type
        instance._new_restriction_type = new_restriction_type
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._mosaic_id.serialize()
        buffer_ += self._reference_mosaic_id.serialize()
        buffer_ += self._restriction_key.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._previous_restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._new_restriction_value.to_bytes(8, byteorder="little", signed=False)
        buffer_ += self._previous_restriction_type.serialize()
        buffer_ += self._new_restriction_type.serialize()
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "mosaic_id: {}, ".format(self._mosaic_id.__str__())
        result += "reference_mosaic_id: {}, ".format(self._reference_mosaic_id.__str__())
        result += "restriction_key: {}, ".format("0x{:X}".format(self._restriction_key))
        result += "previous_restriction_value: {}, ".format("0x{:X}".format(self._previous_restriction_value))
        result += "new_restriction_value: {}, ".format("0x{:X}".format(self._new_restriction_value))
        result += "previous_restriction_type: {}, ".format(self._previous_restriction_type.__str__())
        result += "new_restriction_type: {}, ".format(self._new_restriction_type.__str__())
        result += ")"
        return result


class TransferTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.TRANSFER
    TYPE_HINTS = {
        "signature": "pod:Signature",
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "fee": "pod:Amount",
        "deadline": "pod:Timestamp",
        "recipient_address": "pod:UnresolvedAddress",
        "mosaics": "array[UnresolvedMosaic]",
        "message": "bytes_array"
    }

    def __init__(self):
        self._signature = Signature()
        self._signer_public_key = PublicKey()
        self._version = TransferTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = TransferTransaction.TRANSACTION_TYPE
        self._fee = Amount()
        self._deadline = Timestamp()
        self._recipient_address = UnresolvedAddress()
        self._mosaics = []
        self._message = bytes()
        self._verifiable_entity_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._transfer_transaction_body_reserved_1 = 0  # reserved field
        self._transfer_transaction_body_reserved_2 = 0  # reserved field

    @property
    def signature(self) -> Signature:
        return self._signature

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def fee(self) -> Amount:
        return self._fee

    @property
    def deadline(self) -> Timestamp:
        return self._deadline

    @property
    def recipient_address(self) -> UnresolvedAddress:
        return self._recipient_address

    @property
    def mosaics(self) -> List[UnresolvedMosaic]:
        return self._mosaics

    @property
    def message(self) -> bytes:
        return self._message

    @signature.setter
    def signature(self, value: Signature):
        self._signature = value

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @fee.setter
    def fee(self, value: Amount):
        self._fee = value

    @deadline.setter
    def deadline(self, value: Timestamp):
        self._deadline = value

    @recipient_address.setter
    def recipient_address(self, value: UnresolvedAddress):
        self._recipient_address = value

    @mosaics.setter
    def mosaics(self, value: List[UnresolvedMosaic]):
        self._mosaics = value

    @message.setter
    def message(self, value: bytes):
        self._message = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signature.size()
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.fee.size()
        size += self.deadline.size()
        size += self.recipient_address.size()
        size += 2
        size += 1
        size += 4
        size += 1
        size += sum(map(lambda e: e.size(), self.mosaics))
        size += len(self._message)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> TransferTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        verifiable_entity_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert verifiable_entity_header_reserved_1 == 0, f"Invalid value of reserved field ({verifiable_entity_header_reserved_1})"
        signature = Signature.deserialize(buffer_)
        buffer_ = buffer_[signature.size():]
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        fee = Amount.deserialize(buffer_)
        buffer_ = buffer_[fee.size():]
        deadline = Timestamp.deserialize(buffer_)
        buffer_ = buffer_[deadline.size():]
        recipient_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[recipient_address.size():]
        message_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        mosaics_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        transfer_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert transfer_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({transfer_transaction_body_reserved_1})"
        transfer_transaction_body_reserved_2 = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        assert transfer_transaction_body_reserved_2 == 0, f"Invalid value of reserved field ({transfer_transaction_body_reserved_2})"
        mosaics = ArrayHelpers.read_array_count(buffer_, UnresolvedMosaic, mosaics_count, lambda e: e.mosaic_id)
        buffer_ = buffer_[sum(map(lambda e: e.size(), mosaics)):]
        message = ArrayHelpers.get_bytes(buffer_, message_size)
        buffer_ = buffer_[message_size:]

        instance = TransferTransaction()
        instance._signature = signature
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._fee = fee
        instance._deadline = deadline
        instance._recipient_address = recipient_address
        instance._mosaics = mosaics
        instance._message = message
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._verifiable_entity_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signature.serialize()
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._fee.serialize()
        buffer_ += self._deadline.serialize()
        buffer_ += self._recipient_address.serialize()
        buffer_ += len(self._message).to_bytes(2, byteorder="little", signed=False)  # message_size
        buffer_ += len(self._mosaics).to_bytes(1, byteorder="little", signed=False)  # mosaics_count
        buffer_ += self._transfer_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._transfer_transaction_body_reserved_2.to_bytes(1, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._mosaics, lambda e: e.mosaic_id)
        buffer_ += self._message
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signature: {}, ".format(self._signature.__str__())
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "fee: {}, ".format(self._fee.__str__())
        result += "deadline: {}, ".format(self._deadline.__str__())
        result += "recipient_address: {}, ".format(self._recipient_address.__str__())
        result += "mosaics: {}, ".format(list(map(str, self._mosaics)))
        result += "message: {}, ".format(hexlify(self._message).decode("utf8"))
        result += ")"
        return result


class EmbeddedTransferTransaction:
    TRANSACTION_VERSION: int = 1
    TRANSACTION_TYPE: TransactionType = TransactionType.TRANSFER
    TYPE_HINTS = {
        "signer_public_key": "pod:PublicKey",
        "network": "enum:NetworkType",
        "type_": "enum:TransactionType",
        "recipient_address": "pod:UnresolvedAddress",
        "mosaics": "array[UnresolvedMosaic]",
        "message": "bytes_array"
    }

    def __init__(self):
        self._signer_public_key = PublicKey()
        self._version = EmbeddedTransferTransaction.TRANSACTION_VERSION
        self._network = NetworkType.MAINNET
        self._type_ = EmbeddedTransferTransaction.TRANSACTION_TYPE
        self._recipient_address = UnresolvedAddress()
        self._mosaics = []
        self._message = bytes()
        self._embedded_transaction_header_reserved_1 = 0  # reserved field
        self._entity_body_reserved_1 = 0  # reserved field
        self._transfer_transaction_body_reserved_1 = 0  # reserved field
        self._transfer_transaction_body_reserved_2 = 0  # reserved field

    @property
    def signer_public_key(self) -> PublicKey:
        return self._signer_public_key

    @property
    def version(self) -> int:
        return self._version

    @property
    def network(self) -> NetworkType:
        return self._network

    @property
    def type_(self) -> TransactionType:
        return self._type_

    @property
    def recipient_address(self) -> UnresolvedAddress:
        return self._recipient_address

    @property
    def mosaics(self) -> List[UnresolvedMosaic]:
        return self._mosaics

    @property
    def message(self) -> bytes:
        return self._message

    @signer_public_key.setter
    def signer_public_key(self, value: PublicKey):
        self._signer_public_key = value

    @version.setter
    def version(self, value: int):
        self._version = value

    @network.setter
    def network(self, value: NetworkType):
        self._network = value

    @type_.setter
    def type_(self, value: TransactionType):
        self._type_ = value

    @recipient_address.setter
    def recipient_address(self, value: UnresolvedAddress):
        self._recipient_address = value

    @mosaics.setter
    def mosaics(self, value: List[UnresolvedMosaic]):
        self._mosaics = value

    @message.setter
    def message(self, value: bytes):
        self._message = value

    def size(self) -> int:
        size = 0
        size += 4
        size += 4
        size += self.signer_public_key.size()
        size += 4
        size += 1
        size += self.network.size()
        size += self.type_.size()
        size += self.recipient_address.size()
        size += 2
        size += 1
        size += 4
        size += 1
        size += sum(map(lambda e: e.size(), self.mosaics))
        size += len(self._message)
        return size

    @classmethod
    def deserialize(self, payload: ByteString) -> EmbeddedTransferTransaction:
        buffer_ = memoryview(payload)
        size_ = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        buffer_ = buffer_[:size_ - 4]
        del size_
        embedded_transaction_header_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert embedded_transaction_header_reserved_1 == 0, f"Invalid value of reserved field ({embedded_transaction_header_reserved_1})"
        signer_public_key = PublicKey.deserialize(buffer_)
        buffer_ = buffer_[signer_public_key.size():]
        entity_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert entity_body_reserved_1 == 0, f"Invalid value of reserved field ({entity_body_reserved_1})"
        version = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        network = NetworkType.deserialize(buffer_)
        buffer_ = buffer_[network.size():]
        type_ = TransactionType.deserialize(buffer_)
        buffer_ = buffer_[type_.size():]
        recipient_address = UnresolvedAddress.deserialize(buffer_)
        buffer_ = buffer_[recipient_address.size():]
        message_size = int.from_bytes(buffer_[:2], byteorder="little")
        buffer_ = buffer_[2:]
        mosaics_count = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        transfer_transaction_body_reserved_1 = int.from_bytes(buffer_[:4], byteorder="little")
        buffer_ = buffer_[4:]
        assert transfer_transaction_body_reserved_1 == 0, f"Invalid value of reserved field ({transfer_transaction_body_reserved_1})"
        transfer_transaction_body_reserved_2 = int.from_bytes(buffer_[:1], byteorder="little")
        buffer_ = buffer_[1:]
        assert transfer_transaction_body_reserved_2 == 0, f"Invalid value of reserved field ({transfer_transaction_body_reserved_2})"
        mosaics = ArrayHelpers.read_array_count(buffer_, UnresolvedMosaic, mosaics_count, lambda e: e.mosaic_id)
        buffer_ = buffer_[sum(map(lambda e: e.size(), mosaics)):]
        message = ArrayHelpers.get_bytes(buffer_, message_size)
        buffer_ = buffer_[message_size:]

        instance = EmbeddedTransferTransaction()
        instance._signer_public_key = signer_public_key
        instance._version = version
        instance._network = network
        instance._type_ = type_
        instance._recipient_address = recipient_address
        instance._mosaics = mosaics
        instance._message = message
        return instance

    def serialize(self) -> bytes:
        buffer_ = bytes()
        buffer_ += self.size().to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._embedded_transaction_header_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._signer_public_key.serialize()
        buffer_ += self._entity_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._version.to_bytes(1, byteorder="little", signed=False)
        buffer_ += self._network.serialize()
        buffer_ += self._type_.serialize()
        buffer_ += self._recipient_address.serialize()
        buffer_ += len(self._message).to_bytes(2, byteorder="little", signed=False)  # message_size
        buffer_ += len(self._mosaics).to_bytes(1, byteorder="little", signed=False)  # mosaics_count
        buffer_ += self._transfer_transaction_body_reserved_1.to_bytes(4, byteorder="little", signed=False)
        buffer_ += self._transfer_transaction_body_reserved_2.to_bytes(1, byteorder="little", signed=False)
        buffer_ += ArrayHelpers.write_array(self._mosaics, lambda e: e.mosaic_id)
        buffer_ += self._message
        return buffer_

    def __str__(self) -> str:
        result = "("
        result += "signer_public_key: {}, ".format(self._signer_public_key.__str__())
        result += "version: {}, ".format("0x{:X}".format(self._version))
        result += "network: {}, ".format(self._network.__str__())
        result += "type_: {}, ".format(self._type_.__str__())
        result += "recipient_address: {}, ".format(self._recipient_address.__str__())
        result += "mosaics: {}, ".format(list(map(str, self._mosaics)))
        result += "message: {}, ".format(hexlify(self._message).decode("utf8"))
        result += ")"
        return result


class TransactionFactory:
    @classmethod
    def deserialize(self, payload: bytes) -> Transaction:
        buffer_ = bytes(payload)
        parent = Transaction.deserialize(buffer_)
        mapping = {
            (AccountKeyLinkTransaction.TRANSACTION_TYPE): AccountKeyLinkTransaction,
            (NodeKeyLinkTransaction.TRANSACTION_TYPE): NodeKeyLinkTransaction,
            (AggregateCompleteTransaction.TRANSACTION_TYPE): AggregateCompleteTransaction,
            (AggregateBondedTransaction.TRANSACTION_TYPE): AggregateBondedTransaction,
            (VotingKeyLinkTransaction.TRANSACTION_TYPE): VotingKeyLinkTransaction,
            (VrfKeyLinkTransaction.TRANSACTION_TYPE): VrfKeyLinkTransaction,
            (HashLockTransaction.TRANSACTION_TYPE): HashLockTransaction,
            (SecretLockTransaction.TRANSACTION_TYPE): SecretLockTransaction,
            (SecretProofTransaction.TRANSACTION_TYPE): SecretProofTransaction,
            (AccountMetadataTransaction.TRANSACTION_TYPE): AccountMetadataTransaction,
            (MosaicMetadataTransaction.TRANSACTION_TYPE): MosaicMetadataTransaction,
            (NamespaceMetadataTransaction.TRANSACTION_TYPE): NamespaceMetadataTransaction,
            (MosaicDefinitionTransaction.TRANSACTION_TYPE): MosaicDefinitionTransaction,
            (MosaicSupplyChangeTransaction.TRANSACTION_TYPE): MosaicSupplyChangeTransaction,
            (MosaicSupplyRevocationTransaction.TRANSACTION_TYPE): MosaicSupplyRevocationTransaction,
            (MultisigAccountModificationTransaction.TRANSACTION_TYPE): MultisigAccountModificationTransaction,
            (AddressAliasTransaction.TRANSACTION_TYPE): AddressAliasTransaction,
            (MosaicAliasTransaction.TRANSACTION_TYPE): MosaicAliasTransaction,
            (NamespaceRegistrationTransaction.TRANSACTION_TYPE): NamespaceRegistrationTransaction,
            (AccountAddressRestrictionTransaction.TRANSACTION_TYPE): AccountAddressRestrictionTransaction,
            (AccountMosaicRestrictionTransaction.TRANSACTION_TYPE): AccountMosaicRestrictionTransaction,
            (AccountOperationRestrictionTransaction.TRANSACTION_TYPE): AccountOperationRestrictionTransaction,
            (MosaicAddressRestrictionTransaction.TRANSACTION_TYPE): MosaicAddressRestrictionTransaction,
            (MosaicGlobalRestrictionTransaction.TRANSACTION_TYPE): MosaicGlobalRestrictionTransaction,
            (TransferTransaction.TRANSACTION_TYPE): TransferTransaction
        }
        discriminator = (parent.type_)
        factory_class = mapping[discriminator]
        return factory_class.deserialize(buffer_)

    @classmethod
    def create_by_name(self, entity_name: str) -> Transaction:
        mapping = {
            "account_key_link_transaction": AccountKeyLinkTransaction,
            "node_key_link_transaction": NodeKeyLinkTransaction,
            "aggregate_complete_transaction": AggregateCompleteTransaction,
            "aggregate_bonded_transaction": AggregateBondedTransaction,
            "voting_key_link_transaction": VotingKeyLinkTransaction,
            "vrf_key_link_transaction": VrfKeyLinkTransaction,
            "hash_lock_transaction": HashLockTransaction,
            "secret_lock_transaction": SecretLockTransaction,
            "secret_proof_transaction": SecretProofTransaction,
            "account_metadata_transaction": AccountMetadataTransaction,
            "mosaic_metadata_transaction": MosaicMetadataTransaction,
            "namespace_metadata_transaction": NamespaceMetadataTransaction,
            "mosaic_definition_transaction": MosaicDefinitionTransaction,
            "mosaic_supply_change_transaction": MosaicSupplyChangeTransaction,
            "mosaic_supply_revocation_transaction": MosaicSupplyRevocationTransaction,
            "multisig_account_modification_transaction": MultisigAccountModificationTransaction,
            "address_alias_transaction": AddressAliasTransaction,
            "mosaic_alias_transaction": MosaicAliasTransaction,
            "namespace_registration_transaction": NamespaceRegistrationTransaction,
            "account_address_restriction_transaction": AccountAddressRestrictionTransaction,
            "account_mosaic_restriction_transaction": AccountMosaicRestrictionTransaction,
            "account_operation_restriction_transaction": AccountOperationRestrictionTransaction,
            "mosaic_address_restriction_transaction": MosaicAddressRestrictionTransaction,
            "mosaic_global_restriction_transaction": MosaicGlobalRestrictionTransaction,
            "transfer_transaction": TransferTransaction
        }

        if entity_name not in mapping:
            raise ValueError('unknown Transaction type')

        return mapping[entity_name]()


class EmbeddedTransactionFactory:
    @classmethod
    def deserialize(self, payload: bytes) -> EmbeddedTransaction:
        buffer_ = bytes(payload)
        parent = EmbeddedTransaction.deserialize(buffer_)
        mapping = {
            (EmbeddedAccountKeyLinkTransaction.TRANSACTION_TYPE): EmbeddedAccountKeyLinkTransaction,
            (EmbeddedNodeKeyLinkTransaction.TRANSACTION_TYPE): EmbeddedNodeKeyLinkTransaction,
            (EmbeddedVotingKeyLinkTransaction.TRANSACTION_TYPE): EmbeddedVotingKeyLinkTransaction,
            (EmbeddedVrfKeyLinkTransaction.TRANSACTION_TYPE): EmbeddedVrfKeyLinkTransaction,
            (EmbeddedHashLockTransaction.TRANSACTION_TYPE): EmbeddedHashLockTransaction,
            (EmbeddedSecretLockTransaction.TRANSACTION_TYPE): EmbeddedSecretLockTransaction,
            (EmbeddedSecretProofTransaction.TRANSACTION_TYPE): EmbeddedSecretProofTransaction,
            (EmbeddedAccountMetadataTransaction.TRANSACTION_TYPE): EmbeddedAccountMetadataTransaction,
            (EmbeddedMosaicMetadataTransaction.TRANSACTION_TYPE): EmbeddedMosaicMetadataTransaction,
            (EmbeddedNamespaceMetadataTransaction.TRANSACTION_TYPE): EmbeddedNamespaceMetadataTransaction,
            (EmbeddedMosaicDefinitionTransaction.TRANSACTION_TYPE): EmbeddedMosaicDefinitionTransaction,
            (EmbeddedMosaicSupplyChangeTransaction.TRANSACTION_TYPE): EmbeddedMosaicSupplyChangeTransaction,
            (EmbeddedMosaicSupplyRevocationTransaction.TRANSACTION_TYPE): EmbeddedMosaicSupplyRevocationTransaction,
            (EmbeddedMultisigAccountModificationTransaction.TRANSACTION_TYPE): EmbeddedMultisigAccountModificationTransaction,
            (EmbeddedAddressAliasTransaction.TRANSACTION_TYPE): EmbeddedAddressAliasTransaction,
            (EmbeddedMosaicAliasTransaction.TRANSACTION_TYPE): EmbeddedMosaicAliasTransaction,
            (EmbeddedNamespaceRegistrationTransaction.TRANSACTION_TYPE): EmbeddedNamespaceRegistrationTransaction,
            (EmbeddedAccountAddressRestrictionTransaction.TRANSACTION_TYPE): EmbeddedAccountAddressRestrictionTransaction,
            (EmbeddedAccountMosaicRestrictionTransaction.TRANSACTION_TYPE): EmbeddedAccountMosaicRestrictionTransaction,
            (EmbeddedAccountOperationRestrictionTransaction.TRANSACTION_TYPE): EmbeddedAccountOperationRestrictionTransaction,
            (EmbeddedMosaicAddressRestrictionTransaction.TRANSACTION_TYPE): EmbeddedMosaicAddressRestrictionTransaction,
            (EmbeddedMosaicGlobalRestrictionTransaction.TRANSACTION_TYPE): EmbeddedMosaicGlobalRestrictionTransaction,
            (EmbeddedTransferTransaction.TRANSACTION_TYPE): EmbeddedTransferTransaction
        }
        discriminator = (parent.type_)
        factory_class = mapping[discriminator]
        return factory_class.deserialize(buffer_)

    @classmethod
    def create_by_name(self, entity_name: str) -> EmbeddedTransaction:
        mapping = {
            "account_key_link_transaction": EmbeddedAccountKeyLinkTransaction,
            "node_key_link_transaction": EmbeddedNodeKeyLinkTransaction,
            "voting_key_link_transaction": EmbeddedVotingKeyLinkTransaction,
            "vrf_key_link_transaction": EmbeddedVrfKeyLinkTransaction,
            "hash_lock_transaction": EmbeddedHashLockTransaction,
            "secret_lock_transaction": EmbeddedSecretLockTransaction,
            "secret_proof_transaction": EmbeddedSecretProofTransaction,
            "account_metadata_transaction": EmbeddedAccountMetadataTransaction,
            "mosaic_metadata_transaction": EmbeddedMosaicMetadataTransaction,
            "namespace_metadata_transaction": EmbeddedNamespaceMetadataTransaction,
            "mosaic_definition_transaction": EmbeddedMosaicDefinitionTransaction,
            "mosaic_supply_change_transaction": EmbeddedMosaicSupplyChangeTransaction,
            "mosaic_supply_revocation_transaction": EmbeddedMosaicSupplyRevocationTransaction,
            "multisig_account_modification_transaction": EmbeddedMultisigAccountModificationTransaction,
            "address_alias_transaction": EmbeddedAddressAliasTransaction,
            "mosaic_alias_transaction": EmbeddedMosaicAliasTransaction,
            "namespace_registration_transaction": EmbeddedNamespaceRegistrationTransaction,
            "account_address_restriction_transaction": EmbeddedAccountAddressRestrictionTransaction,
            "account_mosaic_restriction_transaction": EmbeddedAccountMosaicRestrictionTransaction,
            "account_operation_restriction_transaction": EmbeddedAccountOperationRestrictionTransaction,
            "mosaic_address_restriction_transaction": EmbeddedMosaicAddressRestrictionTransaction,
            "mosaic_global_restriction_transaction": EmbeddedMosaicGlobalRestrictionTransaction,
            "transfer_transaction": EmbeddedTransferTransaction
        }

        if entity_name not in mapping:
            raise ValueError('unknown EmbeddedTransaction type')

        return mapping[entity_name]()


class BlockFactory:
    @classmethod
    def deserialize(self, payload: bytes) -> Block:
        buffer_ = bytes(payload)
        parent = Block.deserialize(buffer_)
        mapping = {
            (NemesisBlock.BLOCK_TYPE): NemesisBlock,
            (NormalBlock.BLOCK_TYPE): NormalBlock,
            (ImportanceBlock.BLOCK_TYPE): ImportanceBlock
        }
        discriminator = (parent.type_)
        factory_class = mapping[discriminator]
        return factory_class.deserialize(buffer_)

    @classmethod
    def create_by_name(self, entity_name: str) -> Block:
        mapping = {
            "nemesis_block": NemesisBlock,
            "normal_block": NormalBlock,
            "importance_block": ImportanceBlock
        }

        if entity_name not in mapping:
            raise ValueError('unknown Block type')

        return mapping[entity_name]()


class ReceiptFactory:
    @classmethod
    def deserialize(self, payload: bytes) -> Receipt:
        buffer_ = bytes(payload)
        parent = Receipt.deserialize(buffer_)
        mapping = {
            (HarvestFeeReceipt.RECEIPT_TYPE): HarvestFeeReceipt,
            (InflationReceipt.RECEIPT_TYPE): InflationReceipt,
            (LockHashCreatedFeeReceipt.RECEIPT_TYPE): LockHashCreatedFeeReceipt,
            (LockHashCompletedFeeReceipt.RECEIPT_TYPE): LockHashCompletedFeeReceipt,
            (LockHashExpiredFeeReceipt.RECEIPT_TYPE): LockHashExpiredFeeReceipt,
            (LockSecretCreatedFeeReceipt.RECEIPT_TYPE): LockSecretCreatedFeeReceipt,
            (LockSecretCompletedFeeReceipt.RECEIPT_TYPE): LockSecretCompletedFeeReceipt,
            (LockSecretExpiredFeeReceipt.RECEIPT_TYPE): LockSecretExpiredFeeReceipt,
            (MosaicExpiredReceipt.RECEIPT_TYPE): MosaicExpiredReceipt,
            (MosaicRentalFeeReceipt.RECEIPT_TYPE): MosaicRentalFeeReceipt,
            (NamespaceExpiredReceipt.RECEIPT_TYPE): NamespaceExpiredReceipt,
            (NamespaceDeletedReceipt.RECEIPT_TYPE): NamespaceDeletedReceipt,
            (NamespaceRentalFeeReceipt.RECEIPT_TYPE): NamespaceRentalFeeReceipt
        }
        discriminator = (parent.type_)
        factory_class = mapping[discriminator]
        return factory_class.deserialize(buffer_)

    @classmethod
    def create_by_name(self, entity_name: str) -> Receipt:
        mapping = {
            "harvest_fee_receipt": HarvestFeeReceipt,
            "inflation_receipt": InflationReceipt,
            "lock_hash_created_fee_receipt": LockHashCreatedFeeReceipt,
            "lock_hash_completed_fee_receipt": LockHashCompletedFeeReceipt,
            "lock_hash_expired_fee_receipt": LockHashExpiredFeeReceipt,
            "lock_secret_created_fee_receipt": LockSecretCreatedFeeReceipt,
            "lock_secret_completed_fee_receipt": LockSecretCompletedFeeReceipt,
            "lock_secret_expired_fee_receipt": LockSecretExpiredFeeReceipt,
            "mosaic_expired_receipt": MosaicExpiredReceipt,
            "mosaic_rental_fee_receipt": MosaicRentalFeeReceipt,
            "namespace_expired_receipt": NamespaceExpiredReceipt,
            "namespace_deleted_receipt": NamespaceDeletedReceipt,
            "namespace_rental_fee_receipt": NamespaceRentalFeeReceipt
        }

        if entity_name not in mapping:
            raise ValueError('unknown Receipt type')

        return mapping[entity_name]()
