Exemplo n.º 1
0
 def gen_packet(cls, command, payload):
     version = utils.int2bytes(0x0209)
     command = utils.gen_command_bytes_array(command)
     length = utils.int2bytes(len(payload))
     packet_uuid = uuid.uuid4().bytes
     checksum = hashlib.sha256(payload).digest()[:8]
     return cls(version, command, length, packet_uuid, checksum, payload)
Exemplo n.º 2
0
 def test_int2bytes(self):
     self.assertEqual(utils.int2bytes(0x12345678), '78563412'.decode('hex'),
                      'test int2bytes fail')
     self.assertEqual(utils.int2bytes(0xabcdef12), '12efcdab'.decode('hex'),
                      'test int2bytes fail')
     self.assertEqual(utils.int2bytes(0x0209), '09020000'.decode('hex'),
                      'test int2bytes fail')
Exemplo n.º 3
0
 def test_to_bytes(self):
     self.assertEqual(
         self.post_packet.to_bytes(), ''.join([
             utils.int2bytes(0x0209),
             utils.gen_command_bytes_array('POST'),
             utils.int2bytes(2), self.post_packet.uuid,
             hashlib.sha256('{}').digest()[:8], '{}'
         ]))
     self.assertEqual(
         self.getdata_packet.to_bytes(), ''.join([
             utils.int2bytes(0x0209),
             utils.gen_command_bytes_array('GETDATA'),
             utils.int2bytes(2), self.getdata_packet.uuid,
             hashlib.sha256('{}').digest()[:8], '{}'
         ]))
     self.assertEqual(
         self.data_packet.to_bytes(), ''.join([
             utils.int2bytes(0x0209),
             utils.gen_command_bytes_array('DATA'),
             utils.int2bytes(2), self.data_packet.uuid,
             hashlib.sha256('{}').digest()[:8], '{}'
         ]))
     self.assertEqual(
         self.ack_packet.to_bytes(), ''.join([
             utils.int2bytes(0x0209),
             utils.gen_command_bytes_array('ACK'),
             utils.int2bytes(2), self.ack_packet.uuid,
             hashlib.sha256('{}').digest()[:8], '{}'
         ]))
Exemplo n.º 4
0
    def add_fees(self, output=0, amount=None):
        """ Adds the chosen fees to the chosen output of the transaction.
       :param self: self
       :type self: TX
       :param output: The output where the fees will be charged. The first input will be chosen by default (output=0).
       :type output: int
       :param amount: The amount of fees to be charged. The minimum fees wil be charged by default (amount=None).
       :type amount: int.
       :return: The maximum size of the transaction.
       :rtype: int
       """

        # Minimum fees will be applied
        if amount is None:
            fees = self.get_p2pkh_tx_max_len() * RECOMMENDED_MIN_TX_FEE

        else:
            fees = amount

        # Get the bitcoin amount from the chosen output, cast it into integer and subtract the fees.
        amount = int(change_endianness(self.value[output]), 16) - fees
        # Fill all the missing bytes up to the value length(8 bytes) and get the value back to its LE representation.
        self.value[output] = change_endianness(int2bytes(amount, 8))
        # Update the hex representation of the transaction
        self.to_hex()
Exemplo n.º 5
0
 def test_to_bytes(self):
     self.assertEqual(self.post_packet.to_bytes(), ''.join(
         [utils.int2bytes(0x0209), utils.gen_command_bytes_array('POST'), utils.int2bytes(2), self.post_packet.uuid,
          hashlib.sha256('{}').digest()[:8], '{}']))
     self.assertEqual(self.getdata_packet.to_bytes(), ''.join(
         [utils.int2bytes(0x0209), utils.gen_command_bytes_array('GETDATA'), utils.int2bytes(2),
          self.getdata_packet.uuid, hashlib.sha256('{}').digest()[:8], '{}']))
     self.assertEqual(self.data_packet.to_bytes(), ''.join(
         [utils.int2bytes(0x0209), utils.gen_command_bytes_array('DATA'), utils.int2bytes(2), self.data_packet.uuid,
          hashlib.sha256('{}').digest()[:8], '{}']))
     self.assertEqual(self.ack_packet.to_bytes(), ''.join(
         [utils.int2bytes(0x0209), utils.gen_command_bytes_array('ACK'), utils.int2bytes(2), self.ack_packet.uuid,
          hashlib.sha256('{}').digest()[:8], '{}']))
