Exemplo n.º 1
0
    def getTrustedInput(self, transaction, index):
        result = {}
        # Header
        apdu = [self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x00, 0x00]
        params = bytearray.fromhex("%.8x" % (index))
        params.extend(transaction.version)
        writeVarint(len(transaction.inputs), params)
        apdu.append(len(params))
        apdu.extend(params)
        self.dongle.exchange(bytearray(apdu))
        # Each input
        for trinput in transaction.inputs:
            apdu = [
                self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00
            ]
            params = bytearray(trinput.prevOut)
            writeVarint(len(trinput.script), params)
            apdu.append(len(params))
            apdu.extend(params)
            self.dongle.exchange(bytearray(apdu))
            offset = 0
            while True:
                blockLength = 251
                if ((offset + blockLength) < len(trinput.script)):
                    dataLength = blockLength
                else:
                    dataLength = len(trinput.script) - offset
                params = bytearray(trinput.script[offset:offset + dataLength])
                if ((offset + dataLength) == len(trinput.script)):
                    params.extend(trinput.sequence)
                apdu = [
                    self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80,
                    0x00,
                    len(params)
                ]
                apdu.extend(params)
                self.dongle.exchange(bytearray(apdu))
                offset += dataLength
                if (offset >= len(trinput.script)):
                    break
        # Number of outputs
        apdu = [self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00]
        params = []
        writeVarint(len(transaction.outputs), params)
        apdu.append(len(params))
        apdu.extend(params)
        self.dongle.exchange(bytearray(apdu))
        # Each output
        indexOutput = 0
        for troutput in transaction.outputs:
            apdu = [
                self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00
            ]
            params = bytearray(troutput.amount)
            writeVarint(len(troutput.script), params)
            apdu.append(len(params))
            apdu.extend(params)
            self.dongle.exchange(bytearray(apdu))
            offset = 0
            while (offset < len(troutput.script)):
                blockLength = 255
                if ((offset + blockLength) < len(troutput.script)):
                    dataLength = blockLength
                else:
                    dataLength = len(troutput.script) - offset
                apdu = [
                    self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80,
                    0x00, dataLength
                ]
                apdu.extend(troutput.script[offset:offset + dataLength])
                self.dongle.exchange(bytearray(apdu))
                offset += dataLength

        params = []
        if transaction.extra_data:
            # PACGlobal DIP2 extra data: By appending data to the 'lockTime' transfer we force the device into the
            # BTCHIP_TRANSACTION_PROCESS_EXTRA mode, which gives us the opportunity to sneak with an additional
            # data block.
            if len(transaction.extra_data) > 255 - len(transaction.lockTime):
                # for now the size should be sufficient
                raise Exception(
                    'The size of the DIP2 extra data block has exceeded the limit.'
                )

            writeVarint(len(transaction.extra_data), params)
            params.extend(transaction.extra_data)

        apdu = [
            self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00,
            len(transaction.lockTime) + len(params)
        ]
        # Locktime
        apdu.extend(transaction.lockTime)
        apdu.extend(params)
        response = self.dongle.exchange(bytearray(apdu))
        result['trustedInput'] = True
        result['value'] = response
        return result
Exemplo n.º 2
0
    def getTrustedInput(self, atomic_boolean: AtomicBoolean,
                        ui_tracker: ParsingTracker, transaction, index):
        result = {}
        # Header
        apdu = [
            btchip.BTCHIP_CLA, btchip.BTCHIP_INS_GET_TRUSTED_INPUT, 0x00, 0x00
        ]
        params = bytearray.fromhex("%.8x" % index)
        params.extend(transaction.version)
        writeVarint(len(transaction.inputs), params)
        apdu.append(len(params))
        apdu.extend(params)
        self.dongle.exchange(bytearray(apdu))
        # Each input

        ui_tracker.set_io_amt(len(transaction.inputs),
                              len(transaction.outputs))

        for trinput in transaction.inputs:
            if atomic_boolean.get_value():
                raise UserWarning()
            apdu = [
                btchip.BTCHIP_CLA, btchip.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80,
                0x00
            ]
            params = bytearray(trinput.prevOut)
            writeVarint(len(trinput.script), params)
            apdu.append(len(params))
            apdu.extend(params)
            self.dongle.exchange(bytearray(apdu))
            offset = 0
            while True:
                blockLength = 251
                if ((offset + blockLength) < len(trinput.script)):
                    dataLength = blockLength
                else:
                    dataLength = len(trinput.script) - offset
                params = bytearray(trinput.script[offset:offset + dataLength])
                if ((offset + dataLength) == len(trinput.script)):
                    params.extend(trinput.sequence)
                apdu = [
                    btchip.BTCHIP_CLA, btchip.BTCHIP_INS_GET_TRUSTED_INPUT,
                    0x80, 0x00,
                    len(params)
                ]
                apdu.extend(params)
                self.dongle.exchange(bytearray(apdu))
                offset += dataLength
                if (offset >= len(trinput.script)):
                    break

            ui_tracker.tick_in()

        # Number of outputs
        apdu = [
            btchip.BTCHIP_CLA, btchip.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00
        ]
        params = []
        writeVarint(len(transaction.outputs), params)
        apdu.append(len(params))
        apdu.extend(params)
        self.dongle.exchange(bytearray(apdu))
        # Each output
        indexOutput = 0
        for troutput in transaction.outputs:
            if atomic_boolean.get_value():
                raise UserWarning()
            apdu = [
                btchip.BTCHIP_CLA, btchip.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80,
                0x00
            ]
            params = bytearray(troutput.amount)
            writeVarint(len(troutput.script), params)
            apdu.append(len(params))
            apdu.extend(params)
            self.dongle.exchange(bytearray(apdu))
            offset = 0
            while (offset < len(troutput.script)):
                blockLength = 255
                if ((offset + blockLength) < len(troutput.script)):
                    dataLength = blockLength
                else:
                    dataLength = len(troutput.script) - offset
                apdu = [
                    btchip.BTCHIP_CLA, btchip.BTCHIP_INS_GET_TRUSTED_INPUT,
                    0x80, 0x00, dataLength
                ]
                apdu.extend(troutput.script[offset:offset + dataLength])
                self.dongle.exchange(bytearray(apdu))
                offset += dataLength

            ui_tracker.tick_out()

        # Locktime
        apdu = [
            btchip.BTCHIP_CLA, btchip.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00,
            len(transaction.lockTime)
        ]
        apdu.extend(transaction.lockTime)
        response = self.dongle.exchange(bytearray(apdu))
        result['trustedInput'] = True
        result['value'] = response
        return result
