Пример #1
0
    def serialize(self, include_signature=True):
        milestone = config.get_milestone(self.height - 1)
        if milestone["block"]["idFullSha256"]:
            if len(self.previous_block) != 64:
                raise Exception(
                    "Previous block shoud be SHA256, but found a non SHA256 block id"
                )
            self.previous_block_hex = self.previous_block.encode("utf-8")
        else:
            self.previous_block_hex = Block.to_bytes_hex(self.previous_block)

        bytes_data = bytes()
        bytes_data += write_bit32(self.version)
        bytes_data += write_bit32(self.timestamp)
        bytes_data += write_bit32(self.height)
        bytes_data += unhexlify(self.previous_block_hex)
        bytes_data += write_bit32(self.number_of_transactions)
        bytes_data += write_bit64(int(self.total_amount))
        bytes_data += write_bit64(int(self.total_fee))
        bytes_data += write_bit64(int(self.reward))
        bytes_data += write_bit32(self.payload_length)
        bytes_data += unhexlify(self.payload_hash.encode("utf-8"))
        bytes_data += unhexlify(self.generator_public_key)

        if include_signature and self.block_signature:
            bytes_data += unhexlify(self.block_signature.encode("utf-8"))

        return hexlify(bytes_data)
Пример #2
0
    def get_bytes(self, skip_signature=False, skip_second_signature=False):
        """
        Serializes the given transaction prior to AIP11 (legacy).
        """
        # TODO: rename to to_bytes which makes more sense than get_bytes
        if self.version and self.version != 1:
            raise Exception(
                "Invalid transaction version")  # TODO: better exception

        bytes_data = bytes()
        bytes_data += write_bit8(self.type)
        bytes_data += write_bit32(self.timestamp)
        bytes_data += write_high(self.sender_public_key)

        # Apply a fix for broken type 1 (second signature) and 4 (multi signature)
        # transactions, which were erroneously calculated with a recipient id,
        # also apply a fix for all other broken transactions
        is_broken_type = self.type in [
            TRANSACTION_TYPE_SECOND_SIGNATURE,
            TRANSACTION_TYPE_MULTI_SIGNATURE,
        ]

        if not self.recipient_id or (is_transaction_exception(self.id)
                                     or is_broken_type):
            bytes_data += pack("21x")
        else:
            bytes_data += b58decode_check(self.recipient_id)

        if self.vendor_field:
            encoded_vendor_field = self.vendor_field.encode("utf-8")
            bytes_data += encoded_vendor_field
            num_of_zeroes = 64 - len(encoded_vendor_field)
            if num_of_zeroes > 0:
                bytes_data += pack("{}x".format(num_of_zeroes))
        else:
            bytes_data += pack("64x")

        bytes_data += write_bit64(self.amount)
        bytes_data += write_bit64(self.fee)

        if self.type == TRANSACTION_TYPE_SECOND_SIGNATURE:
            public_key = self.asset["signature"]["publicKey"]
            bytes_data += unhexlify(public_key)
        elif self.type == TRANSACTION_TYPE_DELEGATE_REGISTRATION:
            bytes_data += self.asset["delegate"]["username"].encode()
        elif self.type == TRANSACTION_TYPE_VOTE:
            bytes_data += "".join(self.asset["votes"]).encode()
        elif self.type == TRANSACTION_TYPE_MULTI_SIGNATURE:
            bytes_data += write_bit8(self.asset["multisignature"]["min"])
            bytes_data += write_bit8(self.asset["multisignature"]["lifetime"])
            bytes_data += "".join(
                self.asset["multisignature"]["keysgroup"]).encode()

        if not skip_signature and self.signature:
            bytes_data += write_high(self.signature)

        if not skip_second_signature and self.sign_signature:
            bytes_data += write_high(self.sign_signature)

        return bytes_data
Пример #3
0
    def serialize(self, include_signature=True):
        # TODO: make this a serializer that correctly converts input and checks that it's correct
        # on init
        self.previous_block_hex = Block.to_bytes_hex(int(self.previous_block))

        bytes_data = bytes()
        bytes_data += write_bit32(self.version)
        bytes_data += write_bit32(self.timestamp)
        bytes_data += write_bit32(self.height)
        bytes_data += unhexlify(self.previous_block_hex)
        bytes_data += write_bit32(self.number_of_transactions)
        bytes_data += write_bit64(int(self.total_amount))
        bytes_data += write_bit64(int(self.total_fee))
        bytes_data += write_bit64(int(self.reward))
        bytes_data += write_bit32(self.payload_length)
        bytes_data += unhexlify(self.payload_hash)
        bytes_data += unhexlify(self.generator_public_key)

        if include_signature and self.block_signature:
            bytes_data += unhexlify(self.block_signature)

        return hexlify(bytes_data).decode()