Exemplo n.º 6
0
    def build_p2pkh_std_tx(self,
                           prev_tx_id,
                           prev_out_index,
                           value,
                           scriptPubKey,
                           scriptSig=None,
                           fees=None):
        """ Builds a standard P2PKH transaction using default parameters such as version = 01000000 or
        nSequence = FFFFFFFF.

        :param self: self
        :type self: TX
        :param prev_tx_id: List of references to the previous transactions from where the current transaction will
        redeem some bitcoins.
        :type prev_tx_id: str list
        :param prev_out_index: List of references transaction output from where the funds will be redeemed.
        :type prev_out_index: int list
        :param value: List of value to be transferred to the desired destinations, in Satoshis (The difference between
        the total input value and the total output value will be charged as fee).
        :type value: int list
        :param scriptPubKey: List of scripts that will lock the outputs of the current transaction.
        :type scriptPubKey: hex str list
        :param scriptSig: List of scripts that will provide proof of fulfillment of the redeem conditions from the
        previous transactions (referenced by the prev_tx_id and prev_out_index).
        :type scriptSig: hex str list
        :return: None.
        :rtype: None
        """

        # 4-byte version number (default: 01 little endian).
        self.version = "01000000"

        #############
        #   INPUTS  #
        #############

        # Number of inputs (varint, between 1-9 bytes long).
        n_inputs = len(prev_tx_id)
        self.inputs = encode_varint(n_inputs)  # e.g "01"

        # Reference to the UTXO to redeem.

        # 32-byte hash of the previous transaction (little endian).
        for i in range(n_inputs):
            self.prev_tx_id.append(change_endianness(prev_tx_id[i]))
            # e.g "c7495bd4c5102d7e40c231279eaf9877e825364847ddebc34911f5a0f0d79ea5"

            # 4-byte output index (little endian).
            self.prev_out_index.append(
                change_endianness(int2bytes(prev_out_index[i],
                                            4)))  # e.g "00000000"

        # ScriptSig

        # The order in the tx is: scriptSig_len, scriptSig.
        # Temporary filled with "0" "0" for standard script transactions (Signature)

        for i in range(n_inputs):
            if scriptSig is None:
                self.scriptSig_len.append(
                    "0"
                )  # Input script length (varint, between 1-9 bytes long)
                self.scriptSig.append("0")

            else:
                self.scriptSig_len.append(int2bytes(len(scriptSig[i]) / 2, 1))

            # 4-byte sequence number (default:ffffffff).

            self.nSequence.append("ffffffff")

        #############
        #  OUTPUTS  #
        #############

        # Number of outputs (varint, between 1-9 bytes long).
        n_outputs = len(scriptPubKey)
        self.outputs = encode_varint(n_outputs)  # e.g "01"

        # 8-byte field (64 bit integer) representing the amount of Satoshis to be spent (little endian).
        # 0.00349815 (UTXO value) - 0.00005000 (fee) =  0.00344815 BTC = 344815 (Satoshi) = ef4250 (Little endian)

        for i in range(n_outputs):
            self.value.append(change_endianness(int2bytes(
                value[i], 8)))  # e.g "ef42050000000000"

            # Output script and its length (varint, between 1-9 bytes long)

            self.scriptPubKey_len.append(
                encode_varint(len(scriptPubKey[i]) / 2))  # e.g "06"
            self.scriptPubKey = scriptPubKey  # e.g "010301029488"

        # 4-byte lock time field (default: 0)

        self.nLockTime = "00000000"

        self.to_hex()

        # ToDO: Define a proper way of selecting the fees

        self.add_fees()
Exemplo n.º 7
0
 def test_int2bytes(self):
     self.assertEqual(utils.int2bytes(0x12345678), '78563412'.decode('hex'), 'test int2bytes fail')
     self.assertEqual(utils.int2bytes(0xabcdef12), '12efcdab'.decode('hex'), 'test int2bytes fail')
     self.assertEqual(utils.int2bytes(0x0209), '09020000'.decode('hex'), 'test int2bytes fail')