Exemplo n.º 3
0
 def startUntrustedTransaction(self, newTransaction, inputIndex, outputList, redeemScript, version: bytearray, cashAddr=False, continueSegwit=False):
     # Start building a fake transaction with the passed inputs
     segwit = False
     if newTransaction:
         for passedOutput in outputList:
             if ('witness' in passedOutput) and passedOutput['witness']:
                 segwit = True
                 break
     if newTransaction:
         if segwit:
             p2 = 0x03 if cashAddr else 0x02
         else:
             p2 = 0x00
     else:
             p2 = 0x10 if continueSegwit else 0x80
     apdu = [ self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_START, 0x00, p2 ]
     params = bytearray.fromhex(version) # important to use the combined tx version + tx type field
     writeVarint(len(outputList), params)
     apdu.append(len(params))
     apdu.extend(params)
     self.dongle.exchange(bytearray(apdu))
     # Loop for each input
     currentIndex = 0
     for passedOutput in outputList:
         if ('sequence' in passedOutput) and passedOutput['sequence']:
             sequence = bytearray(unhexlify(passedOutput['sequence']))
         else:
             sequence = bytearray([0xFF, 0xFF, 0xFF, 0xFF]) # default sequence
         apdu = [ self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_START, 0x80, 0x00 ]
         params = []
         script = bytearray(redeemScript)
         if ('trustedInput' in passedOutput) and passedOutput['trustedInput']:
             params.append(0x01)
         elif ('witness' in passedOutput) and passedOutput['witness']:
             params.append(0x02)
         else:
             params.append(0x00)
         if ('trustedInput' in passedOutput) and passedOutput['trustedInput']:
             params.append(len(passedOutput['value']))
         params.extend(passedOutput['value'])
         if currentIndex != inputIndex:
             script = bytearray()
         writeVarint(len(script), params)
         apdu.append(len(params))
         apdu.extend(params)
         self.dongle.exchange(bytearray(apdu))
         offset = 0
         while(offset < len(script)):
             blockLength = 255
             if ((offset + blockLength) < len(script)):
                 dataLength = blockLength
             else:
                 dataLength = len(script) - offset
             params = script[offset : offset + dataLength]
             if ((offset + dataLength) == len(script)):
                 params.extend(sequence)
             apdu = [ self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_START, 0x80, 0x00, len(params) ]
             apdu.extend(params)
             self.dongle.exchange(bytearray(apdu))
             offset += blockLength
         if len(script) == 0:
             apdu = [ self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_START, 0x80, 0x00, len(sequence) ]
             apdu.extend(sequence)
             self.dongle.exchange(bytearray(apdu))
         currentIndex += 1
 def startUntrustedTransaction(self,
                               newTransaction,
                               inputIndex,
                               outputList,
                               redeemScript,
                               version=0x02,
                               overwintered=False):
     # Start building a fake transaction with the passed inputs
     if newTransaction:
         if overwintered:
             p2 = 0x05 if version == 4 else 0x04
         else:
             p2 = 0x00
     else:
         p2 = 0x80
     apdu = [self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_START, 0x00, p2]
     if overwintered and version == 3:
         params = bytearray(
             [version, 0x00, 0x00, 0x80, 0x70, 0x82, 0xc4, 0x03])
     elif overwintered and version == 4:
         params = bytearray(
             [version, 0x00, 0x00, 0x80, 0x85, 0x20, 0x2f, 0x89])
     else:
         params = bytearray([version, 0x00, 0x00, 0x00])
     writeVarint(len(outputList), params)
     apdu.append(len(params))
     apdu.extend(params)
     self.dongle.exchange(bytearray(apdu))
     # Loop for each input
     currentIndex = 0
     for passedOutput in outputList:
         if ('sequence' in passedOutput) and passedOutput['sequence']:
             sequence = bytearray(unhexlify(passedOutput['sequence']))
         else:
             sequence = bytearray([0xFF, 0xFF, 0xFF,
                                   0xFF])  # default sequence
         apdu = [
             self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_START, 0x80, 0x00
         ]
         params = []
         script = bytearray(redeemScript)
         if overwintered:
             params.append(0x02)
         elif ('trustedInput'
               in passedOutput) and passedOutput['trustedInput']:
             params.append(0x01)
         else:
             params.append(0x00)
         if ('trustedInput'
                 in passedOutput) and passedOutput['trustedInput']:
             params.append(len(passedOutput['value']))
         params.extend(passedOutput['value'])
         if currentIndex != inputIndex:
             script = bytearray()
         writeVarint(len(script), params)
         if len(script) == 0:
             params.extend(sequence)
         apdu.append(len(params))
         apdu.extend(params)
         self.dongle.exchange(bytearray(apdu))
         offset = 0
         while (offset < len(script)):
             blockLength = 255
             if ((offset + blockLength) < len(script)):
                 dataLength = blockLength
             else:
                 dataLength = len(script) - offset
             params = script[offset:offset + dataLength]
             if ((offset + dataLength) == len(script)):
                 params.extend(sequence)
             apdu = [
                 self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_START, 0x80,
                 0x00,
                 len(params)
             ]
             apdu.extend(params)
             self.dongle.exchange(bytearray(apdu))
             offset += blockLength
         currentIndex += 1
 def serializeOutputs(self):
     result = []
     writeVarint(len(self.outputs), result)
     for troutput in self.outputs:
         result.extend(troutput.serialize())
     return result