Пример #4
0
    def serialize_full(self):
        if not self.transactions:
            self.transactions = []
        if not self.number_of_transactions:
            self.number_of_transactions = len(self.transactions)

        bytes_data = unhexlify(self.serialize())

        all_transaction_bytes = bytes()
        for transaction in self.transactions:
            serialized_transaction = unhexlify(transaction.serialize())
            bytes_data += write_bit32(len(serialized_transaction))
            all_transaction_bytes += serialized_transaction

        bytes_data += all_transaction_bytes
        return hexlify(bytes_data)
Пример #5
0
    def serialize_full(self):
        # TODO: try to make these as default values instead of checking for it here
        if not self.transactions:
            self.transactions = []
        if not self.number_of_transactions:
            self.number_of_transactions = len(self.transactions)

        bytes_data = unhexlify(self.serialize())

        all_transaction_bytes = bytes()
        for transaction in self.transactions:
            serialized_transaction = Transaction(transaction).serialize()
            bytes_data += write_bit32(len(unhexlify(serialized_transaction)))
            all_transaction_bytes += unhexlify(serialized_transaction)

        bytes_data += all_transaction_bytes
        return hexlify(bytes_data).decode()
Пример #6
0
    def serialize(self):
        """Serialize Transaction
        """
        bytes_data = bytes()  # bytes() or bytes(512)?
        bytes_data += write_bit8(
            0xFF)  # fill, to distinguish between v1 and v2
        bytes_data += write_bit8(self.version or 0x01)
        bytes_data += write_bit8(self.network or config.network["pubKeyHash"])
        bytes_data += write_bit8(self.type)
        bytes_data += write_bit32(self.timestamp)
        bytes_data += write_high(self.sender_public_key.encode("utf-8"))
        bytes_data += write_bit64(self.fee)

        # TODO: test this thorougly as it might be completely wrong
        bytes_data += self._serialize_vendor_field()
        bytes_data += self._serialize_type()
        bytes_data += self._serialize_signatures()

        return hexlify(bytes_data)
Пример #7
0
    def _serialize_type(self):
        """Serialize transaction specific data (eg. delegate registration)
        """
        bytes_data = bytes()

        if self.type == TRANSACTION_TYPE_TRANSFER:
            bytes_data += write_bit64(self.amount)
            bytes_data += write_bit32(self.expiration or 0)
            bytes_data += write_high(
                hexlify(b58decode_check(self.recipient_id)))

        elif self.type == TRANSACTION_TYPE_SECOND_SIGNATURE:
            bytes_data += unhexlify(
                self.asset['signature']['publicKey'].encode('utf-8'))

        elif self.type == TRANSACTION_TYPE_DELEGATE_REGISTRATION:
            delegate_bytes = hexlify(
                self.asset['delegate']['username'].encode('utf-8'))
            bytes_data += write_bit8(len(delegate_bytes))
            bytes_data += unhexlify(delegate_bytes)

        elif self.type == TRANSACTION_TYPE_VOTE:
            vote_bytes = []
            for vote in self.asset['votes']:
                if vote.startswith('+'):
                    vote_bytes.append('01{}'.format(vote[1:]))
                else:
                    vote_bytes.append('00{}'.format(vote[1:]))
            bytes_data += write_bit8(len(self.asset['votes']))
            bytes_data += unhexlify(''.join(vote_bytes))

        elif self.type == TRANSACTION_TYPE_MULTI_SIGNATURE:
            keysgroup = []
            if self.version is None or self.version == 1:
                for key in self.asset['multisignature']['keysgroup']:
                    keysgroup.append(key[1:] if key.startswith('+') else key)
            else:
                keysgroup = self.asset['multisignature']['keysgroup']

            bytes_data += write_bit8(self.asset['multisignature']['min'])
            bytes_data += write_bit8(
                len(self.asset['multisignature']['keysgroup']))
            bytes_data += write_bit8(self.asset['multisignature']['lifetime'])
            bytes_data += unhexlify(''.join(keysgroup))

        elif self.type == TRANSACTION_TYPE_IPFS:
            bytes_data += write_bit8(len(self.asset['ipfs']['dag']) // 2)
            bytes_data += unhexlify(self.asset['ipfs']['dag'])

        elif self.type == TRANSACTION_TYPE_TIMELOCK_TRANSFER:
            bytes_data += write_bit64(self.amount)
            bytes_data += write_bit8(self.timelock_type)
            bytes_data += write_bit64(self.timelock)
            bytes_data += hexlify(b58decode_check(self.recipientId))

        elif self.type == TRANSACTION_TYPE_MULTI_PAYMENT:
            bytes_data += write_bit32(len(self.asset['payments']))
            for payment in self.asset['payments']:
                bytes_data += write_bit64(payment['amount'])
                bytes_data += hexlify(b58decode_check(payment['recipientId']))

        elif self.type == TRANSACTION_TYPE_DELEGATE_RESIGNATION:
            pass
        else:
            raise Exception(
                'Transaction type is invalid')  # TODO: better exception
        return bytes_data
Пример #8
0
    def _serialize_type(self):
        """Serialize transaction specific data (eg. delegate registration)
        """
        bytes_data = bytes()

        if self.type == TRANSACTION_TYPE_TRANSFER:
            bytes_data += write_bit64(self.amount)
            bytes_data += write_bit32(self.expiration or 0)
            bytes_data += write_high(
                hexlify(b58decode_check(self.recipient_id)))

        elif self.type == TRANSACTION_TYPE_SECOND_SIGNATURE:
            bytes_data += unhexlify(
                self.asset["signature"]["publicKey"].encode("utf-8"))

        elif self.type == TRANSACTION_TYPE_DELEGATE_REGISTRATION:
            delegate_bytes = hexlify(
                self.asset["delegate"]["username"].encode("utf-8"))
            bytes_data += write_bit8(len(delegate_bytes))
            bytes_data += unhexlify(delegate_bytes)

        elif self.type == TRANSACTION_TYPE_VOTE:
            vote_bytes = []
            for vote in self.asset["votes"]:
                if vote.startswith("+"):
                    vote_bytes.append("01{}".format(vote[1:]))
                else:
                    vote_bytes.append("00{}".format(vote[1:]))
            bytes_data += write_bit8(len(self.asset["votes"]))
            bytes_data += unhexlify("".join(vote_bytes))

        elif self.type == TRANSACTION_TYPE_MULTI_SIGNATURE:
            keysgroup = []
            if self.version is None or self.version == 1:
                for key in self.asset["multisignature"]["keysgroup"]:
                    keysgroup.append(key[1:] if key.startswith("+") else key)
            else:
                keysgroup = self.asset["multisignature"]["keysgroup"]

            bytes_data += write_bit8(self.asset["multisignature"]["min"])
            bytes_data += write_bit8(
                len(self.asset["multisignature"]["keysgroup"]))
            bytes_data += write_bit8(self.asset["multisignature"]["lifetime"])
            bytes_data += unhexlify("".join(keysgroup).encode("utf-8"))

        elif self.type == TRANSACTION_TYPE_IPFS:
            bytes_data += write_bit8(len(self.asset["ipfs"]["dag"]) // 2)
            bytes_data += unhexlify(self.asset["ipfs"]["dag"])

        elif self.type == TRANSACTION_TYPE_TIMELOCK_TRANSFER:
            bytes_data += write_bit64(self.amount)
            bytes_data += write_bit8(self.timelock_type)
            bytes_data += write_bit64(self.timelock)
            bytes_data += b58decode_check(self.recipient_id)

        elif self.type == TRANSACTION_TYPE_MULTI_PAYMENT:
            bytes_data += write_bit32(len(self.asset["payments"]))
            for payment in self.asset["payments"]:
                bytes_data += write_bit64(payment["amount"])
                bytes_data += b58decode_check(payment["recipientId"])

        elif self.type == TRANSACTION_TYPE_DELEGATE_RESIGNATION:
            pass
        else:
            raise Exception(
                "Transaction type is invalid")  # TODO: better exception
        return bytes_data