Exemplo n.º 6
0
    def getTrustedInput(self, transaction, index):
        result = {}
        # Header
        apdu = [self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x00, 0x00]
        params = bytearray.fromhex("%.8x" % (index))
        params.extend(transaction.version)
        writeVarint(len(transaction.inputs), params)
        apdu.append(len(params))
        apdu.extend(params)
        self.dongle.exchange(bytearray(apdu))
        # Each input
        for trinput in transaction.inputs:
            apdu = [
                self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00
            ]
            params = bytearray(trinput.prevOut)
            writeVarint(len(trinput.script), params)
            apdu.append(len(params))
            apdu.extend(params)
            self.dongle.exchange(bytearray(apdu))
            offset = 0
            while True:
                blockLength = 251
                if ((offset + blockLength) < len(trinput.script)):
                    dataLength = blockLength
                else:
                    dataLength = len(trinput.script) - offset
                params = bytearray(trinput.script[offset:offset + dataLength])
                if ((offset + dataLength) == len(trinput.script)):
                    params.extend(trinput.sequence)
                apdu = [
                    self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80,
                    0x00,
                    len(params)
                ]
                apdu.extend(params)
                self.dongle.exchange(bytearray(apdu))
                offset += dataLength
                if (offset >= len(trinput.script)):
                    break
        # Number of outputs
        apdu = [self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00]
        params = []
        writeVarint(len(transaction.outputs), params)
        apdu.append(len(params))
        apdu.extend(params)
        self.dongle.exchange(bytearray(apdu))
        # Each output
        indexOutput = 0
        for troutput in transaction.outputs:
            apdu = [
                self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00
            ]
            params = bytearray(troutput.amount)
            writeVarint(len(troutput.script), params)
            apdu.append(len(params))
            apdu.extend(params)
            self.dongle.exchange(bytearray(apdu))
            offset = 0
            while (offset < len(troutput.script)):
                blockLength = 255
                if ((offset + blockLength) < len(troutput.script)):
                    dataLength = blockLength
                else:
                    dataLength = len(troutput.script) - offset
                apdu = [
                    self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80,
                    0x00, dataLength
                ]
                apdu.extend(troutput.script[offset:offset + dataLength])
                self.dongle.exchange(bytearray(apdu))
                offset += dataLength

        params = []
        apdu = [
            self.BTCHIP_CLA, self.BTCHIP_INS_GET_TRUSTED_INPUT, 0x80, 0x00,
            len(transaction.lockTime) + len(params)
        ]
        # Locktime
        apdu.extend(transaction.lockTime)
        apdu.extend(params)
        response = self.dongle.exchange(bytearray(apdu))
        result['trustedInput'] = True
        result['value'] = response
        return result